Новая функция, скачивание приватных чатов.
parent
c4057a3525
commit
2f734647e8
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright © 2020-2021 https://t.me/ssleg
|
Copyright © 2021-2022 https://t.me/ssleg
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
Команды для использования:
|
Команды для использования:
|
||||||
--chat имя_чата - добавляет чат в базу и его скачивает. Если чат прикреплен к каналу, введите имя канала вместо чата, он будет обнаружен и скачан.
|
--chat имя_чата - добавляет чат в базу и его скачивает. Если чат прикреплен к каналу, введите имя канала вместо чата, он будет обнаружен и скачан.
|
||||||
--all обновление базы данных, программа скачивает свежие сообщения со всех чатов, которые есть в базе.
|
--all обновление базы данных, программа скачивает свежие сообщения со всех чатов, которые есть в базе.
|
||||||
|
--private меню выбора, добавления и скачивания закрытого чата, на который вы уже подписаны.
|
||||||
|
|
||||||
При запуске без параметров, показывает текущую статистику базы данных: количество сообщений, чатов и занятое ими место.
|
При запуске без параметров, показывает текущую статистику базы данных: количество сообщений, чатов и занятое ими место.
|
||||||
|
|
||||||
|
|
143
chat_reader.py
143
chat_reader.py
|
@ -1,8 +1,8 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
# Telegram chat reader v1.02
|
# Telegram chat reader v1.10
|
||||||
# 23/12/2021
|
# 29/01/2022
|
||||||
# https://t.me/ssleg © 2021
|
# https://t.me/ssleg © 2021-2022
|
||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
@ -13,7 +13,7 @@ from sys import argv
|
||||||
import psycopg2
|
import psycopg2
|
||||||
import toml
|
import toml
|
||||||
from requests import post
|
from requests import post
|
||||||
from telethon import TelegramClient, functions, errors
|
from telethon import TelegramClient, functions, errors, types
|
||||||
|
|
||||||
import reader_module
|
import reader_module
|
||||||
|
|
||||||
|
@ -40,7 +40,8 @@ help_mess = '''
|
||||||
Команды:
|
Команды:
|
||||||
--check - проверяет настройки бд и telegram.
|
--check - проверяет настройки бд и telegram.
|
||||||
--all - скачивает обновления для всех чатов, которые ранее скачивались в бд.
|
--all - скачивает обновления для всех чатов, которые ранее скачивались в бд.
|
||||||
--сhat name - добавляет и скачивает чат @name или чат, подключенный к каналу @name
|
--сhat name - добавляет и скачивает чат @name или чат, подключенный к каналу @name.
|
||||||
|
--private - меню выбора, добавления и скачивания приватных чатов.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,9 +69,17 @@ def set_num_printable(number):
|
||||||
return string
|
return string
|
||||||
|
|
||||||
|
|
||||||
|
# инициализация файла лога
|
||||||
|
# noinspection SpellCheckingInspection
|
||||||
|
def init_log():
|
||||||
|
lfile = logging.FileHandler(log_name, 'w', 'utf-8')
|
||||||
|
lfile.setFormatter(logging.Formatter('%(levelname)s %(module)-13s [%(asctime)s] %(message)s'))
|
||||||
|
logging.basicConfig(level=logging.INFO, handlers=[lfile])
|
||||||
|
|
||||||
|
|
||||||
# словарь чатов в базе данных
|
# словарь чатов в базе данных
|
||||||
def get_db_chats_dict(curs):
|
def get_db_chats_dict(cursor):
|
||||||
curs.execute('''
|
cursor.execute('''
|
||||||
select title, channel_id from chat_reader_channels as crc
|
select title, channel_id from chat_reader_channels as crc
|
||||||
right join
|
right join
|
||||||
(select chat_id from chat_reader_mess group by chat_id) as temp
|
(select chat_id from chat_reader_mess group by chat_id) as temp
|
||||||
|
@ -79,7 +88,7 @@ def get_db_chats_dict(curs):
|
||||||
|
|
||||||
chats_dict = {}
|
chats_dict = {}
|
||||||
|
|
||||||
for row in curs.fetchall():
|
for row in cursor.fetchall():
|
||||||
chats_dict[row[1]] = row[0]
|
chats_dict[row[1]] = row[0]
|
||||||
|
|
||||||
return chats_dict
|
return chats_dict
|
||||||
|
@ -107,6 +116,7 @@ def stat_upload(read_mess):
|
||||||
|
|
||||||
# обновление всех чатов
|
# обновление всех чатов
|
||||||
def update_all():
|
def update_all():
|
||||||
|
init_log()
|
||||||
client = TelegramClient('chat_reader', api_id, api_hash)
|
client = TelegramClient('chat_reader', api_id, api_hash)
|
||||||
|
|
||||||
con = psycopg2.connect(database=database,
|
con = psycopg2.connect(database=database,
|
||||||
|
@ -271,8 +281,31 @@ def check_config():
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
|
|
||||||
|
async def new_chat_load(client, con, cursor, chat_id, chat_title, chat_username):
|
||||||
|
chats_dict = get_db_chats_dict(cursor)
|
||||||
|
if chat_id in chats_dict:
|
||||||
|
levent = f'Чат {chat_title} уже есть в базе.'
|
||||||
|
print(levent)
|
||||||
|
logging.info(levent)
|
||||||
|
else:
|
||||||
|
levent = f'Добавлен чат: id - {chat_id}, название - {chat_title}. читаем...'
|
||||||
|
print(levent)
|
||||||
|
logging.info(levent)
|
||||||
|
cursor.execute('select channel_id from chat_reader_channels where channel_id=%s', (chat_id,))
|
||||||
|
row = cursor.fetchone()
|
||||||
|
if row is None:
|
||||||
|
entry = (chat_id, chat_title, chat_username)
|
||||||
|
cursor.execute('insert into chat_reader_channels (channel_id, title, user_name) values (%s,%s,%s)',
|
||||||
|
entry)
|
||||||
|
con.commit()
|
||||||
|
await reader_module.init(client, con, cursor)
|
||||||
|
read = await reader_module.read_chat(chat_id)
|
||||||
|
stat_upload(read)
|
||||||
|
|
||||||
|
|
||||||
# добавление нового чата
|
# добавление нового чата
|
||||||
def add_new(chat_name):
|
def add_new(chat_name):
|
||||||
|
init_log()
|
||||||
con = psycopg2.connect(database=database,
|
con = psycopg2.connect(database=database,
|
||||||
user=database_user,
|
user=database_user,
|
||||||
password=database_pass,
|
password=database_pass,
|
||||||
|
@ -295,25 +328,7 @@ def add_new(chat_name):
|
||||||
chat_id = info.chats[index].id
|
chat_id = info.chats[index].id
|
||||||
chat_title = info.chats[index].title
|
chat_title = info.chats[index].title
|
||||||
chat_username = info.chats[index].username
|
chat_username = info.chats[index].username
|
||||||
chats_dict = get_db_chats_dict(cursor)
|
await new_chat_load(client, con, cursor, chat_id, chat_title, chat_username)
|
||||||
if chat_id in chats_dict:
|
|
||||||
levent = f'Чат {chat_title} уже есть в базе.'
|
|
||||||
print(levent)
|
|
||||||
logging.info(levent)
|
|
||||||
else:
|
|
||||||
levent = f'Добавлен чат: id - {chat_id}, название - {chat_title}. читаем...'
|
|
||||||
print(levent)
|
|
||||||
logging.info(levent)
|
|
||||||
cursor.execute('select channel_id from chat_reader_channels where channel_id=%s', (chat_id,))
|
|
||||||
row = cursor.fetchone()
|
|
||||||
if row is None:
|
|
||||||
entry = (chat_id, chat_title, chat_username)
|
|
||||||
cursor.execute('insert into chat_reader_channels (channel_id, title, user_name) values (%s,%s,%s)',
|
|
||||||
entry)
|
|
||||||
con.commit()
|
|
||||||
await reader_module.init(client, con, cursor)
|
|
||||||
readed = await reader_module.read_chat(chat_id)
|
|
||||||
stat_upload(readed)
|
|
||||||
|
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
if str(e) == 'Cannot cast InputPeerUser to any kind of InputChannel.':
|
if str(e) == 'Cannot cast InputPeerUser to any kind of InputChannel.':
|
||||||
|
@ -343,6 +358,64 @@ def add_new(chat_name):
|
||||||
con.close()
|
con.close()
|
||||||
|
|
||||||
|
|
||||||
|
# добавление нового приватного чата
|
||||||
|
def add_private():
|
||||||
|
init_log()
|
||||||
|
con = psycopg2.connect(database=database,
|
||||||
|
user=database_user,
|
||||||
|
password=database_pass,
|
||||||
|
host=database_host,
|
||||||
|
port=database_port)
|
||||||
|
cursor = con.cursor()
|
||||||
|
|
||||||
|
client = TelegramClient('chat_reader', api_id, api_hash)
|
||||||
|
|
||||||
|
async def add_private_chat():
|
||||||
|
try:
|
||||||
|
count = 0
|
||||||
|
chats_dict = {}
|
||||||
|
async for dialog in client.iter_dialogs():
|
||||||
|
entity = dialog.entity
|
||||||
|
if type(entity) == types.Channel:
|
||||||
|
if entity.broadcast is False and entity.username is None and entity.has_link is False:
|
||||||
|
count += 1
|
||||||
|
print(f'{count}. {entity.title} ({entity.participants_count} человек)')
|
||||||
|
chats_dict[count] = (entity.id, entity.title)
|
||||||
|
if type(entity) == types.Chat:
|
||||||
|
if entity.deactivated is False:
|
||||||
|
count += 1
|
||||||
|
print(f'{count}. {entity.title} ({entity.participants_count} человек)')
|
||||||
|
chats_dict[count] = (entity.id, entity.title)
|
||||||
|
|
||||||
|
if count > 0:
|
||||||
|
print('')
|
||||||
|
prompt = f'\nВведите номер чата для добавления (от 1 - до {count}) или n для отмены: '
|
||||||
|
input_str = input(prompt)
|
||||||
|
if input_str.isdigit():
|
||||||
|
if 0 < int(input_str) <= count:
|
||||||
|
chat_id = chats_dict[int(input_str)][0]
|
||||||
|
chat_title = chats_dict[int(input_str)][1]
|
||||||
|
chat_username = None
|
||||||
|
await new_chat_load(client, con, cursor, chat_id, chat_title, chat_username)
|
||||||
|
else:
|
||||||
|
print(f'{input_str} > {count}, неверный номер чата, выходим...')
|
||||||
|
elif input_str == 'n':
|
||||||
|
print('Отмена, выходим...')
|
||||||
|
else:
|
||||||
|
print('Это не число и не номер чата, выходим...')
|
||||||
|
else:
|
||||||
|
print('Приватные чаты не обнаружены.')
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
client.start()
|
||||||
|
client.loop.run_until_complete(add_private_chat())
|
||||||
|
|
||||||
|
client.disconnect()
|
||||||
|
con.close()
|
||||||
|
|
||||||
|
|
||||||
# точка входа
|
# точка входа
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
param_dict = toml.load('chat_reader.toml')
|
param_dict = toml.load('chat_reader.toml')
|
||||||
|
@ -365,7 +438,7 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
validated = config.get('validated')
|
validated = config.get('validated')
|
||||||
|
|
||||||
if len(argv) == 1:
|
if 0 <= len(argv) <= 1:
|
||||||
if validated is None:
|
if validated is None:
|
||||||
print(check_mess)
|
print(check_mess)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
@ -384,10 +457,6 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
elif argv[1] == '--all':
|
elif argv[1] == '--all':
|
||||||
if validated is True:
|
if validated is True:
|
||||||
lfile = logging.FileHandler(log_name, 'w', 'utf-8')
|
|
||||||
# noinspection SpellCheckingInspection
|
|
||||||
lfile.setFormatter(logging.Formatter('%(levelname)s %(module)-13s [%(asctime)s] %(message)s'))
|
|
||||||
logging.basicConfig(level=logging.INFO, handlers=[lfile])
|
|
||||||
update_all()
|
update_all()
|
||||||
else:
|
else:
|
||||||
print(check_mess)
|
print(check_mess)
|
||||||
|
@ -395,16 +464,18 @@ if __name__ == '__main__':
|
||||||
elif argv[1] == '--chat':
|
elif argv[1] == '--chat':
|
||||||
if validated is True:
|
if validated is True:
|
||||||
if len(argv) == 3:
|
if len(argv) == 3:
|
||||||
lfile = logging.FileHandler(log_name, 'w', 'utf-8')
|
|
||||||
# noinspection SpellCheckingInspection
|
|
||||||
lfile.setFormatter(logging.Formatter('%(levelname)s %(module)-13s [%(asctime)s] %(message)s'))
|
|
||||||
logging.basicConfig(level=logging.INFO, handlers=[lfile])
|
|
||||||
add_new(argv[2])
|
add_new(argv[2])
|
||||||
else:
|
else:
|
||||||
print('не указано имя чата/канала.')
|
print('не указано имя чата/канала.')
|
||||||
else:
|
else:
|
||||||
print(check_mess)
|
print(check_mess)
|
||||||
|
|
||||||
|
elif argv[1] == '--private':
|
||||||
|
if validated is True:
|
||||||
|
add_private()
|
||||||
|
else:
|
||||||
|
print(check_mess)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print('команда не понята.')
|
print('команда не понята.')
|
||||||
print(help_mess)
|
print(help_mess)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Chat reader module v1.00
|
# Chat reader module v1.10
|
||||||
# 21/12/2021
|
# 29/01/2022
|
||||||
# https://t.me/ssleg © 2021
|
# https://t.me/ssleg © 2021-2022
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from asyncio import sleep
|
from asyncio import sleep
|
||||||
|
@ -62,7 +62,10 @@ async def read_messages(chat_id, start_id, limit):
|
||||||
last_read_id = message_id
|
last_read_id = message_id
|
||||||
message_date = message.date
|
message_date = message.date
|
||||||
message_text = message.text
|
message_text = message.text
|
||||||
message_chat_id = message.peer_id.channel_id
|
if type(message.peer_id) == types.PeerChat:
|
||||||
|
message_chat_id = message.peer_id.chat_id
|
||||||
|
else:
|
||||||
|
message_chat_id = message.peer_id.channel_id
|
||||||
|
|
||||||
message_from = message.from_id
|
message_from = message.from_id
|
||||||
user_id = None
|
user_id = None
|
||||||
|
|
Loading…
Reference in New Issue