Browse Source

Merge branch 'master' into development

# Conflicts:
#	roxbot/utils.py
tags/v1.8.0
Roxie Gibson 6 years ago
parent
commit
b8f6a9d685
4 changed files with 96 additions and 11 deletions
  1. +74
    -0
      roxbot/cogs/fun.py
  2. +18
    -7
      roxbot/http.py
  3. +1
    -1
      roxbot/settings/preferences_example.ini
  4. +3
    -3
      roxbot/utils.py

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

@@ -30,6 +30,8 @@ import random
import datetime

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

import roxbot
@@ -332,6 +334,78 @@ 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 = ""
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():
resp = await roxbot.http.request(random_url, **{"allow_redirects": False})
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)

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))

+ 18
- 7
roxbot/http.py View File

@@ -29,7 +29,19 @@ import json
import aiohttp


async def api_request(url, *, headers=None):
async def request(url, *, headers=None, **kwargs):
"""
Base GET request.
:param url:
:param headers:
:param kwargs:
:return:
"""
async with aiohttp.ClientSession() as session:
return await session.get(url, headers=headers, **kwargs)


async def api_request(url, *, headers=None, **kwargs):
"""
Returns a JSON dict object for most api calls in RoxBot.
:param url: URL Should be a api endpoint that will return
@@ -40,12 +52,11 @@ async def api_request(url, *, headers=None):
headers = {'User-agent': 'RoxBot Discord Bot'}
else:
headers = {'User-agent': 'RoxBot Discord Bot', **headers}
async with aiohttp.ClientSession() as session:
async with session.get(url, headers=headers) as resp:
try:
return json.loads(await resp.read())
except json.JSONDecodeError:
return None
resp = await request(url, headers=headers, **kwargs)
try:
return json.loads(await resp.read())
except json.JSONDecodeError:
return None


async def download_file(url, filename=None):

+ 1
- 1
roxbot/settings/preferences_example.ini View File

@@ -1,5 +1,5 @@
[Roxbot]
OwnerID=142735312626515979
OwnerID=451192272349036545
Token=TokenHere
Command_Prefix=r;
Tatsumaki_Token=TokenHere

+ 3
- 3
roxbot/utils.py View File

@@ -25,7 +25,7 @@ SOFTWARE.
"""


from asyncio import TimeoutError
import asyncio


async def delete_option(bot, ctx, message, delete_emoji, timeout=20):
@@ -40,8 +40,8 @@ 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))
except TimeoutError:
return await message.edit(content="{} requested output be deleted.".format(ctx.author), embed=None)
except asyncio.TimeoutError:
await message.remove_reaction(delete_emoji, bot.user)



Loading…
Cancel
Save