public List <string> Classify(Item itemToTag, string text)
        {
            var tags = new List <string>();

            if (string.IsNullOrWhiteSpace(text))
            {
                return(tags);
            }

            //get all the tags
            var tagItems = ContentSearchService.GetTagsByTemplate(TaxonomyFolderId, InnerItem.Language.Name, InnerItem.Database.Name, TaxonomyItemTemplateIds);

            //loop through and pull out the rules
            foreach (var t in tagItems)
            {
                var rulesField = t.GetItem().Fields[Settings.RulesFieldId];
                if (rulesField == null)
                {
                    continue;
                }

                var rules = RuleFactory.GetRules <RuleContext>(rulesField);

                //run rule against the content
                var ruleContext = new RuleContext {
                    Item = itemToTag
                };
                if (EvaluateRules(rules, ruleContext))
                {
                    tags.Add(t.Name);
                }
            }

            return(tags);
        }
        public Tuple <bool, string> GetTrainingData()
        {
            //get tags from taxonomy mapping folder field
            var tagItems     = ContentSearchService.GetTagsByTemplate(TaxonomyFolderId, LanguageCode, InnerItem.Database.Name, TaxonomyItemTemplateIds);
            var results      = new Dictionary <Guid, string>();
            var trainingData = new List <string>();

            foreach (var tag in tagItems)
            {
                var contentTypes = ContentMappings
                                   .Select(a => a.TemplateField.Guid).ToDictionary(a => a);

                //show on images that have no face item pointing to them
                var links        = Globals.LinkDatabase.GetItemReferrers(tag.GetItem(), false);
                var contentItems = links
                                   .Select(a => a.GetSourceItem())
                                   .Where(a => contentTypes.ContainsKey(a.TemplateID.Guid))
                                   .Take(ItemTrainingCount)
                                   .ToList();

                //todo: if there aren't enough content items for any given tag, we could log that and mention it as an issue for training
                foreach (var c in contentItems)
                {
                    //dedupe
                    if (results.ContainsKey(c.ID.Guid))
                    {
                        continue;
                    }

                    results.Add(c.ID.Guid, string.Empty);

                    //pull content for the items
                    var contentMap  = ContentMappings.First(a => a.TemplateField.Guid == c.TemplateID.Guid);
                    var trainingRow = ContentService.GetTrainingData(c, SourceTagsFieldId, contentMap.ContentFields);
                    if (string.IsNullOrWhiteSpace(trainingRow))
                    {
                        continue;
                    }

                    trainingData.Add(trainingRow);
                }
            }

            if (trainingData.Count == 0)
            {
                return(Tuple.Create(false, "There was no training data"));
            }

            var trainingDataString = string.Join(Environment.NewLine, trainingData);

            DataWrapper.UpdateFields(InnerItem, new Dictionary <ID, string>
            {
                { Settings.TrainingDataFieldId, trainingDataString }
            });

            //var range = ItemTrainingCount * tagItems.Count;
            //if (trainingData.Count < range)
            //    return Tuple.Create(false, $"There's only {trainingData.Count} of the required {range} items. {ItemTrainingCount} items per tag (change in settings).");

            return(Tuple.Create(true, trainingDataString));
        }