Ejemplo n.º 1
0
 async def _prefix(self, ctx, *, new_prefix: str = None):
     """Get prefix and set server prefix.
     Use the argument 'reset' to reset the guild prefix to default.
     """
     bot = ctx.bot
     default_prefix = bot.default_prefix
     if not ctx.guild:
         if new_prefix:
             embed = make_embed(
                 msg_type='error',
                 title=f"Prefix can only be changed in guilds.")
             await ctx.send(embed=embed)
         else:
             embed = make_embed(msg_type='info',
                                title=f"Prefix is {default_prefix}")
             await ctx.send(embed=embed)
     else:
         if new_prefix:
             await ctx.guild_dm.prefix(new_prefix)
             if new_prefix.lower() == 'reset':
                 new_prefix = bot.default_prefix
             embed = make_embed(msg_type='success',
                                title=f"Prefix set to {new_prefix}")
             ctx.bot.prefixes[ctx.guild.id] = new_prefix
             return await ctx.send(embed=embed)
         guild_prefix = await ctx.guild_dm.prefix(new_prefix)
         prefix = guild_prefix if guild_prefix else default_prefix
         embed = make_embed(msg_type='info', title=f"Prefix is {prefix}")
         await ctx.send(embed=embed)
Ejemplo n.º 2
0
    async def guild(self, ctx, *, guild: Guild):
        """Lookup Guild info"""
        if guild:
            if guild.unavailable:
                embed = make_embed(msg_type='error',
                                   title='Guild found, but unavailable!')
            else:
                embed = make_embed(msg_type='info',
                                   thumbnail=guild.icon_url_as(format='png'))
                date_created = datetime.strftime(guild.created_at,
                                                 "UTC %Y/%m/%d %H:%M")
                basic_info = (f"ID: {guild.id}\n"
                              f"Owner: {guild.owner}\n"
                              f"Created: {date_created}\n"
                              f"Region: {guild.region}\n")
                embed.add_field(name=guild.name,
                                value=basic_info,
                                inline=False)
                stats_info = (f"Members: {guild.member_count}\n"
                              f"Roles: {len(guild.roles)}\n"
                              f"Text Channels: {len(guild.text_channels)}\n"
                              f"Channel Categories: {len(guild.categories)}")
                embed.add_field(name='Stats', value=stats_info, inline=False)

                guild_perms = guild.me.guild_permissions
                req_perms = ctx.bot.req_perms
                perms_compare = guild_perms >= req_perms
                core_dir = ctx.bot.core_dir
                data_dir = os.path.join(core_dir, '..', 'data')
                data_file = 'permissions.json'
                perms_info = f"Value: {guild_perms.value}\n"
                perms_info += f"Meets Requirements: {perms_compare}\n"
                with open(os.path.join(data_dir, data_file), "r") as perm_json:
                    perm_dict = json.load(perm_json)

                for perm, bitshift in perm_dict.items():
                    if bool((req_perms.value >> bitshift) & 1):
                        if bool((guild_perms.value >> bitshift) & 1):
                            perms_info += ":white_small_square:  {}\n".format(
                                perm)
                        else:
                            perms_info += ":black_small_square:  {}\n".format(
                                perm)
                embed.add_field(name='Permissions',
                                value=perms_info,
                                inline=False)

                bot_list = [m for m in guild.members if m.bot]
                bot_info = f"Bots: {len(bot_list)}\n"
                if 1 <= len(bot_list) <= 20:
                    for bot in bot_list:
                        online = bot.status == discord.Status.online
                        status = "\U000025ab" if online else "\U000025aa"
                        bot_info += f"{status} {bot}\n"
                embed.add_field(name='Bots', value=bot_info, inline=False)

        else:
            embed = make_embed(msg_type='error', title='Guild not found')
        await ctx.send(embed=embed)
