Esempio n. 1
0
 async def tac(self, ctx):
     """Toggle AutoCucumber.
     Usage: tac"""
     echeck_perms(ctx, ('bot_owner', ))
     self.enabled = not self.enabled
     await ctx.send('Autocucumber is now ' +
                    ('on.' if self.enabled else 'off.'))
Esempio n. 2
0
 async def add_emote(self, ctx, _emote: str):
     """Add a Twitch, FrankerFaceZ, BetterTTV, or Discord emote to the current server.
     Usage: add_emote [name of emote]"""
     echeck_perms(ctx, ('bot_owner', ))
     emote = _emote.replace(':', '')
     ext = 'png'
     async with aiohttp.ClientSession(loop=self.loop) as session:
         with async_timeout.timeout(13):
             try:
                 async with session.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 session.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 session.get(
                                 self.bot.emotes['bttv'][emote]) as resp:
                             emote_img = await resp.read()
                     except KeyError:  # let's try Discord
                         await self.bot.say(
                             '**No such emote!** I can fetch from Twitch, FrankerFaceZ, BetterTTV, or Discord (soon).'
                         )
                         return False
     result = await self.bot.create_custom_emoji(ctx.message.server,
                                                 name=emote,
                                                 image=emote_img)
     await self.bot.say('Added. ' + str(result))
Esempio n. 3
0
 async def guildtree(self, ctx, *ids: str):
     """List the guilds I am in (tree version).
     Usage: guildtree"""
     echeck_perms(ctx, ('bot_owner', ))
     pager = commands.Paginator(prefix='```diff')
     guilds: List[discord.Guild]
     if ids:
         s_map = {i.id: i for i in self.bot.guilds}
         for sid in ids:
             with assert_msg(
                     ctx,
                     '**ID** `%s` **is invalid. (must be 18 numbers)**' %
                     sid):
                 check(len(sid) == 18)
             try:
                 guilds.append(s_map[sid])
             except KeyError:
                 await ctx.send('guild ID **%s** not found.' % sid)
                 return False
     else:
         guilds = self.bot.guilds
     for guild in guilds:
         pager.add_line('+ ' + guild.name +
                        ' [{0} members] [ID {1}]'.format(
                            str(len(guild.members)), guild.id))
         for channel in guild.channels:
             xname = channel.name
             if str(channel.type) == 'voice':
                 xname = '[voice] ' + xname
             pager.add_line('  • ' + xname)
     for page in pager.pages:
         await ctx.send(page)
Esempio n. 4
0
 async def event_calls(self, ctx):
     """Get the specific event calls.
     Usage: event_calls"""
     echeck_perms(ctx, ('bot_owner',))
     emb = discord.Embed(color=random.randint(1, 255**3-1), title='Event Calls')
     emb.description = 'Here are all the event calls made.'
     author = self.bot.user
     emb.set_author(name=str(author), icon_url=(author.avatar_url if author.avatar_url else author.default_avatar_url))
     emb.add_field(name='Total', value=sum(self.bot.event_calls.values()))
     fmap = {
         'Servers': '',
         'Messages': '',
         'Updates': '',
         'Socket': '',
         'Other': ''
     }
     for ev, count in self.bot.event_calls.items():
         if ev.startswith('server'):
             fmap['Servers'] += '**{}**: {}\n'.format(ev, count)
         elif ev.endswith('update'):
             fmap['Updates'] += '**{}**: {}\n'.format(ev, count)
         elif 'message' in ev:
             fmap['Messages'] += '**{}**: {}\n'.format(ev, count)
         elif ev.startswith('socket'):
             fmap['Socket'] += '**{}**: {}\n'.format(ev, count)
         else:
             fmap['Other'] += '**{}**: {}\n'.format(ev, count)
     for name, value in fmap.items():
         if value:
             emb.add_field(name=name, value=value)
     await self.bot.say(embed=emb)
