Esempio n. 1
0
        public async Task <TranslatedSearchResult <ICard> > FindCard(SearchParameters parameters)
        {
            string  sTerm = parameters.SearchTerm;
            Locale  sLoc  = parameters.SearchLocale;
            Locale? tLoc  = parameters.TranslationLocale;
            Version ver   = parameters.Version;

            Catalog sCat = await CatalogService.GetCatalog(sLoc, ver);

            Catalog?tCat = tLoc is null ? null : await CatalogService.GetCatalog(tLoc, ver);

            if (TryFindCardFromCode(sTerm, tCat ?? sCat, out TranslatedSearchResult <ICard>?codeResult))
            {
                return(codeResult !);
            }

            var cardSearcher = new CatalogItemSearcher <ICard>
                               (
                sCat,
                new CardNameGrouper()
                               )
            {
                TermTargetCanonicalizer = new TrimmedAndLowerCanonicalizer(),
                TermMatcherFactory      = new LevenshteinSubstringMatcher.Factory(GreengladeSettings.SubstringBookendWeight, GreengladeSettings.SubstringBookendTaper),
                KeyStrengthThreshold    = GreengladeSettings.StringMatchThreshold,
                KeyConflictResolution   = KeyConflictResolution.Flattened,
                MatchGroupResolver      = new BasicCardGroupResolver(),
                ItemStrengthDownscalers = new[] { new UncollectibleCardStrengthDownscaler(GreengladeSettings.UncollectibleCardDownscaleFactor) },
                ItemDownscaleCurve      = ItemDownscaleCurve.Biased,
                ItemMatchSorter         = new DescendingMatchStrengthSorter <ICard>(),
            };

            SearchResult <ICard> result = cardSearcher.Search(sTerm);

            if (tCat is null)
            {
                return(TranslatedSearchResult <ICard> .FromUntranslatedSearch(result));
            }

            var tMap = new Dictionary <ICard, ICard>();

            foreach (var match in result.Matches)
            {
                ICard sItem = match.Item;
                if (tCat.Cards.TryGetValue(sItem.Code, out var tItem))
                {
                    tMap.Add(sItem, tItem);
                }
                else
                {
                    LogCouldNotTranslateWarning(sItem, sLoc, tCat.Locale, ver);
                }
            }

            return(TranslatedSearchResult <ICard> .FromTranslatedSearch(result, tCat.Locale, tMap));
        }
Esempio n. 2
0
 public async Task <TranslatedSearchResult <CatalogItemUnion> > FindAnything(SearchParameters parameters)
 {
     return(TranslatedSearchResult <CatalogItemUnion> .MergeSearchResults
            (
                await FindCard(parameters),
                await FindKeyword(parameters),
                await FindDeck(parameters),
                new DescendingMatchStrengthSorter <CatalogItemUnion>()
            ));
 }
Esempio n. 3
0
        public async Task <TranslatedSearchResult <LorKeyword> > FindKeyword(SearchParameters parameters)
        {
            string  sTerm = parameters.SearchTerm;
            Locale  sLoc  = parameters.SearchLocale;
            Locale? tLoc  = parameters.TranslationLocale;
            Version ver   = parameters.Version;

            Catalog sCat = await CatalogService.GetCatalog(sLoc, ver);

            Catalog?tCat = tLoc is null ? null : await CatalogService.GetCatalog(tLoc, ver);

            var keywordSearcher = new CatalogItemSearcher <LorKeyword>
                                  (
                sCat,
                new KeywordNameGrouper {
                IncludeVocabTerms = true, IncludeDescriptionlessKeywords = false
            }
                                  )
            {
                TermTargetCanonicalizer = new TrimmedAndLowerCanonicalizer(),
                TermMatcherFactory      = new LevenshteinSubstringMatcher.Factory(GreengladeSettings.SubstringBookendWeight, GreengladeSettings.SubstringBookendTaper),
                KeyStrengthThreshold    = GreengladeSettings.StringMatchThreshold,
                ItemMatchSorter         = new DescendingMatchStrengthSorter <LorKeyword>(),
            };

            SearchResult <LorKeyword> result = keywordSearcher.Search(sTerm);

            if (tCat is null)
            {
                return(TranslatedSearchResult <LorKeyword> .FromUntranslatedSearch(result));
            }

            var tMap = new Dictionary <LorKeyword, LorKeyword>();

            foreach (var match in result.Matches)
            {
                LorKeyword sItem = match.Item;
                if (tCat.Keywords.TryGetValue(sItem.Key, out var tItem))
                {
                    tMap.Add(sItem, tItem);
                }
                else if (tCat.VocabTerms.TryGetValue(sItem.Key, out var vtItem))
                {
                    tItem = new LorKeyword(sItem.Key, vtItem.Name, vtItem.Description);
                    tMap.Add(sItem, tItem);
                }
                else
                {
                    LogCouldNotTranslateWarning(sItem, sLoc, tCat.Locale, ver);
                }
            }

            return(TranslatedSearchResult <LorKeyword> .FromTranslatedSearch(result, tCat.Locale, tMap));
        }
