Build 2901262240: cache users
This commit is contained in:
@@ -39,6 +39,14 @@ from ..clients.radarr import RadarrClient
|
||||
from ..clients.jellyfin import JellyfinClient
|
||||
from ..clients.jellyseerr import JellyseerrClient
|
||||
from ..services.jellyfin_sync import sync_jellyfin_users
|
||||
from ..services.user_cache import (
|
||||
build_jellyseerr_candidate_map,
|
||||
get_cached_jellyfin_users,
|
||||
get_cached_jellyseerr_users,
|
||||
match_jellyseerr_user_id,
|
||||
save_jellyfin_users_cache,
|
||||
save_jellyseerr_users_cache,
|
||||
)
|
||||
import logging
|
||||
from ..logging_config import configure_logging
|
||||
from ..routers import requests as requests_router
|
||||
@@ -235,6 +243,9 @@ async def radarr_options() -> Dict[str, Any]:
|
||||
|
||||
@router.get("/jellyfin/users")
|
||||
async def jellyfin_users() -> Dict[str, Any]:
|
||||
cached = get_cached_jellyfin_users()
|
||||
if cached is not None:
|
||||
return {"users": cached}
|
||||
runtime = get_runtime_settings()
|
||||
client = JellyfinClient(runtime.jellyfin_base_url, runtime.jellyfin_api_key)
|
||||
if not client.configured():
|
||||
@@ -242,18 +253,7 @@ async def jellyfin_users() -> Dict[str, Any]:
|
||||
users = await client.get_users()
|
||||
if not isinstance(users, list):
|
||||
return {"users": []}
|
||||
results = []
|
||||
for user in users:
|
||||
if not isinstance(user, dict):
|
||||
continue
|
||||
results.append(
|
||||
{
|
||||
"id": user.get("Id"),
|
||||
"name": user.get("Name"),
|
||||
"hasPassword": user.get("HasPassword"),
|
||||
"lastLoginDate": user.get("LastLoginDate"),
|
||||
}
|
||||
)
|
||||
results = save_jellyfin_users_cache(users)
|
||||
return {"users": results}
|
||||
|
||||
|
||||
@@ -262,24 +262,13 @@ async def jellyfin_users_sync() -> Dict[str, Any]:
|
||||
imported = await sync_jellyfin_users()
|
||||
return {"status": "ok", "imported": imported}
|
||||
|
||||
def _normalized_handles(value: Any) -> List[str]:
|
||||
if not isinstance(value, str):
|
||||
return []
|
||||
normalized = value.strip().lower()
|
||||
if not normalized:
|
||||
return []
|
||||
handles = [normalized]
|
||||
if "@" in normalized:
|
||||
handles.append(normalized.split("@", 1)[0])
|
||||
return handles
|
||||
|
||||
def _extract_user_candidates(user: Dict[str, Any]) -> List[str]:
|
||||
candidates: List[str] = []
|
||||
for key in ("username", "email", "displayName", "name"):
|
||||
candidates.extend(_normalized_handles(user.get(key)))
|
||||
return list(dict.fromkeys(candidates))
|
||||
|
||||
async def _fetch_all_jellyseerr_users(client: JellyseerrClient) -> List[Dict[str, Any]]:
|
||||
async def _fetch_all_jellyseerr_users(
|
||||
client: JellyseerrClient, use_cache: bool = True
|
||||
) -> List[Dict[str, Any]]:
|
||||
if use_cache:
|
||||
cached = get_cached_jellyseerr_users()
|
||||
if cached is not None:
|
||||
return cached
|
||||
users: List[Dict[str, Any]] = []
|
||||
take = 100
|
||||
skip = 0
|
||||
@@ -299,6 +288,8 @@ async def _fetch_all_jellyseerr_users(client: JellyseerrClient) -> List[Dict[str
|
||||
if len(batch) < take:
|
||||
break
|
||||
skip += take
|
||||
if users:
|
||||
return save_jellyseerr_users_cache(users)
|
||||
return users
|
||||
|
||||
@router.post("/jellyseerr/users/sync")
|
||||
@@ -307,19 +298,11 @@ async def jellyseerr_users_sync() -> Dict[str, Any]:
|
||||
client = JellyseerrClient(runtime.jellyseerr_base_url, runtime.jellyseerr_api_key)
|
||||
if not client.configured():
|
||||
raise HTTPException(status_code=400, detail="Jellyseerr not configured")
|
||||
jellyseerr_users = await _fetch_all_jellyseerr_users(client)
|
||||
jellyseerr_users = await _fetch_all_jellyseerr_users(client, use_cache=False)
|
||||
if not jellyseerr_users:
|
||||
return {"status": "ok", "matched": 0, "skipped": 0, "total": 0}
|
||||
|
||||
candidate_to_id: Dict[str, int] = {}
|
||||
for user in jellyseerr_users:
|
||||
user_id = user.get("id") or user.get("userId") or user.get("Id")
|
||||
try:
|
||||
user_id = int(user_id)
|
||||
except (TypeError, ValueError):
|
||||
continue
|
||||
for candidate in _extract_user_candidates(user):
|
||||
candidate_to_id.setdefault(candidate, user_id)
|
||||
candidate_to_id = build_jellyseerr_candidate_map(jellyseerr_users)
|
||||
|
||||
updated = 0
|
||||
skipped = 0
|
||||
@@ -329,11 +312,7 @@ async def jellyseerr_users_sync() -> Dict[str, Any]:
|
||||
skipped += 1
|
||||
continue
|
||||
username = user.get("username") or ""
|
||||
matched_id = None
|
||||
for handle in _normalized_handles(username):
|
||||
matched_id = candidate_to_id.get(handle)
|
||||
if matched_id is not None:
|
||||
break
|
||||
matched_id = match_jellyseerr_user_id(username, candidate_to_id)
|
||||
if matched_id is not None:
|
||||
set_user_jellyseerr_id(username, matched_id)
|
||||
updated += 1
|
||||
@@ -356,7 +335,7 @@ async def jellyseerr_users_resync() -> Dict[str, Any]:
|
||||
client = JellyseerrClient(runtime.jellyseerr_base_url, runtime.jellyseerr_api_key)
|
||||
if not client.configured():
|
||||
raise HTTPException(status_code=400, detail="Jellyseerr not configured")
|
||||
jellyseerr_users = await _fetch_all_jellyseerr_users(client)
|
||||
jellyseerr_users = await _fetch_all_jellyseerr_users(client, use_cache=False)
|
||||
if not jellyseerr_users:
|
||||
return {"status": "ok", "imported": 0, "cleared": 0}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user