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.""" |