Skip to content
This repository was archived by the owner on Mar 14, 2021. It is now read-only.

Team 20 #16

Open
wants to merge 41 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
ece1140
Merge pull request #1 from discord-python/master
skrungly Mar 23, 2018
54fbeb0
First draft
isik-kaplan Mar 23, 2018
105b415
Adding snakes.txt
isik-kaplan Mar 23, 2018
fd9db0d
Cleaned up a bit, added bot test
invalid-email-address Mar 23, 2018
63ccb69
Added pictures
isik-kaplan Mar 23, 2018
3763038
Embeds and redirects :D
invalid-email-address Mar 23, 2018
47e03d6
Fixed url encoder
isik-kaplan Mar 23, 2018
9b4a683
I don't fucking know
invalid-email-address Mar 23, 2018
73ab47b
I don't fucking know
invalid-email-address Mar 23, 2018
2cbbf34
Fixed up wikipedia's bullshit
invalid-email-address Mar 23, 2018
0ddc2a4
fixed little stuff
isik-kaplan Mar 24, 2018
e766154
Various small edits
Mar 24, 2018
8d89ccf
Various small edits
Mar 24, 2018
002dcfa
fixed more little stuff
Mar 24, 2018
163d4d7
Merge pull request #2 from discord-python/master
skrungly Mar 24, 2018
916a7ac
Added autocomplete kwarg(ish)
Mar 24, 2018
9338eeb
Merge branch 'master' of https://github.com/kingdom5500/code-jam-1
Mar 24, 2018
a626e56
kwarg parsing ^^
Mar 25, 2018
aa43444
fucking hell, had accidentally pushed bot token :I
Mar 25, 2018
532995e
Revert "kwarg parsing ^^"
Mar 25, 2018
992de22
Revert "fucking hell, had accidentally pushed bot token :I"
Mar 25, 2018
305c3fe
Revert "kwarg parsing ^^"
Mar 25, 2018
d419d1c
Well I'm stupid :D
Mar 25, 2018
108e84d
snakes.txt + snakes2.py
isik-kaplan Mar 25, 2018
971d098
Merge branch 'master' of https://github.com/kingdom5500/code-jam-1
isik-kaplan Mar 25, 2018
2c6af66
Added snake_card command (kinda)
Mar 25, 2018
80e01f6
These files are useful
Mar 25, 2018
8bb749d
Finally used .env
Mar 25, 2018
fc5dddb
Arg edits, made by someone
Mar 25, 2018
3330e52
added snkaes.py *duuh*
isik-kaplan Mar 25, 2018
1b5e682
Oops.
Mar 25, 2018
2344edc
Oops.
Mar 25, 2018
94bfad1
Revert "Finally used .env"
Mar 25, 2018
a93cc3b
Revert "These files are useful"
Mar 25, 2018
9f77c25
Touched up some stuff
Mar 25, 2018
626b8b6
Accidentally pushed old token fucking hell
Mar 25, 2018
d31e269
Finishing touches for now. Will still need fine-tuning though
Mar 25, 2018
78ad193
Added my own version. Someone, don't hurt me :(
Mar 25, 2018
e395e6b
Added a comment for clarification :D
Mar 25, 2018
93d1d8e
Improved special cases
Mar 25, 2018
b9ee9c0
Improved special cases
Mar 25, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ name = "pypi"
[packages]
"72eb2aa" = {file = "https://github.com/Rapptz/discord.py/archive/rewrite.zip"}
aiodns = "*"
aiohttp = "<2.3.0,>=2.0.0"
aiohttp = "*"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any particular reason this was done? discord.py doesn't like the latest aiohttp, we locked the version for a reason.

websockets = ">=4.0,<5.0"
google-api-python-client = "*"

[dev-packages]
"flake8" = "*"
Expand Down
122 changes: 107 additions & 15 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

93 changes: 76 additions & 17 deletions bot/cogs/snakes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,33 @@
import logging
from typing import Any, Dict

from googleapiclient.discovery import build
from discord.ext.commands import AutoShardedBot, Context, command
from discord import Embed

import aiohttp
import json
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these imports aren't gonna pass linting. wrong import orders and groupings. you should fix them so they are PEP8 compliant. Why aren't you guys using flake8?

import async_timeout
import random
import difflib

log = logging.getLogger(__name__)

