Example #1
0
    async def print_results(self, ctx, results):
        msg = ctx.message
        nbs = '​'
        discord_fmt = nbs + '```py\n{}\n```'
        is_interactive = self.settings["OUTPUT_REDIRECT"] == "pages"
        res_len = len(discord_fmt.format(results))
        if is_interactive and res_len > self.settings["PAGES_LENGTH"]:
            single_msg = not self.settings["MULTI_MSG_PAGING"]
            page = self.pagify_interactive_results(ctx, results, single_msg=single_msg)
            self.bot.loop.create_task(page)
        elif res_len > 2000:
            if self.settings["OUTPUT_REDIRECT"] == "pm":
                await self.bot.send_message(msg.channel, 'Content too big. Check your PMs')
                enough_paper = self.settings["PM_PAGES"]
                for page in pagify(results, ['\n', ' '], shorten_by=12):
                    await self.bot.send_message(msg.author, discord_fmt.format(page))
                    enough_paper -= 1
                    if not enough_paper:
                        await self.bot.send_message(msg.author,
                                                    "**Too many pages! Think of the trees!**")
                        return
            elif self.settings["OUTPUT_REDIRECT"] == "console":
                await self.bot.send_message(msg.channel, 'Content too big. Check your console')
                print(results)
            else:
                await self.bot.send_message(msg.channel, 'Content too big. Writing to file')
                with open(self.output_file, 'w') as f:
                    f.write(results)
                open_cmd = self.settings["OPEN_CMD"]
                if open_cmd:
                    subprocess.Popen([open_cmd, self.output_file])
        else:

            await self.bot.send_message(msg.channel, discord_fmt.format(results))
Example #2
0
    async def discover_server(self, author: discord.User):
        output = ""
        servers = sorted(self.bot.servers, key=lambda s: s.name)
        for i, server in enumerate(servers, 1):
            output += "{}: {}\n".format(i, server.name)
        output += "Select a server to add to the sync list by number, " 'or enter "-1" to stop adding servers'
        for page in pagify(output, delims=["\n"]):
            dm = await self.bot.send_message(author, box(page))

        message = await self.bot.wait_for_message(channel=dm.channel,
                                                  author=author,
                                                  timeout=15)
        if message is not None:
            try:
                message = int(message.content.strip())
                if message == -1:
                    return -1
                else:
                    server = servers[message - 1]
            except (ValueError, IndexError):
                await self.bot.send_message(author,
                                            "That wasn't a valid choice")
                return None
            else:
                return server
        else:
            await self.bot.say("You took too long, try again later")
            return None
Example #3
0
    async def penis(self, ctx, *users: discord.Member):
        """Detects user's penis length

        This is 100% accurate.
        Enter multiple users for an accurate comparison!"""
        if not users:
            await self.bot.send_cmd_help(ctx)
            return

        dongs = {}
        msg = ""
        state = random.getstate()

        for user in users:
            random.seed(user.id)
            dongs[user] = "8{}D".format("=" * random.randint(0, 30))

        random.setstate(state)
        dongs = sorted(dongs.items(), key=lambda x: x[1])

        for user, dong in dongs:
            msg += "**{}'s size:**\n{}\n".format(user.display_name, dong)

        for page in pagify(msg):
            await self.bot.say(page)
Example #4
0
    async def racfaudit_top(self, ctx, count: int):
        """Show top N members in family."""
        await self.bot.type()

        try:
            member_models = await self.family_member_models()
        except ClashRoyaleAPIError as e:
            await self.bot.say(e.status_message)
            return

        author = ctx.message.author
        if not author.server_permissions.manage_roles:
            count = min(count, 10)

        member_models = sorted(member_models, key=lambda x: x['trophies'], reverse=True)
        results = member_models[:count]

        out = []

        for index, member in enumerate(results, 1):
            out.append('{:<4} {:>4} {:<8} {}'.format(
                index, member['trophies'], member['clan']['name'][5:], member['name']
            ))

        for page in pagify('\n'.join(out)):
            await self.bot.say(box(page, lang='py'))
Example #5
0
    async def _global_leaderboard(self, top: int=10):
        """Prints out the global leaderboard

        Defaults to top 10"""
        if top < 1:
            top = 10
        bank_sorted = sorted(self.bank.get_all_accounts(),
                             key=lambda x: x.balance, reverse=True)
        bank_sorted = [a for a in bank_sorted if a.member] #  exclude users who left
        unique_accounts = []
        for acc in bank_sorted:
            if not self.already_in_list(unique_accounts, acc):
                unique_accounts.append(acc)
        if len(unique_accounts) < top:
            top = len(unique_accounts)
        topten = unique_accounts[:top]
        highscore = ""
        place = 1
        for acc in topten:
            highscore += str(place).ljust(len(str(top)) + 1)
            highscore += ("{} |{}| ".format(acc.member, acc.server)
                          ).ljust(23 - len(str(acc.balance)))
            highscore += str(acc.balance) + "\n"
            place += 1
        if highscore != "":
            for page in pagify(highscore, shorten_by=12):
                await self.bot.say(box(page, lang="py"))
        else:
            await self.bot.say("There are no accounts in the bank.")
