Esempio n. 1
0
    async def scramble(self, ctx, channel: discord.TextChannel = None, *members: discord.Member):
        """Generates a message based on the last 1000 messages in a specified channel
        (or the current one if none was given).
        """
        channel = channel or ctx.channel
        if channel.is_nsfw() and not ctx.channel.is_nsfw():
            return await ctx.send("Cannot post nsfw content in non-nsfw channels.")
        async with ctx.typing():
            if not members:
                msgs = [m.clean_content async for m in channel.history(limit=1000)]
            else:
                msgs = []
                c = 0
                async for m in channel.history(limit=None):
                    if m.author not in members:
                        continue
                    msgs.append(m.clean_content)
                    c += 1
                    if c == 1000:
                        break

            msg = await self.bot.loop.run_in_executor(None, self.generate_message, " ".join(msgs))
        if len(msg) >= 2000:
            await ctx.send("Result was too large! Posting a part of it.")
            msg = msg[:2000]
        await ctx.send(msg)
Esempio n. 2
0
    async def _get_auditresults(
        self,
        channel: TextChannel,
        start: datetime,
        end: Optional[datetime] = None,
    ) -> AuditResults:
        """Returns AuditResults from starttime to current, or end if provided"""
        counter: int = 0
        name_set: MutableSet[str] = set()
        if end is None:
            history_cor = channel.history(after=start)
        else:
            history_cor = channel.history(after=start, before=end)

        async for past_message in history_cor:
            counter += 1
            name_set.add(
                f"{past_message.author.display_name},{past_message.author},{past_message.author.id}"  # noqa
            )

        return AuditResults(
            counter=counter,
            channel=channel.name,
            channel_id=channel.id,
            authors=name_set,
            start=start,
            end=end,
        )
Esempio n. 3
0
	async def activity(self, ctx, channel: discord.TextChannel = None):
		if not channel:
			channel = ctx.channel
			text = 'в этом канале'
		else:
			text = f'в #{channel.id}'
		msg = await ctx.send('**Начинаю вычисление...**')
		counter = 0
		yesterday = datetime.datetime.today() - timedelta(days = 1)
		async for message in channel.history(limit=None, after=yesterday):
			counter += 1
		counter2 = 0
		weekago = datetime.datetime.today() - timedelta(weeks = 1)
		async for message in channel.history(limit=None, after=weekago):
			counter2 += 1
		counter3 = 0
		monthago = datetime.datetime.today() - timedelta(weeks = 4)
		async for message in channel.history(limit=None, after=monthago):
			counter3 += 1
		embed = discord.Embed(title = f'Статиститка сообщений {text}')
		embed.add_field(name = 'За сегодня:', value = f'{counter}', inline = False)
		embed.add_field(name = 'За неделю:', value = f'{counter2}', inline = False) 
		embed.add_field(name = 'За месяц:', value = f'{counter3}', inline = False) 
		embed.set_author(
			name = f'{ctx.author.name}#{ctx.author.discriminator}',
			icon_url = ctx.author.avatar_url
			)
		embed.set_footer(text = f'Канал: #{channel}')
		await msg.edit(content = None, embed = embed)
async def is_changed_exercises(exercises: Exercise, channel : discord.TextChannel):
    async for msg in channel.history():
        if len(msg.embeds) > 0:
            for embed in msg.embeds: # type: discord.Embed
                if embed.url == exercises.view_url:
                    return True
    return False
Esempio n. 5
0
    async def wordmap_command(self, ctx: commands.Context,
                              channel: discord.TextChannel):
        try:
            wordmap_list = game.Wordmap()

            async for message in channel.history(limit=1000):
                words = message.clean_content.split(' ')

                for word in words:
                    english = True
                    clean_word = ''

                    for letter in word:
                        if letter.isalpha():
                            clean_word += letter.lower()
                        elif any(letter == x for x in self.IGNORE_SYMBOLS):
                            continue
                        else:
                            english = False
                            break

                    if english and not clean_word.strip() == '':
                        wordmap_list.inc_word(clean_word)

            top_words = wordmap_list.get_words(100)
            await ctx.send('```\n' + ' '.join(str(word)
                                              for word in top_words) + '\n```')
        except discord.Forbidden:
            await ctx.send('I have no access to the channel!')
