-
-
Notifications
You must be signed in to change notification settings - Fork 16
Team 20 #16
base: master
Are you sure you want to change the base?
Team 20 #16
Changes from 25 commits
ece1140
54fbeb0
105b415
fd9db0d
63ccb69
3763038
47e03d6
9b4a683
73ab47b
2cbbf34
0ddc2a4
e766154
8d89ccf
002dcfa
163d4d7
916a7ac
9338eeb
a626e56
aa43444
532995e
992de22
305c3fe
d419d1c
108e84d
971d098
2c6af66
80e01f6
8bb749d
fc5dddb
3330e52
1b5e682
2344edc
94bfad1
a93cc3b
9f77c25
626b8b6
d31e269
78ad193
e395e6b
93d1d8e
b9ee9c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,39 @@ | ||
| # coding=utf-8 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ya want to explain this? Why delete that file? |
||
|
|
||
| import async_timeout | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't declared in your Pipfile. |
||
| import random | ||
| import difflib | ||
| import logging | ||
| from typing import Any, Dict | ||
| import urllib.parse | ||
| import ast | ||
|
|
||
| import aiohttp | ||
|
|
||
| from typing import Dict, List | ||
| from discord import Embed | ||
| from discord.ext.commands import AutoShardedBot, Context, command | ||
|
|
||
|
|
||
| log = logging.getLogger(__name__) | ||
|
|
||
| # Probably should move these somewhere | ||
|
|
||
| WIKI = "https://en.wikipedia.org/w/api.php?" | ||
| BASEURL = WIKI + "format=json&action=query&prop=extracts|pageimages&exintro=&explaintext=&titles={}&redirects=1" | ||
| FAILIMAGE = "http://i.imgur.com/HtIPyLy.png/beep" | ||
| PYTHON = { | ||
| "name": "Python", | ||
| "info": """Python is a species of programming language, \ | ||
| commonly used by coding beginners and experts alike. It was first discovered \ | ||
| in 1989 by Guido van Rossum in the Netherlands, and was released to the wild \ | ||
| two years later. Its use of dynamic typing is one of many distinct features, \ | ||
| alongside significant whitespace, heavy emphasis on readability, and, above all, \ | ||
| absolutely pain-free software distribution... *sigh*""", | ||
| "image": "https://www.python.org/static/community_logos/python-logo-master-v3-TM-flattened.png" | ||
| } | ||
| with open("bot/snakes.txt") as f: | ||
| SNAKES = [line.strip() for line in f.readlines()] | ||
|
|
||
|
|
||
| class Snakes: | ||
| """ | ||
|
|
@@ -15,31 +43,99 @@ class Snakes: | |
| def __init__(self, bot: AutoShardedBot): | ||
| self.bot = bot | ||
|
|
||
| async def get_snek(self, name: str = None) -> Dict[str, Any]: | ||
| """ | ||
| Go online and fetch information about a snake | ||
| @staticmethod | ||
| def parse_kwarg(kwarg: str): | ||
| """Return the value of a kwarg (needs manual assignment)""" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand - what is this supposed to be doing, and why? |
||
| try: | ||
| items = kwarg.split("=") | ||
| value = items[1] | ||
| except (IndexError, AttributeError): | ||
| value = kwarg | ||
|
|
||
| try: | ||
| parsed = ast.literal_eval(value) | ||
| except (NameError, ValueError): | ||
| parsed = value | ||
|
|
||
| return parsed | ||
|
|
||
| @staticmethod | ||
| def snake_url(name: str): | ||
| """Get the URL of a snake""" | ||
|
|
||
| def format_url(text: str): | ||
| """Get the full URL with that snake :D""" | ||
| return BASEURL.format(urllib.parse.quote_plus(text)) | ||
|
|
||
| # Check if the snake name is valid | ||
| if name.upper() in [name.upper() for name in SNAKES]: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of |
||
| return format_url(name) | ||
|
|
||
| The information includes the name of the snake, a picture of the snake, and various other pieces of info. | ||
| What information you get for the snake is up to you. Be creative! | ||
| # Get the most similar name if a match wasn't found | ||
| return difflib.get_close_matches(name, SNAKES, n=5, cutoff=0) | ||
|
|
||
| If "python" is given as the snake name, you should return information about the programming language, but with | ||
| all the information you'd provide for a real snake. Try to have some fun with this! | ||
| @staticmethod | ||
| async def fetch(session, url: str): | ||
| """Fetch the contents of a URL as a json""" | ||
| async with async_timeout.timeout(10): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not just |
||
| async with session.get(url) as response: | ||
| return await response.json() | ||
|
|
||
| :param name: Optional, the name of the snake to get information for - omit for a random snake | ||
| :return: A dict containing information on a snake | ||
| """ | ||
| async def get_snek(self, name: str = None, autocorrect: str = None, details: List[str] = None) -> Dict[str, str]: | ||
| """If a name is provided, this gets a specific snake. Otherwise, it gets a random snake.""" | ||
|
|
||
| autocorrect = self.parse_kwarg(autocorrect) or False | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ????????? |
||
| details = self.parse_kwarg(details) or [] | ||
|
|
||
| if name is None: | ||
| name = random.choice(SNAKES) | ||
|
|
||
| if name.upper() == "PYTHON": | ||
| return PYTHON | ||
|
|
||
| # Get snake information | ||
| async with aiohttp.ClientSession() as session: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You used a timeout above, but not here. Maybe you meant to have one here? |
||
| url = self.snake_url(name) | ||
|
|
||
| if isinstance(url, list): | ||
| if autocorrect: | ||
| return await self.get_snek(url[0]) | ||
|
|
||
| return { | ||
| "name": "Oops!", | ||
| "info": "We couldn't find that snake, but here are some with similar names:\n\n" + "\n".join(url), | ||
| } | ||
|
|
||
| # Get the content | ||
| response = await self.fetch(session, url) | ||
| page = response["query"]["pages"] | ||
| content = next(iter(page.values())) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Surely there's a simpler way to do that. |
||
|
|
||
| # Parse the full-res image from the thumbnail | ||
| thumb = content.get("thumbnail", {}).get("source", FAILIMAGE) | ||
| image = "/".join(thumb.replace("thumb/", "").split("/")[:-1]) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| return { | ||
| "name": content["title"], | ||
| "info": content.get("extract", "I don't know about that snake!"), | ||
| "image": image | ||
| } | ||
|
|
||
| @command() | ||
| async def get(self, ctx: Context, name: str = None): | ||
| """ | ||
| Go online and fetch information about a snake | ||
| async def get(self, ctx: Context, name: str = None, autocorrect: str = None, details: str = None): | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're missing a docstring here. |
||
| content = await self.get_snek(name, autocorrect, details) | ||
| # Just a temporary thing to make sure it's working | ||
| embed = Embed( | ||
| title=content["name"], | ||
| description=content["info"][:1970], | ||
| color=0x7289da | ||
| ) | ||
|
|
||
| This should make use of your `get_snek` method, using it to get information about a snake. This information | ||
| should be sent back to Discord in an embed. | ||
| if "image" in content: | ||
| embed.set_image(url=content.get("image")) | ||
|
|
||
| :param ctx: Context object passed from discord.py | ||
| :param name: Optional, the name of the snake to get information for - omit for a random snake | ||
| """ | ||
| await ctx.send(embed=embed) | ||
|
|
||
| # Any additional commands can be placed here. Be creative, but keep it to a reasonable amount! | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,5 +36,6 @@ | |
| bot.load_extension("bot.cogs.snakes") | ||
|
|
||
| bot.run(os.environ.get("BOT_TOKEN")) | ||
| #bot.run('bot token goes here for testing') | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should remove this line.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We explained exactly how this works in the docs. |
||
|
|
||
| bot.http_session.close() # Close the aiohttp session when the bot finishes running | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why?