Example #6
0
    async def list(self, ctx, user: discord.Member = None):
        """
        Print out a user's game list (sends as a DM)

        user: (Optional) If given, list a user's game library, otherwise list the message user's library
        """

        author = ctx.message.author

        if not user:
            user = author

        game_list = get_games()

        if check_key(user.id) and game_list.get(user.id, False):
            message = pagify(", ".join(sorted(game_list[user.id])), [', '])

            await self.bot.say(
                "Please check your DM for the full list of games, {}.".format(
                    author.mention))
            await self.bot.send_message(author,
                                        "{}'s games:".format(user.mention))

            for page in message:
                await self.bot.send_message(author, (box(page)))
        else:
            await self.bot.say(
                "{}, you do not have any games. Add one using `[p]game add <game_name>` and/or link your Steam profile with `[p]game steamlink <steam_id>`."
                .format(user.mention))
    async def karmaboard(self, top: int=10):
        """Prints out the karma leaderboard

        Defaults to top 10. Use negative numbers to reverse the leaderboard."""
        reverse=True
        if top == 0:
            top = 10
        elif top < 0:
            reverse=False
            top = -top
        self.karma = dataIO.load_json(KARMA_PATH)
        members_sorted = sorted(self._get_all_members(),
                             key=lambda x: x.karma, reverse=reverse)
        if len(members_sorted) < top:
            top = len(members_sorted)
        topten = members_sorted[:top]
        highscore = ""
        place = 1
        for member in topten:
            highscore += str(place).ljust(len(str(top)) + 1)
            highscore += ("{} | ".format(member.name)
                          ).ljust(18 - len(str(member.karma)))
            highscore += str(member.karma) + "\n"
            place += 1
        if highscore != "":
            for page in pagify(highscore, shorten_by=12):
                await self.bot.say(box(page, lang="py"))
        else:
            await self.bot.say("No one has any karma �")
Example #8
0
    async def _server_leaderboard(self, ctx, top: int = 10):
        """Prints out the server's leaderboard

        Defaults to top 10"""
        # Originally coded by Airenkun - edited by irdumb
        server = ctx.message.server
        if top < 1:
            top = 10
        bank_sorted = sorted(self.bank.get_server_accounts(server),
                             key=lambda x: x.balance,
                             reverse=True)
        bank_sorted = [a for a in bank_sorted
                       if a.member]  #  exclude users who left
        if len(bank_sorted) < top:
            top = len(bank_sorted)
        topten = bank_sorted[:top]
        highscore = ""
        place = 1
        for acc in topten:
            highscore += str(place).ljust(len(str(top)) + 1)
            highscore += (str(acc.member.display_name) +
                          " ").ljust(23 - len(str(acc.balance)))
            highscore += str(acc.balance) + "\n"
            place += 1
        if highscore != "":
            for page in pagify(highscore, shorten_by=12):
                #Adding info site.
                siteInfo = "\nFull rankings at https://ren.injabie3.moe/economy"
                sleepTime = 60
                msgId = await self.bot.say(box(page, lang="py") + siteInfo)
                await asyncio.sleep(sleepTime)
                await self.bot.delete_message(msgId)
        else:
            await self.bot.say("There are no accounts in the bank.")
Example #9
0
 async def partycrash(self, ctx, idnum=None):
     """Lists servers and generates invites for them"""
     owner = ctx.message.author
     if idnum:
         server = discord.utils.get(self.bot.servers, id=idnum)
         if server:
             await self._confirm_invite(server, owner, ctx)
         else:
             await self.bot.say("I'm not in that server")
     else:
         msg = ""
         servers = sorted(self.bot.servers, key=lambda s: s.name)
         for i, server in enumerate(servers, 1):
             msg += "{}: {}\n".format(i, server.name)
         msg += "\nTo post an invite for a server just type its number."
         for page in pagify(msg, delims=["\n"]):
             await self.bot.say(box(page))
             await asyncio.sleep(1.5)  # Just in case for rate limits
         msg = await self.bot.wait_for_message(author=owner, timeout=15)
         if msg is not None:
             try:
                 msg = int(msg.content.strip())
                 server = servers[msg - 1]
             except ValueError:
                 await self.bot.say("You must enter a number.")
             except IndexError:
                 await self.bot.say("Index out of range.")
             else:
                 try:
                     await self._confirm_invite(server, owner, ctx)
                 except discord.Forbidden:
                     await self.bot.say("I'm not allowed to make an invite"
                                        " for {}".format(server.name))
         else:
             await self.bot.say("Response timed out.")
Example #10
0
    async def discover_server(self, author: discord.User):

        shared_servers = []
        for server in self.bot.servers:
            x = server.get_member(author.id)
            if x is not None:
                shared_servers.append(server)
        if len(shared_servers) == 1:
            return shared_servers[0]
        output = ""
        servers = sorted(shared_servers, key=lambda s: s.name)
        for i, server in enumerate(servers, 1):
            output += "{}: {}\n".format(i, server.name)
        output += "\npick the server to make a report in by its number."

        for page in pagify(output, delims=["\n"]):
            dm = await self.bot.send_message(author, box(page))

        message = await self.bot.wait_for_message(channel=dm.channel,
                                                  author=author,
                                                  timeout=45)
        if message is not None:
            try:
                message = int(message.content.strip())
                server = servers[message - 1]
            except (ValueError, IndexError):
                await self.bot.send_message(author,
                                            "That wasn't a valid choice")
                return None
            else:
                return server
        else:
            await self.bot.say("You took too long, try again later")
            return None
Example #11
0
    async def _global_leaderboard(self, top: int=10):
        """Prints out the global leaderboard

        Defaults to top 10"""
        if top < 1:
            top = 10
        bank_sorted = sorted(self.bank.get_all_accounts(),
                             key=lambda x: x.balance, reverse=True)
        unique_accounts = []
        for acc in bank_sorted:
            if not self.already_in_list(unique_accounts, acc):
                unique_accounts.append(acc)
        if len(unique_accounts) < top:
            top = len(unique_accounts)
        topten = unique_accounts[:top]
        highscore = ""
        place = 1
        for acc in topten:
            highscore += str(place).ljust(len(str(top)) + 1)
            highscore += ("{} |{}| ".format(acc.name, acc.server.name)
                          ).ljust(23 - len(str(acc.balance)))
            highscore += str(acc.balance) + "\n"
            place += 1
        if highscore != "":
            for page in pagify(highscore, shorten_by=12):
                await self.bot.say(box(page, lang="py"))
        else:
            await self.bot.say("There are no accounts in the bank.")