Esempio n. 5
0
    async def embed_from_json(self, ctx, *, js_text: str):
        """Send an embed from JSON.
        Usage: embed_from_json [json]"""
        echeck_perms(ctx, ('bot_owner', ))

        class SemiEmbed:
            def __init__(self, obj):
                self.obj = obj

            def to_dict(self):
                return self.obj

        try:
            embed_obj = json.loads(js_text)
        except json.decoder.JSONDecodeError:
            await ctx.send(':warning: **Invalid JSON data!**')
        else:
            sembed = SemiEmbed(embed_obj)
            try:
                await ctx.send(embed=sembed)
            except discord.HTTPException as e:
                if '400' in str(e):
                    await ctx.send(
                        ':warning: **Couldn\'t send embed, check your data!**')
                else:
                    raise e
Esempio n. 6
0
 async def repeat(self, ctx, times : int, *, command: str):
     """Repeats a command a specified number of times.
     Usage: repeat [times] [command]"""
     echeck_perms(ctx, ('bot_admin',))
     msg = copy.copy(ctx.message)
     msg.content = command
     for i in range(times):
         await self.bot.process_commands(msg, ctx.prefix)
Esempio n. 7
0
 async def sendfile(self,
                    ctx,
                    path: str = 'assets/soon.gif',
                    msg: str = '📧 File incoming!'):
     """Send a file to Discord.
     Usage: sendfile [file path] {message}"""
     echeck_perms(ctx, ('bot_owner', ))
     await ctx.send(msg, file=discord.File(path))
Esempio n. 8
0
 async def guildlist(self, ctx):
     """List the guilds I am in.
     Usage: guildlist"""
     echeck_perms(ctx, ('bot_owner', ))
     pager = commands.Paginator()
     for guild in self.bot.guilds:
         pager.add_line(guild.name)
     for page in pager.pages:
         await ctx.send(page)
Esempio n. 9
0
 async def serverlist(self, ctx):
     """List the servers I am in.
     Usage: serverlist"""
     echeck_perms(ctx, ('bot_owner',))
     pager = commands.Paginator()
     for server in self.bot.servers:
         pager.add_line(server.name)
     for page in pager.pages:
         await self.bot.say(page)
Esempio n. 10
0
    async def messages(self, ctx, *number: int):
        """Read contact messages.
        Usage: messages {number}"""
        echeck_perms(ctx, ('bot_owner', ))

        def chan(msg):
            if 'guild' in msg:
                try:
                    guild = {s.id: s for s in self.bot.guilds}[msg['guild_id']]
                except KeyError:
                    return 'guild-removed'
                try:
                    channel = {c.id: c
                               for c in guild.channels}[msg['channel_id']].name
                except KeyError:
                    return 'deleted-channel'
                msg['channel'] = channel
                return channel
            else:
                return 'was-pm'

        if number:
            nums = number
        else:
            nums = range(self.bot.store.get('msgs_read_index', 0),
                         len(self.bot.store['owner_messages']))
        for num in nums:
            msg = self.bot.store['owner_messages'][num]
            emb = discord.Embed(color=random.randint(1, 255**3 - 1))
            author = await self.bot.get_user_info(msg['user_id'])
            emb.set_author(name=str(author), icon_url=author.avatar_url)
            emb.description = msg['message']
            emb.add_field(name='User Tag', value=msg['user'])
            emb.add_field(name='Nickname', value=msg['nick'])
            emb.add_field(name='Message ID', value=msg['message_id'])
            emb.add_field(name='User ID', value=msg['user_id'])
            emb.add_field(name='Channel',
                          value='#' + chan(msg) + '\nID: `' +
                          msg['channel_id'] + '`')
            emb.add_field(name='PM?', value=('Yes' if msg['pm'] else 'No'))
            emb.add_field(name='Date and Time', value=msg['time'])
            emb.add_field(name='Timestamp', value=msg['timestamp'])
            emb.add_field(name='Contains Mention?',
                          value=('Yes' if msg['contains_mention'] else 'No'))
            if 'guild' in msg:
                emb.add_field(name='guild',
                              value='**' + msg['guild'] + '**\nID: `' +
                              msg['guild_id'] + '`\nMembers at the time: ' +
                              str(msg['guild_members']) + '\nMembers now: ' +
                              str(
                                  len({s.id: s
                                       for s in self.bot.guilds
                                       }[msg['guild_id']].members)))
            await ctx.send(embed=emb)
        self.bot.store['msgs_read_index'] = nums[-1]
        await ctx.send('Finished!')
