fix: serialize media publishing decisions
This commit is contained in:
@@ -15,12 +15,12 @@ from ..community_review import ExternalReviewError, map_observation, publish_obs
|
||||
from ..config import settings
|
||||
from ..dependencies import Db
|
||||
from ..importer import ImportAlreadyRunning, ImportSourceError, import_records
|
||||
from rf4_research.media_assets import publish_quality_upgrades, rollback_quality_upgrade
|
||||
from rf4_research.media_assets import preview_quality_upgrades, publish_quality_upgrades, rollback_quality_upgrade
|
||||
|
||||
from ..media_catalog import KNOWN_MEDIA_ROLES, MEDIA_ROLES_BY_ENTITY, MEDIA_ROOT, review_assets, review_file
|
||||
from ..media_catalog import KNOWN_MEDIA_ROLES, MEDIA_ROLES_BY_ENTITY, MEDIA_ROOT, media_manifest_version, review_assets, review_file
|
||||
from ..models import CatchReport, CommunityImportRun, DataSource, ExternalObservation, Fish, ModerationEvent, ModerationStatus, OfficialRecordImport, SourceType, Waterbody
|
||||
from ..public_cache import public_cache
|
||||
from ..schemas import AdminCatchReportOut, AdminMediaDecision, AdminMediaReviewOut, AdminMediaRollback, AdminModerationHistoryOut, AdminSourceStatusOut, CatchReportCreated, ExternalAliasSuggestionOut, ExternalObservationAction, ExternalObservationBulkAction, ExternalObservationBulkDecision, ExternalObservationBulkMapping, ExternalObservationBulkResult, ExternalObservationDecision, ExternalObservationMapping, ExternalObservationOut, ExternalObservationPublished, ImportRunOut, ModerationBulkResult, ModerationBulkUpdate, ModerationUpdate
|
||||
from ..schemas import AdminCatchReportOut, AdminMediaDecision, AdminMediaPreview, AdminMediaReviewOut, AdminMediaRollback, AdminModerationHistoryOut, AdminSourceStatusOut, CatchReportCreated, ExternalAliasSuggestionOut, ExternalObservationAction, ExternalObservationBulkAction, ExternalObservationBulkDecision, ExternalObservationBulkMapping, ExternalObservationBulkResult, ExternalObservationDecision, ExternalObservationMapping, ExternalObservationOut, ExternalObservationPublished, ImportRunOut, ModerationBulkResult, ModerationBulkUpdate, ModerationUpdate
|
||||
from ..storage import delete_screenshot, signed_screenshot_url
|
||||
from ..time_utils import aware
|
||||
|
||||
@@ -35,6 +35,7 @@ def _admin(request: Request, db: Db, authorization: Annotated[str | None, Header
|
||||
@router.get("/api/v1/admin/media/catalog", response_model=list[AdminMediaReviewOut])
|
||||
def admin_media_catalog(
|
||||
_: Annotated[str, Depends(_admin)],
|
||||
response: Response,
|
||||
entity_type: str | None = Query(None, pattern="^(fish|waterbody|tackle|reference)$"),
|
||||
status: str | None = Query(None, pattern="^(approved|upgrade_queued|upgrade_stored)$"),
|
||||
media_role: str | None = Query(None, pattern="^(waterbody_cover|waterbody_map|waterbody_depth_map|waterbody_screenshot|tackle_card|tackle_detail|rig_diagram|tackle_screenshot)$"),
|
||||
@@ -46,6 +47,7 @@ def admin_media_catalog(
|
||||
raise HTTPException(status_code=422, detail="unknown media role")
|
||||
if media_role and (not entity_type or media_role not in MEDIA_ROLES_BY_ENTITY.get(entity_type, set())):
|
||||
raise HTTPException(status_code=422, detail="media role is incompatible with entity type")
|
||||
response.headers["X-Media-Manifest-Version"] = str(media_manifest_version())
|
||||
return review_assets(entity_type, status, media_role, q.strip() if q else None)[offset:offset + limit]
|
||||
|
||||
|
||||
@@ -58,6 +60,20 @@ def admin_media_asset(digest: str, _: Annotated[str, Depends(_admin)]) -> FileRe
|
||||
return FileResponse(path, media_type=media_type, headers={"Cache-Control": "private, no-store"})
|
||||
|
||||
|
||||
@router.post("/api/v1/admin/media/upgrades/preview")
|
||||
def admin_preview_media_upgrades(
|
||||
payload: AdminMediaPreview,
|
||||
_: Annotated[str, Depends(_admin)],
|
||||
) -> dict:
|
||||
try:
|
||||
return preview_quality_upgrades(
|
||||
MEDIA_ROOT / "manifest.json", asset_ids=payload.asset_ids,
|
||||
expected_version=payload.expected_version,
|
||||
)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=409, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@router.post("/api/v1/admin/media/upgrades/publish")
|
||||
def admin_publish_media_upgrades(
|
||||
payload: AdminMediaDecision,
|
||||
@@ -65,7 +81,10 @@ def admin_publish_media_upgrades(
|
||||
) -> dict[str, int]:
|
||||
"""Atomically publish all stored quality upgrades after an explicit decision."""
|
||||
try:
|
||||
return publish_quality_upgrades(MEDIA_ROOT / "manifest.json", note=payload.note)
|
||||
return publish_quality_upgrades(
|
||||
MEDIA_ROOT / "manifest.json", note=payload.note,
|
||||
asset_ids=payload.asset_ids, expected_version=payload.expected_version,
|
||||
)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=409, detail=str(exc)) from exc
|
||||
|
||||
@@ -74,11 +93,12 @@ def admin_publish_media_upgrades(
|
||||
def admin_rollback_media_upgrade(
|
||||
payload: AdminMediaRollback,
|
||||
_: Annotated[str, Depends(_admin)],
|
||||
) -> dict[str, str]:
|
||||
) -> dict:
|
||||
"""Restore one superseded fallback while retaining the reviewed candidate."""
|
||||
try:
|
||||
return rollback_quality_upgrade(
|
||||
MEDIA_ROOT / "manifest.json", asset_url=payload.asset_url, note=payload.note,
|
||||
MEDIA_ROOT / "manifest.json", asset_id=payload.asset_id,
|
||||
note=payload.note, expected_version=payload.expected_version,
|
||||
)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=409, detail=str(exc)) from exc
|
||||
|
||||
Reference in New Issue
Block a user