First product
This commit is contained in:
parent
778da9e2fc
commit
4433d7d2c4
157 changed files with 23975 additions and 0 deletions
167
app/web/routers/dashboard.py
Normal file
167
app/web/routers/dashboard.py
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from fastapi.responses import HTMLResponse
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.db.models import RunTriggerType
|
||||
from app.db.session import get_db_session
|
||||
from app.presentation import dashboard as dashboard_presenter
|
||||
from app.services import ingestion as ingestion_service
|
||||
from app.services import publications as publication_service
|
||||
from app.services import runs as run_service
|
||||
from app.services import user_settings as user_settings_service
|
||||
from app.settings import settings
|
||||
from app.theme import resolve_theme
|
||||
from app.web import common
|
||||
from app.web.deps import get_ingestion_service
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
async def _render_dashboard_page(
|
||||
request: Request,
|
||||
*,
|
||||
db_session: AsyncSession,
|
||||
current_user,
|
||||
theme_name: str,
|
||||
notice: str | None = None,
|
||||
page_error: str | None = None,
|
||||
) -> HTMLResponse:
|
||||
unread_publications = await publication_service.list_new_for_latest_run_for_user(
|
||||
db_session,
|
||||
user_id=current_user.id,
|
||||
limit=50,
|
||||
)
|
||||
recent_runs = await run_service.list_recent_runs_for_user(
|
||||
db_session,
|
||||
user_id=current_user.id,
|
||||
limit=20,
|
||||
)
|
||||
user_settings = await user_settings_service.get_or_create_settings(
|
||||
db_session,
|
||||
user_id=current_user.id,
|
||||
)
|
||||
queue_counts = await run_service.queue_status_counts_for_user(
|
||||
db_session,
|
||||
user_id=current_user.id,
|
||||
)
|
||||
context = common.build_template_context(
|
||||
request,
|
||||
page_title="Dashboard",
|
||||
active_nav="home",
|
||||
theme_name=theme_name,
|
||||
session_user=common.to_session_user(current_user),
|
||||
notice=notice,
|
||||
page_error=page_error,
|
||||
)
|
||||
context["dashboard"] = dashboard_presenter.build_dashboard_view_model(
|
||||
unread_publications=unread_publications,
|
||||
recent_runs=recent_runs,
|
||||
request_delay_seconds=user_settings.request_delay_seconds,
|
||||
queue_counts=queue_counts,
|
||||
)
|
||||
return common.templates.TemplateResponse(
|
||||
request=request,
|
||||
name="index.html",
|
||||
context=context,
|
||||
)
|
||||
|
||||
|
||||
@router.get("/", response_class=HTMLResponse)
|
||||
async def home(
|
||||
request: Request,
|
||||
theme: str | None = None,
|
||||
db_session: AsyncSession = Depends(get_db_session),
|
||||
) -> HTMLResponse:
|
||||
current_user = await common.get_authenticated_user(request, db_session)
|
||||
if current_user is None:
|
||||
return common.redirect_to_login()
|
||||
return await _render_dashboard_page(
|
||||
request,
|
||||
db_session=db_session,
|
||||
current_user=current_user,
|
||||
theme_name=resolve_theme(theme),
|
||||
notice=request.query_params.get("notice"),
|
||||
page_error=request.query_params.get("error"),
|
||||
)
|
||||
|
||||
|
||||
@router.post("/runs/manual")
|
||||
async def run_manual_ingestion(
|
||||
request: Request,
|
||||
db_session: AsyncSession = Depends(get_db_session),
|
||||
ingest_service: ingestion_service.ScholarIngestionService = Depends(get_ingestion_service),
|
||||
):
|
||||
current_user = await common.get_authenticated_user(request, db_session)
|
||||
if current_user is None:
|
||||
return common.redirect_to_login()
|
||||
|
||||
user_settings = await user_settings_service.get_or_create_settings(
|
||||
db_session,
|
||||
user_id=current_user.id,
|
||||
)
|
||||
logger.info(
|
||||
"runs.manual_started",
|
||||
extra={
|
||||
"event": "runs.manual_started",
|
||||
"user_id": current_user.id,
|
||||
"request_delay_seconds": user_settings.request_delay_seconds,
|
||||
"network_error_retries": settings.ingestion_network_error_retries,
|
||||
"max_pages_per_scholar": settings.ingestion_max_pages_per_scholar,
|
||||
"page_size": settings.ingestion_page_size,
|
||||
},
|
||||
)
|
||||
try:
|
||||
run_summary = await ingest_service.run_for_user(
|
||||
db_session,
|
||||
user_id=current_user.id,
|
||||
trigger_type=RunTriggerType.MANUAL,
|
||||
request_delay_seconds=user_settings.request_delay_seconds,
|
||||
network_error_retries=settings.ingestion_network_error_retries,
|
||||
retry_backoff_seconds=settings.ingestion_retry_backoff_seconds,
|
||||
max_pages_per_scholar=settings.ingestion_max_pages_per_scholar,
|
||||
page_size=settings.ingestion_page_size,
|
||||
auto_queue_continuations=settings.ingestion_continuation_queue_enabled,
|
||||
queue_delay_seconds=settings.ingestion_continuation_base_delay_seconds,
|
||||
)
|
||||
except ingestion_service.RunAlreadyInProgressError:
|
||||
await db_session.rollback()
|
||||
return common.redirect_with_message(
|
||||
"/",
|
||||
error="A run is already in progress for this account.",
|
||||
)
|
||||
except Exception:
|
||||
await db_session.rollback()
|
||||
logger.exception(
|
||||
"runs.manual_failed",
|
||||
extra={
|
||||
"event": "runs.manual_failed",
|
||||
"user_id": current_user.id,
|
||||
},
|
||||
)
|
||||
return common.redirect_with_message("/", error="Manual run failed. Check logs for details.")
|
||||
|
||||
logger.info(
|
||||
"runs.manual_completed",
|
||||
extra={
|
||||
"event": "runs.manual_completed",
|
||||
"user_id": current_user.id,
|
||||
"run_id": run_summary.crawl_run_id,
|
||||
"status": run_summary.status.value,
|
||||
"scholar_count": run_summary.scholar_count,
|
||||
"new_publication_count": run_summary.new_publication_count,
|
||||
},
|
||||
)
|
||||
return common.redirect_with_message(
|
||||
"/",
|
||||
notice=(
|
||||
f"Run #{run_summary.crawl_run_id} complete ({run_summary.status.value}). "
|
||||
f"Scholars: {run_summary.scholar_count}, "
|
||||
f"new publications: {run_summary.new_publication_count}."
|
||||
),
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue