Python discord 模块,File() 实例源码
我们从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, 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, 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, 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,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, 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, 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), 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), 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), top_cat_img)
base.save(out_location)
await message.channel.send(file=discord.File(out_location))
os.remove(out_location)
def opendota(self, 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, 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.', 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, 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))
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, 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, 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,"+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]),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]),"+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]),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]),"+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]),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]),"+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]),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]),"+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]),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]),"+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, 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, 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], 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', 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,
file=File(BytesIO(bytes("".join(t_list), 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, 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, 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, webpage: str):
"""Render a webpage to image.
Usage: render [url]"""
echeck_perms(ctx,))
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, 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, 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[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], score))
ava_im1.thumbnail(size)
ava_im2.thumbnail(size)
# paste img1 on top of img2
newimg1 = Image.new('RGBA', size=size, 0))
newimg1.paste(ava_im2, (-offset, 0))
newimg1.paste(ava_im1, (offset, 0))
# paste img2 on top of img1
newimg2 = Image.new('RGBA', 0))
newimg2.paste(ava_im1, 0))
newimg2.paste(ava_im2, 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, 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, *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,
font=font)
y_cur += h + y_pad
if append is not None:
draw.text((x_start, append, 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 dog(cmd, '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 match(self, 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, 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, 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, ms_per_second), "map.gif")
await ctx.send(file=image)
finally:
await thinker.stop_thinking(ctx.message)
def restget(self, 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, 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)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。