Esempio n. 6
0
    async def oof(
        self, ctx: commands.Context, msg_id: int = None, channel: discord.TextChannel = None
    ) -> None:
        """
            react 🅾🇴🇫 to a message

            `msg_id` must be the message ID for desited message within the channel
            `channel` must be the channel where the desired message is defaults to current channel
            if the bot has manage messages permission it will attempt to delete the command
        """
        emojis = ["🅾", "🇴", "🇫"]
        if channel is None:
            channel = ctx.message.channel
        if msg_id is None:
            async for messages in channel.history(limit=2):
                message = messages
        else:
            try:
                message = await channel.fetch_message(msg_id)
            except AttributeError:
                message = await channel.get_message(msg_id)  # type: ignore
                # discord.py backwards compatibility support
            except Exception:
                await ctx.send(
                    "Message ID {} not found in {}".format(msg_id, channel.mention), delete_after=5
                )
                return
        if ctx.channel.permissions_for(ctx.me).manage_messages:
            await ctx.message.delete()
        if channel.permissions_for(ctx.me).add_reactions:
            for emoji in emojis:
                try:
                    await message.add_reaction(emoji)
                except discord.errors.Forbidden:
                    return
Esempio n. 7
0
async def clean_chat(text_channel: TextChannel) -> None:
    """
    Removes all messages in the command channel to prepare for sending a gui.

    ## Raises

        ClientException – The number of messages to delete was more than 100.

        Forbidden – You do not have proper permissions to delete the messages or you’re not using a bot account.

        NotFound – If single delete, then the message was already deleted.

        HTTPException – Deleting the messages failed.
    """
    text_channel_messages: List[Message] = []
    message: Message
    async for message in text_channel.history(limit=101):
        if (datetime.today() - message.created_at).days > 14:
            raise ClientException(
                "Text channel contains messages older then 14 days.")
        if len(text_channel_messages) > 100:
            raise ClientException("Text channel contains over 100 messages.")

        text_channel_messages.append(message)

    logging.info(f"deleted_messages: {str(len(text_channel_messages))}")
    await text_channel.delete_messages(text_channel_messages)
Esempio n. 8
0
	async def end_competition(self, ctx, channel: TextChannel):
		"""End an already running competition"""

		query = "SELECT created FROM competition WHERE channel_id = $1"
		created = await self.bot.pool.fetchval(query, channel.id)
		if not created:
			await ctx.send(embed=self.bot.error("No competition in the channel"))
			return

		candidates = []
		async for message in channel.history(limit=5000, after=created):
			if message.attachments:
				if message.attachments[0].height:
					candidates.append(message)

		candidates_votes = {}
		for message in candidates:
			votes = 0
			for reaction in message.reactions:
				if reaction.emoji == "⬇":
					votes -= 1
				if reaction.emoji == "⬆":
					votes += 1
			candidates_votes[message] = votes

		ordered = []
		for message in sorted(candidates_votes, key=candidates_votes.get, reverse=True):
			ordered.append({message: candidates_votes[message]})

		await ctx.send(embed=self.bot.success(f"And the winnder is {list(ordered[0].keys())[0].author.name}"))
Esempio n. 9
0
async def connect(channel: discord.TextChannel) -> Connection:
    if (type(channel) is not discord.TextChannel):
        raise TypeError("Argument \"channel\" type is not discord.TextChannel")

    tables: Dict[str, Dict[str, Dict[str, Union[dict, discord.TextChannel]]]] = {}
    
    async for message in channel.history(limit=None):
        loaded_data: dict = json.loads(message.content)

        table_name: str = loaded_data.get(TABLE_NAME_KEY)
        data_name: str = loaded_data.get(DATA_NAME_KEY)
        data: dict = loaded_data.get(DATA_KEY)

        if table_name is None:
            continue
        if data_name is None:
            continue
        if data is None:
            continue

        if table_name not in tables:
            tables[table_name] = {}

        tables[table_name][data_name] = {
            "data" : data,
            "message" : message
        }

    return Connection(channel, tables)
