107 lines
3.9 KiB
Python
107 lines
3.9 KiB
Python
from __future__ import annotations
|
|
|
|
import re
|
|
|
|
from fastapi import APIRouter, Request
|
|
from fastapi.responses import RedirectResponse, StreamingResponse
|
|
|
|
from app.core.db.common import CommonSessionLocal
|
|
from app.core.http_responses import ui_access_denied
|
|
from app.core.security.csrf import get_or_create_csrf_token
|
|
from app.core.security.session_auth import get_current_user
|
|
from app.core.templating import templates
|
|
from app.modules.core.rbac.deps import get_user_permissions, get_user_roles
|
|
from app.modules.peer_review_export.service import (
|
|
build_peer_review_evidence,
|
|
build_peer_review_zip,
|
|
can_view_peer_review_export,
|
|
list_peer_review_engagements,
|
|
)
|
|
|
|
router = APIRouter(prefix="/peer-review", tags=["peer-review-evidence-export-ui"])
|
|
|
|
|
|
def _ctx(request: Request, db, user, **extra):
|
|
base = {
|
|
"request": request,
|
|
"current_user": user,
|
|
"current_user_roles": get_user_roles(db, user.id),
|
|
"current_user_permissions": get_user_permissions(db, user.id),
|
|
"csrf_token": get_or_create_csrf_token(request),
|
|
"title": "Peer Review Evidence Export",
|
|
}
|
|
base.update(extra)
|
|
return base
|
|
|
|
|
|
def _safe_filename(value: str) -> str:
|
|
value = re.sub(r"[^A-Za-z0-9._-]+", "_", str(value or "").strip())
|
|
value = value.strip("._")
|
|
return value or "peer_review_evidence"
|
|
|
|
|
|
@router.get("/evidence")
|
|
def evidence_index(request: Request, financial_year: str = "", q: str = ""):
|
|
db = CommonSessionLocal()
|
|
try:
|
|
user = get_current_user(request, db=db)
|
|
if not user:
|
|
return RedirectResponse(url="/login", status_code=303)
|
|
if not can_view_peer_review_export(db, user):
|
|
return ui_access_denied()
|
|
payload = list_peer_review_engagements(db, request, user, financial_year=financial_year, q=q)
|
|
return templates.TemplateResponse(
|
|
"modules/peer_review_export/templates/peer_review_export/index.html",
|
|
_ctx(request, db, user, **payload),
|
|
)
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@router.get("/evidence/{subscription_id}")
|
|
def evidence_detail(request: Request, subscription_id: int):
|
|
db = CommonSessionLocal()
|
|
try:
|
|
user = get_current_user(request, db=db)
|
|
if not user:
|
|
return RedirectResponse(url="/login", status_code=303)
|
|
if not can_view_peer_review_export(db, user):
|
|
return ui_access_denied()
|
|
try:
|
|
payload = build_peer_review_evidence(db, request, user, subscription_id)
|
|
except ValueError:
|
|
return ui_access_denied()
|
|
return templates.TemplateResponse(
|
|
"modules/peer_review_export/templates/peer_review_export/detail.html",
|
|
_ctx(request, db, user, **payload),
|
|
)
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@router.get("/evidence/{subscription_id}/export.zip")
|
|
def evidence_export_zip(request: Request, subscription_id: int):
|
|
db = CommonSessionLocal()
|
|
try:
|
|
user = get_current_user(request, db=db)
|
|
if not user:
|
|
return RedirectResponse(url="/login", status_code=303)
|
|
if not can_view_peer_review_export(db, user):
|
|
return ui_access_denied()
|
|
try:
|
|
payload = build_peer_review_evidence(db, request, user, subscription_id)
|
|
data = build_peer_review_zip(db, request, user, subscription_id)
|
|
except ValueError:
|
|
return ui_access_denied()
|
|
sub = payload["subscription"]
|
|
client_name = sub.client.client_name if sub.client else "client"
|
|
service_name = sub.catalogue.service_name if sub.catalogue else "service"
|
|
filename = _safe_filename(f"peer_review_{client_name}_{service_name}_{sub.financial_year or 'fy'}_{sub.id}.zip")
|
|
return StreamingResponse(
|
|
iter([data]),
|
|
media_type="application/zip",
|
|
headers={"Content-Disposition": f'attachment; filename="{filename}"'},
|
|
)
|
|
finally:
|
|
db.close()
|