Files
plezy/lib/services/seerr/seerr_constants.dart
T
edde746 e4f3888694 fix(seerr): seed advanced requests from the Sonarr anime defaults and expose tags
Requesting an anime series with REQUEST_ADVANCED routed it to the standard
Sonarr profile and root folder. The sheet seeded its pickers from
activeProfileId/activeDirectory only, then posted them as explicit overrides,
which beat the anime defaults Seerr would otherwise apply at approval. A user
without the permission sent no overrides and was routed correctly.

The service DTOs now carry activeAnimeProfileId, activeAnimeDirectory,
activeAnimeLanguageProfileId, activeTags, activeAnimeTags and the instance's
tag list. The sheet detects the TMDB anime keyword on the TV details it
already fetches and seeds each picker the way Seerr's web requester does:
the anime value when the series is an anime and the instance configures one,
else the standard value. Options carry the "(Default)" marker and an anime
series shows the same note as the web UI.

Tags are editable: an inline checklist under the advanced pickers, seeded from
the instance's (anime) default tags and posted as `tags`. It is inline rather
than a nested sheet page because the host builds only the top page, so a push
would dispose the sheet and drop the season and picker selections on the way
back.

close #2215
2026-09-03 16:46:27 +02:00

53 lines
2.1 KiB
Dart

/// Constants for the Seerr (seerr-team/seerr) REST API.
abstract final class SeerrConstants {
/// Every endpoint lives under this prefix on the instance base URL.
static const String apiPath = '/api/v1';
/// Express session cookie issued by the auth endpoints.
static const String sessionCookieName = 'connect.sid';
/// Default port of a Seerr install, tried for schemeless input that names no
/// port of its own.
static const int defaultPort = 5055;
static const Duration probeTimeout = Duration(seconds: 8);
static const Duration authTimeout = Duration(seconds: 20);
static const Duration requestTimeout = Duration(seconds: 30);
/// Quick Connect poll cadence, matching the Seerr web UI's fixed 2000ms.
static const Duration quickConnectPollInterval = Duration(seconds: 2);
/// TMDB keyword Seerr treats as "this series is an anime"
/// (server/api/themoviedb/constants.ts `ANIME_KEYWORD_ID`). Seerr routes
/// such series to a Sonarr instance's anime defaults.
static const int animeKeywordId = 210024;
}
/// Seerr `MediaServerType` values (server/constants/server.ts), sent as
/// `serverType` in the `/auth/jellyfin` body.
abstract final class SeerrMediaServerType {
static const int plex = 1;
static const int jellyfin = 2;
static const int emby = 3;
}
/// Seerr permission bitmask (server/lib/permissions.ts). Only the bits the
/// app checks are named; the full mask is stored on the session untouched.
abstract final class SeerrPermission {
static const int admin = 2;
static const int request = 32;
static const int request4k = 1024;
static const int request4kMovie = 2048;
static const int request4kTv = 4096;
static const int requestAdvanced = 8192;
static const int requestMovie = 262144;
static const int requestTv = 524288;
}
/// Seerr permission semantics: `ADMIN` implies everything, otherwise the
/// user needs at least one of [anyOf].
bool seerrHasPermission(int userPermissions, List<int> anyOf) {
if (userPermissions & SeerrPermission.admin != 0) return true;
return anyOf.any((p) => userPermissions & p != 0);
}