Zrodlo znikalo tylko po dlugim przytrzymaniu przez uzytkownika. Teraz zgloszenie "Response code: 404/410" uruchamia w tle ponowny resolve z serwera; martwe dopiero, gdy ekstraktor mowi "usuniete" albo plik z serwera tez daje 404/410 (dwie kontrole). Na sucho na 84 parach z 14 dni: 0 martwych, 83 zywe, czyli 410 z telefonu prawie zawsze znaczy zly adres, nie skasowany plik. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
58 lines
2.3 KiB
Python
58 lines
2.3 KiB
Python
"""Playback telemetry, POST /playback-events (fire-and-forget z apki).
|
|
|
|
Apka po każdej próbie odtwarzania woła to z origin sceny + wynikiem (success/error).
|
|
Sygnał zasila health/szybkość w rankingu źródeł (run_source_stats agreguje okno 7d).
|
|
Best-effort: apka NIE czeka i ignoruje błąd, telemetria nie może psuć playbacku.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import uuid
|
|
from typing import Annotated, Literal
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from pydantic import BaseModel, Field
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.api.device import get_device_id
|
|
from app.auth import require_api_key
|
|
from app.db import get_session
|
|
from app.models.playback_event import PlaybackEvent
|
|
from app.playback_gone import is_gone_report, verify_gone_async
|
|
|
|
router = APIRouter(prefix="/playback-events", tags=["telemetry"], dependencies=[Depends(require_api_key)])
|
|
|
|
|
|
class PlaybackEventIn(BaseModel):
|
|
# 'tube:<sitetag>', zgodne z playback_sources.origin. Bez tego ping bezużyteczny.
|
|
origin: str = Field(min_length=1, max_length=64)
|
|
status: Literal["success", "error"]
|
|
scene_id: uuid.UUID | None = None
|
|
error_kind: str | None = Field(default=None, max_length=64)
|
|
# Surowa treść błędu z native playera (ExoPlayer message), diagnostyka realnych
|
|
# padów których nie da się odtworzyć na emulatorze (np. watchporn player_error).
|
|
error_detail: str | None = Field(default=None, max_length=512)
|
|
ttff_ms: int | None = Field(default=None, ge=0, le=600_000)
|
|
|
|
|
|
@router.post("", status_code=204)
|
|
def post_playback_event(
|
|
body: PlaybackEventIn,
|
|
session: Annotated[Session, Depends(get_session)],
|
|
device_id: Annotated[str, Depends(get_device_id)],
|
|
) -> None:
|
|
session.add(
|
|
PlaybackEvent(
|
|
origin=body.origin,
|
|
scene_id=body.scene_id,
|
|
status=body.status,
|
|
error_kind=body.error_kind,
|
|
error_detail=body.error_detail if body.status == "error" else None,
|
|
ttff_ms=body.ttff_ms if body.status == "success" else None,
|
|
device_id=device_id,
|
|
)
|
|
)
|
|
session.commit()
|
|
# Plik zniknal (404/410 w odtwarzaczu): serwer sprawdza zrodlo sam i oznacza martwe
|
|
# dopiero po wlasnym potwierdzeniu (app/playback_gone.py).
|
|
if is_gone_report(body.status, body.error_kind, body.error_detail):
|
|
verify_gone_async(body.scene_id, body.origin)
|