2022-11-13 23:16:47 +00:00
|
|
|
import discord
|
|
|
|
import aiohttp
|
|
|
|
import random
|
|
|
|
from discord.ext import commands
|
|
|
|
|
|
|
|
|
|
|
|
class OtherCog(commands.Cog):
|
|
|
|
def __init__(self, bot):
|
|
|
|
self.bot = bot
|
2022-11-14 17:20:31 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
async def get_xkcd(session: aiohttp.ClientSession, n: int) -> dict | None:
|
|
|
|
async with session.get("https://xkcd.com/{!s}/info.0.json".format(n)) as response:
|
|
|
|
if response.status == 200:
|
2022-11-13 23:16:47 +00:00
|
|
|
data = await response.json()
|
2022-11-14 17:20:31 +00:00
|
|
|
return data
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
async def random_xkcd_number(session: aiohttp.ClientSession) -> int:
|
|
|
|
async with session.get("https://c.xkcd.com/random/comic") as response:
|
|
|
|
if response.status != 302:
|
|
|
|
number = random.randint(100, 999)
|
|
|
|
else:
|
|
|
|
number = int(response.headers['location'].split('/')[-2])
|
|
|
|
return number
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
async def random_xkcd(session: aiohttp.ClientSession) -> dict | None:
|
|
|
|
"""Fetches a random XKCD.
|
|
|
|
|
|
|
|
Basically a shorthand for random_xkcd_number and get_xkcd.
|
|
|
|
"""
|
|
|
|
number = await OtherCog.random_xkcd_number(session)
|
|
|
|
return await OtherCog.get_xkcd(session, number)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_xkcd_embed(data: dict) -> discord.Embed:
|
2022-11-13 23:16:47 +00:00
|
|
|
embed = discord.Embed(
|
|
|
|
title=data["safe_title"],
|
|
|
|
description=data['alt'],
|
|
|
|
color=discord.Colour.embed_background()
|
|
|
|
)
|
2022-11-14 17:20:31 +00:00
|
|
|
embed.set_footer(text="XKCD #{!s}".format(data['num']))
|
2022-11-13 23:16:47 +00:00
|
|
|
embed.set_image(url=data['img'])
|
2022-11-14 17:20:31 +00:00
|
|
|
return embed
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
async def generate_xkcd(n: int = None) -> discord.Embed:
|
|
|
|
async with aiohttp.ClientSession() as session:
|
|
|
|
if n is None:
|
|
|
|
data = await OtherCog.random_xkcd(session)
|
|
|
|
n = data['num']
|
|
|
|
else:
|
|
|
|
data = await OtherCog.get_xkcd(session, n)
|
|
|
|
if data is None:
|
|
|
|
return discord.Embed(
|
|
|
|
title="Failed to load XKCD :(",
|
|
|
|
description="Try again later.",
|
|
|
|
color=discord.Colour.red()
|
|
|
|
).set_footer(text="Attempted to retrieve XKCD #{!s}".format(n))
|
|
|
|
return OtherCog.get_xkcd_embed(data)
|
|
|
|
|
|
|
|
class XKCDGalleryView(discord.ui.View):
|
|
|
|
def __init__(self, n: int):
|
|
|
|
super().__init__(timeout=300, disable_on_timeout=True)
|
|
|
|
self.n = n
|
|
|
|
|
|
|
|
@discord.ui.button(label='Previous', style=discord.ButtonStyle.blurple)
|
|
|
|
async def previous_comic(self, _, interaction: discord.Interaction):
|
|
|
|
self.n -= 1
|
|
|
|
await interaction.response.defer()
|
|
|
|
await interaction.edit_original_response(embed=await OtherCog.generate_xkcd(self.n))
|
|
|
|
|
|
|
|
@discord.ui.button(label='Random', style=discord.ButtonStyle.blurple)
|
|
|
|
async def random_comic(self, _, interaction: discord.Interaction):
|
|
|
|
await interaction.response.defer()
|
|
|
|
await interaction.edit_original_response(embed=await OtherCog.generate_xkcd())
|
|
|
|
self.n = random.randint(1, 999)
|
|
|
|
|
|
|
|
@discord.ui.button(label='Next', style=discord.ButtonStyle.blurple)
|
|
|
|
async def next_comic(self, _, interaction: discord.Interaction):
|
|
|
|
self.n += 1
|
|
|
|
await interaction.response.defer()
|
|
|
|
await interaction.edit_original_response(embed=await OtherCog.generate_xkcd(self.n))
|
|
|
|
|
|
|
|
@commands.slash_command()
|
|
|
|
async def xkcd(self, ctx: discord.ApplicationContext, *, number: int = None):
|
|
|
|
"""Shows an XKCD comic"""
|
|
|
|
embed = await self.generate_xkcd(number)
|
|
|
|
view = self.XKCDGalleryView(number)
|
|
|
|
return await ctx.respond(embed=embed, view=view)
|
2022-11-13 23:16:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
def setup(bot):
|
|
|
|
bot.add_cog(OtherCog(bot))
|