Esempio n. 4
0
        private static bool TryFindDeckFromCode(string term, Catalog catalog, out TranslatedSearchResult <Deck>?result)
        {
            if (Deck.TryFromCode(term, catalog, out Deck? deck))
            {
                var usr = SearchResult <Deck> .FromSingleItem(term, catalog.Locale, catalog.Version, deck !);

                result = TranslatedSearchResult <Deck> .FromUntranslatedSearch(usr);

                return(true);
            }
            else
            {
                result = null;
                return(false);
            }
        }
Esempio n. 5
0
        private static bool TryFindCardFromCode(string term, Catalog catalog, out TranslatedSearchResult <ICard>?result)
        {
            if (catalog.Cards.TryGetValue(term, out ICard? card))
            {
                var usr = SearchResult <ICard> .FromSingleItem(term, catalog.Locale, catalog.Version, card);

                result = TranslatedSearchResult <ICard> .FromUntranslatedSearch(usr);

                return(true);
            }
            else
            {
                result = null;
                return(false);
            }
        }
Esempio n. 6
0
        public async Task <TranslatedSearchResult <Deck> > FindDeck(SearchParameters parameters)
        {
            string  term = parameters.SearchTerm;
            Locale  loc  = parameters.TranslationLocale ?? parameters.SearchLocale;
            Version ver  = parameters.Version;
            Catalog cat  = await CatalogService.GetCatalog(loc, ver);

            if (TryFindDeckFromCode(term, cat, out TranslatedSearchResult <Deck>?result))
            {
                return(result !);
            }
            else
            {
                return(TranslatedSearchResult <Deck> .FromUntranslatedSearch(new SearchResult <Deck>(term, loc, ver)));
            }
        }
Esempio n. 7
0
        public async Task <MessageView> BuildView(TranslatedSearchResult <T> item)
        {
            IReadOnlyList <ItemMatch <T> > matches = item.Matches;

            if (matches.Count == 0)
            {
                return(new MessageView($"No results found."));
            }

            string?didYouMean = null;

            if (matches.Count > 1)
            {
                IEnumerable <string?> names = matches.Skip(1).Select(m => $"**{GetItemName(m.Item)}**");
                string namesOutput          = string.Join(" | ", names);
                didYouMean = $"Did you mean: {namesOutput}";
                if (didYouMean.Length > 2048)
                {
                    string s = matches.Count == 2 ? "" : "s";
                    didYouMean = $"*{matches.Count - 1} other result{s}*";
                }
            }

            T uItem = matches[0].Item;

            item.TranslationMap.TryGetValue(uItem, out T? tItem);
            IEnumerable <T> expansion = await ExpandItem(tItem ?? uItem);

            MessageView[] views = await Task.WhenAll(expansion.Select(BuildItemView));

            var messages = new List <MessageInfo>();

            if (didYouMean is null)
            {
                // Just render all item views
                foreach (MessageView view in views)
                {
                    messages.AddRange(view.Messages);
                }
            }
            else if (views.Length == 1 && views[0].Messages.Count == 1)
            {
                // Send the text reply in the same message as the single item message if possible
                MessageInfo itemMessage = views[0].Messages[0];
                if (itemMessage.Text is null)
                {
                    messages.Add(new MessageInfo {
                        Text = didYouMean, Embed = itemMessage.Embed
                    });
                }
                else
                {
                    messages.Add(didYouMean);
                    messages.Add(itemMessage);
                }
            }
            else
            {
                // Send the text reply separately from the multiple item messages
                messages.Add(didYouMean);
                foreach (MessageView view in views)
                {
                    messages.AddRange(view.Messages);
                }
            }

            return(new MessageView(messages));
        }