Example #12
0
    async def whisper(self, ctx, user: discord.User, text):
        """Whisper to someone using the bot
        Same as dming But you use the bot !"""

        author = ctx.message.author
        channel = ctx.message.channel

        try:
            await self.bot.delete_message(ctx.message)
        except:
            raise Exception(
                "Bruh i don't have delete messages perms delete your messaqe")

        prefix = "Ayoo Matey you Getting a Message from {} ({})".format(
            author.name, author.id)
        payload = "{}\n\n``` ***```{}```***".format(prefix, text)

        try:
            for page in pagify(payload, delims=[" ", "\n"], shorten_by=10):
                await self.bot.send_message(user, box(page))
        except discord.errors.Forbidden:
            log.debug(
                "I CAN'T F*****G SEND MSGS TO {} FFS DID HE BLOCK Me ! Or maybe he just has that teng where randoms can't msg :thinking: o well ¯\_(ツ)_/¯"
                .format(user))
        except (discord.errors.NotFound, discord.errors.InvalidArgument):
            log.debug("{} *404* Dis bitch not found~".format(user))
        else:
            reply = await self.bot.say(
                "Whisper Mcfucking *** Delivered***  https://goo.gl/3qCxR4 ")
            await asyncio.sleep(5)
            await self.bot.delete_message(reply)
Example #13
0
 async def _blacklist_list(self, ctx):
     """Lists currently blacklisted channels."""
     channel = ctx.message.channel
     if channel.is_private:
         if channel.id in self.settings["BLACKLIST"]:
             return await self.bot.say("This channel is blacklisted.")
         else:
             return await self.bot.say("This channel is not blacklisted.")
     else:
         if self.settings["BLACKLIST"]:
             is_owner = ctx.message.author.id == self.bot.settings.owner
             channels = []
             for c in self.settings["BLACKLIST"]:
                 channel = discord.utils.get(self.bot.get_all_channels()
                                             if is_owner else
                                             ctx.message.server.channels,
                                             id=c)
                 if channel:
                     channels.append(channel)
                 else:
                     if is_owner:
                         channels.append("Unknown ({})".format(c))
             if channels:
                 for page in pagify("Blacklist: {}".format(", ".join(
                         channels)), [", "]):
                     return await self.bot.say("```{}```".format(
                         page.strip(", ")))
         return await self.bot.say("The blacklist is empty.")
Example #14
0
    async def mention(self, ctx, name: str):
        server = ctx.message.server
        author = ctx.message.author
        channel = ctx.message.channel
        self.init_settings(server)

        name = name.lower()
        if name not in self.raffles[server.id]:
            return await self.bot.say("No such raffle.")
        r = self.raffles[server.id][name]
        entries = r.registered
        members = []
        for e in entries:
            x = server.get_member(e)
            if x is not None:
                members.append(x)

        output = ""
        if channel.permissions_for(author).mention_everyone:
            for member in members:
                output += "{0.mention} , ".format(member)
        else:
            for member in members:
                output += "\n{0.id}: {0.display_name}".format(member)

        for page in pagify(output, delims=["\n", ","]):
            await self.bot.say(page)
Example #15
0
 async def leaderboard(self, ctx, top=10):
     """Displays the win/loss leaderboard"""
     server = ctx.message.server
     if top < 1:
         top = 10
     entries_sorted = sorted(self.arena.get_entries(server),
                             key=lambda x: x.wins,
                             reverse=True)
     entries_sorted = [a for a in entries_sorted if a.member]
     if len(entries_sorted) < top:
         top = len(entries_sorted)
     topentries = entries_sorted[:top]
     highscore = "Wins Losses\n".rjust(23)
     place = 1
     for acc in topentries:
         highscore += str(place).ljust(len(str(top)) + 1)
         highscore += (
             str(acc.member.display_name) +
             " ").ljust(23 - len(str(acc.wins) + " " + str(acc.losses)))
         highscore += str(acc.wins) + " " + str(acc.losses) + "\n"
         place += 1
     if highscore != "":
         for page in pagify(highscore, shorten_by=12):
             await self.bot.say(box(page, lang="py"))
     else:
         await self.bot.say("There are no accounts in the leaderboard")
Example #16
0
 async def todo(self, cmd):
     '''Make your own ToDo list and manage it'''
     if cmd.invoked_subcommand is None:
         try:
             user = str(cmd.message.author)
             index = 0
             if len(self.config[user]) != 0:
                 msg = ''
                 for i in self.config[user]:
                     msg += '*{0}*: {1}\n'.format(index, i)
                     index += 1
                 page_index = 1
                 pages = pagify(msg)
                 for page in pages:
                     nick = cmd.message.author.nick or cmd.message.author.name
                     embed = discord.Embed(description=page)
                     embed.title = '{}\'s ToDo of {} things'.format(
                         nick, len(self.config[user]))
                     embed.colour = discord.Colour.green()
                     embed.set_footer(
                         text='Part {}'.format(page_index),
                         icon_url='https://yamahi.eu/favicon.ico')
                     await self.bot.say(embed=embed)
                     page_index += 1
             else:
                 await self.bot.say('You have nothing to do! :D')
         except KeyError:
             await self.bot.say('You have nothing to do! :D')
         except:
             await self.bot.say('An error happened?!')
Example #17
0
    async def emojis(self, ctx: Context, embed=False):
        """Show all emojis available on server."""
        server = ctx.message.server

        if embed:
            emoji_list = [
                emoji for emoji in server.emojis if not emoji.managed
            ]
            emoji_lists = grouper(25, emoji_list)
            for emoji_list in emoji_lists:
                em = discord.Embed()
                for emoji in emoji_list:
                    if emoji is not None:
                        em.add_field(name=str(emoji),
                                     value="`:{}:`".format(emoji.name))
                await self.bot.say(embed=em)
        else:
            out = []
            for emoji in server.emojis:
                # only include in list if not managed by Twitch
                if not emoji.managed:
                    emoji_str = str(emoji)
                    out.append("{} `:{}:`".format(emoji_str, emoji.name))
            for page in pagify("\n".join(out), shorten_by=12):
                await self.bot.say(page)