Ejemplo n.º 3
0
    async def check_perms(
        self,
        ctx,
        member_or_role: Multi(discord.Member, discord.Role),
        guild_or_channel: Multi(discord.Guild, discord.TextChannel,
                                discord.VoiceChannel) = None):
        """Show permissions of a member or role for the guild and channel."""
        if guild_or_channel:
            if isinstance(guild_or_channel, discord.Guild):
                guild_perms = ctx.guild.me.guild_permissions
        else:
            guild_perms = ctx.guild.me.guild_permissions
            if isinstance(member_or_role, discord.Member):
                chan_perms = ctx.channel.permissions_for(member_or_role)
            else:
                return await ctx.send("Role Permissions aren't done yet.")

        req_perms = ctx.bot.req_perms
        g_perms_compare = guild_perms >= req_perms
        c_perms_compare = chan_perms >= req_perms
        core_dir = ctx.bot.core_dir
        data_dir = os.path.join(core_dir, '..', 'data')
        data_file = 'permissions.json'
        msg = f"**Guild:**\n{ctx.guild}\nID {ctx.guild.id}\n"
        msg += f"**Channel:**\n{ctx.channel}\nID {ctx.channel.id}\n"
        msg += "```py\nGuild     | Channel\n"
        msg += "----------|----------\n"
        msg += "{} | {}\n".format(guild_perms.value, chan_perms.value)
        msg += "{0:9} | {1}```".format(str(g_perms_compare),
                                       str(c_perms_compare))
        y_emj = ":white_small_square:"
        n_emj = ":black_small_square:"

        with open(os.path.join(data_dir, data_file), "r") as perm_json:
            perm_dict = json.load(perm_json)

        for perm, bitshift in perm_dict.items():
            if bool((req_perms.value >> bitshift) & 1):
                guild_bool = bool((guild_perms.value >> bitshift) & 1)
                channel_bool = bool((chan_perms.value >> bitshift) & 1)
                guild_e = y_emj if guild_bool else n_emj
                channel_e = y_emj if channel_bool else n_emj
                msg += f"{guild_e} {channel_e}  {perm}\n"

        try:
            if chan_perms.embed_links:
                embed = make_embed(msg_type='info',
                                   title=f'Permissions for {member_or_role}',
                                   content=msg)
                await ctx.send(embed=embed)
            else:
                await ctx.send(msg)
        except discord.errors.Forbidden:
            embed = make_embed(msg_type='info',
                               title=f'Permissions for {member_or_role}',
                               content=msg)
            await ctx.author.send(embed=embed)
Ejemplo n.º 4
0
    async def guild_perms(self, ctx, guild_id=None):
        """Gets bot's permissions for the guild."""
        if not ctx.guild and not guild_id:
            await ctx.send(embed=make_embed(
                msg_type='error', title="This is a DM. Please provide ID."))
            return
        if guild_id:
            guild = ctx.bot.get_guild(int(guild_id))
            if not guild:
                await ctx.send(
                    embed=make_embed(msg_type='error', title="Guild not found")
                )
                return
        else:
            guild = ctx.guild

        guild_perms = guild.me.guild_permissions
        req_perms = ctx.bot.req_perms
        perms_compare = guild_perms >= req_perms
        core_dir = ctx.bot.core_dir
        data_dir = os.path.join(core_dir, '..', 'data')
        data_file = 'permissions.json'
        msg = f"{guild}\nID {guild.id}\n"
        msg += f"```py\n{guild_perms.value}\n"
        msg += f"{perms_compare}```"

        with open(os.path.join(data_dir, data_file), "r") as perm_json:
            perm_dict = json.load(perm_json)

        for perm, bitshift in perm_dict.items():
            if bool((req_perms.value >> bitshift) & 1):
                if bool((guild_perms.value >> bitshift) & 1):
                    msg += ":white_small_square:  {}\n".format(perm)
                else:
                    msg += ":black_small_square:  {}\n".format(perm)

        try:
            if not isinstance(ctx.channel, discord.DMChannel):
                if not ctx.channel.permissions_for(ctx.guild.me).embed_links:
                    await ctx.send(msg)
                    return
            embed = make_embed(msg_type='info',
                               title='Guild Permissions',
                               content=msg)
            await ctx.send(embed=embed)
        except discord.errors.Forbidden:
            embed = make_embed(msg_type='info',
                               title='Guild Permissions',
                               content=msg)
            await ctx.author.send(embed=embed)
