Example #1
0
    async def purge(self, ctx, num: int, *targets: User):
        """Bulk delete messages of a certain amount posted by some targeted Discord users,
        if not providedit just deletes all the messages which it encounters"""

        total_deleted = 0
        messages = ctx.history(limit=None)
        await messages.__anext__()  # includes the invoker's message, so skip that.

        # discord has a bulk-deletion method which has limits that,
        # messages cannot be deleted older than 14 days.
        # cannot delete more than 100 messages at once.
        async for chunk in chunked(map(lambda m: m[1], takewhile(
                lambda m: m[0] < num and (ctx.message.created_at - m[1].created_at).days < 14,
                filterfalse(lambda m: not(m[1].author in targets or not targets), aenumerate(messages)))), 100):

            chunk = list(chunk)
            await ctx.channel.delete_messages(chunk)  # delete 100 messages at once.
            total_deleted += len(chunk)

        # for the rest follow the manual deletion way.
        async for msg in messages:
            if not total_deleted <= num:
                await ctx.send(f"Purged {num} messages in {ctx.channel.mention}.",
                               delete_after=8)
                break

            if msg.author in targets or targets is None:
                await msg.delete()
                total_deleted += 1
Example #2
0
    async def test_takewhile_coroutine_list(self):
        async def pred(x):
            return x < 3

        it = ait.takewhile(pred, srange)
        for k in [1, 2]:
            self.assertEqual(await ait.next(it), k)
        with self.assertRaises(StopAsyncIteration):
            await ait.next(it)
Example #3
0
    async def test_takewhile_coroutine_gen(self):
        def gen():
            yield 1
            yield 2
            yield 3

        async def pred(x):
            return x < 3

        it = ait.takewhile(pred, gen())
        for k in [1, 2]:
            self.assertEqual(await ait.next(it), k)
        with self.assertRaises(StopAsyncIteration):
            await ait.next(it)
Example #4
0
    async def purge(self,
                    ctx,
                    end: MessageConverter,
                    begin: MessageConverter = None):
        """Delete a range of messages defined by two sentinel messages (inclusive)"""

        total = 0  # deleted total
        ref_time = ctx.message.created_at
        messages = ctx.history(after=end, before=begin, oldest_first=False)

        if not begin:
            messages.__anext__()  # skip invoking message

        # message matching is defined mathematically as,
        #   Selection = [Begin..End] ⊆ Messages
        #
        # for bulk-deletion specifically,
        #   BulkDelete = {m ∈ Selection | Age(m) ≤ 14}  [(2 ≤ |Selection| ≤ 100)]
        bulk_msgs = takewhile(lambda m: (ref_time - m.created_at).days < 15,
                              messages)

        async for bulk in chunked(bulk_msgs, 100):
            if len(bulk) == 1:
                messages = chain(bulk, messages)
                break  # queue remaining for manual deletion.

            await ctx.channel.delete_messages(bulk)  # 100 snowflakes/request
            total += len(bulk)

        # if can't bulk delete anymore, do manual.
        async for m in messages:
            await m.delete()
            total += 1

        await end.delete()
        await ctx.send(f"Purged {total+1} messages in {ctx.channel.mention}")
Example #5
0
    async def test_takewhile_empty(self):
        def pred(x):
            return x < 3

        values = await ait.list(ait.takewhile(pred, []))
        self.assertEqual(values, [])