Example #18
0
    async def listclones(self, ctx):
        """Lists the current autorooms"""
        server = ctx.message.server
        if server.id not in self.settings:
            self.initial_config(server.id)

        channels = self.settings[server.id]['channels']
        if len(channels) == 0:
            return await self.bot.say("No autorooms set for this server")

        fix_list = []
        output = "Current Auto rooms\nChannel ID: Channel Name"
        for c in channels:
            channel = discord.utils.find(
                lambda m: m.id == c, server.channels
            )
            if channel is None:
                fix_list.append(c)
            else:
                output += "\n{}: {}".format(c, channel.name)
        for page in pagify(output, delims=["\n", ","]):
            await self.bot.send_message(ctx.message.author, box(page))
        for c in fix_list:
            channels.remove(c)
            self.save_json
Example #19
0
    async def opensource(self, ctx, channel):
        """Makes you able to communicate with other channels.
        This is cross-server. Type only the channel name or the ID."""
        author = ctx.message.author
        author_channel = ctx.message.channel

        def check(m):
            try:
                return channels[int(m.content)]
            except:
                return False

        channels = self.bot.get_all_channels()
        channels = [
            c for c in channels if c.name.lower() == channel or c.id == channel
        ]
        channels = [c for c in channels if c.type == discord.ChannelType.text]

        if not channels:
            await self.bot.say("No channels found. Remember to type just "
                               "the channel name, no `#`.")
            return

        if len(channels) > 1:
            msg = "Multiple results found.\nChoose a server:\n"
            for i, channel in enumerate(channels):
                msg += "{} - {} ({})\n".format(i, channel.server, channel.id)
            for page in pagify(msg):
                await self.bot.say(page)
            choice = await self.bot.wait_for_message(author=author,
                                                     timeout=30,
                                                     check=check,
                                                     channel=author_channel)
            if choice is None:
                await self.bot.say("You haven't chosen anything.")
                return
            channel = channels[int(choice.content)]
        else:
            channel = channels[0]

        rift = OpenRift(source=author_channel, destination=channel)

        self.open_rifts[author] = rift
        await self.bot.say(
            "A source has been opened! Everything you say "
            "will be relayed to that channel.\n"
            "Responses will be relayed here.\nType `exit` to quit.")
        msg = ""
        while msg == "" or msg is not None:
            msg = await self.bot.wait_for_message(author=author,
                                                  channel=author_channel)
            if msg is not None and msg.content.lower() != "exit":
                try:
                    await self.bot.send_message(channel, msg.content)
                except:
                    await self.bot.say("Couldn't send your message.")
            else:
                break
        del self.open_rifts[author]
        await self.bot.say("Source closed.")
Example #20
0
    async def calendar_list(self, ctx, max_results=5):
        """List events on a calendar."""
        credentials = ServiceAccountCredentials.from_json_keyfile_name(
            SERVICE_KEY_JSON, scopes=SCOPES)
        http = credentials.authorize(httplib2.Http())
        service = discovery.build('calendar', 'v3', http=http)

        now = dt.datetime.utcnow().isoformat() + 'Z'

        await self.bot.say(
            "Getting the upcoming {} events:".format(max_results))

        eventsResult = service.events().list(
            calendarId=RACF_CALENDAR_ID,
            timeMin=now,
            maxResults=max_results,
            singleEvents=True,
            orderBy='startTime').execute()
        events = eventsResult.get('items', [])
        if not events:
            await self.bot.say("No upcoming events found.")

        out = []
        for event in events:
            start = event['start'].get('dateTime', event['start'].get('date'))
            out.append(start)
            out.append(event['summary'])

        for page in pagify('\n'.join(out), shorten_by=24):
            await self.bot.say(page)
Example #21
0
    async def print_results(self, ctx, results):
        msg = ctx.message
        nbs = '​'
        discord_fmt = nbs + '```py\n{}\n```'
        is_interactive = self.settings["OUTPUT_REDIRECT"] == "pages"
        res_len = len(discord_fmt.format(results))
        if is_interactive and res_len > self.settings["PAGES_LENGTH"]:
            single_msg = not self.settings["MULTI_MSG_PAGING"]
            page = self.pagify_interactive_results(ctx, results, single_msg=single_msg)
            self.bot.loop.create_task(page)
        elif res_len > 2000:
            if self.settings["OUTPUT_REDIRECT"] == "pm":
                await self.bot.send_message(msg.channel, 'Content too big. Check your PMs')
                enough_paper = self.settings["PM_PAGES"]
                for page in pagify(results, ['\n', ' '], shorten_by=12):
                    await self.bot.send_message(msg.author, discord_fmt.format(page))
                    enough_paper -= 1
                    if not enough_paper:
                        await self.bot.send_message(msg.author,
                                                    "**Too many pages! Think of the trees!**")
                        return
            elif self.settings["OUTPUT_REDIRECT"] == "console":
                await self.bot.send_message(msg.channel, 'Content too big. Check your console')
                print(results)
            else:
                await self.bot.send_message(msg.channel, 'Content too big. Writing to file')
                with open(self.output_file, 'w') as f:
                    f.write(results)
                open_cmd = self.settings["OPEN_CMD"]
                if open_cmd:
                    subprocess.Popen([open_cmd, self.output_file])
        else:

            await self.bot.send_message(msg.channel, discord_fmt.format(results))