Ejemplo n.º 5
0
    async def channel_perms(self, ctx, channel_id=None):
        """Gets bot's permissions for the channel."""
        if channel_id:
            channel = ctx.bot.get_channel(int(channel_id))
            if not channel:
                await ctx.send(embed=make_embed(msg_type='error',
                                                title="Channel not found"))
                return
        else:
            channel = ctx.channel

        dm_channel = isinstance(channel, discord.DMChannel)
        me = ctx.bot.user if dm_channel else channel.guild.me
        chan_perms = channel.permissions_for(me)
        req_perms = ctx.bot.req_perms
        perms_compare = chan_perms >= req_perms
        core_dir = ctx.bot.core_dir
        data_dir = os.path.join(core_dir, '..', 'data')
        data_file = 'permissions.json'
        msg = ""
        if not dm_channel:
            msg += f"{channel.guild}\nID {channel.guild.id}\n"
        msg += f"{channel}\nID {channel.id}\n"
        msg += f"```py\n{chan_perms.value}\n"
        msg += f"{perms_compare}```"

        with open(os.path.join(data_dir, data_file), "r") as perm_json:
            perm_dict = json.load(perm_json)

        for perm, bitshift in perm_dict.items():
            if bool((req_perms.value >> bitshift) & 1):
                if bool((chan_perms.value >> bitshift) & 1):
                    msg += f":white_small_square:  {perm}\n"
                else:
                    msg += f":black_small_square:  {perm}\n"
        try:
            if not isinstance(ctx.channel, discord.DMChannel):
                if not ctx.channel.permissions_for(ctx.guild.me).embed_links:
                    await ctx.send(msg)
                    return
            embed = make_embed(msg_type='info',
                               title='Channel Permissions',
                               content=msg)
            await ctx.send(embed=embed)
        except discord.errors.Forbidden:
            embed = make_embed(msg_type='info',
                               title='Channel Permissions',
                               content=msg)
            await ctx.author.send(embed=embed)
Ejemplo n.º 6
0
 async def _nickname(self, ctx, *, nickname: str):
     """Sets bot's nickname"""
     try:
         await ctx.guild.me.edit(nick=nickname)
     except discord.Forbidden:
         embed = make_embed(
             msg_type='error',
             title="Failed to set nickname",
             content=("I'm missing permissions to change my nickname. "
                      "Use **{}get guildperms** to check permissions."
                      "").format(ctx.prefix))
         await ctx.send()
     else:
         embed = make_embed(msg_type='success', title="Nickname set.")
         await ctx.send(embed=embed)
Ejemplo n.º 7
0
 async def reload_cm(self, ctx):
     """Reload Cog Manager."""
     bot = ctx.bot
     try:
         bot.unload_extension('meowth.core.cog_manager')
         bot.load_extension('meowth.core.cog_manager')
         embed = make_embed(msg_type='success',
                            title='Cog Manager reloaded.')
         await ctx.send(embed=embed)
     except Exception as e:
         msg = "{}: {}".format(type(e).__name__, e)
         embed = make_embed(msg_type='error',
                            title='Error loading Cog Manager',
                            content=msg)
         await ctx.send(embed=embed)
Ejemplo n.º 8
0
 async def _username(self, ctx, *, username: str):
     """Sets bot's username"""
     try:
         await ctx.bot.user.edit(username=username)
     except discord.HTTPException:
         embed = make_embed(
             msg_type='error',
             title="Failed to change name",
             content=("Remember that you can only do it up to 2 times an "
                      "hour. Use nicknames if you need frequent changes. "
                      "**{}set nickname**").format(ctx.prefix))
         await ctx.send(embed=embed)
     else:
         embed = make_embed(msg_type='success', title="Username set.")
         await ctx.send(embed=embed)
Ejemplo n.º 9
0
    def make_trade_embed(lister, wanted_pokemon, offered_pokemon, note=None):
        """Returns a formatted embed message with trade details."""

        wants = [
            f'{i+1}\u20e3: {pkmn}' for i, pkmn in enumerate(wanted_pokemon)
        ]

        fields_obj = {
            "Wants": '\n'.join(wants),
            "Offers": offered_pokemon.full_name
        }

        if note:
            fields_obj["Note"] = note

        return utils.make_embed(title="Pokemon Trade - {}".format(
            lister.display_name),
                                msg_colour=0x63b2f7,
                                icon=Trade.icon_url,
                                fields=fields_obj,
                                inline=True,
                                footer=lister.display_name,
                                footer_icon=lister.avatar_url_as(format='png',
                                                                 size=256),
                                thumbnail=offered_pokemon.img_url)
