# - *- coding: utf- 8 - *- import os import io import pandas as pd from aiogram import Router, Bot, F from aiogram.filters import Command from aiogram.types import FSInputFile, Message, CallbackQuery, BufferedInputFile from aiogram.utils.media_group import MediaGroupBuilder from tgbot.database.db_users import UserModel, Userx from tgbot.keyboards.reply_main import menu_frep from tgbot.utils.const_functions import ded from tgbot.utils.misc.bot_models import FSM, ARS from tgbot.utils.misc.bot_logging import bot_logger from tgbot.services.parser_tendors import get_tenders_from_url, get_excel_from_tenders, get_articles from tgbot.services.tender_plan import tenders_with_goods, search_in_tenderplan from tgbot.data.config import BOT_SCHEDULER, PATH_EXCEL, PATH_LOGS from tgbot.utils.const_functions import get_date router = Router(name=__name__) # Открытие главного меню @router.message(F.text.in_(())) @router.message(Command(commands=['start'])) async def main_start(message: Message, bot: Bot, state: FSM, arSession: ARS, User: UserModel): await state.clear() bot_logger.warning(f"command start from {User.user_name}") await message.answer( ded(f""" Привет, {User.user_name} Это бот для поиска тендеров на сайте Tender.pro Введите /parser для поиска прямо сейчас (ищет долго, минут 10) Или /get_notif для получения уведомления в 8 и 18 часов Команда /status показывает статус бота Поиск за все время выведет таблицу в которой будут тендеры за все время, не важно какой статус Чтобы обновить таблицу по которой искать просто пришлите ее мне """), reply_markup=menu_frep(message.from_user.id), ) # parser @router.message(F.text.in_(('parser', 'Начать поиск сейчас', 'Поиск в tenderpro'))) @router.message(Command(commands=['parser'])) async def parser(message: Message, bot: Bot, state: FSM, arSession: ARS, User: UserModel): try: bot_logger.warning(f"command parser from {User.user_name}") await message.answer("Идет поиск тендеров") tenders_id = await get_tenders_from_url() bot_logger.warning(f"tenders_id: {tenders_id}") if (len(str(tenders_id))>4000): tenders_id = pd.DataFrame(tenders_id) get_excel_from_tenders(tenders_id) with io.BytesIO() as output: tenders_id.to_excel(output) excel_data = output.getvalue() file_excel = io.BytesIO(excel_data) await message.answer_document(BufferedInputFile(file_excel.getvalue(), f"{message.text}.xlsx"), caption = f"Нашлось по запросу '{message.text}'") else: answ = "" for num, tend in enumerate(tenders_id): answ += f"{num+1}. Наименование/артикул: {tend['article']}, id тендера: {tend['id_tender']}, прием до: {tend['date_until']}, url: {tend['url_tender']} \n \n" mes = f"Ответ на запрос поиска тендеров: \n \n" if answ == "": mes += "Ничего не найдено" else: mes += answ await message.answer(f"{mes}") except Exception as e: await message.answer(f"Ошибка: {e}") # status @router.message(F.text.in_(('status', 'Статус бота'))) @router.message(Command(commands=['status'])) async def status(message: Message, bot: Bot, state: FSM, arSession: ARS, User: UserModel): bot_logger.warning(f"command status from {User.user_name}") jobs = BOT_SCHEDULER.get_jobs() bot_logger.warning(f"jobs: {jobs}") await message.answer(f"jobs: \n{[str(j) for j in jobs]}") # start notification @router.message(F.text.in_(('Получать уведомления', 'get_notif'))) @router.message(Command(commands=['get_notif'])) async def get_notif(message: Message, bot: Bot, state: FSM, arSession: ARS, User: UserModel): bot_logger.warning(f"command get_notif from {User.user_name}") if User.notif == "False": Userx.update(User.user_id, notif = "True") await message.answer("Теперь вы будете получать уведомления") else: await message.answer("Вы уже получаете уведомления") # stop notification @router.message(F.text.in_(('Не получать уведомления', 'stop_get_notif'))) @router.message(Command(commands=['stop_get_notif'])) async def stop_get_notif(message: Message, bot: Bot, state: FSM, arSession: ARS, User: UserModel): bot_logger.warning(f"command stop_get_notif from {User.user_name}") if User.notif == "True": Userx.update(User.user_id, notif = "False") await message.answer("Теперь вы не будете получать уведомления") else: await message.answer("Вы и так не получаете уведомления") # Загрузка таблицы в бот @router.message(F.content_type.in_({'document', 'file'})) async def upload_excel(message: Message, bot: Bot, state: FSM, arSession: ARS, User: UserModel): if (message.document.file_name.find('.xls') != -1): file_id = message.document.file_id file = await bot.get_file(file_id) file_path = file.file_path if message.document.file_name.find('articles_sheet') != -1: link_temp = "tgbot/data/articles_sheet_temp.xlsx" await bot.download_file(file_path, link_temp) try: arts = get_articles(link=link_temp) bot_logger.warning(f"command upload_excel from {User.user_name}. файл: {message.document.file_name}, загружен") await bot.download_file(file_path, "tgbot/data/articles_sheet.xlsx") await message.answer("Таблица загружена") except Exception as e: bot_logger.warning(f"command upload_excel from {User.user_name}. файл: {message.document.file_name}, не загружен. Ошибка {e}") await message.answer(f"Ошибка {e} \nФайл не был загружен") else: await bot.download_file(file_path, f"tgbot/data/price_{message.document.file_name}") await message.answer(f"Таблица {message.document.file_name} загружена") else: bot_logger.warning(f"command upload_excel from {User.user_name}. файл: {message.document.file_name}, не загружен") await message.answer("Файл должен быть с расширением .xls или .xlsx") # Выгрузка таблицы @router.message(F.text.in_(('Показать таблицу', 'get_articles'))) @router.message(Command(commands=['get_sheet', 'article'])) async def get_sheet(message: Message, bot: Bot, state: FSM, arSession: ARS, User: UserModel): await state.clear() await message.answer_document( FSInputFile(PATH_EXCEL), # caption=f"📦 #BACKUP | {get_date()}", caption=f"Таблица, которую вы загрузили и по которой выполняется поиск", ) # Поиск тендеров за все время @router.message(F.text.in_(('Поиск за все время', 'excel_from_tenders'))) @router.message(Command(commands=['excel_from_tenders', 'tenders'])) async def excel_from_tenders(message: Message, bot: Bot, state: FSM, arSession: ARS, User: UserModel): await state.clear() tenders_id = await get_tenders_from_url(tender_state=100) get_excel_from_tenders(tenders_id=tenders_id) await message.answer_document( FSInputFile('tgbot/data/tenders_id_all.xlsx'), # caption=f"📦 #BACKUP | {get_date()}", caption=f"Тендеры за все время.", ) # Получение логов @router.message(Command(commands=['log', 'logs'])) async def admin_log(message: Message, bot: Bot, state: FSM, arSession: ARS, User: UserModel): await state.clear() media_group = MediaGroupBuilder( caption=f"🖨 #LOGS | {get_date(full=False)}", ) if os.path.isfile(PATH_LOGS): media_group.add_document(media=FSInputFile(PATH_LOGS)) if os.path.isfile("tgbot/data/sv_log_err.log"): media_group.add_document(media=FSInputFile("tgbot/data/sv_log_err.log")) if os.path.isfile("tgbot/data/sv_log_out.log"): media_group.add_document(media=FSInputFile("tgbot/data/sv_log_out.log")) await message.answer_media_group(media=media_group.build()) # Поиск тендеров в автопитере @router.message(F.text.in_(('Поиск в автопитере', 'tenders_with_goods'))) @router.message(Command(commands=['tenders_with_goods', 'search_ap'])) async def search_in_ap(message: Message, bot: Bot, state: FSM, arSession: ARS, User: UserModel): await state.clear() bot_logger.warning(f"command search_in_ap from {User.user_name}") await message.answer("Идет поиск тендеров") tenders_with_goods(1) await message.answer_document( FSInputFile('tgbot/data/tenders_with_goods.xlsx'), caption=f"Тендеры в автопитере.", ) # таблица тендеров в автопитере @router.message(F.text.in_(('Показать автопитер', 'excel_ap'))) @router.message(Command(commands=['excel_from_ap', 'show_ap'])) async def excel_from_ap(message: Message, bot: Bot, state: FSM, arSession: ARS, User: UserModel): await state.clear() bot_logger.warning(f"command excel_from_ap from {User.user_name}") await message.answer_document( FSInputFile('tgbot/data/tenders_with_goods.xlsx'), caption=f"Тендеры в автопитере.", ) # Поиск тендеров в tenderplan @router.message(F.text.in_(('Поиск в tenderplan', 'tenders_in_tenderplan'))) @router.message(Command(commands=['tenders_in_tenderplan', 'search_in_tenderplan', 'tenderplan'])) async def search_in_tenderplan1(message: Message, bot: Bot, state: FSM, arSession: ARS, User: UserModel): await state.clear() bot_logger.warning(f"command search_in_tenderplan from {User.user_name}") await message.answer("Идет поиск тендеров") await search_in_tenderplan() await message.answer_document( FSInputFile('tgbot/data/tenders_tenderplan_from_art.xlsx'), caption=f"Тендеры в tenderplan.", ) # таблица тендеров в tenderplan @router.message(F.text.in_(('Показать tenderplan', 'excel_tenderplan'))) @router.message(Command(commands=['excel_from_tenderplan', 'show_tenderplan'])) async def excel_from_tenderplan(message: Message, bot: Bot, state: FSM, arSession: ARS, User: UserModel): await state.clear() bot_logger.warning(f"command excel_from_tenderplan from {User.user_name}") await message.answer_document( FSInputFile('tgbot/data/tenders_tenderplan_from_art.xlsx'), caption=f"Тендеры в tenderplan.", )