Guest User

Untitled

a guest
Mar 24th, 2018
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.22 KB | None | 0 0
  1. from telethon import TelegramClient
  2. from telethon.errors import SessionPasswordNeededError
  3. from telethon.tl.functions.messages import GetHistoryRequest
  4. from telethon.tl.functions.channels import DeleteMessagesRequest
  5. from telethon.tl.types.channel import Channel
  6. import shelve
  7. from os import listdir
  8. from time import sleep
  9.  
  10. # Просто утилиты
  11.  
  12. def chunks(l, n):
  13. """Разбивает список l на чанки размером n. Возвращает генератор"""
  14. for i in range(0, len(l), n):
  15. yield l[i:i + n]
  16.  
  17.  
  18. def print_header(text):
  19. """Просто для красивого вывода"""
  20. print('====================')
  21. print('= {} ='.format(text))
  22. print('====================')
  23.  
  24. ###########################################
  25.  
  26. API_ID = 666666
  27. API_HASH = 'xxxxxxxxxxxxxxxxxxxxxxx'
  28. PHONE = '+xxxxxxxxx'
  29. NUMBER_OF_CHUNKS = 1
  30. CHUNK_SIZE = 1000 # Сколько сообщений нужно просканировать за чанк
  31.  
  32. class DeleterClient(TelegramClient):
  33. def __init__(self, session_user_id, user_phone, api_id, api_hash):
  34. super().__init__(session_user_id, api_id, api_hash)
  35.  
  36. self.messages_to_delete = set()
  37. self.chunk_size = CHUNK_SIZE # Сколько сообщений нужно просканировать за чанк
  38.  
  39. # Проверка соеденения с сервером. Проверка данных приложения
  40. print('Connecting to Telegram servers...')
  41. if not self.connect():
  42. print('Initial connection failed. Retrying...')
  43. if not self.connect():
  44. print('Could not connect to Telegram servers.')
  45. return
  46.  
  47. # Проверка авторизирован ли юзер под сессией
  48. if not self.is_user_authorized():
  49. print('First run. Sending code request...')
  50. self.send_code_request(user_phone)
  51.  
  52. self_user = None
  53. while self_user is None:
  54. code = input('Enter the code you just received: ')
  55. try:
  56. self_user = self.sign_in(user_phone, code)
  57.  
  58. # Two-step verification may be enabled
  59. except SessionPasswordNeededError:
  60. pw = input('Two step verification is enabled. Please enter your password: ')
  61. self_user = self.sign_in(password=pw)
  62.  
  63. # Создание пустого хранилища для сдвигов сканирования
  64. if 'parsed_chunks.db' not in listdir('.'):
  65. self._init_shelve(*self.get_dialogs(0))
  66.  
  67. def run(self):
  68. # Запрос выбора чата для сканирования
  69. peer = self.choose_peer()
  70. # ID пользователя чьи сообщения удалить
  71. from_id = 200200555
  72. # Основная функция выкачки сообщений и фильтрация от нужного юзера
  73. self.filter_messages_from_chunk(peer, from_id)
  74. # Основная функция удаления сообщений юзера из чата
  75. r = self.delete_messages_from_peer(peer)
  76. return r
  77.  
  78. def choose_peer(self):
  79. dialogs, entities = self.get_dialogs(0)
  80. s = ''
  81.  
  82. entities = [entity for entity in entities if isinstance(entity, Channel)] # Удаляем все супергруп и каналов
  83. entities = [entity for entity in entities if entity.megagroup] # А теперь и каналы
  84.  
  85. for i, entity in enumerate(entities):
  86. s += '{}. {}\t | {}\n'.format(i, entity.title, entity.id)
  87.  
  88. print(s)
  89. num = input('Choose group: ')
  90. print('Chosen: ' + entities[int(num)].title)
  91.  
  92. return entities[int(num)]
  93.  
  94. def delete_messages_from_peer(self, peer):
  95. messages_to_delete = list(self.messages_to_delete)
  96. print_header('УДАЛЕНИЕ {} СВОИХ СООБЩЕНИЙ В ЧАТЕ {}'.format(len(messages_to_delete), peer.title))
  97. for chunk_data in chunks(messages_to_delete, 100):
  98. # Поскольку удалить больше чем 100 сообщеий мы не можем - разделяем на маленькие кусочки
  99. r = self(DeleteMessagesRequest(peer, chunk_data))
  100. if r.pts_count:
  101. print('Удалено сообщений: {}'.format(r.pts_count))
  102. sleep(1)
  103. return True
  104.  
  105. def filter_messages_from_chunk(self, peer, from_id):
  106. number_of_chunks = NUMBER_OF_CHUNKS
  107. messages = []
  108.  
  109. for n in range(number_of_chunks):
  110. msgs, status = self.get_chunk(peer, n)
  111. messages.extend(msgs)
  112. if not status:
  113. break
  114.  
  115. # Генератор который фильтрует сообщения от нужного пользователя
  116. filter_generator = (msg.id for msg in messages if msg.from_id == from_id)
  117. self.messages_to_delete.update(filter_generator)
  118.  
  119. def get_chunk(self, peer, chunk_number, limit=100, offset_date=None, offset_id=0, max_id=0, min_id=0):
  120. add_offset = self._shelve_read(peer.id)
  121. print_header('ВЫКАЧКА ЧАНКА #{}'.format(chunk_number))
  122. local_offset = 0
  123. messages = []
  124.  
  125. while True and local_offset < self.chunk_size:
  126. # По скольку лимит на выкачку сообщений 100 - выкачиваем по 100 и делаем шаг равный выкачанному ранее
  127. result = self(GetHistoryRequest(
  128. peer,
  129. limit=limit,
  130. offset_date=offset_date,
  131. offset_id=offset_id,
  132. max_id=max_id,
  133. min_id=min_id,
  134. add_offset=add_offset
  135. ))
  136.  
  137. if result.messages:
  138. print('Скачано сообщений: {}. Сдвиг: {}.'.format(len(result.messages), add_offset))
  139. messages.extend(result.messages)
  140. add_offset += len(result.messages)
  141. local_offset += len(result.messages)
  142. # Записываем значение смещения для данной группы
  143. self._shelve_write(peer.id, add_offset)
  144. else:
  145. print_header('ПОЛУЧЕНО 0 СООБЩЕНИЙ. ВЫКАЧКА ЧАНКА #{} ОСТАНОВЛЕНА, '
  146. 'СКОРЕЕ ВСЕГО ДОШЛО ДО КОНЦА ЧАТА'.format(chunk_number))
  147. return messages, False
  148.  
  149. return messages, True
  150.  
  151. @staticmethod
  152. def _shelve_write(k, v):
  153. with shelve.open('parsed_chunks.db') as db:
  154. db[str(k)] = v
  155.  
  156. @staticmethod
  157. def _shelve_read(k):
  158. with shelve.open('parsed_chunks.db') as db:
  159. return db[str(k)]
  160.  
  161. def _init_shelve(self, dialogs, entities):
  162. for entity in entities:
  163. self._shelve_write(entity.id, 0)
  164.  
  165. client = DeleterClient('Deleter', PHONE, API_ID, API_HASH) # 1 аргумент - название сессии, второй - телефон,
  166. # третий - айди приложения, четвертый - хэш приложения
  167. client.run()
Add Comment
Please, Sign In to add comment