Ejemplo n.º 10
0
 async def _game(self, ctx, *, game: str):
     """Sets the bot's activity"""
     status = ctx.me.status
     game = discord.Game(name=game)
     await ctx.bot.change_presence(status=status, activity=game)
     embed = make_embed(msg_type='success', title='Game set.')
     await ctx.send(embed=embed)
Ejemplo n.º 11
0
    async def embed(self, title, description=None, plain_msg='', *,
                    msg_type=None, title_url=None, colour=None,
                    icon=None, thumbnail='', image='', fields: dict = None,
                    footer=None, footer_icon=None, send=True, inline=False):
        """Send or build an embed using context details."""
        embed = make_embed(title=title, content=description, msg_type=msg_type,
                           title_url=title_url, msg_colour=colour, icon=icon,
                           thumbnail=thumbnail, image=image, guild=self.guild)
        if fields:
            for key, value in fields.items():
                ilf = inline
                if not isinstance(value, str):
                    ilf = value[0]
                    value = value[1]
                embed.add_field(name=key, value=value, inline=ilf)
        if footer:
            footer = {'text':footer}
            if footer_icon:
                footer['icon_url'] = footer_icon
            embed.set_footer(**footer)

        if not send:
            return embed

        return await self.send(plain_msg, embed=embed)
Ejemplo n.º 12
0
    async def status(self, ctx, *, status: str):
        """Sets the bot's online status

        Available statuses:
            online
            idle
            dnd
        """

        statuses = {
            "online": discord.Status.online,
            "idle": discord.Status.idle,
            "dnd": discord.Status.dnd,
            "invisible": discord.Status.invisible
        }

        game = ctx.me.activity

        try:
            status = statuses[status.lower()]
        except KeyError:
            await ctx.bot.send_cmd_help(ctx)
        else:
            await ctx.bot.change_presence(status=status, activity=game)
            embed = make_embed(msg_type='success',
                               title="Status changed to {}.".format(status))
            await ctx.send(embed=embed)
Ejemplo n.º 13
0
 async def _break(self, ctx):
     """Simulates a sudden disconnection."""
     embed = make_embed(msg_type='warning', title='Faking a crash...')
     try:
         await ctx.send(embed=embed)
     except discord.HTTPException:
         pass
     await ctx.bot.logout()
Ejemplo n.º 14
0
    async def on_ready(self):
        intro = "Meowth - Discord bot for Pokemon Go Communities"
        intro_deco = "{0}\n{1}\n{0}".format('='*len(intro), intro)
        if not self.launch_time:
            self.launch_time = datetime.utcnow()
        if not self.launcher:
            print(intro_deco)
        if self.from_restart:
            print("We're back!\n")
        else:
            print("We're on!\n")
        print(f"Bot Version: {self.version}\n")
        if self.debug:
            print(f"Python Version: {self.py_version}")
            print(f"Discord.py Version: {self.dpy_version}")
            print(f"Platform: {self.platform}\n")
        guilds = len(self.guilds)
        users = len(list(self.get_all_members()))
        if guilds:
            print(f"Servers: {guilds}")
            print(f"Members: {users}")
        else:
            print("I'm not in any server yet, so be sure to invite me!")
        if self.invite_url:
            print(f"\nInvite URL: {self.invite_url}\n")
        
        # load extensions marked for preload in config
        for ext in self.preload_ext:
            ext_name = ("meowth.exts."+ext)
            self.load_extension(ext_name)

        if self.from_restart:
            table = self.dbi.table('restart_savedata')
            table.query.order_by(table['restart_snowflake'], asc=False)
            table.query.limit(1)
            last_restart = (await table.query.get())[0]

            embed = make_embed(title='Restart Complete.', msg_type='success')

            guild = self.get_guild(last_restart['restart_guild'])

            if guild:
                channel = guild.get_channel(last_restart['restart_channel'])

                if channel:
                    original_message = await channel.fetch_message(
                        last_restart['restart_message'])
                    return await original_message.edit(embed=embed)

            else:
                channel = self.get_user(last_restart['restart_by'])

            if not channel:
                channel = self.get_user(self.owner)
                if not channel:
                    return self.logger.error('Bot owner not found.')

            return await channel.send(embed=embed)