Example #22
0
    async def send_trade_list(self, channel, items):
        o = []

        def sort_items(item):
            R = dict(Common=1, Rare=2, Epic=3, Legendary=4)
            return R.get(item.rarity), item.get_card, item.give_card

        items = sorted(items, key=sort_items)
        for item in items:
            time = dt.datetime.utcfromtimestamp(item.timestamp)
            d = item._asdict()
            d.update(
                dict(give_card_emoji=self.get_emoji(item.give_card),
                     get_card_emoji=self.get_emoji(item.get_card),
                     r=item.rarity[0].upper(),
                     s='\u2800',
                     time_span=format_timespan(time)))

            o.append(
                "Give: {give_card_emoji} Get: {get_card_emoji} `{s}{r} #{clan_tag:<9} {time_span}{s}`"
                .format(**d))

        if not len(o):
            await self.bot.send_message(
                channel, "No items found matching your request.")
            return

        first_message = None

        for page in pagify("\n".join(o)):
            msg = await self.bot.send_message(channel, page)
            if first_message is None:
                first_message = msg

        return first_message
Example #23
0
    async def _server_leaderboard(self, ctx, top: int=10):
        """Prints out the server's leaderboard

        Defaults to top 10"""
        # Originally coded by Airenkun - edited by irdumb
        server = ctx.message.server
        if top < 1:
            top = 10
        bank_sorted = sorted(self.bank.get_server_accounts(server),
                             key=lambda x: x.balance, reverse=True)
        if len(bank_sorted) < top:
            top = len(bank_sorted)
        topten = bank_sorted[:top]
        highscore = ""
        place = 1
        for acc in topten:
            highscore += str(place).ljust(len(str(top)) + 1)
            highscore += (acc.name + " ").ljust(23 - len(str(acc.balance)))
            highscore += str(acc.balance) + "\n"
            place += 1
        if highscore != "":
            for page in pagify(highscore, shorten_by=12):
                await self.bot.say(box(page, lang="py"))
        else:
            await self.bot.say("There are no accounts in the bank.")
Example #24
0
    async def listroles(self, ctx: Context, *roles):
        """List all the roles on the server."""
        server = ctx.message.server
        if server is None:
            return
        out = []
        out.append("__List of roles on {}__".format(server.name))
        roles_to_list = []
        if len(roles):
            roles_to_list = [
                r for r in server.roles
                if r.name.lower() in [r2.lower() for r2 in roles]
            ]
        else:
            roles_to_list = server.roles

        out_roles = {}
        for role in roles_to_list:
            out_roles[role.id] = {'role': role, 'count': 0}
        for member in server.members:
            for role in member.roles:
                if role in roles_to_list:
                    out_roles[role.id]['count'] += 1
        for role in server.role_hierarchy:
            if role in roles_to_list:
                out.append("**{}** ({} members)".format(
                    role.name, out_roles[role.id]['count']))
        for page in pagify("\n".join(out), shorten_by=12):
            await self.bot.say(page)
 async def trigger_set_list(self):
     """List all active triggers."""
     msg = ''
     if not (self.triggers['text_triggers']
             or self.triggers['user_triggers']):
         await self.bot.say('There are no active triggers.')
         return
     if self.triggers['text_triggers']:
         msg += 'These are the active text triggers:\n'
         for text, emojis in self.triggers['text_triggers'].items():
             emojis_str = " ".join(
                 str(self._lookup_emoji(emoji)) for emoji in emojis)
             if not emojis_str:
                 continue
             msg += '`{text}`: {emojis}\n'.format(text=text,
                                                  emojis=emojis_str)
     if self.triggers['user_triggers']:
         msg += 'These are the active user triggers:\n'
         for user_id, emojis in self.triggers['user_triggers'].items():
             user = discord.utils.get(self.bot.get_all_members(),
                                      id=user_id)
             emojis_str = " ".join(
                 str(self._lookup_emoji(emoji)) for emoji in emojis)
             if user is None or not emojis_str:
                 continue
             msg += '`{user}`: {emojis}\n'.format(user=str(user),
                                                  emojis=emojis_str)
     for page in pagify(msg):
         await self.bot.say(page)
Example #26
0
    async def rlmention(self, ctx, *roles: discord.Role):
        """
        mentions all of the users who are a part of
        at least one of the roles

        Will not mention by @ everyone, requires being a mod or
        the ability to manage messages

        You really should only use this on roles people opt into,
        but I'm also not going to try and enforce that. Use this responsibly.
        It's not my problem if you don't.
        """

        _roles = set(r for r in roles if not r.is_everyone)
        if len(_roles) == 0:
            return await self.bot.say(
                "Hmm, you either didn't give me any roles, "
                "or all of the roles you gave "
                "me are not eligible for "
                "this command.")

        mentions = [
            m.mention for m in ctx.message.server.members
            if not _roles.isdisjoint(m.roles)
        ]

        mention_str = ("Mass mention authorized by {} for members in "
                       "one or more of the following roles: {}\n\n").format(
                           ctx.message.author.mention,
                           ", ".join(r.name for r in _roles))

        mention_str += " ".join(mentions)

        for page in pagify(mention_str, delims=["\n", " "]):
            await self.bot.say(page)
Example #27
0
    async def penis(self, ctx, *users: discord.Member):
        """Detects user's penis length

        This is 100% accurate.
        Enter multiple users for an accurate comparison!"""
        if not users:
            await self.bot.send_cmd_help(ctx)
            return

        dongs = {}
        msg = ""
        state = random.getstate()

        for user in users:
            random.seed(user.id)
            dongs[user] = "8{}D".format("=" * random.randint(0, 30))

        random.setstate(state)
        dongs = sorted(dongs.items(), key=lambda x: x[1])

        for user, dong in dongs:
            msg += "**{}'s size:**\n{}\n".format(user.display_name, dong)

        for page in pagify(msg):
            await self.bot.say(page)
