diff --git a/main.py b/main.py index 502b8d5..1a0aaf3 100644 --- a/main.py +++ b/main.py @@ -5,9 +5,12 @@ import os import subprocess import time from datetime import datetime as dt -from datetime import datetime +from datetime import datetime, timedelta import random +from rarfile import RarFile +import tempfile + # Сторонние библиотеки (third-party) from apscheduler.schedulers.asyncio import AsyncIOScheduler from bs4 import BeautifulSoup @@ -51,9 +54,8 @@ scheduler = AsyncIOScheduler() logging.basicConfig(filename="app.log", level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") logger = logging.getLogger(__name__) - # Инициализация таблицы статуса парсинга -wp.create_table() +# wp.create_table() app.add_middleware( CORSMiddleware, @@ -249,7 +251,6 @@ def gpt_response_message(content, ist_number=1): # except subprocess.CalledProcessError: # print(f"Не удалось перезапустить сервес {service_name}") - # Общие функции проверки ссылок def check_url(url): print(url) @@ -323,7 +324,7 @@ def update_bd_and_create_document(response_text, article_date, url, parsed_at, o logger.info(f"Ошибка при обработке ответа GPT: {ex}") #Функции start первого источника (газета) -def start_pars_one_istochnik(data_init): +def start_pars_one_istochnik(data_init=""): if data_init != ['']: current_day = data_init[0] current_month = data_init[1] @@ -396,8 +397,7 @@ def start_pars_two_istochnik(): # Функции для автоматического запуска def scheduled_parser_1(): - istochnik = "" # пустая строка = текущая дата - start_pars_one_istochnik(istochnik.split(".")) + start_pars_one_istochnik() def scheduled_parser_2(): start_pars_two_istochnik() @@ -407,7 +407,7 @@ class ParserOneRequest(BaseModel): @app.post("/parser_1", summary="Запуск процесса парсинга первого источника") async def process_data(data: ParserOneRequest, background_tasks: BackgroundTasks): - istochnik = data.time.split(".") + istochnik = data.time.split("-") background_tasks.add_task(start_pars_one_istochnik, istochnik) return {"message": "Процесс парсинга 1 источника запущен"} @@ -435,17 +435,12 @@ def set_settings(settings: wp.Source): def delete_task(task_id: int): return print(wp.delete_task(task_id)) -# @app.get("/file_download", summary="Метод для скачивания файла") -# async def download_file(path: str, title: str): -# path = f"./{path}/{title}.docx" #os.path.abspath(path) -# return FileResponse(path=path, filename=f'{title}.docx', media_type='multipart/form-data') - @app.get("/file_download", summary="Метод для скачивания файла") async def download_file(path: str, title: str): file_name = f"{title}.docx" file_path = os.path.join(DOCUMENTS_DIR, path, file_name) logger.warning(f"Файл: {file_path}") - + # Проверяем существование файла if not os.path.exists(file_path): logger.warning(f"Файл не найден: {file_path}") @@ -464,6 +459,85 @@ async def download_file(path: str, title: str): logger.warning(response) return response +class DownloadRange(BaseModel): + data_start: str + data_finish: str + +@app.post("/download_all", summary="Скачать все файлы за период") +async def download_all(dates: DownloadRange): + + date_start = dates.data_start + date_finish = dates.data_finish + # Парсим даты + try: + start_date = datetime.strptime(date_start, "%Y-%m-%d") + finish_date = datetime.strptime(date_finish, "%Y-%m-%d") + except ValueError: + return {"error": "Неверный формат даты. Используйте YYYY-MM-DD"} + + if start_date > finish_date: + return {"error": "Дата начала не может быть позже даты окончания"} + + all_files = [] + + # Собираем файлы за каждый день + current_date = start_date + while current_date <= finish_date: + date_path = current_date.strftime("%Y/%m/%d") + full_dir_path = os.path.join(DOCUMENTS_DIR, date_path) + logger.info(f"Проверяем путь: {full_dir_path}") + + # if os.path.exists(full_dir_path): + for file in os.listdir(full_dir_path): + if file.endswith('.docx'): + all_files.append(os.path.join(full_dir_path, file)) + + current_date += timedelta(days=1) + + logger.info(f"Найдено файлов: {len(all_files)}") + + # print(all_files) + if not all_files: + return {"error": "Файлы не найдены за указанный период", "date_start": date_start, "date_finish": date_finish} + + # Создаём архив во временной директории + archive_name = f"documents.rar" + archive_path = os.path.join(tempfile.gettempdir(), archive_name) + + try: + with RarFile(archive_path, 'w') as rar: + for file_path in all_files: + rar.write(file_path, os.path.basename(file_path)) + except Exception as e: + logger.error(f"Ошибка создания архива: {e}") + return {"error": f"Ошибка создания архива: {e}"} + + logger.info(f"Архив создан: {archive_path}") + + # Возвращаем архив + response = FileResponse( + path=archive_path, + filename=archive_name, + media_type="application/x-rar-compressed" + ) + response.headers["Access-Control-Allow-Origin"] = "*" + response.headers["Access-Control-Allow-Methods"] = "GET, OPTIONS" + response.headers["Access-Control-Allow-Headers"] = "Content-Type" + + # Удаляем архив после отправки + # Примечание: FileResponse сам отдаёт файл, удаление нужно делать после + @response.streaming_callback + async def cleanup(): + await response.body_send() + try: + if os.path.exists(archive_path): + os.remove(archive_path) + logger.info(f"Архив удалён: {archive_path}") + except Exception as e: + logger.warning(f"Не удалось удалить архив: {e}") + + return response + @app.get("/logs") def get_logs(): with open("app.log", "r") as file: diff --git a/requirements.txt b/requirements.txt index df40207..e69de29 100644 Binary files a/requirements.txt and b/requirements.txt differ