Homelabtoolkit v1
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
"""Per-user watch history.
|
||||
|
||||
Every query here is scoped to a single ``user_id`` via the ``/Users/{id}/Items``
|
||||
endpoint, so one user's history is never mixed with another's.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .emby_collections import ITEM_FIELDS, normalize_item
|
||||
|
||||
# Movies and series are what we recommend; episodes are folded into their series.
|
||||
WATCHED_ITEM_TYPES = "Movie,Series"
|
||||
|
||||
|
||||
async def get_watched_items(client, user_id: str, item_types: str = WATCHED_ITEM_TYPES) -> list[dict]:
|
||||
"""Return the user's played items (normalized) for the given types."""
|
||||
if not user_id:
|
||||
return []
|
||||
raw_items = await client.get_all(
|
||||
f"/Users/{user_id}/Items",
|
||||
{
|
||||
"Recursive": "true",
|
||||
"IsPlayed": "true",
|
||||
"Filters": "IsPlayed",
|
||||
"IncludeItemTypes": item_types,
|
||||
"Fields": ITEM_FIELDS,
|
||||
"EnableUserData": "true",
|
||||
},
|
||||
)
|
||||
return [normalize_item(raw) for raw in raw_items]
|
||||
|
||||
|
||||
async def get_watched_item_ids(client, user_id: str, item_types: str = WATCHED_ITEM_TYPES) -> set[str]:
|
||||
"""Return the set of item ids the user has watched."""
|
||||
return {item["id"] for item in await get_watched_items(client, user_id, item_types) if item["id"]}
|
||||
|
||||
|
||||
async def is_item_watched(client, user_id: str, item_id: str) -> bool:
|
||||
"""Whether ``user_id`` has played ``item_id`` (user-specific)."""
|
||||
if not (user_id and item_id):
|
||||
return False
|
||||
data = await client.get(
|
||||
f"/Users/{user_id}/Items",
|
||||
{"Ids": item_id, "EnableUserData": "true"},
|
||||
)
|
||||
items = data.get("Items", []) if isinstance(data, dict) else (data or [])
|
||||
if not items:
|
||||
return False
|
||||
user_data = items[0].get("UserData") or {}
|
||||
return bool(user_data.get("Played", False))
|
||||
Reference in New Issue
Block a user