import re
import pandas as pd
import openpyxl
import tempfile
import asyncio
from telegram import Update
from telegram.ext import Application, MessageHandler, filters, CommandHandler, ContextTypes
class FastDownloadExcel:
def __init__(self, token):
self.BOT_TOKEN = token
self.data_dict = {} # Словарь для хранения данных из имени файла
# Константы для ключей словаря
self.REGION_DECODE_INDEX = "region"
self.RETAILER_DECODE_INDEX = "retailer"
self.SALES_DECODE_INDEX = "sales"
self.SHOPS_DECODE_INDEX = "shops"
self.ALL_SHOPS_DECODE_INDEX = "all_shops"
self.RESIDUAL_FIRST_DECODE_INDEX = "residual_first"
self.RESIDUAL_LAST_DECODE_INDEX = "residual_last"
self.PRICE_PURCH_DECODE_INDEX = "price_purch"
self.SHELF_PRICE_DECODE_INDEX = "shelf_price"
self.CATEGORY_DECODE_INDEX = "category"
# Регулярное выражение для проверки имени файла
# Шаблон ищет два слова и затем 10 чисел, разделённых символом "_"
#filename_pattern = re.compile(r"^([A-Za-zА-Яа-я]+)_([A-Za-zА-Яа-я]+)((?:_[A-Za-zА-Яа-я0-9]+){10})\.(xls|xlsx|xlsm)$")
async def start(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Обработчик команды /start."""
await update.message.reply_text("Привет! Отправь мне Excel файл с правильным именем, и я скажу тебе, что принял его.")
def parse_filename(self, file_name):
"""Парсит имя файла и возвращает словарь с данными, если формат корректный."""
name_parts = file_name.rsplit('.', 1)[0].split('_')
# Проверяем, что в имени 12 частей
if len(name_parts) == 12:
return {
self.REGION_DECODE_INDEX: name_parts[0],
self.RETAILER_DECODE_INDEX: name_parts[1],
self.SALES_DECODE_INDEX: name_parts[2],
self.SHOPS_DECODE_INDEX: name_parts[3],
self.ALL_SHOPS_DECODE_INDEX: name_parts[4],
self.RESIDUAL_FIRST_DECODE_INDEX: name_parts[5],
self.RESIDUAL_LAST_DECODE_INDEX: name_parts[6],
self.PRICE_PURCH_DECODE_INDEX: name_parts[7],
self.SHELF_PRICE_DECODE_INDEX: name_parts[8],
self.CATEGORY_DECODE_INDEX: name_parts[9],
}
return None
async def handle_file(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Обработчик загруженного файла."""
document = update.message.document
if document:
file_name = document.file_name
# Проверка расширения файла
if not file_name.endswith(('.xls', '.xlsx', '.xlsm')):
await update.message.reply_text(
"Это не Excel файл. Пожалуйста, отправь файл с расширением .xls, .xlsx или .xlsm."
)
return
await update.message.reply_text("Спасибо, файл у меня, все хорошо.")
# Обработка имени файла
parsed_data = self.parse_filename(file_name)
if parsed_data:
self.data_dict = parsed_data
await update.message.reply_text("Я добавил данные в словарик.")
print("Текущий словарь:", self.data_dict)
else:
await update.message.reply_text(
"Неверное имя файла. Пожалуйста, отправь файл с правильным форматом имени, например: "
"TEST_Tesco_5_1_2_3_500_0_0_0_0_4.xls"
)
else:
await update.message.reply_text("Пожалуйста, отправь файл в формате документа.")
async def send_dictionary(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Отправка словаря в виде Excel файла."""
if self.data_dict:
df = pd.DataFrame([self.data_dict])
with tempfile.NamedTemporaryFile(suffix=".xlsx", delete=False) as tmp_file:
file_path = tmp_file.name
df.to_excel(file_path, index=False)
await update.message.reply_document(document=open(file_path, 'rb'))
await update.message.reply_text("Наш готовый словарик")
else:
await update.message.reply_text("Словарь пока пуст. Сначала загрузите файл с правильным форматом.")
def run(self):
"""Запуск бота с проверкой на закрытый event loop."""
try:
loop = asyncio.get_running_loop()
if loop.is_closed():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
app = Application.builder().token(self.BOT_TOKEN).build()
app.add_handler(CommandHandler("start", self.start))
app.add_handler(CommandHandler("dictionary", self.send_dictionary))
app.add_handler(MessageHandler(filters.Document.ALL, self.handle_file))
print("Бот запущен.")
app.run_polling()
if __name__ == '__main__':
token = '8196668718:AAGnO9kqI2j6RI_mqnHuwXZk2g6oEJ6pDm4' # Подставьте ваш реальный токен
bot = FastDownloadExcel(token)
bot.run()