Browse Source

;xkcd (#12)

* Clear embed on message deleted by user

* First pass at xkcd cog

* More work on xkcd, title matching, latest & typing while querying

* Move ;xkcd to fun cog

* Fix ;xkcd argument parsing

* Random function for xkcd, called by default (also fixed arguments)

* Refactor/cleanup xkcd

* Added message when random/latest used in xkcd command
tags/v1.8.0
oh 6 years ago
parent
commit
958108c4c0
2 changed files with 77 additions and 1 deletions
  1. +76
    -0
      roxbot/cogs/fun.py
  2. +1
    -1
      roxbot/utils.py

+ 76
- 0
roxbot/cogs/fun.py View File

@@ -3,10 +3,41 @@ import random
import datetime

import discord
from discord import Embed
from discord.ext import commands
from discord.ext.commands import bot

import aiohttp

import roxbot

TITLE_QUERY_URL="http://www.explainxkcd.com/wiki/api.php?format=json&action=query&redirects&titles={}"
XKCD_SITE="https://xkcd.com/{}"
RANDOM_URL="https://c.xkcd.com/random/comic"

async def xkcd_lookup_num(num):
return await roxbot.http.api_request(XKCD_SITE.format(str(num) + "/info.0.json"))

async def xkcd_lookup_latest():
return await roxbot.http.api_request(XKCD_SITE.format("/info.0.json"))

async def xkcd_lookup_title(title):
api = await roxbot.http.api_request(TITLE_QUERY_URL.format(title.replace(" ", "_")))
# if valid, query.redirects.to is the full & proper page title, including the actual number.
try:
full_page_title = api["query"]["redirects"][0]["to"]
num = full_page_title.split(":")[0]
return await xkcd_lookup_num(num)
except KeyError: # this means query,redirects... didn't exist, done like this to save a massive if statement.
return None

async def random_xkcd():
async with aiohttp.ClientSession() as session:
async with session.get(RANDOM_URL, allow_redirects=False) as resp:
comic_url = resp.headers["Location"]
num = comic_url.split("/")[-2] # there's always a trailing / so it's the 2nd last segment
return await xkcd_lookup_num(num)


class Fun:
def __init__(self, bot_client):
@@ -305,6 +336,51 @@ class Fun:
embed.set_footer(text=base_url)
return await ctx.send(embed=embed)

@bot.command()
@commands.has_permissions(add_reactions=True)
@commands.bot_has_permissions(add_reactions=True)
async def xkcd(self, ctx, *, query=None):
"""
Grabs the image & metadata of the given xkcd comic
Example:
{command_prefix}xkcd 666
{command_prefix}xkcd Silent Hammer
{command_prefix}xkcd latest
"""
msg = ""
async with ctx.typing():
# Check if passed a valid number
if query in (None, "random"):
# Get a random comic
msg = "Showing a random xkcd"
comic = await random_xkcd()
elif query.isdigit():
# If so, use that to look up
comic = await xkcd_lookup_num(query)
elif query == "latest":
msg = "Showing the latest xkcd"
# Get the latest comic
comic = await xkcd_lookup_latest()
else:
# Otherwise, assume it's meant to be a name & look up from that.
# Case insensitive, or at least as close as we can get it.
# Titles tend to be in title case so this shouldn't be a problem
query = query.title()
comic = await xkcd_lookup_title(query)

# If we couldn't find anything, return an error.
if not comic:
return await ctx.send("{} - Couldn't find that comic.".format(ctx.message.author.mention))
else:
# Otherwise, show the comic
embed = Embed(title=comic["safe_title"], description="xkcd #{} by Randall Munroe".format(comic["num"]))
embed.set_image(url=comic["img"])
embed.set_footer(text=comic["alt"])
embed.url = XKCD_SITE.format(comic["num"])
output = await ctx.send(msg, embed=embed)
await roxbot.utils.delete_option(self.bot, ctx, output, self.bot.get_emoji(444410658101002261) or "❌")

def setup(bot_client):
bot_client.add_cog(Fun(bot_client))

+ 1
- 1
roxbot/utils.py View File

@@ -13,7 +13,7 @@ async def delete_option(bot, ctx, message, delete_emoji, timeout=20):
await bot.wait_for("reaction_add", timeout=timeout, check=check)
await message.remove_reaction(delete_emoji, bot.user)
await message.remove_reaction(delete_emoji, ctx.author)
return await message.edit(content="{} requested output be deleted.".format(ctx.author))
return await message.edit(content="{} requested output be deleted.".format(ctx.author), embed=None)
except TimeoutError:
await message.remove_reaction(delete_emoji, bot.user)


Loading…
Cancel
Save