mirror of
https://github.com/R0m1k3/Priceflow.git
synced 2026-10-22 14:48:13 +02:00
- Improve domain matching in direct_search_service to handle various formats - Add /discover-all endpoint to discover search URLs for all sites missing one - Add constants for magic numbers and fix linting issues - Better domain cleaning in comparison functions
191 lines
6.2 KiB
Python
191 lines
6.2 KiB
Python
"""
|
|
API Router pour la gestion des sites de recherche
|
|
"""
|
|
|
|
import logging
|
|
import os
|
|
|
|
from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.database import SessionLocal, get_db
|
|
from app.schemas import SearchSiteCreate, SearchSiteResponse, SearchSiteUpdate
|
|
from app.services import search_service
|
|
from app.services.search_url_discovery import discover_search_url
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter(prefix="/api/search-sites", tags=["search-sites"])
|
|
|
|
|
|
@router.get("", response_model=list[SearchSiteResponse])
|
|
async def get_all_sites(db: Session = Depends(get_db)):
|
|
"""Récupère tous les sites de recherche"""
|
|
sites = search_service.get_all_sites(db)
|
|
return sites
|
|
|
|
|
|
@router.get("/{site_id}", response_model=SearchSiteResponse)
|
|
async def get_site(site_id: int, db: Session = Depends(get_db)):
|
|
"""Récupère un site par son ID"""
|
|
site = search_service.get_site_by_id(db, site_id)
|
|
if not site:
|
|
raise HTTPException(status_code=404, detail="Site not found")
|
|
return site
|
|
|
|
|
|
async def _discover_and_update_site(site_id: int, domain: str, db_url: str):
|
|
"""Découvre l'URL de recherche en background et met à jour le site"""
|
|
try:
|
|
logger.info(f"Discovering search URL for site {site_id} ({domain})")
|
|
result = await discover_search_url(domain)
|
|
|
|
if result.get("discovered"):
|
|
# Mettre à jour le site avec l'URL découverte
|
|
db = SessionLocal()
|
|
try:
|
|
update_data = {}
|
|
if result.get("search_url"):
|
|
update_data["search_url"] = result["search_url"]
|
|
if result.get("product_link_selector"):
|
|
update_data["product_link_selector"] = result["product_link_selector"]
|
|
|
|
if update_data:
|
|
search_service.update_site(db, site_id, update_data)
|
|
logger.info(f"Updated site {site_id} with discovered URL: {result.get('search_url')}")
|
|
finally:
|
|
db.close()
|
|
else:
|
|
logger.warning(f"Could not discover search URL for {domain}")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error in background discovery for {domain}: {e}")
|
|
|
|
|
|
@router.post("", response_model=SearchSiteResponse, status_code=201)
|
|
async def create_site(
|
|
site: SearchSiteCreate,
|
|
background_tasks: BackgroundTasks,
|
|
db: Session = Depends(get_db),
|
|
):
|
|
"""
|
|
Crée un nouveau site de recherche.
|
|
Si search_url n'est pas fourni, tente de le découvrir automatiquement.
|
|
"""
|
|
try:
|
|
new_site = search_service.create_site(db, site.model_dump())
|
|
|
|
# Si pas de search_url, lancer la découverte en background
|
|
if not site.search_url:
|
|
db_url = os.getenv("DATABASE_URL", "")
|
|
background_tasks.add_task(
|
|
_discover_and_update_site,
|
|
new_site.id,
|
|
new_site.domain,
|
|
db_url,
|
|
)
|
|
logger.info(f"Started background discovery for site {new_site.id}")
|
|
|
|
return new_site
|
|
except Exception as e:
|
|
raise HTTPException(status_code=400, detail=str(e)) from e
|
|
|
|
|
|
@router.put("/{site_id}", response_model=SearchSiteResponse)
|
|
async def update_site(
|
|
site_id: int,
|
|
site: SearchSiteUpdate,
|
|
db: Session = Depends(get_db),
|
|
):
|
|
"""Met à jour un site de recherche"""
|
|
updated = search_service.update_site(
|
|
db, site_id, site.model_dump(exclude_unset=True)
|
|
)
|
|
if not updated:
|
|
raise HTTPException(status_code=404, detail="Site not found")
|
|
return updated
|
|
|
|
|
|
@router.delete("/{site_id}", status_code=204)
|
|
async def delete_site(site_id: int, db: Session = Depends(get_db)):
|
|
"""Supprime un site de recherche"""
|
|
deleted = search_service.delete_site(db, site_id)
|
|
if not deleted:
|
|
raise HTTPException(status_code=404, detail="Site not found")
|
|
|
|
|
|
@router.post("/{site_id}/discover", response_model=dict)
|
|
async def discover_site_search_url(
|
|
site_id: int,
|
|
db: Session = Depends(get_db),
|
|
):
|
|
"""
|
|
Force la découverte de l'URL de recherche pour un site existant.
|
|
Utile si la découverte automatique n'a pas fonctionné.
|
|
"""
|
|
site = search_service.get_site_by_id(db, site_id)
|
|
if not site:
|
|
raise HTTPException(status_code=404, detail="Site not found")
|
|
|
|
result = await discover_search_url(site.domain)
|
|
|
|
if result.get("discovered"):
|
|
# Mettre à jour le site
|
|
update_data = {}
|
|
if result.get("search_url"):
|
|
update_data["search_url"] = result["search_url"]
|
|
if result.get("product_link_selector"):
|
|
update_data["product_link_selector"] = result["product_link_selector"]
|
|
|
|
if update_data:
|
|
search_service.update_site(db, site_id, update_data)
|
|
|
|
return {
|
|
"success": True,
|
|
"message": f"URL de recherche découverte: {result.get('search_url')}",
|
|
"search_url": result.get("search_url"),
|
|
"product_link_selector": result.get("product_link_selector"),
|
|
}
|
|
else:
|
|
return {
|
|
"success": False,
|
|
"message": "Impossible de découvrir l'URL de recherche automatiquement",
|
|
}
|
|
|
|
|
|
@router.post("/discover-all", response_model=dict)
|
|
async def discover_all_missing_search_urls(
|
|
background_tasks: BackgroundTasks,
|
|
db: Session = Depends(get_db),
|
|
):
|
|
"""
|
|
Lance la découverte d'URL de recherche pour tous les sites qui n'en ont pas.
|
|
La découverte se fait en arrière-plan.
|
|
"""
|
|
sites = search_service.get_all_sites(db)
|
|
sites_to_discover = [s for s in sites if not s.search_url]
|
|
|
|
if not sites_to_discover:
|
|
return {
|
|
"success": True,
|
|
"message": "Tous les sites ont déjà une URL de recherche configurée",
|
|
"sites_queued": 0,
|
|
}
|
|
|
|
db_url = os.getenv("DATABASE_URL", "")
|
|
|
|
for site in sites_to_discover:
|
|
background_tasks.add_task(
|
|
_discover_and_update_site,
|
|
site.id,
|
|
site.domain,
|
|
db_url,
|
|
)
|
|
|
|
return {
|
|
"success": True,
|
|
"message": f"Découverte lancée pour {len(sites_to_discover)} sites",
|
|
"sites_queued": len(sites_to_discover),
|
|
"sites": [{"id": s.id, "domain": s.domain} for s in sites_to_discover],
|
|
}
|