Skip to content

Commit d2f1156

Browse files
committed
Добавлено получение ключевых слов и групп
1 parent 7c9ba63 commit d2f1156

File tree

4 files changed

+213
-3
lines changed

4 files changed

+213
-3
lines changed

handlers/get_dada.py

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
# -*- coding: utf-8 -*-
2+
import os
3+
from datetime import datetime
4+
5+
from aiogram import F
6+
from aiogram.types import Message, FSInputFile
7+
from loguru import logger
8+
from openpyxl import Workbook
9+
from openpyxl.styles import Font, Alignment, PatternFill
10+
11+
from database.database import User, create_keywords_model, create_groups_model
12+
from locales.locales import get_text
13+
from system.dispatcher import router
14+
15+
16+
def create_excel_file(data: list, headers: list, filename: str, sheet_name: str) -> str:
17+
"""
18+
Функция для создания Excel-файла с переданными данными.
19+
:param data: Список кортежей с данными (строки таблицы)
20+
:param headers: Список заголовков столбцов
21+
:param filename: Имя создаваемого файла
22+
:param sheet_name: Имя листа Excel
23+
:return: Путь к созданному файлу
24+
"""
25+
# Создаём новый Excel-файл (рабочую книгу)
26+
workbook = Workbook()
27+
sheet = workbook.active
28+
sheet.title = sheet_name # Название листа
29+
30+
# Настройки оформления заголовков таблицы
31+
header_font = Font(bold=True, color="FFFFFF", size=12) # Жирный белый шрифт
32+
header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid") # Синий фон
33+
header_alignment = Alignment(horizontal="center", vertical="center") # Центрирование текста
34+
35+
# Запись заголовков в первую строку
36+
for col_num, header in enumerate(headers, start=1):
37+
cell = sheet.cell(row=1, column=col_num)
38+
cell.value = header
39+
cell.font = header_font
40+
cell.fill = header_fill
41+
cell.alignment = header_alignment
42+
43+
# Запись данных (начиная со второй строки)
44+
for row_num, row_data in enumerate(data, start=2):
45+
for col_num, cell_value in enumerate(row_data, start=1):
46+
cell = sheet.cell(row=row_num, column=col_num)
47+
cell.value = cell_value
48+
cell.alignment = Alignment(horizontal="left", vertical="center")
49+
50+
# Автоматическая подгонка ширины столбцов под содержимое
51+
for column in sheet.columns:
52+
max_length = 0
53+
column_letter = column[0].column_letter
54+
for cell in column:
55+
try:
56+
if len(str(cell.value)) > max_length:
57+
max_length = len(str(cell.value))
58+
except:
59+
pass
60+
adjusted_width = min(max_length + 2, 50) # ограничиваем ширину 50 символами
61+
sheet.column_dimensions[column_letter].width = adjusted_width
62+
63+
# Создаём папку exports, если её ещё нет
64+
exports_dir = "exports"
65+
os.makedirs(exports_dir, exist_ok=True)
66+
67+
# Сохраняем файл
68+
filepath = os.path.join(exports_dir, filename)
69+
workbook.save(filepath)
70+
logger.info(f"Excel файл создан: {filepath}")
71+
72+
return filepath
73+
74+
75+
@router.message(F.text == "Список ключевых слов")
76+
async def get_keywords_list(message: Message):
77+
"""
78+
Экспорт списка ключевых слов пользователя в Excel-файл.
79+
Отправляет пользователю документ через Telegram.
80+
"""
81+
telegram_user = message.from_user
82+
user = User.get(User.user_id == telegram_user.id)
83+
84+
logger.info(f"Пользователь {telegram_user.id} {telegram_user.username} запросил экспорт ключевых слов")
85+
86+
# Получаем модель таблицы ключевых слов для данного пользователя
87+
KeywordsModel = create_keywords_model(user_id=telegram_user.id)
88+
89+
# Проверяем, существует ли таблица
90+
if not KeywordsModel.table_exists():
91+
KeywordsModel.create_table()
92+
await message.answer(get_text(user.language, "no_keywords"))
93+
return
94+
95+
# Извлекаем все ключевые слова
96+
keywords = list(KeywordsModel.select())
97+
98+
if not keywords:
99+
await message.answer(get_text(user.language, "no_keywords"))
100+
return
101+
102+
# Формируем список данных для записи в Excel
103+
data = []
104+
for idx, keyword in enumerate(keywords, start=1):
105+
data.append((idx, keyword.user_keyword)) # Номер и текст ключевого слова
106+
107+
# Формируем имя файла
108+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
109+
filename = f"keywords_{telegram_user.id}_{timestamp}.xlsx"
110+
headers = ["№", "Ключевое слово / Keyword"]
111+
112+
try:
113+
# Создаём Excel-файл
114+
filepath = create_excel_file(
115+
data=data,
116+
headers=headers,
117+
filename=filename,
118+
sheet_name="Keywords"
119+
)
120+
121+
# Отправляем файл пользователю в Telegram
122+
document = FSInputFile(filepath)
123+
await message.answer_document(
124+
document=document,
125+
caption=f"📋 {get_text(user.language, 'keywords_export')}\n"
126+
f"Всего записей: {len(data)}"
127+
)
128+
129+
# Удаляем файл после отправки
130+
os.remove(filepath)
131+
logger.info(f"Файл ключевых слов отправлен и удалён: {filepath}")
132+
133+
except Exception as e:
134+
logger.exception(f"Ошибка при создании Excel-файла с ключевыми словами: {e}")
135+
await message.answer(get_text(user.language, "export_error"))
136+
137+
138+
@router.message(F.text == "Ссылки для отслеживания")
139+
async def get_tracking_links_list(message: Message):
140+
"""
141+
Экспорт списка ссылок (каналов/групп) для отслеживания в Excel-файл.
142+
Отправляет файл пользователю через Telegram.
143+
"""
144+
telegram_user = message.from_user
145+
user = User.get(User.user_id == telegram_user.id)
146+
147+
logger.info(f"Пользователь {telegram_user.id} {telegram_user.username} запросил экспорт ссылок для отслеживания")
148+
149+
# Получаем модель таблицы групп для данного пользователя
150+
GroupsModel = create_groups_model(user_id=telegram_user.id)
151+
152+
# Проверяем, существует ли таблица
153+
if not GroupsModel.table_exists():
154+
GroupsModel.create_table()
155+
await message.answer(get_text(user.language, "no_tracking_links"))
156+
return
157+
158+
# Извлекаем все записи (группы/каналы)
159+
groups = list(GroupsModel.select())
160+
161+
if not groups:
162+
await message.answer(get_text(user.language, "no_tracking_links"))
163+
return
164+
165+
# Формируем список данных для Excel
166+
data = []
167+
for idx, group in enumerate(groups, start=1):
168+
data.append((idx, group.username_chat_channel)) # Номер и username канала
169+
170+
# Формируем имя файла
171+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
172+
filename = f"tracking_links_{telegram_user.id}_{timestamp}.xlsx"
173+
headers = ["№", "Username канала/группы / Channel/Group Username"]
174+
175+
try:
176+
# Создаём Excel-файл
177+
filepath = create_excel_file(
178+
data=data,
179+
headers=headers,
180+
filename=filename,
181+
sheet_name="Tracking Links"
182+
)
183+
184+
# Отправляем файл пользователю
185+
document = FSInputFile(filepath)
186+
await message.answer_document(
187+
document=document,
188+
caption=f"🔗 {get_text(user.language, 'tracking_links_export')}\n"
189+
f"Всего записей: {len(data)}"
190+
)
191+
192+
# Удаляем файл после отправки
193+
os.remove(filepath)
194+
logger.info(f"Файл ссылок отправлен и удалён: {filepath}")
195+
196+
except Exception as e:
197+
logger.exception(f"Ошибка при создании Excel-файла со ссылками: {e}")
198+
await message.answer(get_text(user.language, "export_error"))
199+
200+
201+
def register_data_export_handlers():
202+
"""
203+
Регистрация хэндлеров экспорта данных.
204+
(Можно вызвать при инициализации бота.)
205+
"""
206+
router.message.register(get_keywords_list)
207+
router.message.register(get_tracking_links_list)

