diff options
| author | Rapptz <[email protected]> | 2016-05-10 08:38:12 -0400 |
|---|---|---|
| committer | Rapptz <[email protected]> | 2016-05-10 08:43:09 -0400 |
| commit | 1f86a9b795326ce72a03f4bde6dbebb676ff60d8 (patch) | |
| tree | 7204baa041f3332f9181025e79e21607b1627c37 | |
| parent | Add Client.delete_messages for bulk delete. (diff) | |
| download | discord.py-1f86a9b795326ce72a03f4bde6dbebb676ff60d8.tar.xz discord.py-1f86a9b795326ce72a03f4bde6dbebb676ff60d8.zip | |
Add Client.purge_from as a high level interface around bulk delete.
| -rw-r--r-- | discord/client.py | 77 | ||||
| -rw-r--r-- | discord/iterators.py | 12 |
2 files changed, 84 insertions, 5 deletions
diff --git a/discord/client.py b/discord/client.py index b90bb813..7c8915f1 100644 --- a/discord/client.py +++ b/discord/client.py @@ -1020,6 +1020,81 @@ class Client: yield from response.release() @asyncio.coroutine + def purge_from(self, channel, *, limit=100, check=None, before=None, after=None): + """|coro| + + Purges a list of messages that meet the criteria given by the predicate + ``check``. If a ``check`` is not provided then all messages are deleted + without discrimination. + + You must have Manage Messages permission to delete messages that aren't + your own. The Read Message History permission is also needed to retrieve + message history. + + Parameters + ----------- + channel : :class:`Channel` + The channel to purge from. + limit : int + The number of messages to search through. This is not the number + of messages that will be deleted, though it can be. + check : predicate + The function used to check if a function should be deleted. + It must take a :class:`Message` as its sole parameter. + before : :class:`Message` + The message before scanning for purging must be. + after : :class:`Message` + The message after scanning for purging must be. + + Raises + ------- + Forbidden + You do not have proper permissions to do the actions required. + HTTPException + Purging the messages failed. + + Returns + -------- + list + The list of messages that were deleted. + """ + + if check is None: + check = lambda m: True + + iterator = LogsFromIterator(self, channel, limit, before, after) + ret = [] + count = 0 + + while True: + try: + msg = yield from iterator.iterate() + except asyncio.QueueEmpty: + # no more messages to poll + if count >= 2: + # more than 2 messages -> bulk delete + to_delete = ret[-count:] + yield from self.delete_messages(to_delete) + yield from asyncio.sleep(1) + elif count == 1: + # delete a single message + yield from self.delete_message(ret[-1]) + + return ret + else: + if count == 100: + # we've reached a full 'queue' + to_delete = ret[-100:] + yield from self.delete_messages(to_delete) + count = 0 + yield from asyncio.sleep(1) + else: + # queue isn't full so just add it in there + if check(msg): + count += 1 + ret.append(msg) + + @asyncio.coroutine def edit_message(self, message, new_content): """|coro| @@ -1462,7 +1537,7 @@ class Client: Forbidden You do not have permissions to change the nickname. HTTPException - Editing the channel failed. + Changing the nickname failed. """ if member == self.user: diff --git a/discord/iterators.py b/discord/iterators.py index 6a1d8952..f74227d8 100644 --- a/discord/iterators.py +++ b/discord/iterators.py @@ -52,6 +52,13 @@ class LogsFromIterator: for element in data: yield from self.messages.put(Message(channel=self.channel, **element)) + @asyncio.coroutine + def iterate(self): + if self.messages.empty(): + yield from self.fill_messages() + + return self.messages.get_nowait() + if PY35: @asyncio.coroutine def __aiter__(self): @@ -59,11 +66,8 @@ class LogsFromIterator: @asyncio.coroutine def __anext__(self): - if self.messages.empty(): - yield from self.fill_messages() - try: - msg = self.messages.get_nowait() + msg = yield from self.iterate() return msg except asyncio.QueueEmpty: # if we're still empty at this point... |