Nice Work

This commit is contained in:
2026-01-13 19:44:02 +00:00
parent b503b372b4
commit 0718377b27
144 changed files with 15587 additions and 2132 deletions
Binary file not shown.
+82
View File
@@ -27,6 +27,7 @@ def create_app(
spotify_backend: SpotifyBackend,
pairing_manager: PairingManager,
persist_state: Callable[[], None],
factory_reset: Callable[[], None],
) -> FastAPI:
app = FastAPI()
app.add_middleware(
@@ -48,6 +49,11 @@ def create_app(
"connected_ssid": snapshot.connected_ssid,
"wifi_profiles_count": snapshot.wifi_profiles_count,
"spotify_status": spotify_backend.status,
"last_nfc": {
"uid": state.last_nfc_uid,
"known": state.last_nfc_known,
},
"last_nfc_at": state.last_nfc_at,
"playback_state": {
"state": state.state.value,
"active_uid": state.active_uid,
@@ -59,8 +65,47 @@ def create_app(
"volume": state.volume,
"last_error": state.last_error,
},
"blocked_tags": controller.config.get("blocked_tags", []),
}
@app.get("/local-tags")
def local_tags(http_request: Request) -> dict[str, Any]:
if not _is_authorized(pairing_manager, http_request):
raise HTTPException(status_code=403, detail="pairing required")
tags = controller.config.get("tags", {})
result = []
if isinstance(tags, dict):
for uid, tag in tags.items():
if not isinstance(tag, dict):
continue
path_value = tag.get("path")
if not isinstance(path_value, str):
continue
root = controller._resolve_path(path_value)
files = []
total_size = 0
if root.exists() and root.is_dir():
for file_path in root.rglob("*"):
if not file_path.is_file():
continue
rel_path = file_path.relative_to(root).as_posix()
files.append(rel_path)
try:
total_size += file_path.stat().st_size
except OSError:
continue
result.append(
{
"uid": uid,
"path": path_value,
"media_exists": bool(files),
"file_count": len(files),
"total_size": total_size,
"files": files,
}
)
return {"tags": result}
@app.post("/command")
def command(request: CommandRequest, http_request: Request) -> dict[str, Any]:
cmd = request.command
@@ -124,6 +169,42 @@ def create_app(
spotify_backend.set_tokens(access_token, refresh_token, expires_at, account_id)
elif cmd == "spotify_clear":
spotify_backend.clear()
elif cmd == "unpair":
pairing_manager.unpair(reset_state=True)
elif cmd == "tag_assign":
uid = payload.get("uid")
media_path = payload.get("media_path")
if not isinstance(uid, str) or not isinstance(media_path, str):
raise HTTPException(status_code=400, detail="uid and media_path required")
controller.set_tag(uid, media_path)
elif cmd == "tag_remove":
uid = payload.get("uid")
if not isinstance(uid, str):
raise HTTPException(status_code=400, detail="uid is required")
controller.remove_tag(uid)
elif cmd == "tag_block":
uid = payload.get("uid")
if not isinstance(uid, str):
raise HTTPException(status_code=400, detail="uid is required")
controller.block_tag(uid)
elif cmd == "tag_unblock":
uid = payload.get("uid")
if not isinstance(uid, str):
raise HTTPException(status_code=400, detail="uid is required")
controller.unblock_tag(uid)
elif cmd == "export_tag":
uid = payload.get("uid")
target_folder = payload.get("target_folder")
if not isinstance(uid, str) or not isinstance(target_folder, str):
raise HTTPException(status_code=400, detail="uid and target_folder required")
if "/" in target_folder or "\\" in target_folder or not target_folder.strip():
raise HTTPException(status_code=400, detail="invalid target_folder")
ok = controller.export_tag_media(uid, target_folder.strip())
if not ok:
raise HTTPException(status_code=500, detail="export failed")
elif cmd == "factory_reset":
factory_reset()
return {"ok": True, "restart_required": True}
else:
raise HTTPException(status_code=400, detail="unknown command")
@@ -139,6 +220,7 @@ def _requires_pairing(command: str) -> bool:
"wifi_reset",
"spotify_set_tokens",
"spotify_clear",
"factory_reset",
}
return command not in allowed_without_pairing