From d3690c4056826d963c4a25b8fc7f5704aa8e93e1 Mon Sep 17 00:00:00 2001 From: Hambira Date: Sat, 30 May 2020 22:36:45 +0530 Subject: "adding xkcd feature" --- bot/exts/evergreen/xkcd.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 bot/exts/evergreen/xkcd.py (limited to 'bot') diff --git a/bot/exts/evergreen/xkcd.py b/bot/exts/evergreen/xkcd.py new file mode 100644 index 00000000..11477216 --- /dev/null +++ b/bot/exts/evergreen/xkcd.py @@ -0,0 +1,72 @@ +import logging +import random + +import discord +from discord.ext import commands + +log = logging.getLogger(__name__) + + +class XKCD(commands.Cog): + """A cog for posting the XKCD .""" + + def __init__(self, bot: commands.Bot): + self.bot = bot + + @commands.command(name="xkcd") + async def fetch_xkcd_comics(self, ctx: commands.Context, comic: str = "latest") -> None: + """Read your Fav XKCD comics.""" + if comic not in ["random", "latest"]: + url = f"https://xkcd.com/{comic}/info.0.json" + else: + url = "https://xkcd.com/info.0.json" + + # ---- random choice ----- + if comic == "random": + async with self.bot.http_session.get(url) as r: + json_data = await r.json() + random_pick = random.randint(1, int(json_data["num"])) + url = f"https://xkcd.com/{random_pick}/info.0.json" + + log.trace(f"Querying xkcd API: {url}") + async with self.bot.http_session.get(url) as r: + if r.status == "200": + json_data = await r.json() + else: + # ----- Exception handling | Guides to use ------ + log.warning(f"Received response {r.status} from: {url}") + # -- get the latest comic number --- + url = f"https://xkcd.com/info.0.json" + async with self.bot.http_session.get(url) as r: + latest_data = await r.json() + + # --- beautify response --- + latest_num = latest_data["num"] + resp = discord.Embed( + title="Guides | Usage", + description=f''' + .xkcd latest (Retrieves the latest comic) + .xkcd random (Retrieves random comic) + .xkcd number (Enter a comic number between 1 & {latest_num}) + ''' + ) + return await ctx.send(embed=resp) + + # --- response variables ---- + day, month, year = json_data["day"], json_data["month"], json_data["year"] + comic_number = json_data["num"] + + # ---- beautify response ---- + embed = discord.Embed( + title=json_data['title'], + description=json_data["alt"] + ) + embed.set_image(url=json_data['img']) + embed.set_footer(text=f"Post date : {day}-{month}-{year} | xkcd comics - {comic_number}") + + await ctx.send(embed=embed) + + +def setup(bot: commands.Bot) -> None: + """XKCD Cog load.""" + bot.add_cog(XKCD(bot)) -- cgit v1.2.3 From 948a64f3de06b946f7e4c3e1e730dd6849c58ca1 Mon Sep 17 00:00:00 2001 From: xithrius Date: Sun, 24 Jan 2021 03:00:47 -0800 Subject: Refactored the xkcd command, added a refresher. --- bot/exts/evergreen/xkcd.py | 113 ++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 57 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/xkcd.py b/bot/exts/evergreen/xkcd.py index 11477216..5c100bf0 100644 --- a/bot/exts/evergreen/xkcd.py +++ b/bot/exts/evergreen/xkcd.py @@ -1,72 +1,71 @@ import logging -import random +from random import randint +from typing import Dict, Optional, Union -import discord -from discord.ext import commands +from discord import Embed +from discord.ext import tasks +from discord.ext.commands import Cog, Context, command + +from bot.bot import Bot log = logging.getLogger(__name__) +URL = "https://xkcd.com/{0}/info.0.json" +LATEST = "https://xkcd.com/info.0.json" + -class XKCD(commands.Cog): - """A cog for posting the XKCD .""" +class XKCD(Cog): + """Retrieving XKCD comics.""" - def __init__(self, bot: commands.Bot): + def __init__(self, bot: Bot) -> None: self.bot = bot + self.latest_comic_info: Dict[str, Union[str, int]] = {} + self.get_latest_comic_info.start() - @commands.command(name="xkcd") - async def fetch_xkcd_comics(self, ctx: commands.Context, comic: str = "latest") -> None: - """Read your Fav XKCD comics.""" - if comic not in ["random", "latest"]: - url = f"https://xkcd.com/{comic}/info.0.json" - else: - url = "https://xkcd.com/info.0.json" - - # ---- random choice ----- - if comic == "random": - async with self.bot.http_session.get(url) as r: - json_data = await r.json() - random_pick = random.randint(1, int(json_data["num"])) - url = f"https://xkcd.com/{random_pick}/info.0.json" - - log.trace(f"Querying xkcd API: {url}") - async with self.bot.http_session.get(url) as r: - if r.status == "200": - json_data = await r.json() + def cog_unload(self) -> None: + """Cancels refreshing of the task for refreshing the most recent comic info.""" + self.get_latest_comic_info.cancel() + + @tasks.loop(minutes=30) + async def get_latest_comic_info(self) -> None: + """Refreshes latest comic's information ever 30 minutes. Also used for finding a random comic.""" + async with self.bot.http_session.get(LATEST) as resp: + if resp.status == 200: + self.latest_comic_info = await resp.json() else: - # ----- Exception handling | Guides to use ------ - log.warning(f"Received response {r.status} from: {url}") - # -- get the latest comic number --- - url = f"https://xkcd.com/info.0.json" - async with self.bot.http_session.get(url) as r: - latest_data = await r.json() - - # --- beautify response --- - latest_num = latest_data["num"] - resp = discord.Embed( - title="Guides | Usage", - description=f''' - .xkcd latest (Retrieves the latest comic) - .xkcd random (Retrieves random comic) - .xkcd number (Enter a comic number between 1 & {latest_num}) - ''' - ) - return await ctx.send(embed=resp) - - # --- response variables ---- - day, month, year = json_data["day"], json_data["month"], json_data["year"] - comic_number = json_data["num"] - - # ---- beautify response ---- - embed = discord.Embed( - title=json_data['title'], - description=json_data["alt"] - ) - embed.set_image(url=json_data['img']) - embed.set_footer(text=f"Post date : {day}-{month}-{year} | xkcd comics - {comic_number}") + log.debug(f"Failed to get latest XKCD comic information. Status code {resp.status}") + + @command(name="xkcd") + async def fetch_xkcd_comics(self, ctx: Context, comic: Optional[str]) -> None: + """ + Getting an xkcd comic's information along with the image. + + To get a random comic, don't type any number as an argument. To get the latest, enter 0. + """ + embed = Embed() + + comic = comic or randint(1, self.latest_comic_info['num']) + + if comic == "latest": + info = self.latest_comic_info + + else: + async with self.bot.http_session.get(URL.format(comic)) as resp: + if resp.status == 200: + info = await resp.json() + else: + embed.description = f"{resp.status}: Could not retrieve xkcd comic #{comic}." + log.debug(f"Retrieving xkcd comic #{comic} failed with status code {resp.status}.") + await ctx.send(embed=embed) + return + + embed.set_image(url=info["img"]) + date = f"{info['year']}/{info['month']}/{info['day']}" + embed.set_footer(text=f"{date} - #{comic}, \'{info['safe_title']}\'") await ctx.send(embed=embed) -def setup(bot: commands.Bot) -> None: - """XKCD Cog load.""" +def setup(bot: Bot) -> None: + """Loading the XKCD cog.""" bot.add_cog(XKCD(bot)) -- cgit v1.2.3 From 075559cddd1ca3d99c5d85e4bc4f01687d845fda Mon Sep 17 00:00:00 2001 From: xithrius Date: Sun, 24 Jan 2021 03:17:40 -0800 Subject: Added footer comic number for random and latest. --- bot/exts/evergreen/xkcd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/xkcd.py b/bot/exts/evergreen/xkcd.py index 5c100bf0..06c3b4a2 100644 --- a/bot/exts/evergreen/xkcd.py +++ b/bot/exts/evergreen/xkcd.py @@ -61,7 +61,7 @@ class XKCD(Cog): embed.set_image(url=info["img"]) date = f"{info['year']}/{info['month']}/{info['day']}" - embed.set_footer(text=f"{date} - #{comic}, \'{info['safe_title']}\'") + embed.set_footer(text=f"{date} - #{info['num']}, \'{info['safe_title']}\'") await ctx.send(embed=embed) -- cgit v1.2.3 From 2d52b09977b73b5f7583e914ffc5465321548f6a Mon Sep 17 00:00:00 2001 From: xithrius Date: Sun, 24 Jan 2021 03:23:34 -0800 Subject: Added soft red color if the command fails. --- bot/exts/evergreen/xkcd.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'bot') diff --git a/bot/exts/evergreen/xkcd.py b/bot/exts/evergreen/xkcd.py index 06c3b4a2..b2f8879a 100644 --- a/bot/exts/evergreen/xkcd.py +++ b/bot/exts/evergreen/xkcd.py @@ -7,6 +7,7 @@ from discord.ext import tasks from discord.ext.commands import Cog, Context, command from bot.bot import Bot +from bot.constants import Colours log = logging.getLogger(__name__) @@ -55,6 +56,7 @@ class XKCD(Cog): info = await resp.json() else: embed.description = f"{resp.status}: Could not retrieve xkcd comic #{comic}." + embed.colour = Colours.soft_red log.debug(f"Retrieving xkcd comic #{comic} failed with status code {resp.status}.") await ctx.send(embed=embed) return -- cgit v1.2.3 From 295f0d33a4257d7d930a4da5ddf2f845f86ac730 Mon Sep 17 00:00:00 2001 From: xithrius Date: Sun, 24 Jan 2021 03:59:09 -0800 Subject: Added handling for comic arguments and interactive comics. --- bot/exts/evergreen/xkcd.py | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/xkcd.py b/bot/exts/evergreen/xkcd.py index b2f8879a..cb61e5b8 100644 --- a/bot/exts/evergreen/xkcd.py +++ b/bot/exts/evergreen/xkcd.py @@ -1,4 +1,5 @@ import logging +import re from random import randint from typing import Dict, Optional, Union @@ -11,8 +12,8 @@ from bot.constants import Colours log = logging.getLogger(__name__) -URL = "https://xkcd.com/{0}/info.0.json" -LATEST = "https://xkcd.com/info.0.json" +COMIC_FORMAT = re.compile(r"latest|[0-9]+") +BASE_URL = "https://xkcd.com" class XKCD(Cog): @@ -30,7 +31,7 @@ class XKCD(Cog): @tasks.loop(minutes=30) async def get_latest_comic_info(self) -> None: """Refreshes latest comic's information ever 30 minutes. Also used for finding a random comic.""" - async with self.bot.http_session.get(LATEST) as resp: + async with self.bot.http_session.get(f"{BASE_URL}/info.0.json") as resp: if resp.status == 200: self.latest_comic_info = await resp.json() else: @@ -41,29 +42,42 @@ class XKCD(Cog): """ Getting an xkcd comic's information along with the image. - To get a random comic, don't type any number as an argument. To get the latest, enter 0. + To get a random comic, don't type any number as an argument. To get the latest, type 'latest'. """ - embed = Embed() + embed = Embed(title=f"XKCD comic #{self.latest_comic_info['num'] if comic == 'latest' else comic}") - comic = comic or randint(1, self.latest_comic_info['num']) + embed.colour = Colours.soft_red + + if (comic := re.match(COMIC_FORMAT, comic)) is None: + embed.description = "Inputted comic parameter should either be an integer or 'latest'." + await ctx.send(embed=embed) + return + + comic = comic.group(0) or randint(1, self.latest_comic_info['num']) if comic == "latest": info = self.latest_comic_info else: - async with self.bot.http_session.get(URL.format(comic)) as resp: + async with self.bot.http_session.get(f"{BASE_URL}/{comic}/info.0.json") as resp: if resp.status == 200: info = await resp.json() else: embed.description = f"{resp.status}: Could not retrieve xkcd comic #{comic}." - embed.colour = Colours.soft_red log.debug(f"Retrieving xkcd comic #{comic} failed with status code {resp.status}.") await ctx.send(embed=embed) return - embed.set_image(url=info["img"]) - date = f"{info['year']}/{info['month']}/{info['day']}" - embed.set_footer(text=f"{date} - #{info['num']}, \'{info['safe_title']}\'") + if info["img"][:-3] in ("jpg", "png", "gif"): + embed.set_image(url=info["img"]) + date = f"{info['year']}/{info['month']}/{info['day']}" + embed.set_footer(text=f"{date} - #{info['num']}, \'{info['safe_title']}\'") + embed.colour = Colours.soft_green + else: + embed.description = ( + "Selected comic is interactive, and cannot be displayed within an embed.\n" + f"Comic can be viewed [here](https://xkcd.com/{info['num']})" + ) await ctx.send(embed=embed) -- cgit v1.2.3 From f5ea1ff1a9013df7426abc3076f66d12e64cb6b8 Mon Sep 17 00:00:00 2001 From: xithrius Date: Sun, 24 Jan 2021 04:00:38 -0800 Subject: Grammer formatting. --- bot/exts/evergreen/xkcd.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/xkcd.py b/bot/exts/evergreen/xkcd.py index cb61e5b8..91006715 100644 --- a/bot/exts/evergreen/xkcd.py +++ b/bot/exts/evergreen/xkcd.py @@ -75,8 +75,8 @@ class XKCD(Cog): embed.colour = Colours.soft_green else: embed.description = ( - "Selected comic is interactive, and cannot be displayed within an embed.\n" - f"Comic can be viewed [here](https://xkcd.com/{info['num']})" + "The selected comic is interactive, and cannot be displayed within an embed.\n" + f"Comic can be viewed [here](https://xkcd.com/{info['num']})." ) await ctx.send(embed=embed) -- cgit v1.2.3 From 2c14deb0cd25ca8f1c80fc6e02d321dca1af75d1 Mon Sep 17 00:00:00 2001 From: xithrius Date: Sun, 24 Jan 2021 04:24:09 -0800 Subject: Finished up optimization of statements. --- bot/exts/evergreen/xkcd.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'bot') diff --git a/bot/exts/evergreen/xkcd.py b/bot/exts/evergreen/xkcd.py index 91006715..e387d3c8 100644 --- a/bot/exts/evergreen/xkcd.py +++ b/bot/exts/evergreen/xkcd.py @@ -44,16 +44,16 @@ class XKCD(Cog): To get a random comic, don't type any number as an argument. To get the latest, type 'latest'. """ - embed = Embed(title=f"XKCD comic #{self.latest_comic_info['num'] if comic == 'latest' else comic}") + embed = Embed(title=f"XKCD comic '{comic}'") embed.colour = Colours.soft_red - if (comic := re.match(COMIC_FORMAT, comic)) is None: + if comic and (comic := re.match(COMIC_FORMAT, comic)) is None: embed.description = "Inputted comic parameter should either be an integer or 'latest'." await ctx.send(embed=embed) return - comic = comic.group(0) or randint(1, self.latest_comic_info['num']) + comic = randint(1, self.latest_comic_info['num']) if comic is None else comic.group(0) if comic == "latest": info = self.latest_comic_info @@ -63,12 +63,15 @@ class XKCD(Cog): if resp.status == 200: info = await resp.json() else: + embed.title = f"XKCD comic #{comic}" embed.description = f"{resp.status}: Could not retrieve xkcd comic #{comic}." log.debug(f"Retrieving xkcd comic #{comic} failed with status code {resp.status}.") await ctx.send(embed=embed) return - if info["img"][:-3] in ("jpg", "png", "gif"): + embed.title = f"XKCD comic #{info['num']}" + + if info["img"][-3:] in ("jpg", "png", "gif"): embed.set_image(url=info["img"]) date = f"{info['year']}/{info['month']}/{info['day']}" embed.set_footer(text=f"{date} - #{info['num']}, \'{info['safe_title']}\'") -- cgit v1.2.3 From 62b1b277146c19ba441b5dcceec073489dd7178a Mon Sep 17 00:00:00 2001 From: Xithrius <15021300+Xithrius@users.noreply.github.com> Date: Sun, 24 Jan 2021 04:38:59 -0800 Subject: Changed comic argument error for fluency of reading. Co-authored-by: ChrisJL --- bot/exts/evergreen/xkcd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/xkcd.py b/bot/exts/evergreen/xkcd.py index e387d3c8..674ad4b0 100644 --- a/bot/exts/evergreen/xkcd.py +++ b/bot/exts/evergreen/xkcd.py @@ -49,7 +49,7 @@ class XKCD(Cog): embed.colour = Colours.soft_red if comic and (comic := re.match(COMIC_FORMAT, comic)) is None: - embed.description = "Inputted comic parameter should either be an integer or 'latest'." + embed.description = "Comic parameter should either be an integer or 'latest'." await ctx.send(embed=embed) return -- cgit v1.2.3 From a81d30f34dc4d4fa6e8550437e6d329a4da4e746 Mon Sep 17 00:00:00 2001 From: xithrius Date: Sun, 24 Jan 2021 05:41:58 -0800 Subject: Removed newline between if/else statement. --- bot/exts/evergreen/xkcd.py | 1 - 1 file changed, 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/evergreen/xkcd.py b/bot/exts/evergreen/xkcd.py index 674ad4b0..d3224bfe 100644 --- a/bot/exts/evergreen/xkcd.py +++ b/bot/exts/evergreen/xkcd.py @@ -57,7 +57,6 @@ class XKCD(Cog): if comic == "latest": info = self.latest_comic_info - else: async with self.bot.http_session.get(f"{BASE_URL}/{comic}/info.0.json") as resp: if resp.status == 200: -- cgit v1.2.3