fix(webui): correct provider pills and apple sidecar login

This commit is contained in:
joshpatra committed 2026-07-08 23:49:17 -04:00
1 parent b204af8602
commit 3b03d31d0f
2 files changed
+37 -21

No files matched your search

+11
View File
@@ -188,6 +188,7 @@ a {
.actions, .actions,
.row-actions { .row-actions {
display: flex; display: flex;
align-items: center;
gap: var(--space-2); gap: var(--space-2);
} }
@@ -757,9 +758,19 @@ tr:last-child td {
.capability-list, .capability-list,
.provider-enabled-list { .provider-enabled-list {
flex-wrap: wrap; flex-wrap: wrap;
align-items: flex-start;
align-self: start;
min-width: 0; min-width: 0;
} }
.capability-pill {
flex: 0 0 auto;
align-self: flex-start;
height: 24px;
min-height: 24px;
line-height: 1;
}
.scrobble-actions { .scrobble-actions {
margin-top: var(--space-4); margin-top: var(--space-4);
} }
+26 -21
View File
@@ -5,6 +5,7 @@ import subprocess
import shutil import shutil
import json import json
import logging import logging
from contextlib import asynccontextmanager
from pathlib import Path from pathlib import Path
from typing import Optional, List, Dict, Any from typing import Optional, List, Dict, Any
from fastapi import FastAPI, File, UploadFile, Query, HTTPException, BackgroundTasks from fastapi import FastAPI, File, UploadFile, Query, HTTPException, BackgroundTasks
@@ -28,8 +29,6 @@ except ImportError as e:
logger.error(f"Failed to import gamdl modules: {e}") logger.error(f"Failed to import gamdl modules: {e}")
# We will let the app start so the user can use the WebUI to troubleshoot if needed. # We will let the app start so the user can use the WebUI to troubleshoot if needed.
app = FastAPI(title="Gamdl All-in-One", version="1.0.0")
# Global states # Global states
wrapper_proc: Optional[subprocess.Popen] = None wrapper_proc: Optional[subprocess.Popen] = None
wrapper_api: Optional[WrapperApi] = None wrapper_api: Optional[WrapperApi] = None
@@ -45,7 +44,8 @@ DATA_DIR.mkdir(exist_ok=True)
import platform import platform
# Environment settings # Environment settings
HTTP_PORT = int(os.getenv("HTTP_PORT", "8080")) WRAPPER_API_PORT = int(os.getenv("WRAPPER_API_PORT", os.getenv("WRAPPER_PORT", "80")))
WRAPPER_WORKER_PORT = int(os.getenv("WRAPPER_WORKER_PORT", os.getenv("HTTP_PORT", "18080")))
arch_env = os.getenv("TARGET_ARCH") arch_env = os.getenv("TARGET_ARCH")
if not arch_env: if not arch_env:
arch_env = platform.machine().lower() arch_env = platform.machine().lower()
@@ -75,7 +75,8 @@ async def start_wrapper_daemon():
logger.info("Starting wrapper-v2 daemon...") logger.info("Starting wrapper-v2 daemon...")
env = os.environ.copy() env = os.environ.copy()
env["HTTP_PORT"] = str(HTTP_PORT) env["WRAPPER_PORT"] = str(WRAPPER_API_PORT)
env["WRAPPER_WORKER_PORT"] = str(WRAPPER_WORKER_PORT)
env["TARGET_ARCH"] = TARGET_ARCH env["TARGET_ARCH"] = TARGET_ARCH
env["WRAPPER_BASE_DIR"] = str(DATA_DIR / "mpl_db") env["WRAPPER_BASE_DIR"] = str(DATA_DIR / "mpl_db")
@@ -107,7 +108,7 @@ async def init_apple_music_api():
global wrapper_api, apple_music_api global wrapper_api, apple_music_api
try: try:
wrapper_api = await WrapperApi.create( wrapper_api = await WrapperApi.create(
base_url=f"http://127.0.0.1:{HTTP_PORT}", base_url=f"http://127.0.0.1:{WRAPPER_API_PORT}",
get_credentials_func=None, get_credentials_func=None,
get_2fa_code=None, get_2fa_code=None,
) )
@@ -119,10 +120,8 @@ async def init_apple_music_api():
except Exception as e: except Exception as e:
logger.warning(f"Could not initialize AppleMusicApi (likely not logged in yet): {e}") logger.warning(f"Could not initialize AppleMusicApi (likely not logged in yet): {e}")
# --- API Endpoints --- @asynccontextmanager
async def lifespan(app: FastAPI):
@app.on_event("startup")
async def startup_event():
# Restore persistent staged libraries if they exist # Restore persistent staged libraries if they exist
persisted_libs_dir = DATA_DIR / "apple_libs" persisted_libs_dir = DATA_DIR / "apple_libs"
if persisted_libs_dir.exists(): if persisted_libs_dir.exists():
@@ -135,14 +134,20 @@ async def startup_event():
# Attempt to start the wrapper daemon on startup # Attempt to start the wrapper daemon on startup
await start_wrapper_daemon() await start_wrapper_daemon()
@app.on_event("shutdown") try:
def shutdown_event(): yield
global wrapper_proc finally:
if wrapper_proc: global wrapper_proc
logger.info("Stopping wrapper-v2 daemon...") if wrapper_proc:
wrapper_proc.terminate() logger.info("Stopping wrapper-v2 daemon...")
wrapper_proc.wait() wrapper_proc.terminate()
logger.info("wrapper-v2 daemon stopped.") wrapper_proc.wait()
logger.info("wrapper-v2 daemon stopped.")
app = FastAPI(title="Gamdl All-in-One", version="1.0.0", lifespan=lifespan)
# --- API Endpoints ---
def check_daemon_status(): def check_daemon_status():
global wrapper_proc global wrapper_proc
@@ -164,7 +169,7 @@ async def health_check():
try: try:
import httpx import httpx
async with httpx.AsyncClient() as client: async with httpx.AsyncClient() as client:
res = await client.get(f"http://127.0.0.1:{HTTP_PORT}/health", timeout=2.0) res = await client.get(f"http://127.0.0.1:{WRAPPER_API_PORT}/health", timeout=2.0)
if res.status_code == 200: if res.status_code == 200:
wrapper_healthy = True wrapper_healthy = True
except Exception: except Exception:
@@ -187,7 +192,7 @@ async def get_me():
try: try:
import httpx import httpx
async with httpx.AsyncClient() as client: async with httpx.AsyncClient() as client:
res = await client.get(f"http://127.0.0.1:{HTTP_PORT}/me") res = await client.get(f"http://127.0.0.1:{WRAPPER_API_PORT}/me")
return res.json() return res.json()
except Exception as e: except Exception as e:
return {"logged_in": False, "error": str(e)} return {"logged_in": False, "error": str(e)}
@@ -202,7 +207,7 @@ async def login(req: LoginRequest):
import httpx import httpx
async with httpx.AsyncClient() as client: async with httpx.AsyncClient() as client:
res = await client.post( res = await client.post(
f"http://127.0.0.1:{HTTP_PORT}/login", f"http://127.0.0.1:{WRAPPER_API_PORT}/login",
json={"username": req.username, "password": req.password} json={"username": req.username, "password": req.password}
) )
# Re-initialize API if login successful immediately (no 2FA) # Re-initialize API if login successful immediately (no 2FA)
@@ -222,7 +227,7 @@ async def login_2fa(req: Login2FARequest):
import httpx import httpx
async with httpx.AsyncClient() as client: async with httpx.AsyncClient() as client:
res = await client.post( res = await client.post(
f"http://127.0.0.1:{HTTP_PORT}/login/2fa", f"http://127.0.0.1:{WRAPPER_API_PORT}/login/2fa",
json={"code": req.code} json={"code": req.code}
) )
if res.status_code == 200: if res.status_code == 200: