aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Shirayuki Nekomata <[email protected]>2020-03-08 11:40:32 +0700
committerGravatar Shirayuki Nekomata <[email protected]>2020-03-08 11:40:32 +0700
commit2e81f05c078bfcff837db1786d535a8cc767ec0f (patch)
tree29bb9ffca7e59a930a35308a1245b5bbaab7c71d
parentMerge 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.py51
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."""