95 lines
3.2 KiB
Python
95 lines
3.2 KiB
Python
"""Overview blueprint routes (Chapter 08 / Chapter 11's route table)."""
|
|
from __future__ import annotations
|
|
|
|
from flask import current_app, jsonify, request
|
|
|
|
from app.blueprints.overview import bp
|
|
from app.blueprints.overview.queries import (
|
|
get_browser_breakdown,
|
|
get_kpis,
|
|
get_status_code_breakdown,
|
|
get_top_referrers,
|
|
get_top_urls,
|
|
get_traffic_chart_series,
|
|
)
|
|
from app.services.background import resume_incomplete_files
|
|
from app.utils.dates import parse_date_range
|
|
from app.utils.htmx import render_htmx_aware
|
|
from app.utils.pagination import parse_pagination
|
|
|
|
|
|
@bp.route("/overview")
|
|
def overview():
|
|
"""Full page on first load, HTMX partial on tab switch / range change (Ch04).
|
|
|
|
Also opportunistically resumes any log_files stuck in queued/processing
|
|
(Ch12 simplification: the replacement for cron's "there's always a
|
|
next tick" guarantee — see app/services/background.py).
|
|
"""
|
|
resume_incomplete_files(current_app._get_current_object())
|
|
from_date, to_date = parse_date_range(request)
|
|
return render_htmx_aware(
|
|
request,
|
|
full_template="overview/index.html",
|
|
partial_template="overview/_content.html",
|
|
from_date=from_date,
|
|
to_date=to_date,
|
|
)
|
|
|
|
|
|
@bp.get("/api/overview/kpis")
|
|
def api_kpis():
|
|
from_date, to_date = parse_date_range(request)
|
|
return jsonify(data=get_kpis(from_date, to_date), meta={"from": from_date.isoformat(), "to": to_date.isoformat()})
|
|
|
|
|
|
@bp.get("/api/overview/traffic-chart")
|
|
def api_traffic_chart():
|
|
from_date, to_date = parse_date_range(request)
|
|
return jsonify(
|
|
data=get_traffic_chart_series(from_date, to_date),
|
|
meta={"from": from_date.isoformat(), "to": to_date.isoformat()},
|
|
)
|
|
|
|
|
|
@bp.get("/api/overview/status-codes")
|
|
def api_status_codes():
|
|
from_date, to_date = parse_date_range(request)
|
|
return jsonify(
|
|
data=get_status_code_breakdown(from_date, to_date),
|
|
meta={"from": from_date.isoformat(), "to": to_date.isoformat()},
|
|
)
|
|
|
|
|
|
@bp.get("/api/overview/top-urls")
|
|
def api_top_urls():
|
|
from_date, to_date = parse_date_range(request)
|
|
page, per_page = parse_pagination(request)
|
|
rows, total = get_top_urls(from_date, to_date, page, per_page)
|
|
return jsonify(
|
|
data={"rows": rows, "total": total},
|
|
meta={"from": from_date.isoformat(), "to": to_date.isoformat(), "page": page, "per_page": per_page},
|
|
)
|
|
|
|
|
|
@bp.get("/api/overview/top-referrers")
|
|
def api_top_referrers():
|
|
from_date, to_date = parse_date_range(request)
|
|
page, per_page = parse_pagination(request)
|
|
rows, total = get_top_referrers(from_date, to_date, page, per_page)
|
|
return jsonify(
|
|
data={"rows": rows, "total": total},
|
|
meta={"from": from_date.isoformat(), "to": to_date.isoformat(), "page": page, "per_page": per_page},
|
|
)
|
|
|
|
|
|
@bp.get("/api/overview/browser-breakdown")
|
|
def api_browser_breakdown():
|
|
"""Chapter 11 addition (Method A, Ch08 follow-up) — not in the
|
|
original route table; see docs/api-contract-final.md."""
|
|
from_date, to_date = parse_date_range(request)
|
|
return jsonify(
|
|
data=get_browser_breakdown(from_date, to_date),
|
|
meta={"from": from_date.isoformat(), "to": to_date.isoformat()},
|
|
)
|