Files
script.service.ultimate/lib/streaming_providers/providers/_template/bookmarks_manager.py
T
2026-10-04 16:41:49 +02:00

97 lines
3.0 KiB
Python

# streaming_providers/providers/_template/bookmarks_manager.py
"""
{TODO: Provider name} bookmarks manager (optional).
Include this file only if the provider supports resume positions.
Providers without bookmarks don't create a bookmarks manager -- the
provider's implements_bookmarks is False and calls to get_bookmarks
return [].
See ../_template/README.md for the contract.
Reference implementation
------------------------
No existing provider implements bookmarks today. The base mixin
ProviderBookmarksMixin (base/provider_mixins/bookmarks.py) documents
the shape callers expect. Read it before writing yours -- the
semantics of position_seconds = -1, the COMPLETION_THRESHOLD, and the
KeyError on delete-missing are all there.
Call frequency
--------------
update_bookmark is called on every playback stop / pause, often
consecutively for the same position. Providers should tolerate
repeated no-op writes to the same position without erroring or
firing spurious events.
Errors
------
Backend failures raise a ProviderError subclass from base.errors
(ServerError, TransportError, ...), per the README's "Errors" section.
NOTE: earlier revisions of this template said RuntimeError. If
ProviderBookmarksMixin still documents RuntimeError, align the two
(callers catching RuntimeError would miss ProviderError).
"""
from typing import List, Optional
from ...base.managers import BookmarksManager
from ...base.models.bookmark import Bookmark, ContentType
from ...base.utils.logger import logger
class YourBookmarksManager(BookmarksManager):
"""Bookmarks for {TODO: provider name}."""
def __init__(
self,
*,
http_manager,
auth,
country,
config,
bookmarks_cache=None,
):
super().__init__(
http_manager=http_manager,
auth=auth,
country=country,
config=config,
)
self._bookmarks_cache = (
bookmarks_cache if bookmarks_cache is not None else {}
)
# ----- Abstract methods -----
def get_bookmarks(self, **kw) -> List[Bookmark]:
"""Return all bookmarks for the user. [] when there are none."""
raise NotImplementedError("YourBookmarksManager.get_bookmarks")
def update_bookmark(
self,
content_id: str,
position_seconds: int,
content_type: ContentType,
duration_seconds: Optional[int] = None,
title: Optional[str] = None,
**kw,
) -> Bookmark:
"""
Save or update a bookmark. Called on playback stop / pause.
position_seconds = -1 marks the content as completed.
Raises a ProviderError subclass if the provider rejects.
"""
raise NotImplementedError("YourBookmarksManager.update_bookmark")
def delete_bookmark(self, content_id: str, **kw) -> None:
"""
Delete a bookmark.
Raises:
KeyError: if no bookmark exists for content_id.
ProviderError: (a subclass) on backend failure.
"""
raise NotImplementedError("YourBookmarksManager.delete_bookmark")