我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用discord.File()。
def longcat(message, match): body_length = min(len(match.group(1)), 20) width = cat_tail.width + body_length * cat_body.width + cat_head.width im = Image.new('RGBA', (width, cat_head.height), 0x00000000) im.paste(cat_tail, (0, 0)) x = cat_tail.width for i in range(body_length): im.paste(cat_body, (x, 0)) x += cat_body.width im.paste(cat_head, (x, 0)) buf = io.BytesIO() im.save(buf, 'png') buf.seek(0) await message.channel.send(file=discord.File(buf, match.group(0) + '.png')) ### BRUTAL SAVAGE REKT
def _dumpcc(self, msg): gid = str(msg.guild.id) self._initialize(gid) if msg.author.id in self.storage[gid]["cc_create_ban"]: raise UserPermissionError("You are banned from editing custom commands.") gid = str(msg.guild.id) self._initialize(gid) args = msg.content.split(" ", 1) if len(args) < 2: raise CommandSyntaxError("No name provided.") name = args[1].lower() if name in self.ccs[gid]: t_cc = { "name": name, "content": self.ccs[gid][name]["content"] } t_cc = json.dumps(t_cc, indent=2, ensure_ascii=False) async with msg.channel.typing(): await respond(msg, "**AFFIRMATIVE. Completed file upload.**", file=File(BytesIO(bytes(t_cc, encoding="utf-8")), filename=name + ".json")) else: raise CommandSyntaxError("No such custom command.")
def jpeg(self, ctx, image_source: converters.Image): """ Drastically lowers an image's quality. This command takes an image, and saves it as a JPEG with the quality of 1. """ im_data = await get_bytesio(self.bot.session, image_source) im = Image.open(im_data).convert('RGB') with BytesIO() as output: await ctx.bot.loop.run_in_executor( None, functools.partial(im.save, output, format='jpeg', quality=1) ) output.seek(0) await ctx.send(file=discord.File(output, filename='jpeg.jpg')) im.close() im_data.close()
def orly(self, ctx, title, guide, author, *, top_text=''): """Generates O'Reilly book covers.""" api_base = 'https://orly-appstore.herokuapp.com/generate?' url = (api_base + f'title={urlescape(title)}&top_text={urlescape(top_text)}&image_code={randrange(0, 41)}' + f'&theme={randrange(0, 17)}&author={urlescape(author)}&guide_text={urlescape(guide)}' + f'&guide_text_placement=bottom_right') try: async with ctx.typing(): async with ctx.bot.session.get(url) as resp: with BytesIO(await resp.read()) as bio: await ctx.send(file=discord.File(filename='orly.png', fp=bio)) except aiohttp.ClientError: await ctx.send("Couldn't contact the API.")
def emote(self, ctx, emote: str): """Get a Twitch, FrankerFaceZ, BetterTTV, or Discord emote. Usage: emote [name of emote]""" emote = emote.replace(':', '') with async_timeout.timeout(13): try: async with self.bot.cog_http.get('https://static-cdn.jtvnw.net/emoticons/v1/' + str(self.bot.emotes['twitch'][emote]['image_id']) + '/1.0') as resp: emote_img = await resp.read() except KeyError: # let's try frankerfacez try: async with self.bot.cog_http.get('https://cdn.frankerfacez.com/emoticon/' + str(self.bot.emotes['ffz'][emote]) + '/1') as resp: emote_img = await resp.read() except KeyError: # let's try BetterTTV try: async with self.bot.cog_http.get(self.bot.emotes['bttv'][emote]) as resp: emote_img = await resp.read() except KeyError: # let's try Discord await ctx.send('**No such emote!** I can fetch from Twitch, FrankerFaceZ, BetterTTV, or Discord (soon).') return False img_bytes = io.BytesIO(emote_img) ext = imghdr.what(img_bytes) await ctx.send(file=discord.File(img_bytes, f'emote.{ext}'))
def qrcode(cmd, message, args): if args: url = 'https://neutrinoapi-qr-code.p.mashape.com/qr-code' content = ' '.join(args) headers = { "X-Mashape-Key": MashapeKey, "Content-Type": "application/x-www-form-urlencoded" } params = { "bg-color": "#FFFFFF", "content": content, "fg-color": "#000000", "height": 512, "width": 512 } async with aiohttp.ClientSession() as session: async with session.post(url, data=params, headers=headers) as data: data = await data.read() output = discord.File(BytesIO(data), filename=f'qr_{message.id}.png') await message.channel.send(file=output) if args[-1].startswith('del'): try: await message.delete() except: pass
def catlen(cmd, message, args): if message.mentions: target = message.mentions[0] else: target = message.author length_number = int(str(target.id)[6]) + int(str(target.id)[9]) img_height = 54 img_width = 62 + (length_number * 15) + 50 base = Image.new('RGBA', (img_width, img_height), (255, 255, 255, 0)) image_location = 'meow' out_location = f'cache/meow_len_{message.id}.png' with Image.open(cmd.resource(f'{image_location}/bot.png')) as bot_cat_img: base.paste(bot_cat_img, (0, 0), bot_cat_img) with Image.open(cmd.resource(f'{image_location}/mid.png')) as mid_cat_img: for n in range(0, length_number - 1): base.paste(mid_cat_img, (62 + (n * 15), 0), mid_cat_img) with Image.open(cmd.resource(f'{image_location}/top.png')) as top_cat_img: base.paste(top_cat_img, (62 + ((length_number - 1) * 15), 0), top_cat_img) base.save(out_location) await message.channel.send(file=discord.File(out_location)) os.remove(out_location)
def opendota(self, ctx, *, query): """Queries the opendota api You can use this to get a json file with details about players or matches etc. Examples: `{cmdpfx}opendota /players/{steamid}` `{cmdpfx}opendota /matches/{match_id}` For more options and a better explanation, check out their [documentation](https://docs.opendota.com)""" query = query.replace("/", " ") query = query.strip() query = "/" + "/".join(query.split(" ")) with ctx.channel.typing(): data = await opendota_query(query) filename = re.search("/([/0-9a-zA-Z]+)", query).group(1).replace("/", "_") filename = settings.resource(f"temp/{filename}.json") write_json(filename, data) await ctx.send(file=discord.File(filename)) os.remove(filename)
def emoticon(self, ctx, name): """Gets the gif of a dota emoticon **Examples:** `{cmdpfx}emoticon pup` `{cmdpfx}emoticon stunned` `{cmdpfx}emoticon naga_song""" await ctx.channel.trigger_typing() emoticon = session.query(Emoticon).filter(Emoticon.name == name).first() if not emoticon: raise UserError(f"Couldn't find an emoticon with the name '{name}'") url = self.vpkurl + emoticon.url image = discord.File(await drawdota.create_dota_emoticon(emoticon, url), f"{name}.gif") await ctx.send(file=image)
def download_data(self, message: discord.Message) -> str: """Checks if an attachment is viable to be used as MIDI input and downloads it.""" if not message.attachments: raise self.SayException('You did not attach a file to ' 'use as MIDI input!, `j!help midi`') attachment = message.attachments[0] if not attachment.filename.endswith('.txt'): raise self.SayException('File must be a .txt!') # see if the file is bigger than 20 KiB as we don't want # to download huge files if attachment.size >= 20 * 1024: raise self.SayException('File is too large. ' 'Your file may only be 20KiB big.') log.info('downloading file to use as MIDI input. ' f'{attachment.size} bytes large.') buffer = io.BytesIO() await attachment.save(buffer) return buffer.getvalue().decode('utf-8')
def on_guild_emojis_update(self, guild, before, after): # we only care when an emoji is added lookup = { e.id for e in before } added = [e for e in after if e.id not in lookup and len(e.roles) == 0] if len(added) == 0: return log.info('Server %s has added %s emojis.', guild, len(added)) if guild.id != BLOB_GUILD_ID: return # not the guild we care about # this is the backup channel channel = self.bot.get_channel(305841865293430795) if channel is None: return for emoji in added: async with self.bot.session.get(emoji.url) as resp: if resp.status != 200: continue data = io.BytesIO(await resp.read()) await channel.send(emoji.name, file=discord.File(data, f'{emoji.name}.png')) await asyncio.sleep(1)
def blobsort(self, ctx): """Sorts the blob post.""" emojis = sorted([e.name for e in ctx.guild.emojis if len(e.roles) == 0]) fp = io.BytesIO() pages = [emojis[i:i + 30] for i in range(0, len(emojis), 30)] for number, page in enumerate(pages, 1): fmt = f'Page {number}\n' fp.write(fmt.encode('utf-8')) for emoji in page: fmt = f':{emoji}: = `:{emoji}:`\n' fp.write(fmt.encode('utf-8')) fp.write(b'\n') fp.seek(0) await ctx.send(file=discord.File(fp, 'blob_posts.txt'))
def emoji(self, ctx, emojiname: str): '''Gibt eine vergrößerte Version eines angegebenen Emojis zurück Beispiel: ----------- :emoji Emilia ''' emoji = discord.utils.find(lambda e: e.name.lower() == emojiname.lower(), self.bot.emojis) if emoji: tempEmojiFile = 'tempEmoji.png' async with aiohttp.ClientSession() as cs: async with cs.get(emoji.url) as img: with open(tempEmojiFile, 'wb') as f: f.write(await img.read()) f = discord.File(tempEmojiFile) await ctx.send(file=f) os.remove(tempEmojiFile) else: await ctx.send(':x: Konnte das angegebene Emoji leider nicht finden :(')
def _quilt(self, avatars): """ Makes a quilt of avatars of avatars that tries to be as square as possible """ xbound = math.ceil(math.sqrt(len(avatars))) ybound = math.ceil(len(avatars) / xbound) size = int(2520 / xbound) base = Image.new(mode='RGBA', size=(xbound * size, ybound * size), color=(0, 0, 0, 0)) x, y = 0, 0 for avatar in avatars: im = Image.open(avatar) base.paste(im.resize((size, size), resample=Image.BILINEAR), box=(x * size, y * size)) if x < xbound - 1: x += 1 else: x = 0 y += 1 buffer = BytesIO() base.save(buffer, 'png') buffer.seek(0) return discord.File(buffer, filename='quilt.png')
def retro(self, ctx, line_1: str, line_2: str = '', *, line_3: str = ''): """Credits: ReinaSakuraba (Reina#0277)""" if not re.fullmatch(r'[A-Za-z0-9 ]+', line_1): return await ctx.send('First line only supports alphanumerical characters.') data = { 'bcg': random.randint(1, 5), 'txt': random.randint(1, 4), 'text1': line_1, 'text2': line_2, 'text3': line_3, } async with ctx.session.post('https://photofunia.com/effects/retro-wave', data=data) as r: txt = await r.text() link = re.search(r'(https?.+?.jpg\?download)', txt) async with ctx.session.get(link.group(1)) as r: await ctx.send(file=discord.File(io.BytesIO(await r.read()), 'retro.jpg'))
def getcolour(self, ctx, *, colour_codes): """Posts color of given hex""" await ctx.message.delete() colour_codes = colour_codes.split() size = (60, 80) if len(colour_codes) > 1 else (200, 200) if len(colour_codes) > 5: return await ctx.send(self.bot.bot_prefix + "Sorry, 5 colour codes maximum") for colour_code in colour_codes: if not colour_code.startswith("#"): colour_code = "#" + colour_code image = Image.new("RGB", size, colour_code) with io.BytesIO() as file: image.save(file, "PNG") file.seek(0) await ctx.send("Colour with hex code {}:".format(colour_code), file=discord.File(file, "colour_file.png")) await asyncio.sleep(1) # Prevent spaminess
def jumbo(self, ctx): """Get a closer look at a custom emoji. **Usage:** `g_jumbo <custom emoji>` **Permission:** User""" umsg = ctx.message.content args = umsg.split(' ') try: emote = args[1] except IndexError: await ctx.send(":x: That is not a custom emote.") return emote_id = None try: if extract_emote_id(emote) is not None: emote_id = extract_emote_id(emote) except: pass if emote_id is None: await ctx.send(":x: That is not a custom emote.") return emote_url = "https://cdn.discordapp.com/emojis/{}.png".format(emote_id) o = AppURLopener() r = o.open(emote_url) data = r.read() with open("./images/emotes/{}.png".format(emote_id), "wb") as avatar: avatar.write(data) avatar.close() await ctx.send(file=discord.File("./images/emotes/{}.png".format(emote_id)))
def cuddle(self, ctx): """For when you just need to cuddle someone uwu **Usage:** `g_cuddle <user(s)>` **Permission:** User""" img = ["./images/cuddlea.gif", "./images/cuddleb.gif", "./images/cuddlec.gif", "./images/cuddled.gif", "./images/cuddlee.gif", "./images/cuddlef.gif", "./images/cuddleg.gif", "./images/cuddleh.gif", "./images/cuddlei.gif", "./images/cuddlej.gif"] var = int(random.random() * len(img)) if len(ctx.message.mentions) == 0: await ctx.send(":x: You must mention a user!") elif len(ctx.message.mentions) > 0: ments = "" for x in range(0, len(ctx.message.mentions)): if ctx.message.mentions[x].id == ctx.message.author.id: msg = '<:godavarublobhug:318227863646109696> Aww, are you lonely? I\'ll cuddle with you, **'+ctx.message.author.display_name+'**!' await ctx.send(file=discord.File(img[var]), content=msg) return if x == 0: ments = ctx.message.mentions[x].display_name elif x == len(ctx.message.mentions) - 1: if len(ctx.message.mentions) == 2: ments = ments+" and "+ctx.message.mentions[x].display_name else: ments = ments+", and "+ctx.message.mentions[x].display_name else: ments = ments+", "+ctx.message.mentions[x].display_name if len(ctx.message.mentions) == 1: pr = "was" else: pr = "were" msg = '<:godavarublobhug:318227863646109696> **' + ments + '** '+pr+' cuddled by **' + ctx.message.author.display_name +'**!' await ctx.send(file=discord.File(img[var]), content=msg) else: await ctx.send("An unexpected error occurred. Please report this to Desiree#3658 on the support guild, link found in g!about.") # just in case. You never know shrug
def hug(self, ctx): """Give a person a big fat hug! Awww! **Usage:** `g_hug <user(s)>` **Permission:** User""" img = ["./images/huga.gif", "./images/hugb.gif", "./images/hugc.gif", "./images/hugd.gif", "./images/huge.gif", "./images/hugf.gif", "./images/hugg.gif", "./images/hugh.gif", "./images/hugi.gif", "./images/hugj.gif"] var = int(random.random() * len(img)) if len(ctx.message.mentions) == 0: await ctx.send(":x: You must mention a user!") elif len(ctx.message.mentions) > 0: ments = "" for x in range(0, len(ctx.message.mentions)): if ctx.message.mentions[x].id == ctx.message.author.id: msg = ':hugging: Aww, are you lonely? I\'ll cuddle with you, **'+ctx.message.author.display_name+'**!' await ctx.send(file=discord.File(img[var]), content=msg) return if x == 0: ments = ctx.message.mentions[x].display_name elif x == len(ctx.message.mentions) - 1: if len(ctx.message.mentions) == 2: ments = ments+" and "+ctx.message.mentions[x].display_name else: ments = ments+", and "+ctx.message.mentions[x].display_name else: ments = ments+", "+ctx.message.mentions[x].display_name if len(ctx.message.mentions) == 1: pr = "was" else: pr = "were" msg = ':hugging: **' + ments + '** '+pr+' hugged by **' + ctx.message.author.display_name +'**!' await ctx.send(file=discord.File(img[var]), content=msg) else: await ctx.send("An unexpected error occurred. Please report this to Desiree#3658 on the support guild, link found in g!about.") # just in case. You never know shrug
def slap(self, ctx): """What the hell did you just say to me? I'm gonna slap you to the moon for that comment! **Usage:** `g_slap <user(s)>` **Permission:** User""" img = ["./images/slapa.gif", "./images/slapb.gif", "./images/slapc.gif", "./images/slapd.gif", "./images/slape.gif", "./images/slapf.gif", "./images/slapg.gif", "./images/slaph.gif", "./images/slapi.gif"] var = int(random.random() * len(img)) if len(ctx.message.mentions) == 0: await ctx.send(":x: You must mention a user!") elif len(ctx.message.mentions) > 0: ments = "" for x in range(0, len(ctx.message.mentions)): if ctx.message.mentions[x].id == ctx.message.author.id: msg = ':raised_hand: This makes no sense... Oh well' await ctx.send(file=discord.File(img[var]), content=msg) return if x == 0: ments = ctx.message.mentions[x].display_name elif x == len(ctx.message.mentions) - 1: if len(ctx.message.mentions) == 2: ments = ments+" and "+ctx.message.mentions[x].display_name else: ments = ments+", and "+ctx.message.mentions[x].display_name else: ments = ments+", "+ctx.message.mentions[x].display_name msg = ':raised_hand: Hyaah! **' + ctx.message.author.display_name + '** has slapped **' + ments + '**!' await ctx.send(file=discord.File(img[var]), content=msg) else: await ctx.send("An unexpected error occurred. Please report this to Desiree#3658 on the support guild, link found in g!about.") # just in case. You never know shrug
def kiss(self, ctx): """Give that special someone a kiss! <3 **Usage:** `g_kiss <user(s)>` **Permission:** User""" img = ["./images/kissa.gif", "./images/kissb.gif", "./images/kissc.gif", "./images/kissd.gif", "./images/kisse.gif", "./images/kissf.gif", "./images/kissg.gif", "./images/kissh.gif", "./images/kissi.gif", "./images/kissj.gif", "./images/kissk.gif"] var = int(random.random() * len(img)) if len(ctx.message.mentions) == 0: await ctx.send(":x: You must mention a user!") elif len(ctx.message.mentions) > 0: ments = "" for x in range(0, len(ctx.message.mentions)): if ctx.message.mentions[x].id == ctx.message.author.id: msg = ":kissing_heart: I don't think you can kiss yourself... I'll kiss you instead!" await ctx.send(file=discord.File(img[var]), content=msg) return if x == 0: ments = ctx.message.mentions[x].display_name elif x == len(ctx.message.mentions) - 1: if len(ctx.message.mentions) == 2: ments = ments+" and "+ctx.message.mentions[x].display_name else: ments = ments+", and "+ctx.message.mentions[x].display_name else: ments = ments+", "+ctx.message.mentions[x].display_name if len(ctx.message.mentions) == 1: pr = "was" else: pr = "were" msg = ':kissing_heart: **' + ments + '** ' + pr + ' kissed by **' + ctx.message.author.display_name +'**!' await ctx.send(file=discord.File(img[var]), content=msg) else: await ctx.send("An unexpected error occurred. Please report this to Desiree#3658 on the support guild, link found in g!about.") # just in case. You never know shrug
def poke(self, ctx): """Do you ever have a friend who just wont stop ignoring you? Just poke them. :eyes: **Usage:** `g_poke <user(s)>` **Permission:** User""" img = ["./images/pokea.gif", "./images/pokeb.gif", "./images/pokec.gif", "./images/poked.gif", "./images/pokee.gif", "./images/pokef.gif", "./images/pokeg.gif", "./images/pokeh.gif", "./images/pokei.gif", "./images/pokej.gif"] var = int(random.random() * len(img)) if len(ctx.message.mentions) == 0: await ctx.send(":x: You must mention a user!") elif len(ctx.message.mentions) > 0: ments = "" for x in range(0, len(ctx.message.mentions)): if ctx.message.mentions[x].id == ctx.message.author.id: msg = ":eyes: You can't poke nothing! I'll poke you instead!" await ctx.send(file=discord.File(img[var]), content=msg) return if x == 0: ments = ctx.message.mentions[x].display_name elif x == len(ctx.message.mentions) - 1: if len(ctx.message.mentions) == 2: ments = ments+" and "+ctx.message.mentions[x].display_name else: ments = ments+", and "+ctx.message.mentions[x].display_name else: ments = ments+", "+ctx.message.mentions[x].display_name if len(ctx.message.mentions) == 1: pr = "was" else: pr = "were" msg = ':eyes: **' + ments + '** ' + pr + ' poked by **' + ctx.message.author.display_name +'**!' await ctx.send(file=discord.File(img[var]), content=msg) else: await ctx.send("An unexpected error occurred. Please report this to Desiree#3658 on the support guild, link found in g!about.") # just in case. You never know shrug
def wakeup(self, ctx): """A way to get your friends off of their lazy butts and wake up. **Usage:** `g_wakeup <user(s)>` **Permission:** User""" img = ["./images/wakeupa.gif", "./images/wakeupb.gif", "./images/wakeupc.gif", "./images/wakeupd.gif", "./images/wakeupe.gif", "./images/wakeupf.gif", "./images/wakeupg.gif", "./images/wakeuph.gif"] var = int(random.random() * len(img)) if len(ctx.message.mentions) == 0: await ctx.send(":x: You must mention a user!") elif len(ctx.message.mentions) > 0: ments = "" for x in range(0, len(ctx.message.mentions)): if ctx.message.mentions[x].id == ctx.message.author.id: msg = '<:morning:319631823766552597> What are you trying to wake up? Well, you do you I guess.' await ctx.send(file=discord.File(img[var]), content=msg) return if x == 0: ments = ctx.message.mentions[x].display_name elif x == len(ctx.message.mentions) - 1: if len(ctx.message.mentions) == 2: ments = ments+" and "+ctx.message.mentions[x].display_name else: ments = ments+", and "+ctx.message.mentions[x].display_name else: ments = ments+", "+ctx.message.mentions[x].display_name msg = '<:morning:319631823766552597> **' + ments + '**, rise and shine! **' + ctx.message.author.display_name + '** wants you to wake up!' await ctx.send(file=discord.File(img[var]), content=msg) else: await ctx.send("An unexpected error occurred. Please report this to Desiree#3658 on the support guild, link found in g!about.") # just in case. You never know shrug
def cry(self, ctx): """When life gets at you and you just wanna let it all out. **Usage:** `g_cry [user(s)]` **Permission:** User""" img = ["./images/crya.gif", "./images/cryb.gif", "./images/cryc.gif", "./images/cryd.gif", "./images/crye.gif", "./images/cryf.gif", "./images/cryg.gif", "./images/cryh.gif", "./images/cryi.gif", "./images/cryj.gif", "./images/cryk.gif"] var = int(random.random() * len(img)) if len(ctx.message.mentions) == 0: msg = ":cry: **"+ctx.message.author.display_name+"** just started to cry!" await ctx.send(file=discord.File(img[var]), content=msg) # desii do not touch this command again elif len(ctx.message.mentions) > 0: ments = "" for x in range(0, len(ctx.message.mentions)): if ctx.message.mentions[x].id == ctx.message.author.id: msg = ":cry: **"+ctx.message.author.display_name+"** just started to cry!" await ctx.send(file=discord.File(img[var]), content=msg) return if x == 0: ments = ctx.message.mentions[x].display_name elif x == len(ctx.message.mentions) - 1: if len(ctx.message.mentions) == 2: ments = ments+" and "+ctx.message.mentions[x].display_name else: ments = ments+", and "+ctx.message.mentions[x].display_name else: ments = ments+", "+ctx.message.mentions[x].display_name else: msg = ":cry: **"+ments+"** just made **"+ctx.message.author.display_name+"** cry!" await ctx.send(file=discord.File(img[var]), content=msg) else: await ctx.send("An unexpected error occurred.") # i mean it
def dog(cmd, message, args): doggie_url = 'http://www.randomdoggiegenerator.com/randomdoggie.php' async with aiohttp.ClientSession() as session: async with session.get(doggie_url) as data: doggie_image = await data.read() with open(f'cache/pupper_{message.id}.png', 'wb') as pupper_img: pupper_img.write(doggie_image) await message.channel.send(file=discord.File(f'cache/pupper_{message.id}.png')) os.remove(f'cache/pupper_{message.id}.png')
def color(cmd, message, args): if args: if len(args) == 1: color_input = args[0] while color_input.startswith('#'): color_input = color_input[1:] if len(color_input) == 6: try: color_tupple = (int(color_input[:2], 16), int(color_input[2:-2], 16), int(color_input[4:], 16)) response = None image = Image.new('RGB', (128, 128), color_tupple) image.save(f'cache/{message.id}.png') except ValueError: response = discord.Embed(color=0xBE1931, title='? Something here is not a number.') else: response = discord.Embed(color=0xBE1931, title='? Invalid HEX color code.') elif len(args) == 3: try: color_tupple = (int(args[0]), int(args[1]), int(args[2])) response = None image = Image.new('RGB', (128, 128), color_tupple) image.save(f'cache/{message.id}.png') except ValueError: response = discord.Embed(color=0xBE1931, title='? Something here is not a number.') else: response = discord.Embed(color=0xBE1931, title='? Invalid input, HEX or RGB sequence, please.') else: response = discord.Embed(color=0xBE1931, title='? Nothing inputted.') if response: await message.channel.send(embed=response) else: img_file = discord.File(f'cache/{message.id}.png') await message.channel.send(file=img_file) os.remove(f'cache/{message.id}.png')
def _dump(self, msg): args = msg.content.split(" ", 3) if len(args) < 3: raise CommandSyntaxError("Wrong number of arguments.") try: m_start = int(args[1]) except ValueError: raise CommandSyntaxError("First Argument is not a valid integer.") try: m_end = int(args[2]) except ValueError: raise CommandSyntaxError("Second Argument is not a valid integer.") try: m_start = await msg.channel.get_message(m_start) except NotFound: raise CommandSyntaxError(f"No message with ID {m_start}") try: m_end = await msg.channel.get_message(m_end) except NotFound: raise CommandSyntaxError(f"No message with ID {m_end}") if len(args) > 3: t_name = args[3]+".txt" else: t_name = str(time.time())+".txt" s = "%Y-%m-%d %H:%M:%S" t_list = [f"{str(m_end.author)} @ {str(m_end.created_at.strftime(s))}\n{m_end.clean_content}\n\n"] async for message in msg.channel.history(before=m_start, after=m_end, reverse=True, limit=None): t_list.append(f"{str(message.author)} @ {str(message.created_at.strftime(s))}\n{message.clean_content}\n\n") t_list.append(f"{str(m_start.author)} @ {str(m_start.created_at.strftime(s))}\n{m_start.clean_content}") t_msg = await respond(msg, f"**AFFIRMATIVE. Processing file {t_name}.**") async with msg.channel.typing(): await respond(msg, "**AFFIRMATIVE. Completed file upload.**", file=File(BytesIO(bytes("".join(t_list), encoding="utf-8")), filename=t_name)) await t_msg.delete()
def export_image(ctx: DogbotContext, image: Image, filename: str): with BytesIO() as bio: # Export the image. coro = ctx.bot.loop.run_in_executor(None, functools.partial(image.save, bio, format='png')) await asyncio.wait([coro], loop=ctx.bot.loop, timeout=5) # Upload to the channel. bio.seek(0) await ctx.send(file=discord.File(bio, filename))
def meme(self, ctx, *, pre_text: str): """Generate a meme! Usage: meme [top text] [bottom text]""" char_table = { '-': '--', '_': '__', '?': '~q', '%': '~p', '#': '~h', # TODO: make '/': '~s', '"': "''", '\n': ' ' } for key in char_table: pre_text = pre_text.replace(key, char_table[key]) pre_text = pre_text.replace(' ', '__bottom__') pre_text = pre_text.replace(' ', '-') if '__bottom__' in pre_text: segments = pre_text.split('__bottom__') else: segments = textwrap.wrap(pre_text, width=int(len(pre_text) / 2)) with async_timeout.timeout(10): async with self.bot.cog_http.get('https://memegen.link/api/templates/') as r: rtext = await r.text() templates = list(json.loads(rtext).values()) rtemp = random.choice(templates) meme_url = rtemp + '/' + segments[0] + '/' + segments[1] + '.jpg' async with self.bot.cog_http.get(meme_url) as r: raw_image = await r.read() await ctx.send(file=discord.File(BytesIO(raw_image), 'meme.jpg'))
def qrcode(self, ctx, *, text: str): """Create a QR code. Usage: qrcode [text to use]""" img_bytes = BytesIO() image = await self.loop.run_in_executor(None, qrcode.make, text) image.save(img_bytes, format='PNG') img_bytes.seek(0) await ctx.send(file=discord.File(img_bytes, 'qrcode.png'))
def screenshot(self, ctx): """Take a screenshot. Usage: screenshot""" echeck_perms(ctx, ('bot_owner',)) if have_pil and sys.platform not in ['linux', 'linux2']: grabber = ImageGrab else: grabber = pyscreenshot image = grabber.grab() img_bytes = io.BytesIO() image.save(img_bytes, format='PNG') img_bytes.seek(0) await ctx.send('This is *probably* what my screen looks like right now.', file=discord.File(img_bytes, 'screenshot.png'))
def render(self, ctx, *, webpage: str): """Render a webpage to image. Usage: render [url]""" echeck_perms(ctx, ('bot_owner',)) await ctx.send(':warning: Not working. ' 'Type `yes` quickly if you\'re fine with this crashing.') if not (await self.bot.wait_for('message', timeout=6.0, check=lambda m: m.content.lower().startswith('yes') and m.author == ctx.author and m.channel == ctx.channel)): return self.web_render = scr.Screenshot() image = self.web_render.capture(webpage) await ctx.send(file=discord.File(io.BytesIO(image), 'webpage.png'))
def dog(cmd, message, args): doggie_url = 'http://www.randomdoggiegenerator.com/randomdoggie.php' async with aiohttp.ClientSession() as session: async with session.get(doggie_url) as data: doggie_image = await data.read() with Image.open(BytesIO(doggie_image)) as img: img.save(f'cache/pupper_{message.id}.png') await message.channel.send(file=discord.File(f'cache/pupper_{message.id}.png')) os.remove(f'cache/pupper_{message.id}.png')
def color(cmd, message, args): if not args: await message.channel.send(cmd.help()) else: if len(args) == 3: for arg in args: if int(arg) > 255: await cmd.bot.send_message(message.channel, 'Error processing inputted variables.\nNo number can be greater than 255 when defining RGB.') return try: clr = (int(args[0]), int(args[1]), int(args[2])) except: await message.channel.send('Error processing inputted variables.') return else: try: clr = str(args[0]).replace('#', '') part1 = clr[:2] part1 = int(part1, 16) part2 = clr[2:-2] part2 = int(part2, 16) part3 = clr[4:] part3 = int(part3, 16) clr = (part1, part2, part3) except: await message.channel.send('Error processing inputted variables.') return img = Image.new('RGB', (50, 50), clr) img.save(f'cache/{message.author.id}.png') await message.channel.send(file=discord.File(f'cache/{message.author.id}.png')) os.remove(f'cache/{message.author.id}.png')
def _default_flip(self, ctx): """Flip called with no arguments""" side = random.choices(SIDES, WEIGHTS)[0] file = discord.File(f'data/images/coins/{side}.png', 'coin.png') embed = (discord.Embed(colour=ctx.bot.colour, description=f'...flipped **{side}**') .set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url) .set_image(url='attachment://coin.png') ) await ctx.send(file=file, embed=embed)
def _flip_image(self, num_sides): images = { Side.heads: self._heads_image, Side.tails: self._tails_image, } stats = collections.Counter() root = num_sides ** 0.5 height, width = round(root), int(math.ceil(root)) sides = (random.choices(SIDES, WEIGHTS)[0] for _ in range(num_sides)) size = self.image_size image = Image.new('RGBA', (width * size, height * size)) for i, side in enumerate(sides): y, x = divmod(i, width) image.paste(images[side], (x * size, y * size)) stats[side] += 1 message = ' and '.join(pluralize(**{str(side)[:-1]: n}) for side, n in stats.items()) f = io.BytesIO() image.save(f, 'png') f.seek(0) return message, discord.File(f, filename='flipcoins.png')
def _create_ship_image(self, score, avatar1, avatar2): ava_im1 = Image.open(avatar1).convert('RGBA') ava_im2 = Image.open(avatar2).convert('RGBA') # Assume the two images are square size = min(ava_im1.size, ava_im2.size) offset = round(_scale(0, 100, size[0], 0, score)) ava_im1.thumbnail(size) ava_im2.thumbnail(size) # paste img1 on top of img2 newimg1 = Image.new('RGBA', size=size, color=(0, 0, 0, 0)) newimg1.paste(ava_im2, (-offset, 0)) newimg1.paste(ava_im1, (offset, 0)) # paste img2 on top of img1 newimg2 = Image.new('RGBA', size=size, color=(0, 0, 0, 0)) newimg2.paste(ava_im1, (offset, 0)) newimg2.paste(ava_im2, (-offset, 0)) # blend with alpha=0.5 im = Image.blend(newimg1, newimg2, alpha=0.6) mask = Image.open(self._mask).convert('L') mask = mask.resize(ava_im1.size, resample=Image.BILINEAR) im.putalpha(mask) f = io.BytesIO() im.save(f, 'png') f.seek(0) return discord.File(f, filename='test.png')
def sql(self, ctx, *, query: str): """Run some SQL.""" # the imports are here because I imagine some people would want to use # this cog as a base for their other cog, and since this one is kinda # odd and unnecessary for most people, I will make it easy to remove # for those people. from .utils.formats import pluralize import time query = self.cleanup_code(query) is_multistatement = query.count(';') > 1 async with ctx.db.get_session() as session: try: start = time.perf_counter() results = [dict(r) async for r in await session.cursor(query)] dt = (time.perf_counter() - start) * 1000.0 except Exception: return await ctx.send(f'```py\n{traceback.format_exc()}\n```') if is_multistatement or not results: return await ctx.send(f'`{dt:.2f}ms: {results}`') print(results) num_rows = len(results) headers = list(results[0]) rendered = _tabulate((list(r.values()) for r in results), headers) fmt = f'```\n{rendered}\n```\n*Returned {pluralize(row=num_rows)} in {dt:.2f}ms*' if len(fmt) > 2000: fp = io.BytesIO(fmt.encode('utf-8')) await ctx.send('Too many results...', file=discord.File(fp, 'results.txt')) else: await ctx.send(fmt)
def chill(self, ctx): """ Channel 1 and chill? """ await ctx.send( content=f"<@&172426880543227904> <@&262334316611239937> <@&172427010310799361>, chill? - {ctx.author}", file=discord.File("bot/resources/chill.jpg")) await ctx.message.delete()
def gg(self, ctx): """ GG EZ """ await ctx.send( file=discord.File("bot/resources/ggez.jpg")) await ctx.message.delete()
def ohno(self, ctx, *words): """Generates your very own SCP-3078 cognitohazardous shitpost. e.g. "when you inhale the devil's mary jane smoke" """ # Damn I tried to imitate the SCP-3078 instances but they don't follow # the same layout in different imitations, so the first one is followed # the best here. font = ImageFont.truetype(join(folder, "Calibri.ttf"), 19) append = None width = 256 x_start = 22 y_cur = 13 y_pad = 3 image = Image.open(join(folder, "SCP-3078.png")) draw = ImageDraw.Draw(image) for word in words: if append is None: append = word else: prev = append append = " ".join([append, word]) w, h = draw.textsize(append, font=font) if w > width: append = word draw.text((x_start, y_cur), prev, fill=(0, 0, 0), font=font) y_cur += h + y_pad if append is not None: draw.text((x_start, y_cur), append, fill=(0, 0, 0), font=font) image_bytes = BytesIO() image.save(image_bytes, format="png") image_bytes.seek(0) await ctx.send(file=File(image_bytes, filename="SCP-3078.png")) image_bytes.close()
def match(self, ctx, match_id : int): """Gets a summary of the dota match with the given id""" await ctx.channel.trigger_typing() match = await get_match(match_id) duration = get_pretty_duration(match['duration'], postfix=False) game_mode = self.dota_game_strings[f"game_mode_{match['game_mode']}"] lobby_type = self.dota_game_strings[f"lobby_type_{match['lobby_type']}"] + " " if lobby_type == "Normal ": lobby_type = "" description = (f"This {lobby_type}**{game_mode}** match ended in {duration} \n" f"More info at [DotaBuff](https://www.dotabuff.com/matches/{match_id}), " f"[OpenDota](https://www.opendota.com/matches/{match_id}), or " f"[STRATZ](https://www.stratz.com/match/{match_id})") embed = discord.Embed(description=description, timestamp=datetime.datetime.utcfromtimestamp(match['start_time']), color=self.embed_color) embed.set_author(name="Match {}".format(match_id), url="https://www.opendota.com/matches/{}".format(match_id)) embed.add_field(name="Game Mode", value=self.dota_game_strings[f"game_mode_{match['game_mode']}"]) embed.add_field(name="Lobby Type", value=self.dota_game_strings[f"lobby_type_{match['lobby_type']}"]) match_image = discord.File(await drawdota.create_match_image(match), filename="matchimage.png") embed.set_image(url=f"attachment://{match_image.filename}") embed.set_footer(text="Started") await ctx.send(embed=embed, file=match_image)
def matches(self, ctx, matchcount=10, player=None): """Gets a list of your recent matches Specifiy a `matchcount` to get a specific number of matches. Default is 10 You can also mention a user to get their recent matches **Example:** `{cmdpfx}matches 5 @PlayerPerson`""" steam32 = await get_check_steamid(player, ctx) await ctx.channel.trigger_typing() matches = await opendota_query(f"/players/{steam32}/recentmatches") if matchcount < 1: raise UserError("Gotta have a matchcount of 1 or more") if matchcount > 20: raise UserError("Sorries, 20 is the maximum number of matches for this command") if not matches: raise UserError("Looks like this player hasn't played any matches") matches = matches[:matchcount] embed = discord.Embed() embed.title = "Recent Matches" embed.url = f"https://www.opendota.com/players/{steam32}" matches_image = await drawdota.draw_matches_table(matches, self.dota_game_strings) matches_image = discord.File(matches_image, "matches.png") embed.set_image(url=f"attachment://{matches_image.filename}") await ctx.send(embed=embed, file=matches_image)
def dotagif(self, ctx, match_id : int, start, end, ms_per_second : int = 100): """Creates a gif of a specific part of a dota match The part of the match that you specify must be less than 10 minutes long `ms_per_second` is how many miliseconds between frames of the gif (each frame is 1 dota second) **Example:** `{cmdpfx}dotagif 3370877768 28:37 30:30`""" await ctx.channel.trigger_typing() match = await get_match(match_id) if not is_parsed(match): raise MatchNotParsedError(match_id, "get laning info") stratz_match = await get_stratz_match(match_id) if not is_stratz_parsed(stratz_match): raise UserError(f"It looks like match `{match_id}` hasn't been parsed by STRATZ") start = int(get_time(start)) end = int(get_time(end)) if end - start > 600: raise UserError("The length of this clip must be less than 10 minutes") if ms_per_second < 1 or ms_per_second > 655350: raise UserError("That is outside the bounds of the `ms_per_second` value") async with ctx.channel.typing(): await thinker.think(ctx.message) try: image = discord.File(await drawdota.create_dota_gif(match, stratz_match, start, end, ms_per_second), "map.gif") await ctx.send(file=image) finally: await thinker.stop_thinking(ctx.message)
def lasagna(self, ctx): """A baked Italian dish Contains wide strips of pasta cooked and layered with meat or vegetables, cheese, and tomato sauce.""" await ctx.send(file=discord.File(settings.resource("images/lasagna.jpg")))
def restget(self, ctx, url): """Gets a json response from a rest api and returns it""" await ctx.channel.trigger_typing() data = await httpgetter.get(url) filename = settings.resource("temp/response.json") write_json(filename, data) await ctx.send(file=discord.File(filename)) os.remove(filename)
def talents(self, ctx, *, hero : str): """Gets the talents of a specific hero You can give this command almost any variant of the hero's name, or the hero's id, in the same format as `{cmdpfx}hero` **Examples:** `{cmdpfx}talents shadow fiend`""" hero = self.lookup_hero(hero) if not hero: raise UserError("That doesn't look like a hero") image = await drawdota.draw_hero_talents(hero) image = discord.File(image, f"{hero.name}_talents.png") await ctx.send(file=image)
def midi(self, ctx: commands.Context, tempo: int=120, *, data: str=None): """ Convert text to MIDI. Multiple channels can be used by splitting text with |. Letters are converted to their pitch values using a mapping. Full documentation about it is not provided, read the code at https://github.com/lnmds/jose/blob/master/ext/midi.py To give longer input than a discord message allows you may upload a .txt file of up to 20 KiB. """ if data is None: try: data = await self.download_data(ctx.message) except Exception as err: log.exception('error downloading file at midi') raise self.SayException('We had an error while downloading ' 'the file, are you sure it is text?') before = time.monotonic() midi_file = await self.make_midi(tempo, data) duration = (time.monotonic() - before) * 1000 if midi_file is None: return await ctx.send('Failed to generate a MIDI file!') file = io.BytesIO() await self.loop.run_in_executor(None, midi_file.writeFile, file) file.seek(0) wrapped = discord.File(file, filename='boop.midi') await ctx.send(f'Took {duration:.3f}ms!', file=wrapped)