Esempio n. 10
0
async def messagecount(ctx, channel: discord.TextChannel = None):
    channel = channel or ctx.channel
    count = 0
    async for _ in channel.history(limit=None):
        count += 1
    await ctx.send("There were {} messages in {}".format(
        count, channel.mention))
Esempio n. 11
0
	async def parse_history(self, ctx, *, channel: discord.TextChannel = None):
		for guild in self.bot.guilds:
			for channel in guild.text_channels:
				print("Processing {}.".format(channel.name))

				async for message in channel.history(limit=None):
					self.store_attachments(message)
Esempio n. 12
0
async def getChHistory(channel: discord.TextChannel) -> None:
    """
    gets rundenvorestellungs history to hand them to the wrapper
    """
    message: discord.Message
    async for message in channel.history(limit=200):
        await wrapMsgCheck(message)
Esempio n. 13
0
    async def duplicate(self,
                        ctx,
                        msgs: int,
                        from_channel: discord.TextChannel,
                        to_channel: discord.TextChannel = None):
        if not to_channel:
            to_channel = ctx.channel

        if not ctx.author.permissions_in(
                from_channel).read_messages or not ctx.author.permissions_in(
                    from_channel).read_message_history:

            return

        elif not ctx.guild.me.permissions_in(ctx.channel).manage_webhooks:

            await ctx.send(
                content=error_string +
                ' **Duplicating messages require me to have `Manage Webhooks` permission in the target channel.**'
            )

        elif not ctx.guild.me.permissions_in(
                from_channel).read_messages or not ctx.guild.me.permissions_in(
                    from_channel).read_message_history:

            await ctx.send(
                content=error_string +
                ' **I do not have enough permissions to fetch messages from** '
                + from_channel.mention)

        else:

            if msgs > 100:
                msgs = 100

            messages = list()
            async for msg in from_channel.history(limit=msgs,
                                                  before=ctx.message):
                messages.append(msg)

            webhook = await ctx.channel.create_webhook(
                name='Message Duplicator')

            for msg in reversed(messages):
                await asyncio.sleep(0.5)
                async with aiohttp.ClientSession() as session:
                    webhook_channel = discord.Webhook.from_url(
                        webhook.url,
                        adapter=discord.AsyncWebhookAdapter(session))
                    try:
                        await webhook_channel.send(
                            username=msg.author.display_name,
                            avatar_url=msg.author.avatar_url,
                            content=msg.content,
                            embeds=msg.embeds,
                            wait=True)
                    except:
                        continue

            await webhook.delete()
Esempio n. 14
0
    async def link_list_item(self, ctx, channel: discord.TextChannel, number: int):
        if number <= 0:
            await ctx.send(f"Number must be greater than 0.")
            return

        if channel.id not in config.list_channels:
            await ctx.send(f"{channel.mention} is not a list channel.")
            return

        counter = 0
        async for message in channel.history(limit = None, oldest_first = True):
            if message.content.strip():
                counter += 1

            if counter == number:
                embed = discord.Embed(
                    title = f"Item #{number} in #{channel.name}",
                    description = message.content,
                    url = message.jump_url
                )
                await ctx.send(
                    content = "",
                    embed = embed
                )
                return

        await ctx.send(f"Unable to find item #{number} in {channel.mention}.")
