diff options
| author | 2020-03-08 11:40:32 +0700 | |
|---|---|---|
| committer | 2020-03-08 11:40:32 +0700 | |
| commit | 2e81f05c078bfcff837db1786d535a8cc767ec0f (patch) | |
| tree | 29bb9ffca7e59a930a35308a1245b5bbaab7c71d | |
| parent | Merge pull request #820 from python-discord/feat/ci/pre-commit-tweaks (diff) | |
Implemented `search` as a subcommand for `tag` that will search in contents instead of names
- `!tag search` will search for multiple keywords, separated by comma, and return tags that has ALL of these keywords.
` !tag search any` is the same as `!tag search` but it return tags that has ANY of the keyword instead.
| -rw-r--r-- | bot/cogs/tags.py | 51 | 
1 files changed, 50 insertions, 1 deletions
diff --git a/bot/cogs/tags.py b/bot/cogs/tags.py index 5da9a4148..965a29596 100644 --- a/bot/cogs/tags.py +++ b/bot/cogs/tags.py @@ -1,7 +1,7 @@  import logging  import re  import time -from typing import Dict, List, Optional +from typing import Dict, List, Optional, Tuple  from discord import Colour, Embed  from discord.ext.commands import Cog, Context, group @@ -86,11 +86,60 @@ class Tags(Cog):              return self._get_suggestions(tag_name)          return found +    async def _get_tags_via_content(self, check: callable, keywords: str) -> Optional[Embed]: +        """ +        Search for tags via contents. + +        `predicate` will be either any or all, or a custom callable to search. Must return a bool. +        """ +        await self._get_tags() + +        keywords_processed: Tuple[str] = tuple(query.strip().casefold() for query in keywords.split(',')) +        founds: list = [ +            tag +            for tag in self._cache.values() +            if check(query in tag['embed']['description'] for query in keywords_processed) +        ] + +        if not founds: +            return None +        elif len(founds) == 1: +            return Embed().from_dict(founds[0]['embed']) +        else: +            return Embed( +                title='Did you mean ...', +                description='\n'.join(tag['title'] for tag in founds[:10]) +            ) +      @group(name='tags', aliases=('tag', 't'), invoke_without_command=True)      async def tags_group(self, ctx: Context, *, tag_name: TagNameConverter = None) -> None:          """Show all known tags, a single tag, or run a subcommand."""          await ctx.invoke(self.get_command, tag_name=tag_name) +    @tags_group.group(name='search', invoke_without_command=True) +    async def search_tag_content(self, ctx: Context, *, keywords: str) -> None: +        """ +        Search inside tags' contents for tags. Allow searching for multiple keywords separated by comma. + +        Only search for tags that has ALL the keywords. +        """ +        result = await self._get_tags_via_content(all, keywords) +        if not result: +            return +        await ctx.send(embed=result) + +    @search_tag_content.command(name='any') +    async def search_tag_content_any_keyword(self, ctx: Context, *, keywords: Optional[str] = None) -> None: +        """ +        Search inside tags' contents for tags. Allow searching for multiple keywords separated by comma. + +        Search for tags that has ANY of the keywords. +        """ +        result = await self._get_tags_via_content(any, keywords or 'any') +        if not result: +            return +        await ctx.send(embed=result) +      @tags_group.command(name='get', aliases=('show', 'g'))      async def get_command(self, ctx: Context, *, tag_name: TagNameConverter = None) -> None:          """Get a specified tag, or a list of all tags if no tag is specified."""  |