Esempio n. 11
0
 async def shutdown(self, ctx):
     """Shut down and stop the bot.
     Usage: shutdown"""
     echeck_perms(ctx, ('bot_owner',))
     await self.bot.say(':warning: Are you **sure** you want to stop the bot? Type `yes` to continue.')
     if not (await self.bot.wait_for_message(timeout=7.0, author=ctx.message.author,
                                             channel=ctx.message.channel,
                                             check=lambda m: m.content.lower().startswith('yes'))):
         return
     await self.bot.logout()
Esempio n. 12
0
 async def rawsetprop(self, ctx, scope: str, pname: str, value: str):
     """Set the value of a property on any level.
     Usage: rawsetprop [scope] [property name] [value]"""
     echeck_perms(ctx, ('bot_admin', ))
     try:
         self.bot.store.set_prop(ctx.message, scope, pname, value)
     except Exception:
         await ctx.send('âš  An error occured.')
         return
     await ctx.send('Successfully set `{0}` as `{1}`!'.format(pname, value))
Esempio n. 13
0
 async def emotispam(self, ctx):
     """Spam some emotes! CRASH WARNING!
     Warning: Instant crash for desktop users.
     Only fixable on web or mobile apps.
     Usage: emotispam"""
     echeck_perms(ctx, ('bot_owner', ))
     _em = emojis
     r = list(range(0, math.ceil(len(emojis) / 2000)))
     for i in r:
         await ctx.send(_em[:2000])
         _em = _em[2000:]
Esempio n. 14
0
 async def dload(self, ctx):
     """Load the datastore from disk.
     Usage: dload"""
     echeck_perms(ctx, ('bot_owner',))
     await self.bot.say('**ARE YOU SURE YOU WANT TO LOAD THE DATASTORE?** *yes, no*')
     resp = await self.bot.wait_for_message(channel=ctx.message.channel, author=ctx.message.author)
     if resp.content.lower() == 'yes':
         await self.bot.store.read()
         await self.bot.say('**Read the datastore from disk, overwriting current copy!**')
     else:
         await self.bot.say('**Didn\'t say yes, aborting.**')
Esempio n. 15
0
    async def broadcast(self, ctx, *, broadcast_text: str):
        """Broadcast a message to all guilds.
        Usage: broadcast [message]"""
        echeck_perms(ctx, ('bot_owner', ))
        err = ''

        def get_prefix(s):
            props = self.bot.store['properties']
            servs = props['by_guild']
            if s.id in servs:
                if 'command_prefix' in servs[s.id]:
                    return servs[s.id]['command_prefix']
                else:
                    return props['global']['command_prefix']
            else:
                return props['global']['command_prefix']

        if self.bot.selfbot:
            await ctx.send(
                ''':warning: **This could potentially get you banned with a selfbot.**
If you're sure you want to do this, type `yes` within 8 seconds.''')
            if not (await self.bot.wait_for(
                    'message',
                    timeout=8.0,
                    check=lambda m: m.content.lower().startswith('yes') and m.
                    author == ctx.author and m.channel == ctx.channel)):
                return
        for i in self.bot.guilds:
            text = broadcast_text.replace('%prefix%', get_prefix(i))
            if i.id in self.bot.store['nobroadcast']:
                pass
            else:
                try:
                    self.last_broadcasts[i.id] = await i.default_channel.send(
                        text)
                except discord.Forbidden:
                    satisfied = False
                    c_count = 0
                    try_channels = i.channels
                    channel_count = len(try_channels) - 1
                    while not satisfied:
                        with suppress(discord.Forbidden,
                                      discord.HTTPException):
                            self.last_broadcasts[
                                i.id] = await try_channels[c_count].send(text)
                            satisfied = True
                        if c_count >= channel_count:
                            err += f'`[WARN]` Couldn\'t broadcast to guild **{i.name}**\n'
                            satisfied = True
                        c_count += 1
                await asyncio.sleep(0.175)
        if err:
            await ctx.send(err)
