Files
script.service.ultimate/lib/streaming_providers/base/managers/bookmarks.py
T
2026-10-07 12:12:10 +02:00

97 lines
3.2 KiB
Python

# streaming_providers/base/managers/bookmarks.py
"""
BookmarksManager ABC.
Public interface
----------------
get_bookmarks(**kw) -> List[Bookmark] [abstract]
update_bookmark(content_id, position_seconds, ...) -> Bookmark [abstract]
delete_bookmark(content_id, **kw) -> None [abstract]
Constructor contract
--------------------
Four required keyword-only collaborators.
Return-value conventions
------------------------
get_bookmarks returns [] when the user has no bookmarks. Not an error.
update_bookmark raises OperationFailedError if the provider rejects the write
(e.g. content inaccessible, backend error). It is called on every
playback stop / pause, so providers should tolerate a write that
overwrites the same position with a no-op rather than failing.
delete_bookmark raises ItemNotFoundError if no bookmark exists for
content_id, so callers can distinguish "already gone" from "successfully
deleted". The base ProviderBookmarksMixin documents the same rule (as
KeyError; ItemNotFoundError is a KeyError subclass).
ItemNotFoundError is both a NotFoundError (ProviderError) and a KeyError, and
OperationFailedError is both a ProviderError and a RuntimeError, so handlers
written against the old KeyError / RuntimeError convention keep working.
Caller guidance
---------------
`position_seconds = -1` marks the content as completed. A position
that reaches the model's COMPLETION_THRESHOLD (>= 95% by default) is
also treated as completed by the caller -- providers just store what
they are given.
"""
from __future__ import annotations
from abc import abstractmethod
from typing import Any, List, Optional
from ..models.bookmark import Bookmark, ContentType
from ._base import ManagerBase
class BookmarksManager(ManagerBase):
"""Abstract base for provider bookmarks managers."""
# ------------------------------------------------------------------
# Abstract
# ------------------------------------------------------------------
@abstractmethod
def get_bookmarks(self, **kw: Any) -> List[Bookmark]:
"""
Return all bookmarks for the authenticated user.
Return [] when the user has no bookmarks.
"""
raise NotImplementedError
@abstractmethod
def update_bookmark(
self,
content_id: str,
position_seconds: int,
content_type: ContentType,
duration_seconds: Optional[int] = None,
title: Optional[str] = None,
**kw: Any,
) -> Bookmark:
"""
Save or update a bookmark.
Called on playback stop / pause, so should be tolerant of
repeated writes to the same position (a no-op write is fine).
Raises OperationFailedError (also a RuntimeError) if the provider
rejects the write.
"""
raise NotImplementedError
@abstractmethod
def delete_bookmark(self, content_id: str, **kw: Any) -> None:
"""
Delete a bookmark.
Raises:
ItemNotFoundError: if no bookmark exists for content_id
(also a KeyError).
OperationFailedError: on backend failure (also a RuntimeError).
"""
raise NotImplementedError