keyboards/keyboards.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ def main_menu_keyboard():
1818
return ReplyKeyboardMarkup(
1919
keyboard=[
2020
[KeyboardButton(text="Запуск отслеживания")],
21+
[KeyboardButton(text="Список ключевых слов")],
22+
[KeyboardButton(text="Ссылки для отслеживания")],
2123
[KeyboardButton(text="Настройки")]
2224
],
2325
resize_keyboard=True,

main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from handlers.connect_group import register_entering_group_handler
99
from handlers.entering_keyword import register_entering_keyword_handler
10+
from handlers.get_dada import register_data_export_handlers
1011
from handlers.handlers import register_greeting_handlers
1112
from system.dispatcher import dp, bot
1213

@@ -19,10 +20,9 @@ async def main() -> None:
1920
:return: None
2021
"""
2122
register_greeting_handlers()
22-
2323
register_entering_keyword_handler() # Регистрация обработчика для ввода и записи в БД ключевых слов
24-
2524
register_entering_group_handler() # Регистрация обработчика для ввода и записи в БД групп (техническая группа)
25+
register_data_export_handlers() # Выдача пользователю введенных им данных
2626

2727
await dp.start_polling(bot)
2828

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ python-dotenv~=1.1.1
44
dotenv~=0.9.9
55
logging~=0.4.9.6
66
peewee~=3.18.2
7-
Telethon~=1.40.0
7+
Telethon~=1.40.0
8+
openpyxl~=3.1.5

0 commit comments

Comments
 (0)