#!/usr/bin/env python3 """ Search for and pull information about XKCD comics. """ import random import requests from module import commands, url_callback def get_info(number=None): if number: url = f"https://xkcd.com/{number}/info.0.json" else: url = "https://xkcd.com/info.0.json" res = requests.get(url, verify=True) res.raise_for_status() data = res.json() data['url'] = f"https://xkcd.com/{data['num']}" return data def validate_num(num, max_int): """Ensures that the given number is a valid comic id.""" if num < 0: # nth latest num += max_int if num < 0: num = 1 elif num == 0: num = 1 elif num > max_int: num = max_int return num def parse_data(data): """Parses the retrieved data into a proper message for the bot.""" msg = f"[\x0304XKCD\x03] \x0307{data['url']}\x03 | " \ + f"\x0310{data['safe_title']}\x03 | " \ + f"\x0310Alt-text: \x0312{data['alt']}" return msg @commands('xkcd') def xkcd(bot, trigger): """ .xkcd - Finds an xkcd comic strip. If no input is provided it will return a random comic If numeric input is provided it will return that comic, or the nth-latest comic if the number is non-positive """ latest = get_info() max_int = latest['num'] if len(trigger.args) >= 2: try: num = int(trigger.args[1]) except ValueError: return bot.reply("Invalid input.") num = validate_num(num, max_int) data = get_info(num) else: num = random.randint(1, max_int) data = get_info(num) msg = parse_data(data) bot.msg(msg) @url_callback('xkcd.com/') def get_url(bot, url): """Callback for the URL module.""" _, _, num = url.partition("xkcd.com/") try: num = int(num.replace("/", "")) except ValueError: return latest = get_info() max_int = latest['num'] num = validate_num(num, max_int) data = get_info(num) msg = parse_data(data) bot.msg(msg)