diff options
-rw-r--r-- | Dockerfile | 2 | ||||
-rw-r--r-- | Pipfile | 2 | ||||
-rw-r--r-- | Pipfile.lock | 75 | ||||
-rw-r--r-- | bot/__init__.py | 2 | ||||
-rw-r--r-- | bot/constants.py | 3 | ||||
-rw-r--r-- | bot/exts/evergreen/fun.py | 8 | ||||
-rw-r--r-- | bot/exts/evergreen/wikipedia.py | 114 |
7 files changed, 164 insertions, 42 deletions
@@ -9,7 +9,7 @@ ENV PIP_NO_CACHE_DIR=false \ # Install git to be able to dowload git dependencies in the Pipfile RUN apt-get -y update \ && apt-get install -y \ - git \ + ffmpeg \ && rm -rf /var/lib/apt/lists/* # Install pipenv @@ -7,12 +7,12 @@ name = "pypi" aiodns = "~=2.0" arrow = "~=0.14" beautifulsoup4 = "~=4.8" -discord-py = {git = "https://github.com/Rapptz/discord.py.git",ref = "0bc15fa130b8f01fe2d67446a2184d474b0d0ba7"} fuzzywuzzy = "~=0.17" pillow = "~=7.2" pytz = "~=2019.2" sentry-sdk = "~=0.14.2" PyYAML = "~=5.3.1" +"discord.py" = {extras = ["voice"], version = "~=1.4.1"} [dev-packages] flake8 = "~=3.8" diff --git a/Pipfile.lock b/Pipfile.lock index 3a0f783f..6e6a3c2e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "adb128691a19bd4e99d1456a2ec374aa4c0968b385cc5046e1ad98bfa64cf978" + "sha256": "1077d14c4a0456f57062e91e403a107d6321a385ea2bc2e8c833e0b6c22801e4" }, "pipfile-spec": 6, "requires": { @@ -130,9 +130,16 @@ ], "version": "==3.0.4" }, - "discord-py": { - "git": "https://github.com/Rapptz/discord.py.git", - "ref": "0bc15fa130b8f01fe2d67446a2184d474b0d0ba7" + "discord.py": { + "extras": [ + "voice" + ], + "hashes": [ + "sha256:98ea3096a3585c9c379209926f530808f5fcf4930928d8cfb579d2562d119570", + "sha256:f9decb3bfa94613d922376288617e6a6f969260923643e2897f4540c34793442" + ], + "index": "pypi", + "version": "==1.4.1" }, "fuzzywuzzy": { "hashes": [ @@ -249,12 +256,38 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.20" }, + "pynacl": { + "hashes": [ + "sha256:05c26f93964373fc0abe332676cb6735f0ecad27711035b9472751faa8521255", + "sha256:0c6100edd16fefd1557da078c7a31e7b7d7a52ce39fdca2bec29d4f7b6e7600c", + "sha256:0d0a8171a68edf51add1e73d2159c4bc19fc0718e79dec51166e940856c2f28e", + "sha256:1c780712b206317a746ace34c209b8c29dbfd841dfbc02aa27f2084dd3db77ae", + "sha256:2424c8b9f41aa65bbdbd7a64e73a7450ebb4aa9ddedc6a081e7afcc4c97f7621", + "sha256:2d23c04e8d709444220557ae48ed01f3f1086439f12dbf11976e849a4926db56", + "sha256:30f36a9c70450c7878053fa1344aca0145fd47d845270b43a7ee9192a051bf39", + "sha256:37aa336a317209f1bb099ad177fef0da45be36a2aa664507c5d72015f956c310", + "sha256:4943decfc5b905748f0756fdd99d4f9498d7064815c4cf3643820c9028b711d1", + "sha256:53126cd91356342dcae7e209f840212a58dcf1177ad52c1d938d428eebc9fee5", + "sha256:57ef38a65056e7800859e5ba9e6091053cd06e1038983016effaffe0efcd594a", + "sha256:5bd61e9b44c543016ce1f6aef48606280e45f892a928ca7068fba30021e9b786", + "sha256:6482d3017a0c0327a49dddc8bd1074cc730d45db2ccb09c3bac1f8f32d1eb61b", + "sha256:7d3ce02c0784b7cbcc771a2da6ea51f87e8716004512493a2b69016326301c3b", + "sha256:a14e499c0f5955dcc3991f785f3f8e2130ed504fa3a7f44009ff458ad6bdd17f", + "sha256:a39f54ccbcd2757d1d63b0ec00a00980c0b382c62865b61a505163943624ab20", + "sha256:aabb0c5232910a20eec8563503c153a8e78bbf5459490c49ab31f6adf3f3a415", + "sha256:bd4ecb473a96ad0f90c20acba4f0bf0df91a4e03a1f4dd6a4bdc9ca75aa3a715", + "sha256:bf459128feb543cfca16a95f8da31e2e65e4c5257d2f3dfa8c0c1031139c9c92", + "sha256:e2da3c13307eac601f3de04887624939aca8ee3c9488a0bb0eca4fb9401fc6b1", + "sha256:f67814c38162f4deb31f68d590771a29d5ae3b1bd64b75cf232308e5c74777e0" + ], + "version": "==1.3.0" + }, "python-dateutil": { "hashes": [ "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==2.8.1" }, "pytz": { @@ -295,7 +328,7 @@ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.15.0" }, "soupsieve": { @@ -314,34 +347,6 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", "version": "==1.25.10" }, - "websockets": { - "hashes": [ - "sha256:0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5", - "sha256:1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5", - "sha256:20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308", - "sha256:295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb", - "sha256:2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a", - "sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c", - "sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170", - "sha256:3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422", - "sha256:4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8", - "sha256:5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485", - "sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f", - "sha256:751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8", - "sha256:7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc", - "sha256:965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779", - "sha256:9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989", - "sha256:9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1", - "sha256:c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092", - "sha256:c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824", - "sha256:ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d", - "sha256:d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55", - "sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36", - "sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b" - ], - "markers": "python_full_version >= '3.6.1'", - "version": "==8.1" - }, "yarl": { "hashes": [ "sha256:04a54f126a0732af75e5edc9addeaa2113e2ca7c6fce8974a63549a70a25e50e", @@ -558,7 +563,7 @@ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.15.0" }, "snowballstemmer": { diff --git a/bot/__init__.py b/bot/__init__.py index 6976e089..a9a0865e 100644 --- a/bot/__init__.py +++ b/bot/__init__.py @@ -37,7 +37,7 @@ os.makedirs(log_dir, exist_ok=True) # File handler rotates logs every 5 MB file_handler = logging.handlers.RotatingFileHandler( - log_file, maxBytes=5*(2**20), backupCount=10) + log_file, maxBytes=5 * (2**20), backupCount=10) file_handler.setLevel(logging.TRACE if Client.debug else logging.DEBUG) # Console handler prints to terminal diff --git a/bot/constants.py b/bot/constants.py index fa428a61..7c8f72cb 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -262,3 +262,6 @@ POSITIVE_REPLIES = [ "Aye aye, cap'n!", "I'll allow it.", ] + +class Wikipedia: + total_chance = 3 diff --git a/bot/exts/evergreen/fun.py b/bot/exts/evergreen/fun.py index e6cdf716..de6a92c6 100644 --- a/bot/exts/evergreen/fun.py +++ b/bot/exts/evergreen/fun.py @@ -7,7 +7,7 @@ from typing import Callable, Iterable, Tuple, Union from discord import Embed, Message from discord.ext import commands -from discord.ext.commands import Bot, Cog, Context, MessageConverter +from discord.ext.commands import Bot, Cog, Context, MessageConverter, clean_content from bot import utils from bot.constants import Colours, Emojis @@ -71,7 +71,7 @@ class Fun(Cog): await ctx.send(output) @commands.command(name="uwu", aliases=("uwuwize", "uwuify",)) - async def uwu_command(self, ctx: Context, *, text: str) -> None: + async def uwu_command(self, ctx: Context, *, text: clean_content(fix_channel_mentions=True)) -> None: """Converts a given `text` into it's uwu equivalent.""" conversion_func = functools.partial( utils.replace_many, replacements=UWU_WORDS, ignore_case=True, match_case=True @@ -87,7 +87,7 @@ class Fun(Cog): await ctx.send(content=converted_text, embed=embed) @commands.command(name="randomcase", aliases=("rcase", "randomcaps", "rcaps",)) - async def randomcase_command(self, ctx: Context, *, text: str) -> None: + async def randomcase_command(self, ctx: Context, *, text: clean_content(fix_channel_mentions=True)) -> None: """Randomly converts the casing of a given `text`.""" def conversion_func(text: str) -> str: """Randomly converts the casing of a given string.""" @@ -193,7 +193,7 @@ class Fun(Cog): msg = await Fun._get_discord_message(ctx, text) # Ensure the user has read permissions for the channel the message is in if isinstance(msg, Message) and ctx.author.permissions_in(msg.channel).read_messages: - text = msg.content + text = msg.clean_content # Take first embed because we can't send multiple embeds if msg.embeds: embed = msg.embeds[0] diff --git a/bot/exts/evergreen/wikipedia.py b/bot/exts/evergreen/wikipedia.py new file mode 100644 index 00000000..be36e2c4 --- /dev/null +++ b/bot/exts/evergreen/wikipedia.py @@ -0,0 +1,114 @@ +import asyncio +import datetime +import logging +from typing import List, Optional + +from aiohttp import client_exceptions +from discord import Color, Embed, Message +from discord.ext import commands + +from bot.constants import Wikipedia + +log = logging.getLogger(__name__) + +SEARCH_API = "https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch={search_term}&format=json" +WIKIPEDIA_URL = "https://en.wikipedia.org/wiki/{title}" + + +class WikipediaSearch(commands.Cog): + """Get info from wikipedia.""" + + def __init__(self, bot: commands.Bot): + self.bot = bot + self.http_session = bot.http_session + + @staticmethod + def formatted_wiki_url(index: int, title: str) -> str: + """Formating wikipedia link with index and title.""" + return f'`{index}` [{title}]({WIKIPEDIA_URL.format(title=title.replace(" ", "_"))})' + + async def search_wikipedia(self, search_term: str) -> Optional[List[str]]: + """Search wikipedia and return the first 10 pages found.""" + pages = [] + async with self.http_session.get(SEARCH_API.format(search_term=search_term)) as response: + try: + data = await response.json() + + search_results = data["query"]["search"] + + # Ignore pages with "may refer to" + for search_result in search_results: + log.info("trying to append titles") + if "may refer to" not in search_result["snippet"]: + pages.append(search_result["title"]) + except client_exceptions.ContentTypeError: + pages = None + + log.info("Finished appending titles") + return pages + + @commands.cooldown(1, 10, commands.BucketType.user) + @commands.command(name="wikipedia", aliases=["wiki"]) + async def wikipedia_search_command(self, ctx: commands.Context, *, search: str) -> None: + """Return list of results containing your search query from wikipedia.""" + titles = await self.search_wikipedia(search) + + def check(message: Message) -> bool: + return message.author.id == ctx.author.id and message.channel == ctx.channel + + if not titles: + await ctx.send("Sorry, we could not find a wikipedia article using that search term") + return + + async with ctx.typing(): + log.info("Finished appending titles to titles_no_underscore list") + + s_desc = "\n".join(self.formatted_wiki_url(index, title) for index, title in enumerate(titles, start=1)) + embed = Embed(colour=Color.blue(), title=f"Wikipedia results for `{search}`", description=s_desc) + embed.timestamp = datetime.datetime.utcnow() + await ctx.send(embed=embed) + embed = Embed(colour=Color.green(), description="Enter number to choose") + msg = await ctx.send(embed=embed) + titles_len = len(titles) # getting length of list + + for retry_count in range(1, Wikipedia.total_chance + 1): + retries_left = Wikipedia.total_chance - retry_count + if retry_count < Wikipedia.total_chance: + error_msg = f"You have `{retries_left}/{Wikipedia.total_chance}` chances left" + else: + error_msg = 'Please try again by using `.wiki` command' + try: + message = await ctx.bot.wait_for('message', timeout=60.0, check=check) + response_from_user = await self.bot.get_context(message) + + if response_from_user.command: + return + + response = int(message.content) + if response < 0: + await ctx.send(f"Sorry, but you can't give negative index, {error_msg}") + elif response == 0: + await ctx.send(f"Sorry, please give an integer between `1` to `{titles_len}`, {error_msg}") + else: + await ctx.send(WIKIPEDIA_URL.format(title=titles[response - 1].replace(" ", "_"))) + break + + except asyncio.TimeoutError: + embed = Embed(colour=Color.red(), description=f"Time's up {ctx.author.mention}") + await msg.edit(embed=embed) + break + + except ValueError: + await ctx.send(f"Sorry, but you cannot do that, I will only accept an positive integer, {error_msg}") + + except IndexError: + await ctx.send(f"Sorry, please give an integer between `1` to `{titles_len}`, {error_msg}") + + except Exception as e: + log.info(f"Caught exception {e}, breaking out of retry loop") + break + + +def setup(bot: commands.Bot) -> None: + """Wikipedia Cog load.""" + bot.add_cog(WikipediaSearch(bot)) |