Ejemplo n.º 15
0
 async def runas(self, ctx, member: discord.Member, *, new_cmd):
     """Run a command as a different member."""
     if await ctx.bot.is_owner(member):
         await ctx.send(embed=make_embed(
             msg_type='error', title='No, you may not run as owner.'))
         return
     ctx.message.content = new_cmd
     ctx.message.author = member
     await ctx.bot.process_commands(ctx.message)
Ejemplo n.º 16
0
 async def _shutdown(self, ctx):
     """Shuts down the bot"""
     embed = make_embed(title='Shutting down.',
                        msg_colour='red',
                        icon="https://i.imgur.com/uBYS8DR.png")
     try:
         await ctx.send(embed=embed)
     except discord.HTTPException:
         pass
     await ctx.bot.shutdown()
Ejemplo n.º 17
0
    async def _stats(self, ctx):
        """Shows stats about bot"""
        bot = ctx.bot
        owner = await bot.get_user_info(ctx.bot.owner)
        uptime_str = bot.uptime_str
        cpu_p = await ctx.bot.loop.run_in_executor(None, self.get_cpu)
        mem = psutil.virtual_memory()
        mem_p = round((mem.available / mem.total) * 100, 2)
        bot_process = psutil.Process()
        ppid = bot_process.ppid()
        p_mem = bot_process.memory_info().rss
        swapped = psutil.swap_memory().used

        data_sizes = {'B': 1, 'KB': 1024, 'MB': 1048576, 'GB': 1073741824}
        for size, value in data_sizes.items():
            if (p_mem / value) > 1 < 1024:
                p_mem_str = "{} {}".format(round(p_mem / value, 2), size)
            if (swapped / value) > 1 < 1024:
                swap_str = "{} {}".format(round(swapped / value, 2), size)

        member_count = 0
        server_count = 0
        for guild in bot.guilds:
            server_count += 1
            member_count += guild.member_count

        msg_table = bot.dbi.table('discord_messages')
        msg_table.query(msg_table['*'].count)
        message_count = await msg_table.query.get_value()

        cmd_table = bot.dbi.table('command_log')
        cmd_table.query(cmd_table['*'].count)
        command_count = await cmd_table.query.get_value()

        embed = make_embed(msg_type='info', title="Bot Statistics")
        instance_msg = (f"**Owner:** {owner}\n**Uptime:** {uptime_str}\n"
                        f"**Version:** {bot.version}\n"
                        f"**D.Py Ver:** {bot.dpy_version}\n"
                        f"**Python:** {bot.py_version}")
        session_msg = (
            f"**Servers:** {server_count}\n**Members:** {member_count}\n"
            f"**Messages:** {message_count}\n"
            f"**Commands:** {command_count}\n"
            f"**Reconnections:** {bot.resumed_count}")
        process_msg = (f"**PID:** {ppid}\n**Process RAM:** {p_mem_str}\n"
                       f"**Swap File:** {swap_str}\n**System RAM:** {mem_p}\n"
                       f"**System CPU:** {cpu_p}\n")
        embed.add_field(name="ACTIVITY", value=session_msg)
        embed.add_field(name="PROCESS", value=process_msg)
        embed.add_field(name="INSTANCE", value=instance_msg)

        try:
            await ctx.send(embed=embed)
        except discord.HTTPException:
            await ctx.send("I need the `Embed links` permission to send this")
Ejemplo n.º 18
0
    async def purge(self, ctx, msg_number: int = 10):
        """Delete a number of messages from the channel.

        Default is 10. Max 100."""
        if msg_number > 100:
            embed = make_embed(
                msg_type='info',
                title="ERROR",
                content="No more than 100 messages can be purged at a time.",
                guild=ctx.guild)
            await ctx.send(embed=embed)
            return

        def is_unpinned(m):
            return not m.pinned

        deleted = await ctx.channel.purge(limit=msg_number, check=is_unpinned)
        embed = make_embed(msg_type='success',
                           title='Deleted {} message{}'.format(
                               len(deleted), "s" if len(deleted) > 1 else ""))
        result_msg = await ctx.send(embed=embed)
        await asyncio.sleep(3)
        await result_msg.delete()