Esempio n. 15
0
 async def mood(self,ctx,user: discord.Member=None, channel: discord.TextChannel=None):
     'Finds out how a user is doing using sentiment analysis'
     if not user:
         user = ctx.author
     if not channel:
         channel = ctx.channel
     async with ctx.channel.typing():
         counter = 0             # Getting user's last 15 messages
         serverprefix = prefix(self.bot,ctx.message)
         user_messages = []
         async for message in channel.history(limit=200):
             if (not message.content.startswith(serverprefix)) and message.author == user:  # making sure not to analyze "o!mood" message as well as only adding messages from user
                 user_messages.append(message.content)
                 counter += 1
             if counter > 15:
                 break
         if counter == 0:
             await ctx.send("You have send 0 messages (not beginning with '{}') within the last 200 messages in this channel.".format(serverprefix))
             return
         sentiments = []
         for message in user_messages:
             opinion = TextBlob(message).sentiment # Getting opinion of message
             sentiments.append((opinion.polarity + 1) / 2) # Adding message's sentiment to sentiment array (opinion.sentiment.polarity is -1.0 - 1.0, so it is normalized)
         overall_sentiment = sum(sentiments) / len(sentiments) # Averaging out sentiments
     await ctx.send("{} is {}% happy!".format(user.display_name, int(overall_sentiment * 100))) # overall_sentiment is converted to an percentage without a fractional
Esempio n. 16
0
    async def getall(self, ctx, channel: discord.TextChannel, message_id: int):
        """
        Gets ALL messages with it's formatting from Aurelia after the specified message.

        For now, limit is 100 messages
        """
        messages = []
        try:
            message = await channel.fetch_message(message_id)
        except:
            await ctx.send("Sorry, that message could not be found.",
                           delete_after=30)
            return

        async for m in channel.history(limit=100, after=message.created_at):
            if m.author == ctx.guild.me:
                messages.append(m)

        for message in messages:
            if message.content == "":
                await ctx.send("(no message content)")
            else:
                await ctx.send("{}".format(
                    escape(message.content,
                           formatting=True,
                           mass_mentions=True)))
            await asyncio.sleep(0.2)
Esempio n. 17
0
async def getUserMessagesInChannel(channel:discord.TextChannel,user:Union[discord.Member,discord.User]) -> List[discord.Message]:
    messages = list()
    async for message in channel.history(limit=None,oldest_first=True):
        if message.author == user:
            messages.append(message)
    
    return messages
    async def store_latest_chat_messages(self,
                                         channel: TextChannel,
                                         is_backfill: bool = False) -> None:
        """
        Attempts to load chat messages since the last timestamp
        in the database.
        @param channel: The discord text channel.
        @param is_backfill: Whether or not backfill from beginning of time.
        """
        last_timestamp = self.db_manager.get_last_message_timestamp(channel.id)
        after = (datetime.utcfromtimestamp(last_timestamp)
                 if last_timestamp else None)

        if is_backfill:
            after = None
            self.db_manager.reset_cache()

        messages_processed = 0
        async for msg in channel.history(limit=None, after=after):

            self.db_manager.add_new_message(
                discord_user=DiscordUser(msg.author.name,
                                         msg.author.display_name,
                                         msg.author.discriminator),
                timestamp=int(
                    msg.created_at.replace(tzinfo=timezone.utc).timestamp()),
                message_channel_id=channel.id,
                message_word_count=len(msg.content.split()),
                message_char_count=len(msg.content))
            messages_processed += 1
            if messages_processed % 100 == 0:
                print(messages_processed)
Esempio n. 19
0
    async def count(self, ctx: Context, channel: TextChannel, limit: int,
                    *kwargs: str) -> None:
        """Count Messages that contain given keywords."""

        count = 0

        async for message in channel.history(limit=limit):

            # Checking for any matching kwargs in normal message content.
            content = message.content

            # Checking for any matching kwargs in 'embed' content.
            # Will be searching for title, description and author.
            if len(message.embeds) > 0:
                embed = message.embeds[0]
                embed_dict = embed.to_dict()

                content += str(embed.title) + str(embed.description)

                if 'author' in embed_dict:
                    content += str(embed_dict['author']['name'])

            if any(word in content.lower() for word in kwargs):
                count += 1

        await ctx.send(f"Count: {count}")
Esempio n. 20
0
async def total_messages(ctx, channel: discord.TextChannel=None):
    channel = channel or ctx.channel
    count = 0
    async for _ in channel.history(limit=None):
        count += 1
    embed = discord.Embed(title="Total Messages", description=f"Total messages sent in {channel.mention}: {count}", color=discord.Colour.purple())
    await ctx.channel.send(embed=embed)