Esempio n. 16
0
 async def command_calls(self, ctx):
     """Get the specific command calls.
     Usage: command_calls"""
     echeck_perms(ctx, ('bot_owner',))
     emb = discord.Embed(color=random.randint(1, 255**3-1), title='Command Calls')
     emb.description = 'Here are all the command calls made.'
     author = self.bot.user
     emb.set_author(name=str(author), icon_url=(author.avatar_url if author.avatar_url else author.default_avatar_url))
     emb.add_field(name='Total', value=sum(self.bot.command_calls.values()))
     for cmd, count in reversed(sorted(self.bot.command_calls.items(), key=lambda i: i[1])):
         emb.add_field(name=cmd, value=count)
     await self.bot.say(embed=emb)
Esempio n. 17
0
 async def gemote_msg(self, ctx, *, text: str):
     """Send a message with emotes, bypassing the cross server emote restriction.
     Usage: gemote_msg [message]"""
     echeck_perms(ctx, ('bot_owner', ))
     emb = discord.Embed(color=random.randint(1, 255**3 - 1))
     final = text[:]
     for emoji in self.bot.get_all_emojis():
         final = final.replace(':%s:' % emoji.name,
                               str(emoji).replace(':', ';_!:'))
     final = final.replace(';_!:', ':')
     emb.description = final
     await self.bot.say(embed=emb)
Esempio n. 18
0
 async def restart(self, ctx):
     """Restarts this bot.
     Usage: restart"""
     echeck_perms(ctx, ('bot_owner', ))
     self.bot.store_writer.cancel()
     await self.bot.store.commit()
     if ctx.invoked_with != 'update':
         await ctx.send(
             'I\'ll try to restart. Hopefully I come back alive :stuck_out_tongue:'
         )
     self.logger.info('The bot is now restarting!')
     # self.bot.is_restart = True
     os.execl(sys.executable, sys.executable, *sys.argv)
Esempio n. 19
0
    async def restart(self, ctx):
        """Restarts this bot.
        Usage: restart"""
        echeck_perms(ctx, ('bot_owner',))
#        for i in self.bot.servers:
#            await self.bot.send_message(i.default_channel, 'This bot (' + self.bname + ') is now restarting!')
        self.bot.store_writer.cancel()
        await self.bot.store.commit()
        if ctx.invoked_with != 'update':
            await self.bot.say('I\'ll try to restart. Hopefully I come back alive :stuck_out_tongue:')
        self.logger.info('The bot is now restarting!')
        self.bot.is_restart = True
        os.execl(sys.executable, sys.executable, *sys.argv)
Esempio n. 20
0
 async def ban(self, ctx, *, member: discord.Member):
     """Ban someone from the server.
     Usage: ban [member]"""
     echeck_perms(ctx, ('ban_members', ))
     await self.bot.say(':hammer: **Are you sure you want to ban ' +
                        member.mention + '?**')
     if not (await self.bot.wait_for_message(
             timeout=6.0,
             author=ctx.message.author,
             channel=ctx.message.channel,
             check=lambda m: m.content.lower().startswith('y'))):
         await self.bot.say('Not banning.')
         return
     await self.bot.ban(member)
     await self.bot.say(':hammer: Banned. It was just about time.')