Example #28
0
    async def list(self, ctx):
        """List all the current filtered words. Sends to DMs."""
        server = ctx.message.server
        author = ctx.message.author
        if server.id not in self.settings:
            self.settings[server.id] = self.defaults
        msg = "Filterping is currently {}.\nCurrent filter list:\n".format(
            "ENABLED" if self.settings[server.id]["ENABLED"] else "disabled")

        items = []
        for m in self.settings[server.id]["FILTER"].keys():
            pings = []
            for p in self.settings[server.id]["FILTER"][m]:
                p_member = server.get_member(p)
                if p_member is not None:
                    pings.append(p_member.name)
            items.append("{}: pings {}".format(
                m, ", ".join(pings) if len(pings) > 0 else "nobody"))
        msg += "\n".join(items)

        if len(self.settings[server.id]["FILTER"].keys()) > 0:
            try:
                for page in pagify(msg, delims=["\n"], shorten_by=8):
                    await self.bot.send_message(author, page)
                    await self.bot.say("Sent to DMs.")
            except discord.Forbidden:
                await self.bot.say("I can't send DMs to you.")
        else:
            await self.bot.say("This server has no filters set up.")
    async def _on_command_error(self, error, ctx: commands.Context):
        """Fires when a command error occurs."""
        if not self.log_channels or not isinstance(error, commands.CommandInvokeError):
            return
        destinations = [c for c in self.bot.get_all_channels() if c.id in self.log_channels]
        destinations += [c for c in self.bot.private_channels if c.id in self.log_channels]
        error_title = "Exception in command `{}`".format(ctx.command.qualified_name)
        log = "".join(traceback.format_exception(type(error), error,
                                                    error.__traceback__))

        embed = discord.Embed(title=error_title, colour=discord.Colour.red(), timestamp=ctx.message.timestamp)
        embed.add_field(name="Invoker", value="{0.mention}\n({0})\nID: {0.id}".format(ctx.message.author))
        embed.add_field(name="Content", value=ctx.message.content)
        channel = ctx.message.channel
        if channel.is_private:
            _channel_disp = "Private channel"
        else:
            _channel_disp = "{0.mention}\n({0})\nID: {0.id}".format(channel)
        embed.add_field(name="Channel", value=_channel_disp)
        if not channel.is_private:
            embed.add_field(name="Server", value="{0.name}\nID: {0.id}".format(ctx.message.server))
        for channel in destinations:
            try:
                await self.bot.send_message(channel, embed=embed)
            except discord.errors.Forbidden: # If bot can't embed
                msg = ("Invoker: {}\n"
                       "Content: {}\n"
                       "Channel: {}".format(str(ctx.message.author), ctx.message.content, _channel_disp))
                if not channel.is_private:
                    msg += "\nServer : {}".format(ctx.message.server.name)
                await self.bot.send_message(channel, box(msg))
            for page in pagify(log):
                await self.bot.send_message(channel, box(page, lang="py"))
Example #30
0
    async def _send_list(self, repo_name=None):
        """Lists installable cogs"""
        retlist = []
        if repo_name and repo_name in self.repos:
            msg = "Available cogs:\n"
            for cog in sorted(self.repos[repo_name].keys()):
                if 'url' == cog:
                    continue
                data = self.get_info_data(repo_name, cog)
                if data:
                    retlist.append([cog, data.get("SHORT", "")])
                else:
                    retlist.append([cog, ''])
        else:
            msg = "Available repos:\n"
            for repo_name in sorted(self.repos.keys()):
                data = self.get_info_data(repo_name)
                if data:
                    retlist.append([repo_name, data.get("SHORT", "")])
                else:
                    retlist.append([repo_name, ""])

        col_width = max(len(row[0]) for row in retlist) + 2
        for row in retlist:
            msg += "\t" + "".join(word.ljust(col_width) for word in row) + "\n"
        for page in pagify(msg, delims=['\n'], shorten_by=8):
            await self.bot.say(box(page))
Example #31
0
    async def _server_leaderboard(self, ctx, top: int=10):
        """Prints out the server's leaderboard

        Defaults to top 10"""
        # Originally coded by Airenkun - edited by irdumb
        server = ctx.message.server
        if top < 1:
            top = 10
        bank_sorted = sorted(self.bank.get_server_accounts(server),
                             key=lambda x: x.balance, reverse=True)
        bank_sorted = [a for a in bank_sorted if a.member] #  exclude users who left
        if len(bank_sorted) < top:
            top = len(bank_sorted)
        topten = bank_sorted[:top]
        highscore = ""
        place = 1
        for acc in topten:
            highscore += str(place).ljust(len(str(top)) + 1)
            highscore += (str(acc.member.display_name) + " ").ljust(23 - len(str(acc.balance)))
            highscore += str(acc.balance) + "\n"
            place += 1
        if highscore != "":
            for page in pagify(highscore, shorten_by=12):
                await self.bot.say(box(page, lang="py"))
        else:
            await self.bot.say("There are no accounts in the bank.")
Example #32
0
    async def _send_list(self, repo_name=None):
        """Lists installable modules"""
        retlist = []
        if repo_name and repo_name in self.repos:
            msg = "Available modules:\n"
            for cog in sorted(self.repos[repo_name].keys()):
                if 'url' == cog:
                    continue
                data = self.get_info_data(repo_name, cog)
                if data and data.get("HIDDEN") is True:
                    continue
                if data:
                    retlist.append([cog, data.get("SHORT", "")])
                else:
                    retlist.append([cog, ''])
        else:
            if self.repos:
                msg = "Available repos:\n"
                for repo_name in sorted(self.repos.keys()):
                    data = self.get_info_data(repo_name)
                    if data:
                        retlist.append([repo_name, data.get("SHORT", "")])
                    else:
                        retlist.append([repo_name, ""])
            else:
                await self.bot.say("You haven't added a repository yet.\n"
                                   "Start now! {}".format(REPOS_LIST))
                return

        col_width = max(len(row[0]) for row in retlist) + 2
        for row in retlist:
            msg += "\t" + "".join(word.ljust(col_width) for word in row) + "\n"
        msg += "\nRepositories list: {}".format(REPOS_LIST)
        for page in pagify(msg, delims=['\n'], shorten_by=8):
            await self.bot.say(box(page))