Esempio n. 21
0
 async def log(self, ctx, number: int, channel: discord.TextChannel):
     'Logs past messages of a channel into a text file'
     async for message in channel.history(limit=number):
         output = ((((('```' + str(message.author)) + ' at ') +
                     str(message.created_at)) + ': \n') +
                   str(message.content)) + '\n```'
         await ctx.send(output)
Esempio n. 22
0
    async def fetch_message(
        self,
        channel: TextChannel,
        predicate: Union[Callable[[Message], bool], int, User, ClientUser],
        step: int = 100,
    ) -> Message:
        """Scroll a messageable's history indefinitely until the predicate returns true for a given message.

        Parameters
        ----------
        channel : :class:`TextChannel`
        predicate : Optional[Callable[[str, Any], bool]]
        step : :class:`int`

        Returns
        -------
        message : :class:`discord.Message`
        """
        before = None

        if isinstance(predicate, int):
            snowflake = predicate
            predicate = lambda message: message.id == snowflake

        elif isinstance(predicate, (User, ClientUser)):
            author = predicate
            predicate = lambda message: message.author == author

        while True:
            async for message_ in channel.history(limit=step, before=before):
                if predicate(message_):
                    return message_

                before = message_
Esempio n. 23
0
    async def chatchart(self, ctx, channel: discord.TextChannel = None, messages=5000):
        """
        Generates a pie chart, representing the last 5000 messages in the specified channel.
        """
        e = discord.Embed(description="Loading...", colour=0x00ccff)
        e.set_thumbnail(url="https://i.imgur.com/vSp4xRk.gif")
        em = await ctx.send(embed=e)

        if channel is None:
            channel = ctx.message.channel
        history = []
        if not channel.permissions_for(ctx.message.author).read_messages == True:
            await em.delete()
            return await ctx.send("You're not allowed to access that channel.")
        try:
            async for msg in channel.history(limit=messages):
                history.append(msg)
        except discord.errors.Forbidden:
            await em.delete()
            return await ctx.send("No permissions to read that channel.")
        msg_data = {"total count": 0, "users": {}}

        for msg in history:
            if len(msg.author.name) >= 20:
                short_name = "{}...".format(msg.author.name[:20]).replace("$", "\$")
            else:
                short_name = msg.author.name.replace("$", "\$")
            whole_name = "{}#{}".format(short_name, msg.author.discriminator)
            if msg.author.bot:
                pass
            elif whole_name in msg_data["users"]:
                msg_data["users"][whole_name]["msgcount"] += 1
                msg_data["total count"] += 1
            else:
                msg_data["users"][whole_name] = {}
                msg_data["users"][whole_name]["msgcount"] = 1
                msg_data["total count"] += 1

        if msg_data['users'] == {}:
            await em.delete()
            return await ctx.message.channel.send(f'Only bots have sent messages in {channel.mention}')

        for usr in msg_data["users"]:
            pd = float(msg_data["users"][usr]["msgcount"]) / float(msg_data["total count"])
            msg_data["users"][usr]["percent"] = round(pd * 100, 1)

        top_ten = heapq.nlargest(
            20,
            [
                (x, msg_data["users"][x][y])
                for x in msg_data["users"]
                for y in msg_data["users"][x]
                if y == "percent"
            ],
            key=lambda x: x[1],
        )
        others = 100 - sum(x[1] for x in top_ten)
        img = self.create_chart(top_ten, others, channel)
        await em.delete()
        await ctx.message.channel.send(file=discord.File(img, "chart.png"))