Esempio n. 21
0
 async def console_msg(self, ctx):
     """Allow you to type here in the console.
     Usage: console_msg"""
     echeck_perms(ctx, ('bot_owner',))
     def console_task(ch):
         while True:
             text_in = input('Message> ')
             if text_in == 'quit':
                 return
             else:
                 self.loop.create_task(self.bot.send_message(ch, text_in))
     await self.bot.say('Now entering: Console message mode')
     print('Type \'quit\' to exit.')
     await self.loop.run_in_executor(None, console_task, ctx.message.channel)
     await self.bot.say('Exited console message mode')
Esempio n. 22
0
 async def update(self, ctx):
     """Auto-updates this bot and restarts if any code was updated.
     Usage: update"""
     echeck_perms(ctx, ('bot_owner', ))
     restart = not ctx.invoked_with.startswith('r')
     msg = await ctx.send('Trying to update...')
     r_key = ', now restarting' if restart else ''
     r_not_key = ', not restarting' if restart else ''
     dest = ctx.channel if self.bot.selfbot else ctx.author
     try:
         gitout = await self.loop.run_in_executor(
             None,
             functools.partial(subprocess.check_output, ['git', 'pull'],
                               stderr=subprocess.STDOUT))
         gitout = gitout.decode('utf-8')
     except (subprocess.CalledProcessError, FileNotFoundError) as exp:
         if ('status 128' in str(exp)) or isinstance(
                 exp, FileNotFoundError):
             with async_timeout.timeout(25):  # for streaming
                 async with self.bot.cog_http.get(
                         'https://github.com/Armored-Dragon/goldmine/archive/master.zip'
                 ) as r:
                     tarball = await r.read()
             with zipfile.ZipFile(io.BytesIO(tarball)) as z:
                 z.extractall(os.path.join(self.bot.dir, 'data'))
             distutils.dir_util.copy_tree(
                 os.path.join(self.bot.dir, 'data', 'goldmine-master'),
                 self.bot.dir)
             shutil.rmtree(
                 os.path.join(self.bot.dir, 'data', 'goldmine-master'))
             gitout = 'Successfully updated via zip.\nZip size: ' + str(
                 sys.getsizeof(tarball) / 1048576) + ' MB'
         else:
             await msg.edit(
                 content='An error occured while attempting to update!')
             await dest.send('```' + str(exp) + '```')
             gitout = False
     if gitout != False:
         await dest.send('Update Output:\n```' + gitout + '```')
     if not gitout:
         await msg.edit(content=msg.content + f'\nUpdate failed{r_not_key}.'
                        )
     elif gitout.split('\n')[-2:][0] == 'Already up-to-date.':
         await msg.edit(content=f'Bot was already up-to-date{r_not_key}.')
     else:
         await msg.edit(content=f'Bot was able to update{r_key}.')
     if restart:
         await self.restart.invoke(ctx)
Esempio n. 23
0
 async 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 self.bot.upload(
         img_bytes,
         filename='screenshot.png',
         content='This is *probably* what my screen looks like right now.')
Esempio n. 24
0
 async def msg_rate(self, ctx):
     """Get the message rate.
     Usage: msg_rate"""
     echeck_perms(ctx, ('bot_owner',))
     msg = await self.bot.say('Please wait...')
     start_time = datetime.now()
     m = {'messages': 0}
     async def msg_task(m):
         while True:
             await self.bot.wait_for_message()
             m['messages'] += 1
     task = self.loop.create_task(msg_task(m))
     await asyncio.sleep(8)
     task.cancel()
     time_elapsed = datetime.now() - start_time
     time_elapsed = time_elapsed.total_seconds()
     await self.bot.edit_message(msg, 'I seem to be getting ' + str(round(m['messages'] / time_elapsed, 2)) + ' messages per second.')
Esempio n. 25
0
 async def dload(self, ctx):
     """Load the datastore from disk.
     Usage: dload"""
     echeck_perms(ctx, ('bot_owner', ))
     await ctx.send(
         '**ARE YOU SURE YOU WANT TO LOAD THE DATASTORE?** *yes, no*')
     resp = await self.bot.wait_for(
         'message',
         timeout=15,
         check=lambda m: m.channel == ctx.channel and m.author == ctx.author
     )
     if resp.content.lower() == 'yes':
         self.bot.store.read()
         await ctx.send(
             '**Read the datastore from disk, overwriting current copy!**')
     else:
         await ctx.send('**Didn\'t say yes, aborting.**')