Example #33
0
    async def ownerkeenlog_users(self, ctx, *args):
        """Show debug"""
        parser = KeenLogger.parser()
        try:
            p_args = parser.parse_args(args)
        except SystemExit:
            await send_cmd_help(ctx)
            return

        await self.bot.type()
        server = ctx.message.server
        s = self.message_search.server_messages(server, p_args)

        results = [{
            "author_id": doc.author.id,
            "channel_id": doc.channel.id,
            "timestamp": doc.timestamp,
            "rng_index": None,
            "rng_timestamp": None,
            "doc": doc
        } for doc in s.scan()]

        p = pprint.PrettyPrinter(indent="4")
        out = p.pformat(results)

        for page in pagify(out, shorten_by=80):
            await self.bot.say(box(page, lang='py'))
Example #34
0
 async def print_results(self, ctx, results):
     msg = ctx.message
     discord_fmt = '```py\n{}\n```'
     if len(discord_fmt.format(results)) > 2000:
         if self.settings["OUTPUT_REDIRECT"] == "pm":
             await self.bot.send_message(msg.channel,
                                         'Content too big. Check your PMs')
             enough_paper = 20
             for page in pagify(results, ['\n', ' '], shorten_by=12):
                 await self.bot.send_message(msg.author,
                                             discord_fmt.format(page))
                 enough_paper -= 1
                 if not enough_paper:
                     await self.bot.send_message(
                         msg.author,
                         "**Too many pages! Think of the trees!**")
                     return
         elif self.settings["OUTPUT_REDIRECT"] == "console":
             await self.bot.send_message(
                 msg.channel, 'Content too big. Check your console')
             print(results)
         else:
             await self.bot.send_message(
                 msg.channel, 'Content too big. Writing to file')
             with open(self.output_file, 'w') as f:
                 f.write(results)
             open_cmd = self.settings["OPEN_CMD"]
             if open_cmd:
                 subprocess.Popen([open_cmd, self.output_file])
     else:
         await self.bot.send_message(msg.channel,
                                     discord_fmt.format(results))
Example #35
0
    def page_results(self, results, single_msg=True):
        nbs = '​'
        discord_fmt = nbs + '```py\n{}\n```'
        prompt = ("  Output too long. Navigate pages with ({}close/next)"
                  .format('' if single_msg else 'prev/'))

        pages = [p for p in pagify(results, ['\n', ' '],
                                   page_length=self.settings["PAGES_LENGTH"])]
        # results is not a generator, so no reason to keep this as one
        pages = [discord_fmt.format(p) + 'pg. {}/{}'
                 .format(c + 1, len(pages))
                 for c, p in enumerate(pages)]
        pages[0] += prompt
        return pages
Example #36
0
 async def show(self, ctx, trigger_name : str):
     """Shows all responses of a trigger"""
     trigger = self.get_trigger_by_name(trigger_name)
     if trigger:
         payload = self.elaborate_payload(trigger.responses, truncate=9999)
         if payload:
             payload = "\n\n".join(payload)
             if len(payload) > 2000:
                 for page in pagify(payload, delims=[" "]):
                     await self.bot.whisper(page)
             else:
                 await self.bot.say(payload)
         else:
             await self.bot.say("That trigger has no responses.")
     else:
         await self.bot.say("That trigger doesn't exist.")
    async def _send_list(self, repo_name=None):
        """Lists installable cogs

        Repositories list:
        https://twentysix26.github.io/Red-Docs/red_cog_approved_repos/"""
        retlist = []
        if repo_name and repo_name in self.repos:
            msg = "Available cogs:\n"
            for cog in sorted(self.repos[repo_name].keys()):
                if 'url' == cog:
                    continue
                data = self.get_info_data(repo_name, cog)
                if data and data.get("HIDDEN") is True:
                    continue
                if data:
                    retlist.append([cog, data.get("SHORT", "")])
                else:
                    retlist.append([cog, ''])
        else:
            if self.repos:
                msg = "Available repos:\n"
                for repo_name in sorted(self.repos.keys()):
                    data = self.get_info_data(repo_name)
                    if data:
                        retlist.append([repo_name, data.get("SHORT", "")])
                    else:
                        retlist.append([repo_name, ""])
            else:
                await self.bot.say("You haven't added a repository yet.\n"
                                   "Start now! {}".format(REPOS_LIST))
                return

        col_width = max(len(row[0]) for row in retlist) + 2
        for row in retlist:
            msg += "\t" + "".join(word.ljust(col_width) for word in row) + "\n"
        msg += "\nRepositories list: {}".format(REPOS_LIST)
        for page in pagify(msg, delims=['\n'], shorten_by=8):
            await self.bot.say(box(page))
Example #38
0
    async def _list(self, ctx, trigger_type="local"):
        """Lists local / global triggers

        Defaults to local"""
        server = ctx.message.server
        results = []
        if trigger_type == "local":
            for trigger in self.triggers:
                if trigger.server == server.id:
                    results.append(trigger)
        elif trigger_type == "global":
            for trigger in self.triggers:
                if trigger.server is None:
                    results.append(trigger)
        else:
            await self.bot.say("Invalid type.")
            return
        if results:
            results = ", ".join([r.name for r in results])
            for page in pagify(results, delims=[" ", "\n"]):
                await self.bot.say("```\n{}\n```".format(page.lstrip(" "), results))
        else:
            await self.bot.say("I couldn't find any trigger of that type.")