# Probably should move these somewhere
BASEURL = "https://en.wikipedia.org/w/api.php?format=json&action=query&prop=extracts|pageimages&exintro=&explaintext=&titles={}&redirects=1"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line is 140 characters. it's not gonna pass linting and it's just not okay to do even if it did.

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 file:
SNAKES = list(map(lambda ln: ln.strip('\n'), file.readlines()))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't even know where to begin with this line.

  • don't use map and lambdas, use list comps. this isn't Python 1.0.
  • a simple ln.strip() will also remove newlines (and spaces) from the start and end. why even specify the \n?
  • don't call the file variable file, that's a python 2 builtin which means syntax highlighting looks funky in most editors.
  • ln is a shitty variable name. just call it line. this isn't code golf.



class Snakes:
"""
Expand All @@ -15,31 +38,67 @@ class Snakes:
def __init__(self, bot: AutoShardedBot):
self.bot = bot

@staticmethod
def snake_url(name) -> str:
Copy link

@schwartzadev schwartzadev Mar 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type hint name here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name should be typehinted.

"""Get the URL of a snake"""

def encode_url(text):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The standard lib already provides a tool for this:
urllib.parse.quote_plus

"""Encode a string to URL-friendly format"""
return BASEURL.format(text.replace(' ', '%20').replace("'", '%27'))

# Check if the snake name is known
if name.upper() in list(map(lambda n: n.upper(), SNAKES)):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, please use a list comp.

return encode_url(name)

# Get a list of similar names if a match wasn't found
matches = difflib.get_close_matches(name, SNAKES, n=1)
return encode_url(matches[0] if matches != [] else random.choice(SNAKES))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needless empty list comparison. if matches alone would do the same job.


@staticmethod
async def fetch(session, url):
"""Fetch the contents of a URL as a json"""
async with async_timeout.timeout(10):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just with aiohttp.Timeout(10):?

async with session.get(url) as response:
return await response.json()

async def get_snek(self, name: str = None) -> Dict[str, Any]:
"""
Go online and fetch information about a snake
"""Get a snake with a given name, or otherwise randomly"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Poorly written docstring. "otherwise randomly".

"If a name is provided, this gets a specific snake. Otherwise, it gets a random snake."

if name is None:
name = random.choice([x.strip('\n') for x in SNAKES])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't you already strip out the newlines when you created SNAKES?


elif name.upper() == "PYTHON":
return PYTHON

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 snake information
async with aiohttp.ClientSession() as session:
Copy link
Contributor

Choose a reason for hiding this comment

The 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 "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!
# Get the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get the what?

response = await self.fetch(session, url)
page = response["query"]["pages"]
content = next(iter(page.values()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surely there's a simpler way to do that.


: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
"""
# Parse the full-res image from the thumbnail
thumb = content.get("thumbnail", {}).get("source", "http://i.imgur.com/HtIPyLy.png/beep")
image = "/".join(thumb.replace("thumb/", "").split("/")[:-1])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

split() takes another parameter for the number of times the string should be split. Take a look at that, maybe?


# WHY WOULD YOU USE DICTIONARY LITERAL IN A RETURN STATEMENT but okay lol

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems fine from the way you've done this - not sure I have any qualms with it but maybe consider making a class for this return object...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

returning a dictionary literal seems fine. this comment, however, does not.

return {
"name": content["title"],
"info": content.get("extract", "") or "I don't know about that snake!",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't do this. the second param of .get is what to return if the get fails.

"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

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.
content = await self.get_snek(name)
# Just a temporary thing to make sure it's working
em = Embed()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's no two letter maxlimit on variable names. what's wrong with embed = Embed()?

em.title = content["name"]
em.description = content["info"][:1970] + "\n\nPS. If the image is a fucking map, blame wikipedia. -Somejuan"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other teams seem to have found a way not to return maps. :P

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed they have, but we aren't other teams :D

em.set_image(url=content["image"])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some of this can be more concise:

embed=discord.Embed(
    title=content["name"],
    description=content["info"][:1970] + "\n\nPS. If the image is a fucking map, blame wikipedia. -Somejuan"
)


: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=em)

# Any additional commands can be placed here. Be creative, but keep it to a reasonable amount!

Expand Down
4 changes: 3 additions & 1 deletion run.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
# Commands, etc
bot.load_extension("bot.cogs.snakes")

bot.run(os.environ.get("BOT_TOKEN"))
#bot.run(os.environ.get("BOT_TOKEN"))
# I SWEAR TO GOD, HONESTLY WATCH ME LEAVE THIS TOKEN IN LMAO
bot.run('BOT TOKEN')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this run properly?


bot.http_session.close() # Close the aiohttp session when the bot finishes running