Ejemplo n.º 19
0
 def make_offer_embed(trader, listed_pokemon, offer):
     return utils.make_embed(title="Pokemon Trade Offer - {}".format(
         trader.display_name),
                             msg_colour=0x63b2f7,
                             icon=Trade.icon_url,
                             fields={
                                 "You Offered": listed_pokemon.full_name,
                                 "They Offer": offer.full_name
                             },
                             inline=True,
                             footer=trader.display_name,
                             footer_icon=trader.avatar_url_as(format='png',
                                                              size=256),
                             thumbnail=offer.img_url)
Ejemplo n.º 20
0
 async def _bot_invite(self, ctx, plain_url: bool = False):
     """Shows bot's invite url"""
     invite_url = ctx.bot.invite_url
     if plain_url:
         await ctx.send("Invite URL: <{}>".format(invite_url))
         return
     else:
         embed = make_embed(title='Click to invite me to your server!',
                            title_url=invite_url,
                            msg_colour='blue',
                            icon="https://i.imgur.com/DtPWJPG.png")
     try:
         await ctx.send(embed=embed)
     except discord.errors.Forbidden:
         await ctx.send("Invite URL: <{}>".format(invite_url))
Ejemplo n.º 21
0
    async def _about(self, ctx):
        """Shows info about the bot"""
        bot = ctx.bot
        author_repo = "https://github.com/FoglyOgly"
        bot_repo = author_repo + "/Meowth"
        uptime_str = bot.uptime_str
        owner = await ctx.get.user(ctx.bot.owner)
        invite_str = "[Invite Me!]({})".format(bot.invite_url)

        if ctx.guild:
            prefix = bot.prefixes.get(ctx.guild.id, bot.default_prefix)
        else:
            prefix = bot.default_prefix

        member_count = 0
        server_count = 0

        server_count = len(bot.guilds)
        member_count = sum([g.member_count for g in bot.guilds])

        about = [
            "A Bot for Pokemon Go Communities!",
            f"**[Docs & Source!]({bot_repo})** | **{invite_str}**\n\n",
            f"Guild Prefix: `{prefix}`\n", f"Help: `{prefix}help`\n\n",
            f"**Owner:** {owner}", f"**Uptime:** {uptime_str}",
            f"**Servers:** {server_count}", f"**Members:** {member_count}"
        ]

        # embed_colour = await url_color(bot.avatar_small)
        embed = make_embed(
            icon=bot.avatar_small,
            title=f"{bot.user}",
            content='\n'.join(about),
            # msg_colour=embed_colour
        )
        embed.set_thumbnail(url=bot.avatar)

        try:
            await ctx.send(embed=embed)
        except discord.HTTPException:
            await ctx.send("I need the `Embed links` permission to send this")
Ejemplo n.º 22
0
 async def _restart(self, ctx):
     """Restarts the bot"""
     embed = make_embed(title='Restarting...',
                        msg_colour='red',
                        icon="https://i.imgur.com/uBYS8DR.png")
     try:
         restart_msg = await ctx.send(embed=embed)
     except discord.HTTPException:
         restart_msg = None
     data = {
         'restart_snowflake': next(snowflake.create()),
         'restart_by': ctx.author.id,
         'restart_channel': ctx.channel.id,
         'restart_guild': ctx.guild.id
     }
     if restart_msg:
         data['restart_message'] = restart_msg.id
     table = ctx.bot.dbi.table('restart_savedata')
     table.insert(**data)
     await table.insert.commit()
     await ctx.bot.shutdown(restart=True)
Ejemplo n.º 23
0
 async def _resumed(self, ctx):
     """Gets the number of websocket reconnections."""
     r_c = ctx.bot.resumed_count
     embed = make_embed(msg_type='info',
                        title=f"Connections Resumed: {r_c}")
     await ctx.send(embed=embed)