Esempio n. 26
0
 async def ban(self, ctx, *, member: discord.Member):
     """Ban someone from the guild.
     Usage: ban [member]"""
     echeck_perms(ctx, ('ban_members', ))
     await ctx.send(':hammer: **Are you sure you want to ban ' +
                    member.mention + '?**')
     if not (await self.bot.wait_for(
             'message',
             timeout=6.0,
             check=lambda m: m.content.lower().startswith('y') and m.channel
             == ctx.channel and m.author == ctx.author)):
         await ctx.send('Not banning.')
         return
     await member.ban(
         reason=
         'Ban was requested by command (from someone with the Ban Members permission)'
     )
     await ctx.send(':hammer: Banned. It was just about time.')
Esempio n. 27
0
 async def seref(self, ctx, *, code: str):
     """Evaluate some code (multi-statement) in command scope.
     Usage: seref [code to execute]"""
     echeck_perms(ctx, ('bot_owner',))
     dc = self.dc_funcs
     def print(*ina: str):
         self.loop.create_task(self.bot.say(' '.join(ina)))
         return True
     try:
         ev_output = exec(bdel(bdel(code, '```python'), '```py').strip('`'))
     except Exception as e:
         ev_output = 'An exception of type %s occured!\n' % type(e).__name__ + str(e)
     o = str(ev_output)
     if ev_output is None:
         await self.bot.say('✅')
         return
     if ctx.invoked_with.startswith('r'):
         await self.bot.say(o)
     else:
         await self.bot.say('```py\n' + o + '```')
Esempio n. 28
0
 async def render(self, ctx, *, webpage: str):
     """Render a webpage to image.
     Usage: render [url]"""
     echeck_perms(ctx, ('bot_owner', ))
     await self.bot.say(
         ':warning: Not yet working.'
         'Type `yes` within 6 seconds to proceed and maybe crash your bot.')
     if not (await self.bot.wait_for_message(
             timeout=6.0,
             author=ctx.message.author,
             channel=ctx.message.channel,
             check=lambda m: m.content.lower().startswith('yes'))):
         return
     try:
         self.web_render = scr.Screenshot()
     except ImportError:
         await self.bot.say('The bot owner hasn\'t enabled this feature!')
         return
     image = self.web_render.capture(webpage)
     await self.bot.upload(io.BytesIO(image), filename='webpage.png')
Esempio n. 29
0
 async def memberlist(self, ctx, *server_ids: str):
     """List the members of a server.
     Usage: memberlist [server ids]"""
     echeck_perms(ctx, ('bot_owner',))
     if not server_ids:
         await self.bot.say('**You need to specify at least 1 server ID!**')
         return False
     pager = commands.Paginator(prefix='```diff')
     pager.add_line('< -- SERVERS <-> MEMBERS -- >')
     server_table = {i.id: i for i in self.bot.servers}
     for sid in server_ids:
         with assert_msg(ctx, f'**ID** `{sid}` **is invalid. (must be 18 numbers)**'):
             check(len(sid) == 18)
         try:
             server = server_table[sid]
         except KeyError:
             await self.bot.say(f'**ID** `{sid}` **was not found.**')
             return False
         pager.add_line('+ ' + server.name + ' [{0} members] [ID {1}]'.format(str(len(server.members)), server.id))
         for member in server.members:
             pager.add_line('- ' + str(member))
     for page in pager.pages:
         await self.bot.say(page)
Esempio n. 30
0
 async def setprop(self, ctx, pname: str, *, value: str):
     """Set the value of a property on server level.
     Usage: setprop [property name] [value]"""
     echeck_perms(ctx, ('manage_server', ))
     self.bot.store.set_prop(ctx.message, 'by_server', pname, value)
     await self.bot.say(':white_check_mark:')