async def kitsu(self, ctx, *, name: str): """ Get manga or anime from kitsu.io """ req = "anime" if ctx.invoked_with == "kitsu" else ctx.invoked_with url = f"https://kitsu.io/api/edge/{req}" params = {"filter[text]": name, "page[limit]": 1} async with ctx.bot.session.get(url, params=params) as resp: if not resp.status == 200: raise exceptions.WebAPIInvalidResponse(api="kitsu", status=resp.status) data = await resp.json(content_type="application/vnd.api+json") if not data["meta"]["count"]: raise exceptions.WebAPINoResults(api="kitsu", q=name) attributes = data["data"][0]["attributes"] embed = discord.Embed( title=attributes["canonicalTitle"], url=f"https://kitsu.io/{req}/{attributes['slug']}", description=attributes["synopsis"], ) for field, item in FIELDS.items(): embed.add_field(name=ctx._(field), value=attributes[item]) if attributes["endDate"]: embed.add_field(name=ctx._("enddate"), value=attributes["endDate"]) embed.set_thumbnail(url=attributes["posterImage"]["original"]) await ctx.send(embed=embed)
async def xkcd(self, ctx, number: int = None): """Display a (or the latest) comic from xkcd.""" if number: url = f"https://xkcd.com/{number}/info.0.json" else: url = f"https://xkcd.com/info.0.json" async with ctx.bot.session.get(url) as resp: if resp.status not in [200, 404]: raise exceptions.WebAPIInvalidResponse(api="xkcd", status=resp.status) if resp.status == 404: await ctx.send( ctx._("not_a_comic").format(num=number, comic="XKCD")) return data = await resp.json() number = data["num"] image = data["img"] title = data["safe_title"] day = data["day"] month = data["month"] year = data["year"] link = f"https://xkcd.com/{number}" embed = discord.Embed(title=f"{number} - **{title}**", url=link) embed.set_footer(text=ctx._("published") + f"{year}{month}{day}") embed.set_image(url=image) await ctx.send(embed=embed)
async def jisho(self, ctx, *, word: str): """Translate a word into Japanese.""" url = API_JISHO_ORG.format(word) headers = {"Content-type": "application/json"} async with ctx.bot.session.get(url, headers=headers) as response: if response.status == 200: data = await response.text() response = json.loads(data) else: raise exceptions.WebAPIInvalidResponse( api="jisho", status=response.status ) data = response["data"][0] japanese = data["japanese"][0] senses = data["senses"][0]["english_definitions"] title = japanese.get("word", "???") reading = japanese.get("reading", "???") embed = discord.Embed(title=title, description=reading) embed.add_field(name=ctx._("english"), value=", ".join(senses)) try: speech = data["senses"][0]["parts_of_speech"][0] embed.set_footer(text=speech or "???") except (KeyError, IndexError): speech = None await ctx.send(embed=embed)
async def npm(self, ctx, package: str, version: str = "latest"): """ Look up a package on the official Node.js package manager registry. """ data_url = URL_NPM_API.format(package=package, version=version) async with ctx.bot.session.get(data_url) as resp: if not resp.status in [200, 404]: raise exceptions.WebAPIInvalidResponse(api="NPMjs", status=resp.status) if resp.status == 404: await ctx.send("{package} isn't a package on PyPI!") return info = await resp.json() embed = discord.Embed( title=f"{info['name']} `({info['version']})`", description=helpers.smart_truncate(info["description"]), url=URL_PYPI_PACKAGE.format(package=package), ) if "author" in info: embed.add_field(name=ctx._("author"), value=info["author"]["name"]) for field in FIELDS_NPM & info.keys(): embed.add_field(name=ctx._(field), value=info[field]) embed.set_thumbnail( url= "https://raw.githubusercontent.com/npm/logos/master/npm%20square/n-64.png" ) await ctx.send(embed=embed)
async def pypi(self, ctx, package: str): """ Look up a package on the Python Package Index. """ data_url = URL_PYPI_API.format(package=package) async with ctx.bot.session.get(data_url) as resp: if not resp.status in [200, 404]: raise exceptions.WebAPIInvalidResponse(api="PyPI", status=resp.status) if resp.status == 404: await ctx.send("{package} isn't a package on PyPI!") return data = await resp.json() info = data["info"] embed = discord.Embed( title=f"{info['name']} `({info['version']})`", description=helpers.smart_truncate(info["description"]), url=URL_PYPI_PACKAGE.format(package=package), ) for field in FIELDS_PYPI & info.keys(): if info[field]: embed.add_field(name=ctx._(field), value=info[field]) embed.set_thumbnail(url="http://i.imgur.com/1Pp5s56.png") await ctx.send(embed=embed)
async def urban(self, ctx, *, word: str): """Grab a word from urban dictionary.""" params = {"term": word} async with ctx.bot.session.get( API_URBAN_DICTIONARY, params=params ) as response: if response.status == 200: data = await response.text() response = json.loads(data) else: raise exceptions.WebAPIInvalidResponse( api="urbandictionary.com", status=response.status ) if not response["list"]: raise exceptions.WebAPINoResults(api="urbandictionary", q=word) content = response["list"][0] thumbs_up = content["thumbs_up"] thumbs_down = content["thumbs_down"] embed = discord.Embed( title=content["word"], description=content["author"], url=content["permalink"], ) if "definition" in content: embed.add_field( name=ctx._("definition"), value=content["definition"], inline=False, ) if "example" in content: embed.add_field( name=ctx._("example"), value=content["example"], inline=False, ) embed.add_field( name=ctx._("upvotes"), value=f":thumbsup::skin-tone-2: {thumbs_up}", inline=True, ) embed.add_field( name=ctx._("downvotes"), value=f":thumbsdown::skin-tone-2: {thumbs_down}", inline=True, ) await ctx.send(embed=embed)
async def inspiro(self, ctx): """Generate a random image from Inspirobot.""" async with ctx.bot.session.get(INSPIROBOT_URL) as resp: if resp.status != 200: raise exceptions.WebAPIInvalidResponse(api="inspirobot", status=resp.status) url = await resp.text() embed = discord.Embed() embed.set_image(url=url) embed.set_footer(text=ctx._("provided_by {service}").format( service="inspirobot.me")) await ctx.send(embed=embed)
async def image(self, ctx): """Image search command, common for all APIs.""" async with ctx.bot.session.get(url) as resp: if not resp.status == 200: raise exceptions.WebAPIInvalidResponse(api=service, status=resp.status) data = await resp.json(content_type=None) # some APIs don't set it img = TEXT.get(service, "") + data[key] embed = discord.Embed() embed.set_image(url=img) embed.set_footer(text=ctx._("provided_by {service}").format( service=urlparse(url).netloc)) await ctx.send(embed=embed)
async def image(self, ctx): """Image search command, common for all categories.""" async with ctx.bot.session.get(WEEBSH_API, params={"type": category}, headers=self._headers) as resp: if not resp.status == 200: raise exceptions.WebAPIInvalidResponse(api="weeb.sh", status=resp.status) data = await resp.json() # some APIs don't set it img = data["url"] embed = discord.Embed() embed.set_image(url=img) embed.set_footer(text=ctx._("provided_by {service}").format( service="weebsh")) await ctx.send(embed=embed)
async def fakegit(self, ctx): """Generate a fake commit message that looks like a Discord webhook.""" async with ctx.bot.session.get(WHATTHECOMMIT_API_URL) as resp: if resp.status != 200: raise exceptions.WebAPIInvalidResponse(api="whatthecommit", status=resp.status) data = await resp.json() guild = ctx.guild.name.lower().replace(" ", "_") channel = ctx.channel.name.lower().replace(" ", "_") embed = discord.Embed( title=f"[{guild}:{channel}] 1 new commit", description= f"[`{data['hash'][:8]}`]({data['permalink']}) {data['commit_message']}", url=data["permalink"], ) embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url) await ctx.send(embed=embed)
async def mcskin(self, ctx, user: str, image: str = "full"): url = URL_MCUUID_API.format(user=user) # Mojang API returns empty response instead of 404 :( async with ctx.bot.session.get(url) as resp: if resp.status == 204: uuid = None else: uuid = (await resp.json())["id"] if not uuid: await ctx.send(ctx._("mc_usernotfound").format(user)) return url = URL_MCSKIN_API.format(image=image, uuid=uuid) async with ctx.bot.session.get(url) as resp: if resp.status == 200: image = BytesIO(await resp.read()) else: raise exceptions.WebAPIInvalidResponse(api="surgeplay", status=resp.status) await ctx.send(file=discord.File(fp=image, filename=f"{uuid}.png"))