lint / ruff (push) Successful in 14s
tests / desktop (push) Successful in 22s
docker / image (push) Successful in 43s
tests / web (push) Successful in 39s
tests / android-core (push) Successful in 1m1s
tests / backend (push) Successful in 2m12s
android / apk (push) Successful in 6m50s
54 lines
1.8 KiB
Python
54 lines
1.8 KiB
Python
"""The Android OTA feed.
|
|
|
|
The APK never comes from the phone's own Gitea credentials — the repository is
|
|
private. The backend reads the newest successful Actions artifact and re-serves
|
|
it here, behind the same auth as the rest of `/api`.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, HTTPException
|
|
from fastapi.responses import FileResponse
|
|
|
|
from app.services import android_updates
|
|
|
|
router = APIRouter(prefix="/api/updates", tags=["updates"])
|
|
|
|
|
|
def _raise_http(exc: android_updates.UpdateUnavailable) -> None:
|
|
if isinstance(exc, android_updates.UpdateNotConfigured):
|
|
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
|
if isinstance(exc, android_updates.UpdateNotFound):
|
|
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
|
raise HTTPException(status_code=502, detail=str(exc)) from exc
|
|
|
|
|
|
@router.get("/android")
|
|
def android_update() -> dict:
|
|
"""Metadata for the newest successful master build.
|
|
|
|
The client compares `version_code` with its own; the backend deliberately
|
|
does not try to know which build the phone is running.
|
|
"""
|
|
try:
|
|
return android_updates.latest_android()
|
|
except android_updates.UpdateUnavailable as exc:
|
|
_raise_http(exc)
|
|
|
|
|
|
@router.get("/android/apk")
|
|
def android_apk() -> FileResponse:
|
|
"""The APK for the newest successful master build."""
|
|
try:
|
|
path, metadata = android_updates.android_apk()
|
|
except android_updates.UpdateUnavailable as exc:
|
|
_raise_http(exc)
|
|
|
|
version = metadata.get("version_name") or metadata.get("version_code") or "latest"
|
|
return FileResponse(
|
|
path,
|
|
media_type="application/vnd.android.package-archive",
|
|
filename=f"kadence-{version}.apk",
|
|
headers={"Cache-Control": "no-store"},
|
|
)
|