Esempio n. 24
0
    async def oof(self,
                  ctx: commands.Context,
                  msg_id: int = None,
                  channel: discord.TextChannel = None) -> None:
        """
        React 🅾🇴🇫 to a message.

        `msg_id` must be the message ID for desited message within the channel.
        `channel` must be the channel where the desired message is defaults to current channel
        if the bot has manage messages permission it will attempt to delete the command.
        """
        if channel is None:
            channel = ctx.message.channel
        if msg_id is None:
            async for messages in channel.history(limit=2):
                message = messages
        else:
            try:
                message = await channel.fetch_message(msg_id)
            except discord.NotFound:
                return await ctx.send("Message ID {} not found in {}".format(
                    msg_id, channel.mention),
                                      delete_after=5)

        if channel.permissions_for(ctx.me).add_reactions:
            with contextlib.suppress(discord.HTTPException):
                for emoji in ("🅾", "🇴", "🇫"):
                    await message.add_reaction(emoji)
        if ctx.channel.permissions_for(ctx.me).manage_messages:
            await ctx.message.delete()
Esempio n. 25
0
async def scan_recount(bot: commands.Bot,
                       channel: discord.TextChannel,
                       messages: int,
                       start_date=None) -> None:
    async for m in channel.history(limit=messages, before=start_date):
        if await functions.needs_recount(bot, m):
            await functions.recount_reactions(bot, m)
Esempio n. 26
0
def filter_history(channel: discord.TextChannel, **kwargs) -> typing.Coroutine[typing.Any, None, list[discord.Message]]:
    check = kwargs.pop('check', lambda m: True)
    limit = kwargs.pop('limit', sys.maxsize)
    return aioitertools.list(aioitertools.map(
        operator.itemgetter(1),
        aioitertools.zip(range(limit), channel.history(limit=None, **kwargs).filter(check))
    ))
Esempio n. 27
0
    async def oof(self,
                  ctx,
                  msg_id: int = None,
                  channel: discord.TextChannel = None):
        """
            react 🅾🇴🇫 to a message

            `msg_id` must be the message ID for desited message within the channel
            `channel` must be the channel where the desired message is defaults to current channel
            if the bot has manage messages permission it will attempt to delete the command
        """
        emojis = ["🅾", "🇴", "🇫"]
        if channel is None:
            channel = ctx.message.channel
        if msg_id is None:
            async for message in channel.history(limit=2):
                msg_id = message
        else:
            try:
                msg_id = await channel.get_message(msg_id)
            except:
                await ctx.send("Message ID {} not found in {}".format(
                    msg_id, channel.mention),
                               delete_after=5)
                return
        if ctx.channel.permissions_for(ctx.me).manage_messages:
            await ctx.message.delete()
        if channel.permissions_for(ctx.me).add_reactions:
            for emoji in emojis:
                try:
                    await msg_id.add_reaction(emoji)
                except:
                    pass
Esempio n. 28
0
    async def link_list_item(self, ctx, channel: discord.TextChannel, number: int):
        if number <= 0:
            await ctx.send(f"Number must be greater than 0.")
            return False

        if channel.id not in config.list_channels:
            await ctx.send(f"{channel.mention} is not a list channel.")
            return False

        counter = 0
        async for message in channel.history(limit=None, oldest_first=True):
            if message.content.strip():
                counter += 1

            if counter == number:
                embed = discord.Embed(
                    title=f"Item #{number} in #{channel.name}",
                    description=message.content.replace("​", "").strip(),
                )
                embed.add_field(name="Jump URL", value=f"[Jump!]({message.jump_url})")

                await ctx.send(content="", embed=embed)
                return True

        await ctx.send(f"Unable to find item #{number} in {channel.mention}.")
        return False
Esempio n. 29
0
    async def get_messages(self, channel: TextChannel) -> list:
        """Get messages from active-works channel, Wil only get its own messages."""
        messages = []
        async for message in channel.history(limit=30):
            if message.author.id == self.bot.user.id: messages.append(message)

        return messages
Esempio n. 30
0
    async def react(self,
                    ctx,
                    msg_id: int = None,
                    channel: discord.TextChannel = None):
        """
            react to a message

            msg_id must be the message ID for desited message within the channel
            channel must be the channel where the desired message is defaults to current channel
            if the bot has manage messages permission it will attempt to delete the command
        """
        emojis = [
            "<:thinkking:602975162618609676>",
            "<:aldythink:646061177377390612>",
            "<:k3llyThinking:631777147064811532>", "🤔"
        ]
        if channel is None:
            channel = ctx.message.channel
        if msg_id is None:
            async for message in channel.history(limit=2):
                msg_id = message
        else:
            msg_id = await channel.fetch_message(msg_id)
        if ctx.channel.permissions_for(ctx.me).manage_messages:
            await ctx.message.delete()

        for emoji in emojis:
            await msg_id.add_reaction(emoji)