Example #39
0
    async def riftopen(self, ctx, channel):
        """Makes you able to communicate with other channels through Red

        This is cross-server. Type only the channel name or the ID."""
        author = ctx.message.author
        author_channel = ctx.message.channel

        def check(m):
            try:
                return channels[int(m.content)]
            except:
                return False

        channels = self.bot.get_all_channels()
        channels = [c for c in channels
                    if c.name.lower() == channel or c.id == channel]
        channels = [c for c in channels if c.type == discord.ChannelType.text]


        if not channels:
            await self.bot.say("No channels found. Remember to type just "
                               "the channel name, no `#`.")
            return

        if len(channels) > 1:
            msg = "Multiple results found.\nChoose a server:\n"
            for i, channel in enumerate(channels):
                msg += "{} - {} ({})\n".format(i, channel.server, channel.id)
            for page in pagify(msg):
                await self.bot.say(page)
            choice = await self.bot.wait_for_message(author=author,
                                                     timeout=30,
                                                     check=check,
                                                     channel=author_channel)
            if choice is None:
                await self.bot.say("You haven't chosen anything.")
                return
            channel = channels[int(choice.content)]
        else:
            channel = channels[0]

        rift = OpenRift(source=author_channel, destination=channel)

        self.open_rifts[author] = rift
        await self.bot.say("A rift has been opened! Everything you say "
                           "will be relayed to that channel.\n"
                           "Responses will be relayed here.\nType "
                           "`exit` to quit.")
        msg = ""
        while msg == "" or msg is not None:
            msg = await self.bot.wait_for_message(author=author,
                                                  channel=author_channel)
            if msg is not None and msg.content.lower() != "exit":
                try:
                    await self.bot.send_message(channel, msg.content)
                except:
                    await self.bot.say("Couldn't send your message.")
            else:
                break
        del self.open_rifts[author]
        await self.bot.say("Rift closed.")
    async def update(self, ctx):
        """Updates cogs"""

        tasknum = 0
        num_repos = len(self.repos)

        min_dt = 0.5
        burst_inc = 0.1/(NUM_THREADS)
        touch_n = tasknum
        touch_t = time()

        def regulate(touch_t, touch_n):
            dt = time() - touch_t
            if dt + burst_inc*(touch_n) > min_dt:
                touch_n = 0
                touch_t = time()
                return True, touch_t, touch_n
            return False, touch_t, touch_n + 1

        tasks = []
        for r in self.repos:
            task = partial(self.update_repo, r)
            task = self.bot.loop.run_in_executor(self.executor, task)
            tasks.append(task)

        base_msg = "Downloading updated cogs, please wait... "
        status = ' %d/%d repos updated' % (tasknum, num_repos)
        msg = await self.bot.say(base_msg + status)

        updated_cogs = []
        new_cogs = []
        deleted_cogs = []
        failed_cogs = []
        error_repos = {}
        installed_updated_cogs = []

        for f in as_completed(tasks):
            tasknum += 1
            try:
                name, updates, oldhash = await f
                if updates:
                    if type(updates) is dict:
                        for k, l in updates.items():
                            tl = [(name, c, oldhash) for c in l]
                            if k == 'A':
                                new_cogs.extend(tl)
                            elif k == 'D':
                                deleted_cogs.extend(tl)
                            elif k == 'M':
                                updated_cogs.extend(tl)
            except UpdateError as e:
                name, what = e.args
                error_repos[name] = what
            edit, touch_t, touch_n = regulate(touch_t, touch_n)
            if edit:
                status = ' %d/%d repos updated' % (tasknum, num_repos)
                msg = await self._robust_edit(msg, base_msg + status)
        status = 'done. '

        for t in updated_cogs:
            repo, cog, _ = t
            if self.repos[repo][cog]['INSTALLED']:
                try:
                    await self.install(repo, cog,
                                       no_install_on_reqs_fail=False)
                except RequirementFail:
                    failed_cogs.append(t)
                else:
                    installed_updated_cogs.append(t)

        for t in updated_cogs.copy():
            if t in failed_cogs:
                updated_cogs.remove(t)

        if not any(self.repos[repo][cog]['INSTALLED'] for
                   repo, cog, _ in updated_cogs):
            status += ' No updates to apply. '

        if new_cogs:
            status += '\nNew cogs: ' \
                   + ', '.join('%s/%s' % c[:2] for c in new_cogs) + '.'
        if deleted_cogs:
            status += '\nDeleted cogs: ' \
                   + ', '.join('%s/%s' % c[:2] for c in deleted_cogs) + '.'
        if updated_cogs:
            status += '\nUpdated cogs: ' \
                   + ', '.join('%s/%s' % c[:2] for c in updated_cogs) + '.'
        if failed_cogs:
            status += '\nCogs that got new requirements which have ' + \
                   'failed to install: ' + \
                   ', '.join('%s/%s' % c[:2] for c in failed_cogs) + '.'
        if error_repos:
            status += '\nThe following repos failed to update: '
            for n, what in error_repos.items():
                status += '\n%s: %s' % (n, what)

        msg = await self._robust_edit(msg, base_msg + status)

        if not installed_updated_cogs:
            return

        patchnote_lang = 'Prolog'
        shorten_by = 8 + len(patchnote_lang)
        for note in self.patch_notes_handler(installed_updated_cogs):
            if note is None:
                continue
            for page in pagify(note, delims=['\n'], shorten_by=shorten_by):
                await self.bot.say(box(page, patchnote_lang))

        await self.bot.say("Cogs updated. Reload updated cogs? (yes/no)")
        answer = await self.bot.wait_for_message(timeout=15,
                                                 author=ctx.message.author)
        if answer is None:
            await self.bot.say("Ok then, you can reload cogs with"
                               " `{}reload <cog_name>`".format(ctx.prefix))
        elif answer.content.lower().strip() == "yes":
            registry = dataIO.load_json(os.path.join("data", "red", "cogs.json"))
            update_list = []
            fail_list = []
            for repo, cog, _ in installed_updated_cogs:
                if not registry.get('cogs.' + cog, False):
                    continue
                try:
                    self.bot.unload_extension("cogs." + cog)
                    self.bot.load_extension("cogs." + cog)
                    update_list.append(cog)
                except:
                    fail_list.append(cog)
            msg = 'Done.'
            if update_list:
                msg += " The following cogs were reloaded: "\
                    + ', '.join(update_list) + "\n"
            if fail_list:
                msg += " The following cogs failed to reload: "\
                    + ', '.join(fail_list)
            await self.bot.say(msg)

        else:
            await self.bot.say("Ok then, you can reload cogs with"
                               " `{}reload <cog_name>`".format(ctx.prefix))