From 2c8656c29669ebdafea769c5871f55ec016ddced Mon Sep 17 00:00:00 2001 From: Alexander Popov Date: Sat, 5 Jul 2025 16:48:16 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D1=91=D0=BD=20?= =?UTF-8?q?=D0=B0=D0=BB=D0=B3=D0=BE=D1=80=D0=B8=D1=82=D0=BC=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B7=D0=BD=D0=B0?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=BF=D0=BE=D0=B1=D0=B5=D0=B4?= =?UTF-8?q?=20=D0=B8=20=D0=BF=D0=BE=D0=B6=D0=B5=D1=80=D1=82=D0=B2=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ClanStat/__main__.py | 5 +- ClanStat/actions.py | 8 ++- ClanStat/collect.py | 115 ++++++++++++++++++++++++------------------- ClanStat/db.py | 7 ++- ClanStat/utils.py | 6 ++- HISTORY.md | 6 ++- 6 files changed, 88 insertions(+), 59 deletions(-) diff --git a/ClanStat/__main__.py b/ClanStat/__main__.py index 8ebf5d9..a1ea552 100644 --- a/ClanStat/__main__.py +++ b/ClanStat/__main__.py @@ -48,7 +48,10 @@ if __name__ == '__main__': client.run(main()) except exceptions.unauthorized_401.AuthKeyUnregistered: rich_print('Ошибка Telegram: [bold red][401 AUTH_KEY_UNREGISTERED][/bold red]') - rich_print('Удалите файлы авторизации [bold green]Pyrogram[/bold green]:'' [italic yellow]*.session, *.session-journal[/italic yellow]') + rich_print( + 'Удалите файлы авторизации [bold green]Pyrogram[/bold green]:' + ' [italic yellow]*.session, *.session-journal[/italic yellow]' + ) except KeyboardInterrupt: pass diff --git a/ClanStat/actions.py b/ClanStat/actions.py index 6296081..caf2a6f 100644 --- a/ClanStat/actions.py +++ b/ClanStat/actions.py @@ -1,3 +1,7 @@ +""" +🩻 ... +""" + # Импорт модулей стандартной библиотеки import time @@ -8,7 +12,7 @@ from .collect import parse_wins_top, parse_donates_top async def get_top_wins() -> None: """⚔️ Получает топ клана по победам""" - logger.info('Выполняется получения списка побед клана') + logger.info('⚔️ Выполняется получения списка побед клана') await client.send_message(BOT_NAME, '🛡 Мой клан') time.sleep(1) @@ -44,7 +48,7 @@ async def get_top_wins() -> None: async def get_top_donates() -> None: """💠 Получает топ клана по пожертвованиям""" - logger.info('Выполняется получения списка пожертвований клана') + logger.info('💠 Выполняется получения списка пожертвований клана') await client.send_message(BOT_NAME, '🛡 Мой клан') time.sleep(2) diff --git a/ClanStat/collect.py b/ClanStat/collect.py index 4bc909d..af79fca 100644 --- a/ClanStat/collect.py +++ b/ClanStat/collect.py @@ -1,7 +1,14 @@ +""" +🩻 ... +""" + # Импорт модулей стандартной библиотеки import re +import io # Импорт сторонних модулей +from rich import print as rich_print +from rich.table import Table from pyrogram.types import Message from pyrogram.enums import MessageEntityType @@ -12,69 +19,75 @@ from .utils import get_telegram_id, get_telegram_data, clean_icons async def parse_wins_top(message: Message) -> None: """⚔️ Выполняет парсинг данных топа побед членов клана""" - if message.text.startswith('🏆 Топ по победам'): - players = message.text.split('\n') - players.pop(0) - players.pop(0) - WINS = list() + if not message.text.startswith('🏆 Топ по победам'): + return - for idx, player in enumerate(players): - player = re.sub(r'^\d+. ', '', player) # удаляет нумерацию - player, battle_count = player.split(' - ') # разделяет ник и количество побед в клановых сражениях - player = clean_icons(player) + WINS = await parse_tops(message, '⚔') - battle_count = battle_count.replace(' ⚔', '') # удаляем эмодзи мечей - battle_count = int(re.sub(r'[^\x00-\x7F]', '', battle_count)) # преобразовывает строку в число + # 📟 Отрисовывает таблицу побед + table = Table(show_header=True) + table.add_column('ID', style='dim', justify='right', width=12) + table.add_column('Username', style='magenta') + table.add_column('Count', style='green', width=7) + table.add_column('URL', style='yellow') + for i in WINS: + table.add_row(str(i['telegram_id']), i['username'], str(i['count']), i['url']) + rich_print(table) - player_url, player_telegram_id = await get_telegram_data(message, idx) - - WINS.append( - { - 'telegram_id': player_telegram_id, - 'username': player, - 'count': battle_count, - 'url': player_url, - } - ) - - print(WINS) - db.add_data(WINS, True) - else: - pass + db.add_data(WINS, True) # Добавляет данные в базу данных async def parse_donates_top(message: Message) -> None: """💠 Выполняет парсинг данных топа пожертвований членов клана""" - if message.text.startswith('🏆 Топ по пожертвованиям'): - players = message.text.split('\n') - # Удаляет из массива строку с заголовком и последующую пустую строку - players.pop(0) - players.pop(0) + if not message.text.startswith('🏆 Топ по пожертвованиям'): + return - DONATES = list() + DONATES = await parse_tops(message, '💠') - for idx, player in enumerate(players): - player = re.sub(r'^\d+. ', '', player) # удаляет нумерацию - player, donates_count = player.split(' - ') # разделяет ник и количество пожертвований в клановую сокровищницу - player = clean_icons(player) + # 📟 Отрисовывает таблицу побед + table = Table(show_header=True) + table.add_column('ID', style='dim', justify='right', width=12) + table.add_column('Username', style='magenta') + table.add_column('Count', style='green', width=7) + table.add_column('URL', style='yellow') + for i in DONATES: + table.add_row(str(i['telegram_id']), i['username'], str(i['count']), i['url']) + rich_print(table) - donates_count = donates_count.replace(' 💠', '') # удаляем эмодзи пожертвований - donates_count = int(re.sub(r'[^\x00-\x7F]', '', donates_count)) # преобразовывает строку в число + db.add_data(DONATES, False) # Добавляет данные в базу данных - player_url, player_telegram_id = await get_telegram_data(message, idx) - DONATES.append( - { - 'telegram_id': player_telegram_id, - 'username': player, - 'count': donates_count, - 'url': player_url, - } - ) +async def parse_tops(message: Message, emoji_replace: str) -> list: + """...""" - print(DONATES) - db.add_data(DONATES, False) - else: - pass + top_data = list() + + msg_buffer = io.StringIO(message.text) + msg_buffer.readline() + msg_buffer.readline() + + for e in message.entities: + player_line = msg_buffer.readline() + player_name, battle_count = player_line.split(' - ') + player = clean_icons(message.text[e.offset : e.offset + e.length]) + player_name = clean_icons(re.sub(r'^\d+. ', '', player_name)) + battle_count = battle_count.replace(f' {emoji_replace}', '') # Удаляет эмодзи + battle_count = int(re.sub(r'[^\x00-\x7F]', '', battle_count)) + + if player not in player_name: + top_data.append({'telegram_id': None, 'username': player_name, 'count': battle_count, 'url': None}) + msg_buffer.readline() + continue + + if e.type is MessageEntityType.TEXT_LINK: + player_url = e.url + player_telegram_id = await get_telegram_id(player_url.replace('http://t.me/', '')) + elif e.type is MessageEntityType.TEXT_MENTION: + player_url = e.url + player_telegram_id = e.user.id + + top_data.append({'telegram_id': player_telegram_id, 'username': player, 'count': battle_count, 'url': player_url}) + + return top_data diff --git a/ClanStat/db.py b/ClanStat/db.py index de84d23..a72d264 100644 --- a/ClanStat/db.py +++ b/ClanStat/db.py @@ -1,3 +1,7 @@ +""" +🗃️ Работа с базой данных +""" + # Импорт модулей стандартной библиотеки import json @@ -42,8 +46,7 @@ class DataBase(object): } """Настройки TCP""" - - self.conn = psycopg2.connect(**connection_kwargs, **keepalive_kwargs) # Выполняет подключение к базе данных + self.conn = psycopg2.connect(**connection_kwargs, **keepalive_kwargs) # Выполняет подключение к базе данных self.conn.autocommit = True # Активирует автоматический коммит транзакций return True diff --git a/ClanStat/utils.py b/ClanStat/utils.py index 2f282ce..4d8e930 100644 --- a/ClanStat/utils.py +++ b/ClanStat/utils.py @@ -1,3 +1,7 @@ +""" +🧰 Утилиты +""" + # Импорт сторонних модулей from pyrogram.types import Message from pyrogram.enums import MessageEntityType @@ -32,7 +36,7 @@ async def get_telegram_data(message: Message, idx: int) -> tuple(): def clean_icons(text: str) -> str: - """Удаляет иконки подписок из ников""" + """💎 Удаляет иконки подписок из ников""" # оставляет ники игроков, Python не может в эмодзи в RegExp, по этому пришлось делать через str.replace() # player = re.sub(r'\s[⚡⚜]$', '', player) diff --git a/HISTORY.md b/HISTORY.md index abb794d..09b1299 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -14,5 +14,7 @@ include_toc: true ## 2.2.4 -* Добавлено сообщение об ошибке **401** `AUTH_KEY_UNREGISTERED` -* Добавлены emoji в приветственное сообщение +* 🟢 Добавлено сообщение об ошибке **401** `AUTH_KEY_UNREGISTERED` +* 🟢 Добавлены emoji в приветственное сообщение +* 🟢 Результаты в терминале отображаются в таблице +* 🟢 Изменён алгоритм получения значений побед и пожертвований