async def userinfo(self, ctx): """Get user info. Ex: >info @user""" if ctx.invoked_subcommand is None: pre = cmd_prefix_len() name = ctx.message.content[4 + pre:].strip() if name: try: user = ctx.message.mentions[0] except: user = ctx.guild.get_member_named(name) if not user: user = ctx.guild.get_member(int(name)) if not user: await ctx.send(self.bot.bot_prefix + 'Could not find user.') return else: user = ctx.message.author # Thanks to IgneelDxD for help on this if user.avatar_url[54:].startswith('a_'): avi = 'https://images.discordapp.net/avatars/' + user.avatar_url[ 35:-10] else: avi = user.avatar_url role = user.top_role.name if role == "@everyone": role = "N/A" voice_state = None if not user.voice else user.voice.channel if embed_perms(ctx.message): em = discord.Embed(timestamp=ctx.message.created_at, colour=0x708DD0) em.add_field(name='User ID', value=user.id, inline=True) em.add_field(name='Nick', value=user.nick, inline=True) em.add_field(name='Status', value=user.status, inline=True) em.add_field(name='In Voice', value=voice_state, inline=True) em.add_field(name='Game', value=user.game, inline=True) em.add_field(name='Highest Role', value=role, inline=True) em.add_field(name='Account Created', value=user.created_at.__format__( '%A, %d. %B %Y @ %H:%M:%S')) em.add_field(name='Join Date', value=user.joined_at.__format__( '%A, %d. %B %Y @ %H:%M:%S')) em.set_thumbnail(url=avi) em.set_author(name=user, icon_url='https://i.imgur.com/RHagTDg.png') await ctx.send(embed=em) else: msg = '**User Info:** ```User ID: %s\nNick: %s\nStatus: %s\nIn Voice: %s\nGame: %s\nHighest Role: %s\nAccount Created: %s\nJoin Date: %s\nAvatar url:%s```' % ( user.id, user.nick, user.status, voice_state, user.game, role, user.created_at.__format__('%A, %d. %B %Y @ %H:%M:%S'), user.joined_at.__format__('%A, %d. %B %Y @ %H:%M:%S'), avi) await ctx.send(self.bot.bot_prefix + msg) await ctx.message.delete()
async def customcommands(self, ctx): with open('settings/commands.json', 'r') as c: cmds = json.load(c) sortedcmds = sorted(cmds.keys(), key=lambda x: x.lower()) msgs = [] part = '' pre = cmd_prefix_len() if ctx.message.content[10 + pre:].strip( ) and ctx.message.content[10 + pre:].strip() != 'gist': one_cmd = True list_cmd = ctx.message.content.strip().split(' ')[1] for cmd in sortedcmds: if one_cmd and list_cmd == cmd: if type(cmds[cmd]) is list: part = cmd + ': ' for i in cmds[cmd]: part += str(i[0]) + ' | ' part = part.rstrip(' | ') break else: part = cmd else: for cmd in sortedcmds: if type(cmds[cmd]) is list: check = cmd + ': ' for i in cmds[cmd]: check += str(i[0]) + ' | ' check = check.rstrip(' | ') + '\n\n' else: check = cmd + '\n\n' if len(part + check) > 1900: msgs.append(part) part = check else: part += check msgs.append(part) if 'gist' in ctx.message.content or 'Gist' in ctx.message.content: msgs = '\n'.join(msgs) url = PythonGists.Gist(description='Custom Commands', content=str(msgs), name='commands.txt') await self.bot.send_message( ctx.message.channel, self.bot.bot_prefix + 'List of Custom Commands: %s' % url) else: if len(msgs) == 1: await self.bot.send_message( ctx.message.channel, '```css\n[List of Custom Commands]\n%s ```' % msgs[0].rstrip()) else: for b, i in enumerate(msgs): await self.bot.send_message( ctx.message.channel, '```css\n[List of Custom Commands %s/%s]\n%s ```' % (b + 1, len(msgs), i.rstrip()))
async def gist(self, ctx): """Posts to gist""" if ctx.invoked_subcommand is None: pre = cmd_prefix_len() url = PythonGists.Gist( description='Created in channel: {} in server: {}'.format( ctx.message.channel, ctx.message.server), content=ctx.message.content[4 + pre:].strip(), name='Output') await self.bot.send_message( ctx.message.channel, self.bot.bot_prefix + 'Gist output: ' + url) await self.bot.delete_message(ctx.message)
async def userinfo(self, ctx, *, name=""): """Get user info. Ex: [p]info @user""" if ctx.invoked_subcommand is None: pre = cmd_prefix_len() if name: try: user = ctx.message.mentions[0] except IndexError: user = ctx.guild.get_member_named(name) if not user: user = ctx.guild.get_member(int(name)) if not user: user = self.bot.get_user(int(name)) if not user: await ctx.send(self.bot.bot_prefix + 'Could not find user.') return else: user = ctx.message.author if user.avatar_url_as(static_format='png')[54:].startswith('a_'): avi = user.avatar_url.rsplit("?", 1)[0] else: avi = user.avatar_url_as(static_format='png') if isinstance(user, discord.Member): role = user.top_role.name if role == "@everyone": role = "N/A" voice_state = None if not user.voice else user.voice.channel if embed_perms(ctx.message): em = discord.Embed(timestamp=ctx.message.created_at, colour=0x708DD0) em.add_field(name='User ID', value=user.id, inline=True) if isinstance(user, discord.Member): em.add_field(name='Nick', value=user.nick, inline=True) em.add_field(name='Status', value=user.status, inline=True) em.add_field(name='In Voice', value=voice_state, inline=True) em.add_field(name='Game', value=user.activity, inline=True) em.add_field(name='Highest Role', value=role, inline=True) em.add_field(name='Account Created', value=user.created_at.__format__('%A, %d. %B %Y @ %H:%M:%S')) if isinstance(user, discord.Member): em.add_field(name='Join Date', value=user.joined_at.__format__('%A, %d. %B %Y @ %H:%M:%S')) em.set_thumbnail(url=avi) em.set_author(name=user, icon_url='https://i.imgur.com/RHagTDg.png') await ctx.send(embed=em) else: if isinstance(user, discord.Member): msg = '**User Info:** ```User ID: %s\nNick: %s\nStatus: %s\nIn Voice: %s\nGame: %s\nHighest Role: %s\nAccount Created: %s\nJoin Date: %s\nAvatar url:%s```' % (user.id, user.nick, user.status, voice_state, user.activity, role, user.created_at.__format__('%A, %d. %B %Y @ %H:%M:%S'), user.joined_at.__format__('%A, %d. %B %Y @ %H:%M:%S'), avi) else: msg = '**User Info:** ```User ID: %s\nAccount Created: %s\nAvatar url:%s```' % (user.id, user.created_at.__format__('%A, %d. %B %Y @ %H:%M:%S'), avi) await ctx.send(self.bot.bot_prefix + msg) await ctx.message.delete()
async def customcommands(self, ctx): with open('settings/commands.json', 'r') as c: cmds = json.load(c) sortedcmds = sorted(cmds.keys(), key=lambda x: x.lower()) msgs = [] part = '' pre = cmd_prefix_len() if ctx.message.content[10 + pre:].strip() and ctx.message.content[10 + pre:].strip() != 'haste': one_cmd = True list_cmd = ctx.message.content.strip().split(' ')[1] for cmd in sortedcmds: if one_cmd and list_cmd == cmd: if type(cmds[cmd]) is list: part = cmd + ': ' for i in cmds[cmd]: part += str(i[0]) + ' | ' part = part.rstrip(' | ') break else: part = cmd else: for cmd in sortedcmds: if type(cmds[cmd]) is list: check = cmd + ': ' for i in cmds[cmd]: check += str(i[0]) + ' | ' check = check.rstrip(' | ') + '\n\n' else: check = cmd + '\n\n' if len(part + check) > 1900: msgs.append(part) part = check else: part += check msgs.append(part) if 'haste' in ctx.message.content or 'Haste' in ctx.message.content: msgs = '\n'.join(msgs) url = await hastebin(str(msgs), self.bot.session) await ctx.send(self.bot.bot_prefix + 'List of Custom Commands: %s' % url) else: if len(msgs) == 1: await ctx.send( '```css\n[List of Custom Commands]\n%s ```' % msgs[0].rstrip()) else: for b, i in enumerate(msgs): await ctx.send( '```css\n[List of Custom Commands %s/%s]\n%s ```' % ( b + 1, len(msgs), i.rstrip()))
async def userinfo(self, ctx, *, name=""): """Get user info. Ex: [p]info @user""" if ctx.invoked_subcommand is None: pre = cmd_prefix_len() if name: try: user = ctx.message.mentions[0] except IndexError: user = ctx.guild.get_member_named(name) if not user: user = ctx.guild.get_member(int(name)) if not user: user = self.bot.get_user(int(name)) if not user: await ctx.send(self.bot.bot_prefix + 'Could not find user.') return else: user = ctx.message.author avi = user.avatar_url if isinstance(user, discord.Member): role = user.top_role.name if role == "@everyone": role = "N/A" voice_state = None if not user.voice else user.voice.channel if embed_perms(ctx.message): em = discord.Embed(timestamp=ctx.message.created_at, colour=0x708DD0) em.add_field(name='User ID', value=user.id, inline=True) if isinstance(user, discord.Member): em.add_field(name='Nick', value=user.nick, inline=True) em.add_field(name='Status', value=user.status, inline=True) em.add_field(name='In Voice', value=voice_state, inline=True) em.add_field(name='Game', value=user.activity, inline=True) em.add_field(name='Highest Role', value=role, inline=True) em.add_field(name='Account Created', value=user.created_at.__format__('%A, %d. %B %Y @ %H:%M:%S')) if isinstance(user, discord.Member): em.add_field(name='Join Date', value=user.joined_at.__format__('%A, %d. %B %Y @ %H:%M:%S')) em.set_thumbnail(url=avi) em.set_author(name=user, icon_url='https://i.imgur.com/RHagTDg.png') await ctx.send(embed=em) else: if isinstance(user, discord.Member): msg = '**User Info:** ```User ID: %s\nNick: %s\nStatus: %s\nIn Voice: %s\nGame: %s\nHighest Role: %s\nAccount Created: %s\nJoin Date: %s\nAvatar url:%s```' % (user.id, user.nick, user.status, voice_state, user.activity, role, user.created_at.__format__('%A, %d. %B %Y @ %H:%M:%S'), user.joined_at.__format__('%A, %d. %B %Y @ %H:%M:%S'), avi) else: msg = '**User Info:** ```User ID: %s\nAccount Created: %s\nAvatar url:%s```' % (user.id, user.created_at.__format__('%A, %d. %B %Y @ %H:%M:%S'), avi) await ctx.send(self.bot.bot_prefix + msg) await ctx.message.delete()
async def ascii(self, ctx): """Convert text to ascii art. Ex: >ascii stuff >help ascii for more info.""" if ctx.invoked_subcommand is None: pre = cmd_prefix_len() if ctx.message.content[pre + 5:]: with open('settings/optional_config.json', 'r+') as fp: opt = json.load(fp) msg = str( figlet_format(ctx.message.content[pre + 5:].strip(), font=opt['ascii_font'])) if len(msg) > 2000: await self.bot.send_message( ctx.message.channel, self.bot.bot_prefix + 'Message too long, rip.') else: await self.bot.delete_message(ctx.message) await self.bot.send_message( ctx.message.channel, self.bot.bot_prefix + '```{}```'.format(msg)) else: await self.bot.send_message( ctx.message.channel, self.bot.bot_prefix + 'Please input text to convert to ascii art. Ex: ``>ascii stuff``' )
async def quote(self, ctx, *, msg: str = None): """Quote a message. >help quote for more info. >quote - quotes the last message sent in the channel. >quote <words> - tries to search for a message in the server that contains the given words and quotes it. >quote <message_id> - quotes the message with the given message id. Ex: >quote 302355374524644290(Enable developer mode to copy message ids). >quote <words> | channel=<channel_name> - quotes the message with the given words from the channel name specified in the second argument >quote <message_id> | channel=<channel_name> - quotes the message with the given message id in the given channel name""" result = channel = None pre = cmd_prefix_len() await self.bot.delete_message(ctx.message) if msg: try: length = len(self.bot.all_log[ctx.message.channel.id + ' ' + ctx.message.server.id]) if length < 201: size = length else: size = 200 for channel in ctx.message.server.channels: if str(channel.type) == 'text': if channel.id + ' ' + ctx.message.server.id in self.bot.all_log: for i in range(length - 2, length - size, -1): try: search = self.bot.all_log[ channel.id + ' ' + ctx.message.server.id][i] except: continue if (msg.lower().strip() in search[0].content.lower() and (search[0].author != ctx.message.author or search[0].content[pre:7] != 'quote ') ) or (ctx.message.content[6:].strip() == search[0].id): result = search[0] break if result: break except KeyError: pass if not result: if " | channel=" in msg: channelList = [] for channels in self.bot.get_all_channels(): if channels.name == msg.split("| channel=")[1]: channelList.append(channels) msg = msg.split(" | channel=")[0] for channel in channelList: if str(channel.type) == 'text': if channel.id + ' ' + ctx.message.server.id in self.bot.all_log: for i in range(length - 2, length - size, -1): try: search = self.bot.all_log[ channel.id + ' ' + ctx.message.server.id][i] except: continue if (msg.lower().strip() in search[0].content.lower() and (search[0].author != ctx.message.author or search[0].content[pre:7] != 'quote ') ) or (ctx.message.content[6:].strip() == search[0].id): result = search[0] break if result: break if not result: for channel in channelList: try: async for sent_message in self.bot.logs_from( channel, limit=500): if (msg.lower().strip() in sent_message.content and (sent_message.author != ctx.message.author or sent_message.content[pre:7] != 'quote ')) or (msg.strip() == sent_message.id): result = sent_message break except: pass if result: break if not result: for channel in ctx.message.server.channels: try: async for sent_message in self.bot.logs_from( channel, limit=500): if (msg.lower().strip() in sent_message.content and (sent_message.author != ctx.message.author or sent_message.content[pre:7] != 'quote ') ) or (msg.strip() == sent_message.id): result = sent_message break except: pass if result: break else: channel = ctx.message.channel search = self.bot.all_log[ctx.message.channel.id + ' ' + ctx.message.server.id][-2] result = search[0] if result: sender = result.author.nick if result.author.nick else result.author.name if embed_perms(ctx.message) and result.content: em = discord.Embed(description=result.content, timestamp=result.timestamp) with open('settings/optional_config.json') as fp: opt = json.load(fp) try: embed_color = opt['quoteembed_color'] if embed_color == "auto": em.color = result.author.top_role.color else: em.color = int('0x' + embed_color, 16) except: em.color = 0xbc0b0b em.set_author(name=sender, icon_url=result.author.avatar_url) if channel != ctx.message.channel: em.set_footer(text='#{} | {} '.format( channel.name, channel.server.name)) await self.bot.send_message(ctx.message.channel, embed=em) else: await self.bot.send_message( ctx.message.channel, '%s - %s```%s```' % (sender, result.timestamp, result.content)) else: await self.bot.send_message( ctx.message.channel, self.bot.bot_prefix + 'No quote found.')
async def game(self, ctx, *, game: str = None): """Set game/stream. Ex: >game napping >help game for more info Your game/stream status will not show for yourself, only other people can see it. This is a limitation of how the client works and how the api interacts with the client. --Setting game-- To set a rotating game status, do >game game1 | game2 | game3 | etc. It will then prompt you with an interval in seconds to wait before changing the game and after that the order in which to change (in order or random) Ex: >game with matches | sleeping | watching anime --Setting stream-- Same as above but you also need a link to the stream. (must be a valid link to a stream or else the status will not show as streaming). Add the link like so: <words>=<link> Ex: >stream Underwatch=https://www.twitch.tv/a_seagull or >stream Some moba=https://www.twitch.tv/doublelift | Underwatch=https://www.twitch.tv/a_seagull""" pre = cmd_prefix_len() if ctx.message.content[pre:].startswith('game'): is_stream = False status_type = 'Game' else: is_stream = True status_type = 'Stream' self.bot.is_stream = True if game: # Cycle games if more than one game is given. if ' | ' in game: await self.bot.send_message( ctx.message.channel, self.bot.bot_prefix + 'Input interval in seconds to wait before changing to the next {} (``n`` to cancel):' .format(status_type.lower())) def check(msg): return msg.content.isdigit() or msg.content.lower().strip( ) == 'n' def check2(msg): return msg.content == 'random' or msg.content.lower( ).strip() == 'r' or msg.content.lower().strip( ) == 'order' or msg.content.lower().strip() == 'o' reply = await self.bot.wait_for_message( author=ctx.message.author, check=check, timeout=60) if not reply: return if reply.content.lower().strip() == 'n': return await self.bot.send_message( ctx.message.channel, self.bot.bot_prefix + 'Cancelled') elif reply.content.strip().isdigit(): interval = int(reply.content.strip()) if interval >= 10: self.bot.game_interval = interval games = game.split(' | ') if len(games) != 2: await self.bot.send_message( ctx.message.channel, self.bot.bot_prefix + 'Change {} in order or randomly? Input ``o`` for order or ``r`` for random:' .format(status_type.lower())) s = await self.bot.wait_for_message( author=ctx.message.author, check=check2, timeout=60) if not s: return if s.content.strip() == 'r' or s.content.strip( ) == 'random': await self.bot.send_message( ctx.message.channel, self.bot.bot_prefix + '{status} set. {status} will randomly change every ``{time}`` seconds' .format(status=status_type, time=reply.content.strip())) loop_type = 'random' else: loop_type = 'ordered' else: loop_type = 'ordered' if loop_type == 'ordered': await self.bot.send_message( ctx.message.channel, self.bot.bot_prefix + '{status} set. {status} will change every ``{time}`` seconds' .format(status=status_type, time=reply.content.strip())) stream = 'yes' if is_stream else 'no' games = { 'games': game.split(' | '), 'interval': interval, 'type': loop_type, 'stream': stream } with open('settings/games.json', 'w') as g: json.dump(games, g, indent=4) self.bot.game = game.split(' | ')[0] else: return await self.bot.send_message( ctx.message.channel, self.bot.bot_prefix + 'Cancelled. Interval is too short. Must be at least 10 seconds.' ) # Set game if only one game is given. else: self.bot.game_interval = None self.bot.game = game stream = 'yes' if is_stream else 'no' games = { 'games': str(self.bot.game), 'interval': '0', 'type': 'none', 'stream': stream } with open('settings/games.json', 'w') as g: json.dump(games, g, indent=4) if is_stream and '=' in game: g, url = game.split('=') await self.bot.send_message( ctx.message.channel, self.bot.bot_prefix + 'Stream set as: ``Streaming %s``' % g) await self.bot.change_presence( game=discord.Game(name=g, type=1, url=url)) else: await self.bot.send_message( ctx.message.channel, self.bot.bot_prefix + 'Game set as: ``Playing %s``' % game) await self.bot.change_presence(game=discord.Game(name=game) ) # Remove game status. else: self.bot.game_interval = None self.bot.game = None self.bot.is_stream = False await self.bot.change_presence(game=None) await self.bot.send_message( ctx.message.channel, self.bot.bot_prefix + 'Set playing status off') if os.path.isfile('settings/games.json'): os.remove('settings/games.json')
async def imagedump(self, ctx): """Mass downloads images from a channel. [p]help imagedump for info. ----Simple---- [p]imagedump <n> - checks the last <n> messages in this chat and downloads all the images/gifs/webms found. ----More options---- Example: I want a new wallpaper. I'll check the last 5000 messages in this channel and download 100 items with type .png that fit on my 16:9 monitor with dimensions 1920x1080. This is what I would do: [p]imagedump 5000 | items=100 | type=png | ratio=16:9 | dim=1920x1080 ---- General Syntax (only include the options you want): [p]imagedump <n> | items=<m> | before=YYYY-MM-DD | after=YYYY-MM-DD | dim=WidthxHeight | ratio=Width:Height | type=<type_of_item> | channel=<id> | user=<id> - add any one or more of these to the command to furthur specify your requirements to find items. - items=<m> - when checking the last <n> messages, only download <m> items max. - before=YYYY-MM-DD - check <n> messages before this date. Ex: before=2017-02-16 - after=YYYY-MM-DD - check <n> messages after this date. - dim=WidthxHeight - only download items with these dimensions. Ex: dim=1920x1080 Optionally, do dim>=WidthxHeight for images greater than or equal and dim<=WidthxHeight for less than or equal to these dimensions. - ratio=Width:Height - only download items with these ratios. Ex: ratio=16:9 - type=<type_of_item> - only download these types of files. Ex: type=png or type=gif, webm All options: jpg, png, gif (includes gifv), webm. - channel=<id> - download from a different channel (can be a from a different server). Enable developer mode, right click on the channel name, and hit copy id to get the id. Ex: channel=299293492645986307 - user=<id> - download only items posted by this user. Enable developer mode, right click on user, copy id to get their id. Ex: user=124910128582361092 """ if ctx.invoked_subcommand is None: pre = cmd_prefix_len() error = 'Invalid syntax. ``>imagedump <n>`` where n is the number of messages to search in this channel. Ex: ``>imagedump 100``\n``>imagedump dir path/to/directory`` if you want to change where images are saved.' if ctx.message.content[9 + pre:].strip(): finished_dls = os.listdir('cogs/utils/') finished = [] for i in finished_dls: if i.startswith('finished'): finished.append(i) for i in finished: os.remove('cogs/utils/{}'.format(i)) if ctx.message.content[pre + 10] == 's': silent = True msg = ctx.message.content[11 + pre:].strip() else: silent = False msg = ctx.message.content[9 + pre:].strip() before = after = limit_images = user = None type_of_items = ['jpg', 'jpeg', 'png', 'gif', 'gifv', 'webm'] x = y = dimx = dimy = 'None' fixed = 'no' before_msg = after_msg = limit_images_msg = type_of_items_msg = dimensions_msg = ratio_msg = channel_msg = user_msg = '' simple = True channel = ctx.message.channel if ' | ' not in msg: if msg.isdigit(): limit = int(msg) + 1 else: return await ctx.send(self.bot.bot_prefix + error) else: simple = False msg = msg.split(' | ') if msg[0].strip().isdigit(): limit = int(msg[0].strip()) + 1 else: return await ctx.send(self.bot.bot_prefix + error) for i in msg: if i.strip().lower().startswith('items='): limit_images = i.strip()[6:].strip() if limit_images.isdigit(): limit_images_msg = 'Up to {} items. '.format( limit_images) limit_images = int(limit_images) else: return await ctx.send( self.bot.bot_prefix + 'Invalid Syntax. ``items=`` should be the number of images. Ex: ``>imagedump 500 | items=10``' ) if i.strip().lower().startswith('dim='): dimensions = i.strip()[4:].strip() if 'x' not in dimensions: return await ctx.send( self.bot.bot_prefix + 'Invalid Syntax. ``dim=`` should be the dimensions of the image in the form WidthxHeight. Ex: ``>imagedump 500 | dim=1920x1080``' ) x, y = dimensions.split('x') if not x.strip().isdigit() or not y.strip( ).isdigit(): return await ctx.send( self.bot.bot_prefix + 'Invalid Syntax. ``dim=`` should be the dimensions of the image in the form WidthxHeight. Ex: ``>imagedump 500 | dim=1920x1080``' ) else: x, y = x.strip(), y.strip() fixed = 'yes' dimensions_msg = 'Dimensions: {}. '.format( dimensions) if i.strip().lower().startswith('dim>='): dimensions = i.strip()[5:].strip() if 'x' not in dimensions: return await ctx.send( self.bot.bot_prefix + 'Invalid Syntax. ``dim>=`` should be the dimensions of the image in the form WidthxHeight. Ex: ``>imagedump 500 | dim>=1920x1080``' ) x, y = dimensions.split('x') if not x.strip().isdigit() or not y.strip( ).isdigit(): return await ctx.send( self.bot.bot_prefix + 'Invalid Syntax. ``dim>=`` should be the dimensions of the image in the form WidthxHeight. Ex: ``>imagedump 500 | dim>=1920x1080``' ) else: x, y = x.strip(), y.strip() fixed = 'more' dimensions_msg = 'Dimensions: {} or larger. '.format( dimensions) if i.strip().lower().startswith('dim<='): dimensions = i.strip()[5:].strip() if 'x' not in dimensions: return await ctx.send( self.bot.bot_prefix + 'Invalid Syntax. ``dim<=`` should be the dimensions of the image in the form WidthxHeight. Ex: ``>imagedump 500 | dim<=1920x1080``' ) x, y = dimensions.split('x') if not x.strip().isdigit() or not y.strip( ).isdigit(): return await ctx.send( self.bot.bot_prefix + 'Invalid Syntax. ``dim<=`` should be the dimensions of the image in the form WidthxHeight. Ex: ``>imagedump 500 | dim<=1920x1080``' ) else: x, y = x.strip(), y.strip() fixed = 'less' dimensions_msg = 'Dimensions: {} or smaller. '.format( dimensions) if i.strip().lower().startswith('ratio='): ratio = i.strip()[6:].strip() if ':' not in ratio: return await ctx.send( self.bot.bot_prefix + 'Invalid Syntax. ``ratio=`` should be the ratio of the image in the form w:h. Ex: ``>imagedump 500 | ratio=16:9``' ) dimx, dimy = ratio.split(':') if not dimx.strip().isdigit() or not dimy.strip( ).isdigit(): return await ctx.send( self.bot.bot_prefix + 'Invalid Syntax. ``ratio=`` should be the ratio of the image in the form w:h. Ex: ``>imagedump 500 | ratio=16:9``' ) else: dimx, dimy = dimx.strip(), dimy.strip() ratio_msg = 'Ratio: {}.'.format(ratio) if i.strip().lower().startswith('before='): try: date = i.strip()[7:].strip() before = datetime.strptime(date, '%Y-%m-%d') before_msg = 'Before: {} '.format(date) except: return await ctx.send( self.bot.bot_prefix + 'Invalid Syntax. ``before=`` should be a date in the format YYYY-MM-DD. Ex: ``>imagedump 500 | before=2017-02-15``' ) if i.strip().lower().startswith('after='): try: date = i.strip()[6:].strip() after = datetime.strptime(date, '%Y-%m-%d') after_msg = 'After: {} '.format(date) except: return await ctx.send( self.bot.bot_prefix + 'Invalid Syntax. ``after=`` should be a date in the format YYYY-MM-DD. Ex: ``>imagedump 500 | after=2017-02-15``' ) if i.strip().lower().startswith('type='): type = i.strip()[5:].strip() if ',' in type: type_of_items = type.split(',') else: type_of_items = [type] for i in type_of_items: if 'png' in i or 'jpg' in i or 'gif' in i or 'webm' in i: pass else: return await ctx.send( self.bot.bot_prefix + 'Invalid Syntax. ``type=`` should be tye type(s) of items to download. Ex: ``>imagedump 500 | type=png`` or ``>imagedump 500 | type=png, gif``' ) if 'jpg' in type_of_items or '.jpg' in type_of_items: type_of_items.append('.jpeg') type_of_items_msg = 'Types: {} '.format(type) if i.strip().lower().startswith('channel='): channel = i.strip()[8:].strip() channel = self.bot.get_channel(int(channel)) if not channel: return await ctx.send( self.bot.bot_prefix + 'Channel not found. Are you using the right syntax? ``channel=`` should be the channel id. ' 'Ex: ``>imagedump 500 | channel=299431230984683520``' ) limit -= 1 channel_msg = 'Channel: {} '.format(channel.name) if i.strip().lower().startswith('user='******'User not found. Are you using the right syntax? ``user=`` should be the user\'s id. ' 'Ex: ``>imagedump 500 | user=124910128582361092``' ) user_msg = 'User: {}'.format(user.name) await ctx.message.delete() with open('settings/optional_config.json', 'r+') as fp: opt = json.load(fp) if 'image_dump_delay' not in opt: opt['image_dump_delay'] = "0" fp.seek(0) fp.truncate() json.dump(opt, fp, indent=4) if 'image_dump_location' not in opt: path = '' else: path = opt['image_dump_location'] if not os.path.exists('{}image_dump'.format(path)): os.makedirs('{}image_dump'.format(path)) try: new_dump = time.strftime( "%Y-%m-%dT%H_%M_%S_" ) + channel.name + '_' + channel.guild.name except: new_dump = time.strftime("%Y-%m-%dT%H_%M_%S_") new_dump = "".join( [x if x.isalnum() else "_" for x in new_dump]) new_dump.replace('/', '_') os.makedirs('{}image_dump/{}'.format(path, new_dump)) if not silent: which_channel = 'in this channel...' if ctx.message.channel != channel: which_channel = 'in channel ``{}``'.format( channel.name) if not simple: params = 'Parameters: ``{}{}{}{}{}{}{}{}``'.format( limit_images_msg, before_msg, after_msg, dimensions_msg, ratio_msg, type_of_items_msg, channel_msg, user_msg) else: params = '' await ctx.send( self.bot.bot_prefix + 'Downloading all images/gifs/webms from the last {} messages {}\nSaving to ``image_dump/{}`` Check console for progress.\n{}' .format(str(limit - 1), which_channel, new_dump, params)) start = time.time() images = [] if limit > 100000: print( 'Fetching last %s messages (this may take a few minutes)...' % str(limit - 1)) else: print('Fetching last %s messages...' % str(limit - 1)) async for message in channel.history(limit=limit, before=before, after=after): if message.author == user or not user: for url in self.check_images(message, images, type_of_items): if url: images.append(url) if len(images) == limit_images: break with open('cogs/utils/urls{}.txt'.format(new_dump), 'w') as fp: for url in images: fp.write(url + '\n') args = [ sys.executable, 'cogs/utils/image_dump.py', path, new_dump, opt['image_dump_delay'], x, y, dimx, dimy, fixed ] p = subprocess.Popen(args) self.bot.imagedumps.append(p) while p.poll() is None: await asyncio.sleep(1) if os.path.exists('cogs/utils/paused{}.txt'.format(new_dump)): return try: with open('cogs/utils/finished{}.txt'.format(new_dump), 'r') as fp: stop = float(fp.readline()) total = fp.readline() failures = fp.readline() size = fp.readline() except: return print( 'Something went wrong when saving items and the download was stopped. Error posted above.' ) try: os.remove('cogs/utils/finished{}.txt'.format(new_dump)) except: pass if int(failures) != 0: if not silent: await ctx.send( self.bot.bot_prefix + 'Done! ``{}`` items downloaded. ``{}`` However, ``{}`` items failed to download. Check your console for more info on which ones were missed. ' 'Finished in: ``{} seconds.``'.format( str(total), size, str(failures), str(round(stop - start, 2)))) else: print( '{} items failed to download. See above for missed links. ' 'Finished in: {} seconds.'.format( str(failures), str(round(stop - start, 2)))) else: if not silent: await ctx.send( self.bot.bot_prefix + 'Done! ``{}`` items downloaded. ``{}`` Finished in: ``{} seconds.``' .format(str(total), size, str(round(stop - start, 2)))) else: print('Finished in: {} seconds'.format( str(round(stop - start, 2)))) else: await ctx.send( self.bot.bot_prefix + 'Invalid syntax. ``>imagedump <n>`` where n is the number of messages to search in this channel. ' 'Ex: ``>imagedump 100``\n``>imagedump dir path/to/directory`` if you want to change where images are saved.' )
async def server(self, ctx): """Various info about the server. >help server for more info.""" if ctx.invoked_subcommand is None: pre = cmd_prefix_len() if ctx.message.content[6 + pre:].strip(): server = None try: float(ctx.message.content[6 + pre:].strip()) server = self.bot.get_server(ctx.message.content[6 + pre:].strip()) if not server: return await self.bot.send_message(ctx.message.channel, self.bot.bot_prefix + 'Server not found.') except: for i in self.bot.servers: if i.name.lower() == ctx.message.content[6 + pre:].lower().strip(): server = i break if not server: return await self.bot.send_message(ctx.message.channel, self.bot.bot_prefix + 'Could not find server. Note: You must be a member of the server you are trying to search.') else: server = ctx.message.server online = 0 for i in server.members: if str(i.status) == 'online' or str(i.status) == 'idle' or str(i.status) == 'dnd': online += 1 all_users = [] for user in server.members: all_users.append('{}#{}'.format(user.name, user.discriminator)) all_users.sort() all = '\n'.join(all_users) channel_count = 0 for channel in server.channels: if channel.type == discord.ChannelType.text: channel_count += 1 role_count = len(server.roles) emoji_count = len(server.emojis) if embed_perms(ctx.message): em = discord.Embed(color=0xea7938) em.add_field(name='Name', value=server.name) em.add_field(name='Owner', value=server.owner, inline=False) em.add_field(name='Members', value=server.member_count) em.add_field(name='Currently Online', value=online) em.add_field(name='Text Channels', value=str(channel_count)) em.add_field(name='Region', value=server.region) em.add_field(name='Verification Level', value=str(server.verification_level)) em.add_field(name='Highest role', value=server.role_hierarchy[0]) em.add_field(name='Number of Roles', value=str(role_count)) em.add_field(name='Number of Emotes', value=str(emoji_count)) url = PythonGists.Gist(description='All Users in: %s' % server.name, content=str(all), name='server.txt') gist_of_users = '[List of all {} users in this server]({})'.format(server.member_count, url) em.add_field(name='Users', value=gist_of_users) em.add_field(name='Created At', value=server.created_at.__format__('%A, %d. %B %Y @ %H:%M:%S')) em.set_thumbnail(url=server.icon_url) em.set_author(name='Server Info', icon_url='https://i.imgur.com/RHagTDg.png') em.set_footer(text='Server ID: %s' % server.id) await self.bot.send_message(ctx.message.channel, embed=em) else: msg = '**Server Info:** ```Name: %s\nOwner: %s\nMembers: %s\nCurrently Online: %s\nRegion: %s\nVerification Level: %s\nHighest Role: %s\nDefault Channel: %s\nCreated At: %s\nServer avatar: : %s```' % ( server.name, server.owner, server.member_count, online, server.region, str(server.verification_level), server.role_hierarchy[0], server.default_channel, server.created_at.__format__('%A, %d. %B %Y @ %H:%M:%S'), server.icon_url) await self.bot.send_message(ctx.message.channel, self.bot.bot_prefix + msg) await self.bot.delete_message(ctx.message)
async def imagedump(self, ctx): """Mass downloads images from a channel. [p]help imagedump for info. ----Simple---- [p]imagedump <n> - checks the last <n> messages in this chat and downloads all the images/gifs/webms found. ----More options---- Example: I want a new wallpaper. I'll check the last 5000 messages in this channel and download 100 items with type .png that fit on my 16:9 monitor with dimensions 1920x1080. This is what I would do: [p]imagedump 5000 | items=100 | type=png | ratio=16:9 | dim=1920x1080 ---- General Syntax (only include the options you want): [p]imagedump <n> | items=<m> | before=YYYY-MM-DD | after=YYYY-MM-DD | dim=WidthxHeight | ratio=Width:Height | type=<type_of_item> | channel=<id> | user=<id> - add any one or more of these to the command to furthur specify your requirements to find items. - items=<m> - when checking the last <n> messages, only download <m> items max. - before=YYYY-MM-DD - check <n> messages before this date. Ex: before=2017-02-16 - after=YYYY-MM-DD - check <n> messages after this date. - dim=WidthxHeight - only download items with these dimensions. Ex: dim=1920x1080 Optionally, do dim>=WidthxHeight for images greater than or equal and dim<=WidthxHeight for less than or equal to these dimensions. - ratio=Width:Height - only download items with these ratios. Ex: ratio=16:9 - type=<type_of_item> - only download these types of files. Ex: type=png or type=gif, webm All options: jpg, png, gif (includes gifv), webm. - channel=<id> - download from a different channel (can be a from a different server). Enable developer mode, right click on the channel name, and hit copy id to get the id. Ex: channel=299293492645986307 - user=<id> - download only items posted by this user. Enable developer mode, right click on user, copy id to get their id. Ex: user=124910128582361092 """ if ctx.invoked_subcommand is None: pre = cmd_prefix_len() error = 'Invalid syntax. ``>imagedump <n>`` where n is the number of messages to search in this channel. Ex: ``>imagedump 100``\n``>imagedump dir path/to/directory`` if you want to change where images are saved.' if ctx.message.content[9 + pre:].strip(): finished_dls = os.listdir('cogs/utils/') finished = [] for i in finished_dls: if i.startswith('finished'): finished.append(i) for i in finished: os.remove('cogs/utils/{}'.format(i)) if ctx.message.content[pre + 10] == 's': silent = True msg = ctx.message.content[11 + pre:].strip() else: silent = False msg = ctx.message.content[9 + pre:].strip() before = after = limit_images = user = None type_of_items = ['jpg', 'jpeg', 'png', 'gif', 'gifv', 'webm'] x = y = dimx = dimy = 'None' fixed = 'no' before_msg = after_msg = limit_images_msg = type_of_items_msg = dimensions_msg = ratio_msg = channel_msg = user_msg = '' simple = True channel = ctx.message.channel if ' | ' not in msg: if msg.isdigit(): limit = int(msg) + 1 else: return await ctx.send(self.bot.bot_prefix + error) else: simple = False msg = msg.split(' | ') if msg[0].strip().isdigit(): limit = int(msg[0].strip()) + 1 else: return await ctx.send(self.bot.bot_prefix + error) for i in msg: if i.strip().lower().startswith('items='): limit_images = i.strip()[6:].strip() if limit_images.isdigit(): limit_images_msg = 'Up to {} items. '.format(limit_images) limit_images = int(limit_images) else: return await ctx.send(self.bot.bot_prefix + 'Invalid Syntax. ``items=`` should be the number of images. Ex: ``>imagedump 500 | items=10``') if i.strip().lower().startswith('dim='): dimensions = i.strip()[4:].strip() if 'x' not in dimensions: return await ctx.send(self.bot.bot_prefix + 'Invalid Syntax. ``dim=`` should be the dimensions of the image in the form WidthxHeight. Ex: ``>imagedump 500 | dim=1920x1080``') x, y = dimensions.split('x') if not x.strip().isdigit() or not y.strip().isdigit(): return await ctx.send(self.bot.bot_prefix + 'Invalid Syntax. ``dim=`` should be the dimensions of the image in the form WidthxHeight. Ex: ``>imagedump 500 | dim=1920x1080``') else: x, y = x.strip(), y.strip() fixed = 'yes' dimensions_msg = 'Dimensions: {}. '.format(dimensions) if i.strip().lower().startswith('dim>='): dimensions = i.strip()[5:].strip() if 'x' not in dimensions: return await ctx.send(self.bot.bot_prefix + 'Invalid Syntax. ``dim>=`` should be the dimensions of the image in the form WidthxHeight. Ex: ``>imagedump 500 | dim>=1920x1080``') x, y = dimensions.split('x') if not x.strip().isdigit() or not y.strip().isdigit(): return await ctx.send(self.bot.bot_prefix + 'Invalid Syntax. ``dim>=`` should be the dimensions of the image in the form WidthxHeight. Ex: ``>imagedump 500 | dim>=1920x1080``') else: x, y = x.strip(), y.strip() fixed = 'more' dimensions_msg = 'Dimensions: {} or larger. '.format(dimensions) if i.strip().lower().startswith('dim<='): dimensions = i.strip()[5:].strip() if 'x' not in dimensions: return await ctx.send(self.bot.bot_prefix + 'Invalid Syntax. ``dim<=`` should be the dimensions of the image in the form WidthxHeight. Ex: ``>imagedump 500 | dim<=1920x1080``') x, y = dimensions.split('x') if not x.strip().isdigit() or not y.strip().isdigit(): return await ctx.send(self.bot.bot_prefix + 'Invalid Syntax. ``dim<=`` should be the dimensions of the image in the form WidthxHeight. Ex: ``>imagedump 500 | dim<=1920x1080``') else: x, y = x.strip(), y.strip() fixed = 'less' dimensions_msg = 'Dimensions: {} or smaller. '.format(dimensions) if i.strip().lower().startswith('ratio='): ratio = i.strip()[6:].strip() if ':' not in ratio: return await ctx.send(self.bot.bot_prefix + 'Invalid Syntax. ``ratio=`` should be the ratio of the image in the form w:h. Ex: ``>imagedump 500 | ratio=16:9``') dimx, dimy = ratio.split(':') if not dimx.strip().isdigit() or not dimy.strip().isdigit(): return await ctx.send(self.bot.bot_prefix + 'Invalid Syntax. ``ratio=`` should be the ratio of the image in the form w:h. Ex: ``>imagedump 500 | ratio=16:9``') else: dimx, dimy = dimx.strip(), dimy.strip() ratio_msg = 'Ratio: {}.'.format(ratio) if i.strip().lower().startswith('before='): try: date = i.strip()[7:].strip() before = datetime.strptime(date, '%Y-%m-%d') before_msg = 'Before: {} '.format(date) except: return await ctx.send(self.bot.bot_prefix + 'Invalid Syntax. ``before=`` should be a date in the format YYYY-MM-DD. Ex: ``>imagedump 500 | before=2017-02-15``') if i.strip().lower().startswith('after='): try: date = i.strip()[6:].strip() after = datetime.strptime(date, '%Y-%m-%d') after_msg = 'After: {} '.format(date) except: return await ctx.send(self.bot.bot_prefix + 'Invalid Syntax. ``after=`` should be a date in the format YYYY-MM-DD. Ex: ``>imagedump 500 | after=2017-02-15``') if i.strip().lower().startswith('type='): type = i.strip()[5:].strip() if ',' in type: type_of_items = type.split(',') else: type_of_items = [type] for i in type_of_items: if 'png' in i or 'jpg' in i or 'gif' in i or 'webm' in i: pass else: return await ctx.send(self.bot.bot_prefix + 'Invalid Syntax. ``type=`` should be tye type(s) of items to download. Ex: ``>imagedump 500 | type=png`` or ``>imagedump 500 | type=png, gif``') if 'jpg' in type_of_items or '.jpg' in type_of_items: type_of_items.append('.jpeg') type_of_items_msg = 'Types: {} '.format(type) if i.strip().lower().startswith('channel='): channel = i.strip()[8:].strip() channel = self.bot.get_channel(int(channel)) if not channel: return await ctx.send(self.bot.bot_prefix + 'Channel not found. Are you using the right syntax? ``channel=`` should be the channel id. ' 'Ex: ``>imagedump 500 | channel=299431230984683520``') limit -= 1 channel_msg = 'Channel: {} '.format(channel.name) if i.strip().lower().startswith('user='******'User not found. Are you using the right syntax? ``user=`` should be the user\'s id. ' 'Ex: ``>imagedump 500 | user=124910128582361092``') user_msg = 'User: {}'.format(user.name) await ctx.message.delete() with open('settings/optional_config.json', 'r+') as fp: opt = json.load(fp) if 'image_dump_delay' not in opt: opt['image_dump_delay'] = "0" fp.seek(0) fp.truncate() json.dump(opt, fp, indent=4) if 'image_dump_location' not in opt: path = '' else: path = opt['image_dump_location'] if not os.path.exists('{}image_dump'.format(path)): os.makedirs('{}image_dump'.format(path)) try: new_dump = time.strftime("%Y-%m-%dT%H_%M_%S_") + channel.name + '_' + channel.guild.name except: new_dump = time.strftime("%Y-%m-%dT%H_%M_%S_") new_dump = "".join([x if x.isalnum() else "_" for x in new_dump]) new_dump.replace('/', '_') os.makedirs('{}image_dump/{}'.format(path, new_dump)) if not silent: which_channel = 'in this channel...' if ctx.message.channel != channel: which_channel = 'in channel ``{}``'.format(channel.name) if not simple: params = 'Parameters: ``{}{}{}{}{}{}{}{}``'.format(limit_images_msg, before_msg, after_msg, dimensions_msg, ratio_msg, type_of_items_msg, channel_msg, user_msg) else: params = '' await ctx.send(self.bot.bot_prefix + 'Downloading all images/gifs/webms from the last {} messages {}\nSaving to ``image_dump/{}`` Check console for progress.\n{}'.format(str(limit-1), which_channel, new_dump, params)) start = time.time() images = [] if limit > 100000: print('Fetching last %s messages (this may take a few minutes)...' % str(limit - 1)) else: print('Fetching last %s messages...' % str(limit-1)) async for message in channel.history(limit=limit, before=before, after=after): if message.author == user or not user: for url in self.check_images(message, images, type_of_items): if url: images.append(url) if len(images) == limit_images: break with open('cogs/utils/urls{}.txt'.format(new_dump), 'w') as fp: for url in images: fp.write(url + '\n') args = [sys.executable, 'cogs/utils/image_dump.py', path, new_dump, opt['image_dump_delay'], x, y, dimx, dimy, fixed] p = subprocess.Popen(args) self.bot.imagedumps.append(p) while p.poll() is None: await asyncio.sleep(1) if os.path.exists('cogs/utils/paused{}.txt'.format(new_dump)): return try: with open('cogs/utils/finished{}.txt'.format(new_dump), 'r') as fp: stop = float(fp.readline()) total = fp.readline() failures = fp.readline() size = fp.readline() except: return print('Something went wrong when saving items and the download was stopped. Error posted above.') try: os.remove('cogs/utils/finished{}.txt'.format(new_dump)) except: pass if int(failures) != 0: if not silent: await ctx.send(self.bot.bot_prefix + 'Done! ``{}`` items downloaded. ``{}`` However, ``{}`` items failed to download. Check your console for more info on which ones were missed. ' 'Finished in: ``{} seconds.``'.format(str(total), size, str(failures), str(round(stop - start, 2)))) else: print('{} items failed to download. See above for missed links. ' 'Finished in: {} seconds.'.format(str(failures), str(round(stop - start, 2)))) else: if not silent: await ctx.send(self.bot.bot_prefix + 'Done! ``{}`` items downloaded. ``{}`` Finished in: ``{} seconds.``'.format(str(total), size, str(round(stop-start, 2)))) else: print('Finished in: {} seconds'.format(str(round(stop-start, 2)))) else: await ctx.send(self.bot.bot_prefix + 'Invalid syntax. ``>imagedump <n>`` where n is the number of messages to search in this channel. ' 'Ex: ``>imagedump 100``\n``>imagedump dir path/to/directory`` if you want to change where images are saved.')
async def quote(self, ctx, *, msg: str = None): """Quote a message. >help quote for more info. >quote - quotes the last message sent in the channel. >quote <words> - tries to search for a message in the server that contains the given words and quotes it. >quote <message_id> - quotes the message with the given message id. Ex: >quote 302355374524644290(Enable developer mode to copy message ids). >quote <words> | channel=<channel_name> - quotes the message with the given words from the channel name specified in the second argument >quote <message_id> | channel=<channel_name> - quotes the message with the given message id in the given channel name >quote <user_mention_name_or_id> - quotes the last member sent by a specific user""" await ctx.message.delete() result = None pre = cmd_prefix_len() channel = ctx.channel if msg: user = get_user(ctx.message, msg) if " | channel=" in msg: channel = next((ch for ch in self.bot.get_all_channels() if ch.name == msg.split("| channel=")[1]), None) msg = msg.split(" | channel=")[0] if not channel: return await ctx.send(self.bot.bot_prefix + "Could not find specified channel.") if not isinstance(channel, discord.channel.TextChannel): return await ctx.send( self.bot.bot_prefix + "This command is only supported in server text channels.") try: length = len(self.bot.all_log[str(ctx.message.channel.id) + ' ' + str(ctx.message.guild.id)]) except: pass else: size = length if length < 201 else 200 for channel in ctx.message.guild.channels: if type(channel) == discord.channel.TextChannel: if str(channel.id) + ' ' + str( ctx.message.guild.id) in self.bot.all_log: for i in range(length - 2, length - size, -1): try: search = self.bot.all_log[ str(channel.id) + ' ' + str(ctx.message.guild.id)][i] except: continue if (msg.lower().strip() in search[0].content.lower() and (search[0].author != ctx.message.author or search[0].content[pre:7] != 'quote ') ) or (ctx.message.content[6:].strip() == str(search[0].id)) or ( search[0].author == user and search[0].channel == ctx.message.channel): result = search[0] break if result: break if not result: try: async for sent_message in channel.history(limit=500): if (msg.lower().strip() in sent_message.content and (sent_message.author != ctx.message.author or sent_message.content[pre:7] != 'quote ')) or ( msg.strip() == str( sent_message.id)) or (msg.author == user): result = sent_message break except: pass else: if not isinstance(channel, discord.channel.TextChannel): return await ctx.send( self.bot.bot_prefix + "This command is only supported in server text channels.") try: search = self.bot.all_log[str(ctx.message.channel.id) + ' ' + str(ctx.message.guild.id)][-2] result = search[0] except KeyError: try: messages = await channel.history(limit=2).flatten() result = messages[0] except: pass if result: sender = result.author.nick if result.author.nick else result.author.name if embed_perms(ctx.message) and result.content: color = get_config_value("optional_config", "quoteembed_color") if color == "auto": color = result.author.top_role.color elif color == "": color = 0xbc0b0b else: color = int('0x' + color, 16) em = discord.Embed(color=color, description=result.content, timestamp=result.created_at) em.set_author(name=sender, icon_url=result.author.avatar_url) if channel != ctx.message.channel: em.set_footer(text='#{} | {} '.format( channel.name, channel.guild.name)) await ctx.send(embed=em) else: await ctx.send('%s - %s```%s```' % (sender, result.created_at, result.content)) else: await ctx.send(self.bot.bot_prefix + 'No quote found.')