сортировка по странам + перенос работы с бд
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2026-04-25 16:03:04 +10:00
parent 92cb60aa1d
commit 17343efe8c
3 changed files with 394 additions and 63 deletions

141
main.py
View File

@@ -17,19 +17,22 @@ from bs4 import BeautifulSoup
from contextlib import asynccontextmanager
from docx import Document
from newspaper import Article
from fastapi import BackgroundTasks, FastAPI, Query, Request, Depends
from fastapi import BackgroundTasks, FastAPI, Query, Request, Depends, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse
from pydantic import BaseModel, HttpUrl
from typing import List
from urllib.parse import urljoin, urlparse, urldefrag
import uvicorn
import requests
# Локальные импорты
# import settings_work as sw
import parser_bd as pbd
import work_parser as wp
DOCUMENTS_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "documents")
@asynccontextmanager
@@ -207,9 +210,9 @@ def extract_text_from_url(url, timeout=10, verify=True):
return "\n".join(content_text), time_t
# GPT_SERVER_URL = os.getenv('GPT_SERVER_URL', 'http://45.129.78.228:8484')
GPT_SERVER_URL = os.getenv('GPT_SERVER_URL', 'http://45.129.78.228:8484')
# GPT_SERVER_URL = os.getenv('GPT_SERVER_URL', 'http://172.17.0.1:8484')
GPT_SERVER_URL = os.getenv('GPT_SERVER_URL', 'http://127.0.0.1:8484')
# GPT_SERVER_URL = os.getenv('GPT_SERVER_URL', 'http://127.0.0.1:8484')
def gpt_response_message(content: str, name_promt: str):
contentGPT = wp.get_promt(name_promt).replace('{content}', content)
@@ -248,24 +251,11 @@ def gpt_response_message(content: str, name_promt: str):
# Общие функции проверки ссылок
def check_url(url):
try:
response = wp.check_url_exists(url) #get('http://45.129.78.228:8002/check_url_exists', params={'url': url})
if response.status_code == 200:
result = response.json()
# print(result["exists"])
return result["exists"]
else:
# print(f"Ошибка: {response.status_code}")
# Если сервис недоступен — считаем, что URL новый (пропускаем)
return False
except requests.exceptions.Timeout:
# print(f"Timeout при проверке URL: {url}")
# logger.warning(f"check_url timeout: {url}")
# Если таймаут — считаем, что URL новый (пропускаем)
return False
result = pbd.check_url_exists_in_db(url)
return result.get("exists", False)
except Exception as e:
# print(f"Ошибка при проверке URL: {e}")
# logger.error(f"check_url error: {e}")
# Если ошибка — считаем, что URL новый (пропускаем)
logger.error(f"check_url error: {e}")
return False
# функции даты первого источника (газета)
@@ -296,7 +286,11 @@ def update_bd_and_create_document(response_text, article_date, url, parsed_at, o
data['status'] = False
data['viewed'] = False
data['other'] = other
print(requests.post('http://45.129.78.228:8002/save_parsed_data', json=data))
# Заменяем HTTP-запрос на прямой вызов функции через pbd
parsed_data = pbd.ParsedData(**data)
pbd.save_parsed_data_to_db(parsed_data)
print("Данные успешно сохранены в БД")
path_day = article_date.split()[0]
documents_path = os.path.join(DOCUMENTS_DIR, path_day)
@@ -364,7 +358,7 @@ def start_pars_one_istochnik(data_init=""):
response_text = gpt_response_message(text, "source1")
print(response_text)
if response_text:
update_bd_and_create_document(response_text=response_text, article_date=f"{current_year}/{current_month}/{current_day}", url=link, parsed_at=str(dt.now()), original_text=text, other=url)
update_bd_and_create_document(response_text=response_text, article_date=f"{current_year}/{current_month}/{current_day}", url=link, parsed_at=str(dt.now()), original_text=text, other="source1")
wp.update_task(task_id, status='completed', finished_at=datetime.utcnow())
@@ -392,7 +386,7 @@ def start_pars_two_istochnik():
response_text = gpt_response_message(text, "source2")
print(response_text)
if response_text:
update_bd_and_create_document(response_text=response_text, article_date=time_text, url=hrefs, parsed_at=str(dt.now()), original_text=text, other=url)
update_bd_and_create_document(response_text=response_text, article_date=time_text, url=hrefs, parsed_at=str(dt.now()), original_text=text, other="source2")
except:
continue
@@ -446,7 +440,7 @@ def start_pars_all_istochnik(url:str, promt:str):
response_text = gpt_response_message(str(article.text), promt)
print(response_text)
if response_text:
update_bd_and_create_document(response_text=response_text, article_date=time_text, url=abs_url, parsed_at=str(dt.now()), original_text=article.text, other=url)
update_bd_and_create_document(response_text=response_text, article_date=time_text, url=abs_url, parsed_at=str(dt.now()), original_text=article.text, other=promt)
else:
wp.add_error_url(url, abs_url)
except Exception as e:
@@ -637,6 +631,105 @@ async def get_logs():
lines = file.readlines()[-10:] # последние 10 строк
return {"logs": lines}
# ==================== Эндпоинты из parser_bd.py ====================
@app.post("/save_parsed_data", summary="Сохранить данные парсинга")
def save_parsed_data(data: pbd.ParsedData):
try:
pbd.save_parsed_data_to_db(data)
return {"status": "success", "message": "Данные успешно сохранены"}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Ошибка при сохранении данных: {e}")
@app.post("/update_viewed_status", summary="Обновляет поле viewed")
def update_viewed_status(url: str, viewed: bool):
"""
Обновляет поле 'viewed' записи в БД по заданному URL.
"""
try:
result = pbd.update_viewed_status_in_db(url, viewed)
if not result.get("found"):
raise HTTPException(status_code=404, detail="Запись с указанным URL не найдена")
except Exception as e:
if isinstance(e, HTTPException):
raise e
raise HTTPException(status_code=500, detail=f"Ошибка при сохранении данных: {e}")
return {"status": "success", "message": "Статус просмотра успешно обновлен"}
@app.post("/update_status_status", summary="Обновляет поле status")
def update_status_status(url: str, status: bool):
"""
Обновляет поле 'status' записи в БД по заданному URL.
"""
try:
result = pbd.update_status_status_in_db(url, status)
if not result.get("found"):
raise HTTPException(status_code=404, detail="Запись с указанным URL не найдена")
except Exception as e:
if isinstance(e, HTTPException):
raise e
raise HTTPException(status_code=500, detail=f"Ошибка при сохранении данных: {e}")
return {"status": "success", "message": "Статус просмотра успешно обновлен"}
@app.get("/check_url_exists", summary="Проверяет url")
def check_url_exists(url: str):
"""
Проверяет, есть ли указанный URL в базе данных.
Возвращает true, если есть, иначе false.
"""
try:
return pbd.check_url_exists_in_db(url)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Ошибка при проверке: {e}")
@app.get("/records", summary="Получить записи из БД с пагинацией", response_model=List[pbd.ParsedData])
def get_records(offset: int = Query(0, ge=0), limit: int = Query(10, ge=1, le=100)):
"""
Возвращает записи из таблицы url с учетом offset и limit.
"""
try:
return pbd.get_records_from_db(offset, limit)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Ошибка при получении записей из БД: {e}")
@app.get("/records_all/count", summary="Получить общее количество записей")
def get_records_count(item: str = Query("default")):
"""
Возвращает общее количество записей в таблице.
"""
try:
return pbd.get_records_count_from_db(item)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Ошибка при получении количества: {e}")
@app.get("/poisk/count", summary="Получить количество результатов поиска")
def get_poisk_count(query: str, item: str = Query("default")):
try:
return pbd.get_poisk_count_from_db(query, item)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Ошибка при получении количества: {e}")
@app.get("/poisk", summary="Поиск с пагинацией")
def poisk(query: str, offset: int = Query(0, ge=0), limit: int = Query(10, ge=1, le=100), item: str = Query("default")):
try:
return pbd.poisk_from_db(query, offset, limit, item)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Ошибка при поиске: {e}")
@app.get("/records_all", summary="Получить все записи из БД + сортирует + пагинация", response_model=List[pbd.ParsedData])
def get_records_all(item: str = Query("default"), offset: int = Query(0, ge=0), limit: int = Query(10, ge=1, le=100)):
"""
Возвращает записи из таблицы url с учетом фильтрации и пагинации.
"""
try:
return pbd.get_records_all_from_db(item, offset, limit)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Ошибка при получении записей из БД: {e}")
if __name__ == "__main__":
uvicorn.run("main:app", port=8001, reload=True)