From ed5c44a26040d41d8df88edc93f16801c21aea72 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Tue, 5 Jun 2018 21:27:49 +0200 Subject: [PATCH] Support deleting more than 100 messages at once --- telethon/telegram_client.py | 19 +++++++++---------- telethon/utils.py | 12 ++++++++++++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/telethon/telegram_client.py b/telethon/telegram_client.py index 6345ebb2..fb4f07ef 100644 --- a/telethon/telegram_client.py +++ b/telethon/telegram_client.py @@ -1092,25 +1092,24 @@ class TelegramClient(TelegramBareClient): This has no effect on channels or megagroups. Returns: - The :tl:`AffectedMessages`. + A list of :tl:`AffectedMessages`, each item being the result + for the delete calls of the messages in chunks of 100 each. """ if not utils.is_list_like(message_ids): message_ids = (message_ids,) - message_ids = [ + message_ids = ( m.id if isinstance(m, (Message, MessageService, MessageEmpty)) else int(m) for m in message_ids - ] - - if entity is None: - return self(messages.DeleteMessagesRequest(message_ids, revoke=revoke)) - - entity = self.get_input_entity(entity) + ) + entity = self.get_input_entity(entity) if entity else None if isinstance(entity, InputPeerChannel): - return self(channels.DeleteMessagesRequest(entity, message_ids)) + return self([channels.DeleteMessagesRequest(entity, list(c)) + for c in utils.chunks(message_ids)]) else: - return self(messages.DeleteMessagesRequest(message_ids, revoke=revoke)) + return self([messages.DeleteMessagesRequest(list(c), revoke) + for c in utils.chunks(message_ids)]) def iter_messages(self, entity, limit=None, offset_date=None, offset_id=0, max_id=0, min_id=0, add_offset=0, diff --git a/telethon/utils.py b/telethon/utils.py index 806f7848..312b47ac 100644 --- a/telethon/utils.py +++ b/telethon/utils.py @@ -2,6 +2,7 @@ Utilities for working with the Telegram API itself (such as handy methods to convert between an entity like an User, Chat, etc. into its Input version) """ +import itertools import math import mimetypes import os @@ -56,6 +57,17 @@ class Default: """ +def chunks(iterable, size=100): + """ + Turns the given iterable into chunks of the specified size, + which is 100 by default since that's what Telegram uses the most. + """ + it = iter(iterable) + size -= 1 + for head in it: + yield itertools.chain([head], itertools.islice(it, size)) + + def get_display_name(entity): """ Gets the display name for the given entity, if it's an :tl:`User`,