async def sendComic(ctx, comic, integer): comicNum = xkcd.getLatestComicNum() comic = await makeComic(ctx, comic, integer) def check(reaction, user): return user == ctx.author and str(reaction.emoji) in ["◀️", "🎲", "▶️"] while True: try: reaction, user = await client.wait_for("reaction_add", timeout=60, check=check) if str(reaction.emoji ) == "▶️" and integer < comicNum and user == ctx.author: integer += 1 await comic.delete() comic = xkcd.getComic(integer) comic = await makeComic(ctx, comic, integer) elif str(reaction.emoji ) == "◀️" and integer > 1 and user == ctx.author: integer -= 1 await comic.delete() comic = xkcd.getComic(integer) comic = await makeComic(ctx, comic, integer) elif str(reaction.emoji) == "🎲" and user == ctx.author: await comic.delete() rand = randrange(1, xkcd.getLatestComicNum()) comic = xkcd.getComic(rand) comic = await makeComic(ctx, comic, rand) except asyncio.TimeoutError: break
async def xkcd(self, *, comic): comic = comic.lower() """Show xkcd comic by number. Use "latest" to show the latest comic, or "random" to show a random comic.""" if comic == "latest": # await self.bot.say("https://xkcd.com/{}/".format(xkcd.getLatestComic().number)) comicpage = "https://xkcd.com/{}/".format(xkcd.getLatestComic().number) page = requests.get(comicpage).content soup = BeautifulSoup(page, "html.parser") comicImageBlock = soup.find("div",{"id":"comic"}) comicImageTag = comicImageBlock.find("img") comicURL = comicImageTag['src'] embed = discord.Embed(title='Latest xkcd', description='Here\'s your comic!', color=0xFFFFFF) embed.set_image(url='https:{}'.format(comicURL)) await self.bot.say(embed=embed) elif comic == "random": # await self.bot.say("https://xkcd.com/{}/".format(xkcd.getRandomComic().number)) comicpage = "https://xkcd.com/{}/".format(xkcd.getRandomComic().number) page = requests.get(comicpage).content soup = BeautifulSoup(page, "html.parser") comicImageBlock = soup.find("div",{"id":"comic"}) comicImageTag = comicImageBlock.find("img") comicURL = comicImageTag['src'] embed = discord.Embed(title='Random xkcd', description='Here\'s your comic!', color=0xFFFFFF) embed.set_image(url='https:{}'.format(comicURL)) await self.bot.say(embed=embed) elif comic.isdigit(): # await self.bot.say("https://xkcd.com/{}/".format(xkcd.getComic(comic).number)) comicpage = "https://xkcd.com/{}/".format(xkcd.getComic(comic).number) page = requests.get(comicpage).content soup = BeautifulSoup(page, "html.parser") comicImageBlock = soup.find("div",{"id":"comic"}) comicImageTag = comicImageBlock.find("img") comicURL = comicImageTag['src'] embed = discord.Embed(title='xkcd number {}'.format(comic), description='Here\'s your comic!', color=0xFFFFFF) embed.set_image(url='https:{}'.format(comicURL)) await self.bot.say(embed=embed) elif comic in self.word_responses: # await self.bot.say("https://xkcd.com/{}/".format(xkcd.getComic(self.word_responses[comic]).number)) comicpage = "https://xkcd.com/{}/".format(xkcd.getComic(self.word_responses[comic]).number) page = requests.get(comicpage).content soup = BeautifulSoup(page, "html.parser") comicImageBlock = soup.find("div",{"id":"comic"}) comicImageTag = comicImageBlock.find("img") comicURL = comicImageTag['src'] embed = discord.Embed(title='Keyphrase: {}'.format(comic), description='Here\'s your comic!', color=0xFFFFFF) embed.set_image(url='https:{}'.format(comicURL)) await self.bot.say(embed=embed) else: await self.bot.say("I can't find that one!")
async def xkcd(self, ctx: KurisuContext, *, comic): """Show xkcd comic by number. Use "latest" to show the latest comic, or "random" to show a random comic.""" comic = comic.lower() if comic == "latest": await ctx.send("https://xkcd.com/{}/".format(xkcd.getLatestComic().number)) elif comic == "random": await ctx.send("https://xkcd.com/{}/".format(xkcd.getRandomComic().number)) elif comic.isdecimal(): await ctx.send("https://xkcd.com/{}/".format(xkcd.getComic(comic).number)) elif comic in self.word_responses: await ctx.send("https://xkcd.com/{}/".format(xkcd.getComic(self.word_responses[comic]).number)) else: await ctx.send("I can't find that one!")
async def xkcd(self, *, comic): comic = comic.lower() """Show xkcd comic by number. Use "latest" to show the latest comic, or "random" to show a random comic.""" if comic == "latest": await self.bot.say("https://xkcd.com/{}/".format(xkcd.getLatestComic().number)) elif comic == "random": await self.bot.say("https://xkcd.com/{}/".format(xkcd.getRandomComic().number)) elif comic.isdigit(): await self.bot.say("https://xkcd.com/{}/".format(xkcd.getComic(comic).number)) elif comic in self.word_responses: await self.bot.say("https://xkcd.com/{}/".format(xkcd.getComic(self.word_responses[comic]).number)) else: await self.bot.say("I can't find that one!")
async def xkcd(self, *, comic): comic = comic.lower() """Show xkcd comic by number. Use "latest" to show the latest comic, or "random" to show a random comic.""" if comic == "latest": await self.bot.say("", embed=await self.embed_xkcd_comic(xkcd.getLatestComic())) elif comic == "random": await self.bot.say("", embed=await self.embed_xkcd_comic(xkcd.getRandomComic())) elif comic.isdigit(): await self.bot.say("", embed=await self.embed_xkcd_comic(xkcd.getComic(comic))) elif comic in self.word_responses: await self.bot.say("", embed=await self.embed_xkcd_comic(xkcd.getComic(self.word_responses[comic]))) else: await self.bot.say("I can't find that one!")
class XKCD: """A plugin for those on the internet with good humor.""" def __init__(self, bot): self.bot = bot # Helper function for getting comics async def get_comic(self, comic, number=None): case = { "latest": lambda: xkcd.getLatestComic(), "random": lambda: xkcd.getRandomComic(), "number": lambda: xkcd.getComic(number), } function = case.get(comic, None) comic = self.bot.loop.run_in_executor(None, function) while True: await asyncio.sleep(0.25) if comic.done(): comic = comic.result() break try: link = comic.getImageLink() title = comic.getAsciiTitle().decode("ascii") alt_text = comic.getAsciiAltText().decode("ascii") number = comic.number return f"{number} - {link}\n**Title:** {title}\n**Alt:** {alt_text}" except AttributeError: return "\U00002754 Can't find that comic."
async def getXKCD(self, ctx, comic_number): """ Gets an XKCD comic and returns info about it ;param comic_number: the number of the xkcd comic :return: XKCD comic link, title, alt-text, and image title """ if -1 < int(comic_number) < xkcd.getLatestComicNum( ): # check for valid XKCD comic # get info about XCKD comic comic = xkcd.getComic(comic_number) comic_link = comic.getImageLink() alt_text = comic.getAltText() comic_name = comic.getImageName() comic_title = comic.getTitle() await ctx.send( f'```' f'Here is XKCD comic {comic_number}\nTitle: {comic_title}' f'```') await ctx.send(comic_link) await ctx.send( f'```' f'Alternate text: {alt_text}\nImage file name: {comic_name} ' f'```') else: await ctx.send( f'Invalid comic number. Please enter a number between 0 and {xkcd.getLatestComicNum()}' )
async def xkcd_command(self, ctx, *, number=None): try: if number == None: a = comic.getRandomComic() title = a.getTitle() link = a.getImageLink() exp = a.getExplanation() embed = discord.Embed(title=f"xkcd - {title}", description=f"{a.altText}", color=0xf5f5dc) embed.set_footer(text=("For explanation refer to: " + exp)) embed.set_image(url=link) await ctx.send(embed=embed) else: number = int(number) limit = comic.getLatestComicNum() if number < 1 or number > limit: await ctx.send("Please enter a number between 1 to 1988") else: a = comic.getComic(number, silent=True) title = a.getTitle() link = a.getImageLink() exp = a.getExplanation() embed = discord.Embed(title=f"xkcd - {title}", description=f"{a.altText}", color=0xf5f5dc) embed.set_footer(text=("For explanation refer to: " + exp)) embed.set_image(url=link) await ctx.send(embed=embed) except Exception as e: await ctx.send(f'There was an error trying to fetch comic: {e}')
async def on_xkcd(ctx): num = random.randint(0, xkcd.getLatestComicNum()) comic = xkcd.getComic(num) url = comic.getImageLink() embed = Embed(title="Laugh at this.", description="\u200B") embed.set_image(url=url) await ctx.reply(embed=embed)
async def getComic(self, context, comic_num=None): """ If argument is empty, get today's comic """ if comic_num is None: comic = xkcd.getTodayComic() comic_title = comic["title"] comic_text = comic["alt"] comic_picture = comic["img"] await context.send( f"{context.author.mention}, here is today's xkcd comic!") comic_message = discord.Embed(title=comic_title, description=comic_text) comic_message.add_field(name="Image url", value=comic_picture) comic_message.set_image(url=comic_picture) await context.send(embed=comic_message) else: comic = xkcd.getComic(comic_num) comic_title = comic["title"] comic_text = comic["alt"] comic_picture = comic["img"] await context.send( f"{context.author.mention}, here is a xkcd comic {comic_num}!") comic_message = discord.Embed(title=comic_title, description=comic_text) comic_message.add_field(name="Image url", value=comic_picture) comic_message.set_image(url=comic_picture) await context.send(embed=comic_message)
async def xkcd(self, ctx, query: int = None): """Queries a random XKCD comic. Do xkcd <number> to pick a specific comic.""" if query == 404: em = discord.Embed(color=discord.Color.red()) em.title = "\N{CROSS MARK} Error" em.description = "Error 404: Comic Not Found" return await ctx.send(embed=em) latest_comic = xkcd.getLatestComicNum() if query: query_req = 1 <= int(query) <= int(latest_comic) if query_req: comic = xkcd.getComic(query) else: em = discord.Embed(color=discord.Color.red()) em.title = "\N{CROSS MARK} Error" em.description = f"It has to be between 1 and {str(latest_comic)}!" return await ctx.send(embed=em) else: comic = xkcd.getRandomComic() embed = discord.Embed(title=f"xkcd {comic.number}: {comic.title}", url=comic.link) embed.set_image(url=comic.imageLink) embed.set_footer(text=comic.altText) await ctx.send(embed=embed)
async def getxkcd(self, ctx, comic_number): """ !getxkcd <comic_num> Gets an XKCD comic comic_num and returns various info about it. comic_num = integer """ if -1 < int(comic_number) < xkcd.getLatestComicNum(): # check for valid XKCD comic # get info about XCKD comic comic = xkcd.getComic(comic_number) comic_link = comic.getImageLink() alt_text = comic.getAltText() comic_name = comic.getImageName() comic_title = comic.getTitle() await ctx.send(f'```' f'Here is XKCD comic {comic_number}\nTitle: {comic_title}' f'```') await ctx.send(comic_link) await ctx.send(f'```' f'Alternate text: {alt_text}\nImage file name: {comic_name} ' f'```') else: await ctx.send(f'Invalid comic number. ' f'Please enter a number between 0 and {xkcd.getLatestComicNum()}')
async def xkcd(self, args, mobj): """ Returns the most likely xkcd to be referenced by the keywords """ xkcd_urls = search( f"site:xkcd.com -forums -wiki -blog {' '.join(args)}", 3) match = False for i, cur in enumerate(xkcd_urls): id = re.match(r"https://[\.m]*xkcd.com/(\d*)/", cur.link) if id: match = True break if not match: return await self.error(mobj.channel, "Nothing Found") comic = xkcd.getComic(int(id.group(1))) if comic == -1: return await self.error(mobj.channel, "Nothing Found") embed = Embed( title=comic.getTitle(), url=f"https://xkcd.com/{id.group(1)}", colour=Color(0x7289da) ) embed.set_image(url=comic.getImageLink()) embed.add_field(name="Alt-Text", value=comic.getAltText()) embed.add_field(name="Explanation", value=f"[Link]({comic.getExplanation()})") return await self.embed(mobj.channel, embed)
async def get_comic(self, comic, number=None) -> Embed: """Helper function to get comics""" case = { "latest": lambda: comics.getLatestComic(), "random": lambda: comics.getRandomComic(), "number": lambda: comics.getComic(number), } function = case.get(comic, None) exc = self.bot.loop.run_in_executor(None, function) while not exc.done(): await asyncio.sleep(0.1) result = exc.result() try: image_link = result.getImageLink() title = result.getAsciiTitle().decode("ascii") alt_text = result.getAsciiAltText().decode("ascii") number = result.number embed = Embed(title=title, url=f"https://xkcd.com/{number}", color=0x96A8C8) embed.add_field(name=str(number), value=alt_text) embed.set_image(url=image_link) return embed except AttributeError as error: embed = Embed(title="Error", color=0xFF0000) embed.add_field(name="Details", value=str(error)) return embed
async def xkcd(self, *, number=None): """xkcd comic""" try: if number == None: a = com.getRandomComic() title = a.getTitle() link = a.getImageLink() exp = a.getExplanation() embed = discord.Embed(title="xkcd", color=0xf5f5dc) embed.add_field(name="Title", value=title, inline=False) embed.set_footer(text=("For explanation refer to: " + exp)) embed.set_image(url=link) await self.bot.say(embed=embed) else: number = int(number) limit = com.getLatestComicNum() if number < 1 or number > limit: await self.bot.say( "Please enter a number between 1 to 1988") else: a = com.getComic(number, silent=True) title = a.getTitle() link = a.getImageLink() exp = a.getExplanation() embed = discord.Embed(title="xkcd", color=0xf5f5dc) embed.add_field(name="Title", value=title, inline=False) embed.set_footer(text=("For explanation refer to: " + exp)) embed.set_image(url=link) await self.bot.say(embed=embed) except Exception as e: await self.bot.say(f'Unable to fetch comic : {e}')
def get_comic(self, number): if number == None: comic = xkcd.getRandomComic() else: comic = xkcd.getComic(number) embed = Embed(description=comic.getAltText()) embed.set_author(name=comic.getTitle()) embed.set_image(url=comic.getImageLink()) return embed
async def on_message(self, message): # http://stackoverflow.com/questions/839994/extracting-a-url-in-python urls = re.findall(r'(https?://\S+)', message.content) for url in urls: ps = urlparse(url) if ps.netloc == "xkcd.com" or ps.netloc == "www.xkcd.com": comicnum = ps.path.replace('/', '') await self.bot.send_message(message.channel, embed=await self.embed_xkcd_comic( xkcd.getComic(comicnum)))
def test_download_comic_2x(self): # Try to download a 2x comic dlname = "xkcd-unittestpython_environment_2x.png" test = xkcd.getComic(1987) test.download(outputFile=dlname, x2=True) path = os.path.join(os.path.expanduser("~"), "Downloads", dlname) self.assertTrue(os.path.exists(path)) # Delete the downloaded file os.remove(path)
def test_download_comic(self): # Try to download a comic. dlname = "xkcd-unittestserver_attention_span.png" test = xkcd.getComic(869) test.download(outputFile=dlname) path = os.path.join(os.path.expanduser("~"), "Downloads", dlname) self.assertTrue(os.path.exists(path)) # Delete the downloaded file os.remove(path)
def xkcd_get(payload: str, message: Message, replies: Replies) -> None: """Get the comic with the given number or a ramdom comic if no number is provided.""" if not payload: comic = xkcd.getRandomComic() elif payload.isdigit(): comic = xkcd.getComic(int(payload)) else: comic = None if comic is None or comic.number == -1: replies.add(text="❌ Invalid comic number", quote=message) else: replies.add(**_get_reply(comic))
async def comic(ctx, integer=xkcd.getLatestComicNum()): comicNum = xkcd.getLatestComicNum() try: integer = int(integer) except ValueError: await invalidComic(ctx, integer) return if integer <= comicNum: comic = xkcd.getComic(integer) await sendComic(ctx, comic, integer) else: await invalidComic(ctx, integer)
def generate_comic_for_mode(current_comic_id, first_comic_id, max_comic_id, mode): """ Given the current comic ID plus the limits, do the logic for the different modes defined. Modes ---------- 'random': gets a comic randomly 'previous': gets the previous comic_id from the current_comic_id 'next': gets the next comic_id from the current_comic_id Parameters ---------- current_comic_id: current comic first_comic_id: lower boundary max_comic_id: upper boundry mode: string Returns ------- xkcd.Comic object filled properly """ if mode == 'random': comic = xkcd.getRandomComic() if mode == 'previous': if first_comic_id < current_comic_id < max_comic_id: previous_comic_id = int(current_comic_id) - 1 comic = xkcd.getComic(previous_comic_id) else: comic = xkcd.getComic(first_comic_id) if mode == 'next': if first_comic_id <= current_comic_id < max_comic_id: next_comic_id = int(current_comic_id) + 1 comic = xkcd.getComic(next_comic_id) else: comic = xkcd.getComic(max_comic_id) return comic
async def xkcd(self, comicnum): """Show xkcd comic by number. Use "latest" to show the latest comic, or "random" to show a random comic.""" if comicnum == "latest": await self.bot.say("", embed=await self.embed_xkcd_comic(xkcd.getLatestComic())) elif comicnum == "random": await self.bot.say("", embed=await self.embed_xkcd_comic(xkcd.getRandomComic())) else: await self.bot.say("", embed=await self.embed_xkcd_comic(xkcd.getComic(comicnum)))
def xkcd_response(text): match = re.match(r'!xkcd ?(\w+)? ?(\w+)?', text) if not match: return False option = match.group(1) link = match.group(2) comic = xkcd.getRandomComic() if option: if option == 'today': comic = xkcd.getLatestComic() elif option.isdigit(): comic = xkcd.getComic(int(option)) if link == 'link': return comic.link + '\n' + (EXPLAIN + str(comic.number)) else: return comic.title + '\n' + comic.imageLink + '\n' + comic.altText + '\n' + (EXPLAIN + str(comic.number))
async def execute_command(self, client, msg, content): image_url = "" title = "" alt_text = "" if len(content) == 0: comic = xkcd.getRandomComic() image_url = comic.getImageLink() title = comic.getTitle() alt_text = comic.getAltText() elif content.isnumeric(): try: comic = xkcd.getComic(int(content), silent=False) image_url = comic.getImageLink() title = comic.getTitle() alt_text = comic.getAltText() except: await utils.delay_send( msg.channel, client.messages["no_xkcd_found"].format(content)) return else: async with utils.get_aiohttp().post( "https://relevant-xkcd-backend.herokuapp.com/search", data={"search": content}, ) as request: text = await request.text() response = json.loads(text) if not response["success"] or len(response["results"]) == 0: await utils.delay_send( msg.channel, client.messages["no_xkcd_found"].format(content)) return image_url = response["results"][0]["image"] title = response["results"][0]["title"] alt_text = response["results"][0]["titletext"] msg_to_send = "**" + title + ":** " + alt_text tmp_file = BytesIO() async with utils.get_aiohttp().get(image_url) as r: tmp_file.write(await r.read()) tmp_file.seek(0) await msg.channel.send(msg_to_send, file=discord.File(tmp_file, "xkcd.png"))
def xkcd_response(text): """!xkcd (#|today|random)? 'link'?: returns an xkcd comic. default random""" match = re.match(r'!xkcd ?(\w+)? ?(\w+)?', text) if not match: return False option = match.group(1) link = match.group(2) comic = xkcd.getRandomComic() if option: if option == 'today': comic = xkcd.getLatestComic() elif option.isdigit(): comic = xkcd.getComic(int(option)) if link == 'link': return comic.link + '\n' + (EXPLAIN + str(comic.number)) else: return comic.title + '\n' + comic.imageLink + '\n' + comic.altText + '\n' + ( EXPLAIN + str(comic.number))
def xkcdR(content): import xkcd print("Loading xkcd") print(content) if content == "random": print("Getting Random") comic = xkcd.getRandomComic() elif content == "latest": print("Getting latest") comic = xkcd.getLatestComic() else: print("Getting by id") comic = xkcd.getComic(int(content)) print("Downloading Comic") comic.download(output="/home/victor/PycharmProjects/wppchatbot/", outputFile="xkcd.png") altText = comic.getAltText() print(altText) return "!xkcd.png|" + altText
async def xkcd(self, ctx, number=None): """Sends the link of a random xkcd comic to the chat. if a number is specified, send the comic referring to that number.""" if number: comic = xkcd.getComic(number) else: comic = xkcd.getRandomComic() comicurl = comic.getImageLink() embed = discord.Embed(description=f'[Image Link]({comicurl})') embed.set_image(url=comicurl) embed.colour = 0x42c2f4 try: await ctx.channel.send(embed=embed) except: pass
async def getxkcd(self, ctx, call='random'): """Functions that call to xkcd comics API""" if call == 'random': comic = xkcd.getRandomComic() elif call == 'latest': comic = xkcd.getLatestComic() elif call.isdigit(): comic = xkcd.getComic(call) else: await ctx.send('Hmm... I can\'t find a comic with that parameter.') ctitle = comic.getTitle() catext = comic.getAltText() curl = comic.getImageLink() cimgn = comic.getImageName() cnumber = str(comic)[38:] # Embed and say message embed = discord.Embed(title=ctitle, description=catext) embed.set_image(url=curl) embed.set_footer(text='xkcd issue {}: {}'.format(cnumber, cimgn)) await ctx.send(embed=embed)
class XKCD(commands.Cog): """A plugin to retrieve XKCD comics.""" def __init__(self, bot: commands.Bot): self.bot = bot self.name = "xkcd" # Helper function for getting comics async def get_comic(self, comic, number=None) -> Embed: case = { "latest": lambda: xkcd.getLatestComic(), "random": lambda: xkcd.getRandomComic(), "number": lambda: xkcd.getComic(number) } function = case.get(comic, None) exc = self.bot.loop.run_in_executor(None, function) while not exc.done(): await asyncio.sleep(0.1) exc = exc.result() try: image_link = exc.getImageLink() title = exc.getAsciiTitle().decode("ascii") alt_text = exc.getAsciiAltText().decode("ascii") number = exc.number embed = Embed(title=title, url=link, color=0x96A8C8) embed.add_field(name=str(number), value=alt_text) embed.set_image(image_link) return embed except AttributeError as error: embed = Embed(title="Error", color=0xff0000) embed.add_field(name="Details", value=str(error)) return embed
def test_no_such_comic(self): bad = xkcd.getComic(-100) self.assertEqual(bad.number, -1)
def xkcd_by_number(self, msg, matches): comic = xkcd.getComic(int(matches.group(1))) return self.return_comic(msg, comic)
def test_comic(self): # Get a comic to test. test = xkcd.getComic(869) self.assertEqual(test.number, 869) self.assertEqual(test.title, "Server Attention Span") self.assertEqual(test.imageName, "server_attention_span.png")
def send_new_comic(number, chat_id): comic = xkcd.getComic(number) bot.sendMessage(chat_id=chat_id, text="Title:\n%s" % comic.getTitle()) bot.sendPhoto(chat_id=chat_id, photo=comic.getImageLink()) bot.sendMessage(chat_id=chat_id, text="Alt text:\n%s" % comic.getAltText())