Esempio n. 31
0
    async def chatchart(self, ctx, channel: discord.TextChannel = None, messages=5000):
        """
        Generates a pie chart, representing the last 5000 messages in the specified channel.
        """
        e = discord.Embed(description="Loading...", colour=0x00CCFF)
        e.set_thumbnail(url="https://i.imgur.com/vSp4xRk.gif")
        em = await ctx.send(embed=e)

        if channel is None:
            channel = ctx.message.channel
        history = []
        if not channel.permissions_for(ctx.message.author).read_messages == True:
            await em.delete()
            return await ctx.send("You're not allowed to access that channel.")
        try:
            async for msg in channel.history(limit=messages):
                history.append(msg)
        except discord.errors.Forbidden:
            await em.delete()
            return await ctx.send("No permissions to read that channel.")
        msg_data = {"total count": 0, "users": {}}

        for msg in history:
            if len(msg.author.name) >= 20:
                short_name = "{}...".format(msg.author.name[:20])
            else:
                short_name = msg.author.name
            whole_name = "{}#{}".format(short_name, msg.author.discriminator)
            if msg.author.bot:
                pass
            elif whole_name in msg_data["users"]:
                msg_data["users"][whole_name]["msgcount"] += 1
                msg_data["total count"] += 1
            else:
                msg_data["users"][whole_name] = {}
                msg_data["users"][whole_name]["msgcount"] = 1
                msg_data["total count"] += 1

        for usr in msg_data["users"]:
            pd = float(msg_data["users"][usr]["msgcount"]) / float(msg_data["total count"])
            msg_data["users"][usr]["percent"] = round(pd * 100, 1)

        top_ten = heapq.nlargest(
            20,
            [
                (x, msg_data["users"][x][y])
                for x in msg_data["users"]
                for y in msg_data["users"][x]
                if y == "percent"
            ],
            key=lambda x: x[1],
        )
        others = 100 - sum(x[1] for x in top_ten)
        img = self.create_chart(top_ten, others, channel)
        await em.delete()
        await ctx.message.channel.send(file=discord.File(img, "chart.png"))
Esempio n. 32
0
    async def get_messages_for_deletion(
        *,
        channel: discord.TextChannel,
        number: int = None,
        check: Callable[[discord.Message], bool] = lambda x: True,
        before: Union[discord.Message, datetime] = None,
        after: Union[discord.Message, datetime] = None,
        delete_pinned: bool = False,
    ) -> List[discord.Message]:
        """
        Gets a list of messages meeting the requirements to be deleted.
        Generally, the requirements are:
        - We don't have the number of messages to be deleted already
        - The message passes a provided check (if no check is provided,
          this is automatically true)
        - The message is less than 14 days old
        - The message is not pinned

        Warning: Due to the way the API hands messages back in chunks,
        passing after and a number together is not advisable.
        If you need to accomplish this, you should filter messages on
        the entire applicable range, rather than use this utility.
        """

        # This isn't actually two weeks ago to allow some wiggle room on API limits
        two_weeks_ago = datetime.utcnow() - timedelta(days=14, minutes=-5)

        def message_filter(message):
            return (
                check(message)
                and message.created_at > two_weeks_ago
                and (delete_pinned or not message.pinned)
            )

        if after:
            if isinstance(after, discord.Message):
                after = after.created_at
            after = max(after, two_weeks_ago)

        collected = []
        async for message in channel.history(
            limit=None, before=before, after=after, reverse=False
        ):
            if message.created_at < two_weeks_ago:
                break
            if message_filter(message):
                collected.append(message)
                if number and number <= len(collected):
                    break

        return collected