mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-12 20:15:10 +00:00
feat(search): add ANONYMOUS_SEARCH to skip the login for a service
A service that sets the flag gets no cookie load, no authenticate() call and no cookie save on a search, on the CLI and in the REST search handler. /api/services reports it as anonymous_search.
This commit is contained in:
@@ -100,6 +100,7 @@ Declared at class level to configure framework behaviour:
|
||||
| `GEOBLOCK` | `tuple[str, ...]` | IP region codes where the service refuses to work. Every other region is allowed. Default `()`. |
|
||||
| `VAULT_TAG` | `Optional[str]` | Overrides the key-vault namespace so sibling services can share one vault. Default `None` (use the service's own tag). |
|
||||
| `AUTH_METHODS` | `Optional[tuple[str, ...]]` | Auth methods accepted (`"cookies"` / `"credentials"`). When `None`, the REST `/services` endpoint infers them from `authenticate()`. |
|
||||
| `ANONYMOUS_SEARCH` | `bool` | Set `True` when `search()` needs no login and no state from `authenticate()`. A search then skips the cookie load, `authenticate()` and the cookie save. Default `False`. |
|
||||
| `NO_SUBTITLES` | `bool` | Set `True` on a service with no subtitle tracks to skip subtitle handling entirely. |
|
||||
| `ANIME` | `bool` | Set `True` when the catalogue is anime, so metadata lookups prefer AniList. A title's own `anime` flag overrides it. |
|
||||
| `DAILY` | `bool` | Set `True` when the catalogue is daily/date-based (talk shows, news, sports), so unshackle names episodes by air date. A title's own `daily` flag overrides it. |
|
||||
@@ -609,6 +610,12 @@ Override any of these to react to pipeline stages (all no-ops by default):
|
||||
`on_track_repacked`, `on_track_multiplex`. Also override `search()` to yield
|
||||
`SearchResult` objects for `unshackle search`.
|
||||
|
||||
!!! warning "Set `ANONYMOUS_SEARCH` only for a search that needs no account"
|
||||
With `ANONYMOUS_SEARCH = True`, `search()` operates on an HTTP session with no cookies, and
|
||||
`authenticate()` does not run. Set it only when the search results do not depend on the
|
||||
account, and when `search()` does its own setup. A `search()` that reads a token, a header
|
||||
or a region from `authenticate()` fails or gives results for the wrong region.
|
||||
|
||||
```python
|
||||
def search(self) -> Generator[SearchResult, None, None]:
|
||||
results = self.session.get(self.config["endpoints"]["search"],
|
||||
|
||||
@@ -98,6 +98,7 @@ Show the streaming services available on this server, filtered by your allowlist
|
||||
],
|
||||
"needs_auth": true,
|
||||
"has_search": true,
|
||||
"anonymous_search": false,
|
||||
"has_drm": true,
|
||||
"auth_methods": ["cookies"]
|
||||
}
|
||||
@@ -120,6 +121,7 @@ Field notes:
|
||||
| `cli_params` | Array of parameter descriptors. Arguments have `{name, kind: "argument", required}`; options have `{name, kind: "option", opts, is_flag, default, help, type, multiple}` and, for choice options, a `choices` list. |
|
||||
| `needs_auth` | Whether the service overrides `authenticate()`. |
|
||||
| `has_search` | Whether the service supports `POST /api/search`. |
|
||||
| `anonymous_search` | Whether `POST /api/search` operates with no login for this service. The server then ignores `credentials` and `cookies` on a search. |
|
||||
| `has_drm` | Whether the service overrides a Widevine or PlayReady license hook. |
|
||||
| `pending_update` | Set to `true` while a service repository refresh waits for this service's jobs to finish before it swaps in the new code. Absent otherwise. |
|
||||
| `server_accounts` | Present when the server lends its own accounts for this service: `{regions: ["ca", "gb"], global: bool}`, the regions those accounts cover. A client sends no credentials, cookies, or cache for such a service. |
|
||||
@@ -134,6 +136,8 @@ Field notes:
|
||||
|
||||
Find titles in a service by query string. The service must have a `search()` method (see `has_search` above).
|
||||
|
||||
For a service with `anonymous_search`, the server does not log in and ignores `credentials` and `cookies`. The server account check still applies.
|
||||
|
||||
**Request body**
|
||||
|
||||
| Field | Type | Required | Default | Description |
|
||||
|
||||
@@ -150,6 +150,7 @@ curl "$BASE/api/services" \
|
||||
"help": "EXAMPLE service documentation...",
|
||||
"needs_auth": true,
|
||||
"has_search": true,
|
||||
"anonymous_search": false,
|
||||
"has_drm": true,
|
||||
"auth_methods": ["cookies", "credentials"],
|
||||
"cli_params": []
|
||||
|
||||
@@ -66,6 +66,7 @@ Declared at the top of your service class, these are static descriptors:
|
||||
| `GEOBLOCK` | `tuple[str, ...]` | ISO region codes where the service refuses to work; every other region is allowed. Use it for a service that works worldwide except in its home market. |
|
||||
| `VAULT_TAG` | `Optional[str]` | Overrides the key-vault namespace; defaults to the service's own tag. |
|
||||
| `AUTH_METHODS` | `Optional[tuple[str, ...]]` | Accepted auth methods (`"cookies"` / `"credentials"`). When `None`, the REST `/services` endpoint infers them from `authenticate()`. |
|
||||
| `ANONYMOUS_SEARCH` | `bool` | `search()` needs no login and no state from `authenticate()`. A search then skips the cookie load, `authenticate()` and the cookie save. Default `False`. |
|
||||
| `ANIME` | `bool` | The catalogue is anime, so metadata lookups prefer AniList. A title's own `anime` flag overrides it. |
|
||||
| `DAILY` | `bool` | The catalogue is daily/date-based, so unshackle names episodes by air date. A title's own `daily` flag overrides it. |
|
||||
|
||||
@@ -83,7 +84,8 @@ These are abstract. A service will not load unless it defines all three:
|
||||
`CookieJar` into `self.session.cookies` and stores `self.credential`. Override it to
|
||||
do a real login handshake.
|
||||
- **`search()`**: raises `NotImplementedError` by default. Write it so that the
|
||||
`search` command can operate.
|
||||
`search` command can operate. unshackle calls `authenticate()` first, unless the
|
||||
service sets `ANONYMOUS_SEARCH`.
|
||||
- **DRM license hooks**: `get_widevine_service_certificate`, `get_widevine_license`,
|
||||
`get_playready_license` (delegates to Widevine by default), and
|
||||
`get_clearkey_license` (returns `None` by default). See [DRM hooks](#drm-hooks) below.
|
||||
|
||||
Reference in New Issue
Block a user