This commit is contained in:
102
main.py
102
main.py
@@ -5,9 +5,12 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
from datetime import datetime as dt
|
from datetime import datetime as dt
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
from rarfile import RarFile
|
||||||
|
import tempfile
|
||||||
|
|
||||||
# Сторонние библиотеки (third-party)
|
# Сторонние библиотеки (third-party)
|
||||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||||
from bs4 import BeautifulSoup
|
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")
|
logging.basicConfig(filename="app.log", level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# Инициализация таблицы статуса парсинга
|
# Инициализация таблицы статуса парсинга
|
||||||
wp.create_table()
|
# wp.create_table()
|
||||||
|
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
@@ -249,7 +251,6 @@ def gpt_response_message(content, ist_number=1):
|
|||||||
# except subprocess.CalledProcessError:
|
# except subprocess.CalledProcessError:
|
||||||
# print(f"Не удалось перезапустить сервес {service_name}")
|
# print(f"Не удалось перезапустить сервес {service_name}")
|
||||||
|
|
||||||
|
|
||||||
# Общие функции проверки ссылок
|
# Общие функции проверки ссылок
|
||||||
def check_url(url):
|
def check_url(url):
|
||||||
print(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}")
|
logger.info(f"Ошибка при обработке ответа GPT: {ex}")
|
||||||
|
|
||||||
#Функции start первого источника (газета)
|
#Функции start первого источника (газета)
|
||||||
def start_pars_one_istochnik(data_init):
|
def start_pars_one_istochnik(data_init=""):
|
||||||
if data_init != ['']:
|
if data_init != ['']:
|
||||||
current_day = data_init[0]
|
current_day = data_init[0]
|
||||||
current_month = data_init[1]
|
current_month = data_init[1]
|
||||||
@@ -396,8 +397,7 @@ def start_pars_two_istochnik():
|
|||||||
|
|
||||||
# Функции для автоматического запуска
|
# Функции для автоматического запуска
|
||||||
def scheduled_parser_1():
|
def scheduled_parser_1():
|
||||||
istochnik = "" # пустая строка = текущая дата
|
start_pars_one_istochnik()
|
||||||
start_pars_one_istochnik(istochnik.split("."))
|
|
||||||
|
|
||||||
def scheduled_parser_2():
|
def scheduled_parser_2():
|
||||||
start_pars_two_istochnik()
|
start_pars_two_istochnik()
|
||||||
@@ -407,7 +407,7 @@ class ParserOneRequest(BaseModel):
|
|||||||
|
|
||||||
@app.post("/parser_1", summary="Запуск процесса парсинга первого источника")
|
@app.post("/parser_1", summary="Запуск процесса парсинга первого источника")
|
||||||
async def process_data(data: ParserOneRequest, background_tasks: BackgroundTasks):
|
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)
|
background_tasks.add_task(start_pars_one_istochnik, istochnik)
|
||||||
return {"message": "Процесс парсинга 1 источника запущен"}
|
return {"message": "Процесс парсинга 1 источника запущен"}
|
||||||
|
|
||||||
@@ -435,17 +435,12 @@ def set_settings(settings: wp.Source):
|
|||||||
def delete_task(task_id: int):
|
def delete_task(task_id: int):
|
||||||
return print(wp.delete_task(task_id))
|
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="Метод для скачивания файла")
|
@app.get("/file_download", summary="Метод для скачивания файла")
|
||||||
async def download_file(path: str, title: str):
|
async def download_file(path: str, title: str):
|
||||||
file_name = f"{title}.docx"
|
file_name = f"{title}.docx"
|
||||||
file_path = os.path.join(DOCUMENTS_DIR, path, file_name)
|
file_path = os.path.join(DOCUMENTS_DIR, path, file_name)
|
||||||
logger.warning(f"Файл: {file_path}")
|
logger.warning(f"Файл: {file_path}")
|
||||||
|
|
||||||
# Проверяем существование файла
|
# Проверяем существование файла
|
||||||
if not os.path.exists(file_path):
|
if not os.path.exists(file_path):
|
||||||
logger.warning(f"Файл не найден: {file_path}")
|
logger.warning(f"Файл не найден: {file_path}")
|
||||||
@@ -464,6 +459,85 @@ async def download_file(path: str, title: str):
|
|||||||
logger.warning(response)
|
logger.warning(response)
|
||||||
return 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")
|
@app.get("/logs")
|
||||||
def get_logs():
|
def get_logs():
|
||||||
with open("app.log", "r") as file:
|
with open("app.log", "r") as file:
|
||||||
|
|||||||
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
Reference in New Issue
Block a user