* fix(collections): repair broken builtin collection templates A live audit of the builtin template catalog (all 40 MDBList URLs and all 10 TMDB franchise IDs fetched) found two dead sources, a silent bundle-apply collision, and several templates whose defaults contradict their descriptions: - Repoint mdblist_misc_a24 and mdblist_misc_criterion_collection to live lists; the original irvingbeano/shtluck lists were deleted on MDBList (404), so every sync of those collections failed. - Retitle mdblist_charts_popular_movies to "IMDb MovieMeter Top 100". It shared the "popular-movies" title slug with tmdb_popular_movies, and bundle apply dedupes by slug per library, so applying all_defaults silently skipped it. Poster regenerated from the raw plate with the new title; new handler test asserts builtin title slugs stay unique. - Raise the shared default limit 50 -> 100, give the IMDb Top 250 templates an explicit 250 (limit*4 fetch trim previously never scanned entries 201-250), and drop the limit on catalog lists (Criterion, A24) so they hold every owned title. - Correct IFC Films to MediaMovie (live list is 100% movies; as MediaMixed it was offered to TV libraries where it always synced empty) and fix the Trakt Popular descriptions (ratings-based, not "most-watched"). - Update stale limit docs in collection-templates.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(collections): raise import limit caps above IMDb Top 250 default The IMDb Top 250 templates now default to 250 items, but the template config forms rendered their Max Items input with max=200 and the user import API rejected limits above 200, so applying those templates from the direct galleries failed native validation or got a 400. Raise the cap to 500 on both sides, wired to shared constants: sync's fetch trim (collectionSourceFetchMax) never scans more than 500 source entries, so a larger explicit limit could never be satisfied anyway. collectionutil.MaxExplicitItemLimit backs validateOptionalLimit, and COLLECTION_MAX_ITEMS in lib/collectionTemplates backs all seven Max Items inputs (gallery forms + admin import/editor dialogs). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1897 lines
74 KiB
Go
1897 lines
74 KiB
Go
package templates
|
||
|
||
// Built-in template catalog. Each entry pairs a curated source configuration
|
||
// with presentation metadata (icon, description, sync cadence). The IDs are
|
||
// stable strings so they can be referenced across the API and UI without
|
||
// drifting when descriptions are tweaked.
|
||
//
|
||
// Sync cadences favour conservative defaults — a heavy library does not need
|
||
// "Trending" to refresh more than every six hours, and TMDB rate-limits make
|
||
// hourly refreshes wasteful for shared servers.
|
||
//
|
||
// builtinDefaultLimit caps the matched items per collection. Sync scans up to
|
||
// 4× the limit from the source list (see collectionutil.SourceFetchLimit), so
|
||
// finite canonical lists (IMDb Top 250, Criterion) carry explicit larger
|
||
// limits — the shared default would silently truncate them.
|
||
const builtinDefaultLimit = 100
|
||
|
||
var builtinTemplates = []Template{
|
||
// ── Trending (TMDB) ─────────────────────────────────────────────────────
|
||
{
|
||
ID: "tmdb_trending_all_today",
|
||
Title: "Trending Today (All)",
|
||
Description: "Movies and TV shows trending across TMDB in the last 24 hours.",
|
||
Icon: "🔥",
|
||
Category: CategoryTrending,
|
||
Source: SourceTMDB,
|
||
MediaKind: MediaMixed,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 */6 * * *",
|
||
Featured: true,
|
||
Tags: []string{"daily", "discovery"},
|
||
TMDB: &TMDBSpec{Preset: "trending", MediaType: "all", TimeWindow: "day"},
|
||
},
|
||
{
|
||
ID: "tmdb_trending_movies_week",
|
||
Title: "Trending Movies This Week",
|
||
Description: "Top trending movies on TMDB over the past seven days.",
|
||
Icon: "🎬",
|
||
Category: CategoryTrending,
|
||
Source: SourceTMDB,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
Featured: true,
|
||
TMDB: &TMDBSpec{Preset: "trending", MediaType: "movie", TimeWindow: "week"},
|
||
},
|
||
{
|
||
ID: "tmdb_trending_tv_week",
|
||
Title: "Trending TV This Week",
|
||
Description: "Top trending TV shows on TMDB over the past seven days.",
|
||
Icon: "📺",
|
||
Category: CategoryTrending,
|
||
Source: SourceTMDB,
|
||
MediaKind: MediaTV,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
Featured: true,
|
||
TMDB: &TMDBSpec{Preset: "trending", MediaType: "tv", TimeWindow: "week"},
|
||
},
|
||
{
|
||
ID: "trakt_trending_movies",
|
||
Title: "Trakt Trending Movies",
|
||
Description: "Movies with the most active watchers on Trakt right now.",
|
||
Icon: "📈",
|
||
Category: CategoryTrending,
|
||
Source: SourceTrakt,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 */6 * * *",
|
||
Trakt: &TraktSpec{Preset: "trending", MediaType: "movie"},
|
||
},
|
||
{
|
||
ID: "trakt_trending_shows",
|
||
Title: "Trakt Trending Shows",
|
||
Description: "Shows with the most active watchers on Trakt right now.",
|
||
Icon: "📈",
|
||
Category: CategoryTrending,
|
||
Source: SourceTrakt,
|
||
MediaKind: MediaTV,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 */6 * * *",
|
||
Trakt: &TraktSpec{Preset: "trending", MediaType: "tv"},
|
||
},
|
||
|
||
// ── Popular ────────────────────────────────────────────────────────────
|
||
{
|
||
ID: "tmdb_popular_movies",
|
||
Title: "Popular Movies",
|
||
Description: "Perennial favourites ranked by TMDB's popularity score.",
|
||
Icon: "⭐",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDB,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDB: &TMDBSpec{Preset: "popular", MediaType: "movie"},
|
||
},
|
||
{
|
||
ID: "tmdb_popular_tv",
|
||
Title: "Popular TV Shows",
|
||
Description: "Perennial favourites ranked by TMDB's popularity score.",
|
||
Icon: "⭐",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDB,
|
||
MediaKind: MediaTV,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDB: &TMDBSpec{Preset: "popular", MediaType: "tv"},
|
||
},
|
||
{
|
||
ID: "trakt_popular_movies",
|
||
Title: "Trakt Popular Movies",
|
||
Description: "Trakt's most popular movies of all time, ranked by user ratings.",
|
||
Icon: "🌟",
|
||
Category: CategoryPopular,
|
||
Source: SourceTrakt,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
Trakt: &TraktSpec{Preset: "popular", MediaType: "movie"},
|
||
},
|
||
{
|
||
ID: "trakt_popular_shows",
|
||
Title: "Trakt Popular Shows",
|
||
Description: "Trakt's most popular shows of all time, ranked by user ratings.",
|
||
Icon: "🌟",
|
||
Category: CategoryPopular,
|
||
Source: SourceTrakt,
|
||
MediaKind: MediaTV,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
Trakt: &TraktSpec{Preset: "popular", MediaType: "tv"},
|
||
},
|
||
|
||
// ── Top Rated ──────────────────────────────────────────────────────────
|
||
{
|
||
ID: "tmdb_top_rated_movies",
|
||
Title: "Top Rated Movies",
|
||
Description: "TMDB's highest-rated movies of all time.",
|
||
Icon: "🏆",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDB,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDB: &TMDBSpec{Preset: "top_rated", MediaType: "movie"},
|
||
},
|
||
{
|
||
ID: "tmdb_top_rated_tv",
|
||
Title: "Top Rated TV",
|
||
Description: "TMDB's highest-rated TV shows of all time.",
|
||
Icon: "🏆",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDB,
|
||
MediaKind: MediaTV,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDB: &TMDBSpec{Preset: "top_rated", MediaType: "tv"},
|
||
},
|
||
|
||
// ── In Theaters / Now Playing ──────────────────────────────────────────
|
||
{
|
||
ID: "tmdb_now_playing",
|
||
Title: "Now Playing in Theaters",
|
||
Description: "Movies currently playing in theatrical release.",
|
||
Icon: "🎟️",
|
||
Category: CategoryInTheaters,
|
||
Source: SourceTMDB,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 5 * * *",
|
||
TMDB: &TMDBSpec{Preset: "now_playing", MediaType: "movie"},
|
||
},
|
||
|
||
// ── Upcoming ───────────────────────────────────────────────────────────
|
||
{
|
||
ID: "tmdb_upcoming",
|
||
Title: "Upcoming Movies",
|
||
Description: "Theatrical releases coming soon, sourced from TMDB.",
|
||
Icon: "🗓️",
|
||
Category: CategoryUpcoming,
|
||
Source: SourceTMDB,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 5 * * *",
|
||
TMDB: &TMDBSpec{Preset: "upcoming", MediaType: "movie"},
|
||
},
|
||
|
||
// ── Airing TV ──────────────────────────────────────────────────────────
|
||
{
|
||
ID: "tmdb_airing_today",
|
||
Title: "Airing Today",
|
||
Description: "TV shows broadcasting new episodes today.",
|
||
Icon: "📡",
|
||
Category: CategoryAiring,
|
||
Source: SourceTMDB,
|
||
MediaKind: MediaTV,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 */6 * * *",
|
||
TMDB: &TMDBSpec{Preset: "airing_today", MediaType: "tv"},
|
||
},
|
||
{
|
||
ID: "tmdb_on_the_air",
|
||
Title: "On The Air This Week",
|
||
Description: "TV shows airing new episodes within the week.",
|
||
Icon: "📺",
|
||
Category: CategoryAiring,
|
||
Source: SourceTMDB,
|
||
MediaKind: MediaTV,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 5 * * *",
|
||
TMDB: &TMDBSpec{Preset: "on_the_air", MediaType: "tv"},
|
||
},
|
||
|
||
// ── Editorial / Profile-personalised ───────────────────────────────────
|
||
{
|
||
ID: "trakt_recommended_movies",
|
||
Title: "Trakt Recommended Movies",
|
||
Description: "Personalised movie picks for a connected Trakt profile.",
|
||
Icon: "🎯",
|
||
Category: CategoryEditorial,
|
||
Source: SourceTrakt,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 7 * * *",
|
||
RequiresProfile: true,
|
||
Trakt: &TraktSpec{Preset: "recommended", MediaType: "movie"},
|
||
},
|
||
{
|
||
ID: "trakt_recommended_shows",
|
||
Title: "Trakt Recommended Shows",
|
||
Description: "Personalised show picks for a connected Trakt profile.",
|
||
Icon: "🎯",
|
||
Category: CategoryEditorial,
|
||
Source: SourceTrakt,
|
||
MediaKind: MediaTV,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 7 * * *",
|
||
RequiresProfile: true,
|
||
Trakt: &TraktSpec{Preset: "recommended", MediaType: "tv"},
|
||
},
|
||
|
||
// ── Streaming Services (MDBList, community-curated) ────────────────────
|
||
// These point at top-ranked public lists from the MDBList /toplists/ page.
|
||
// They are user-maintained, so the URLs may eventually be retired by the
|
||
// list owner; if that happens the import will fail loudly during sync and
|
||
// the template can be retired or repointed in this file.
|
||
{
|
||
ID: "mdblist_netflix_movies",
|
||
Title: "Netflix Movies",
|
||
Description: "Movies currently available on Netflix (community-maintained MDBList).",
|
||
Icon: "🅽",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/garycrawfordgc/netflix-movies/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_netflix_shows",
|
||
Title: "Netflix Shows",
|
||
Description: "TV shows currently available on Netflix (community-maintained MDBList).",
|
||
Icon: "🅽",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaTV,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/garycrawfordgc/netflix-shows/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_disney_movies",
|
||
Title: "Disney+ Movies",
|
||
Description: "Movies currently available on Disney+ (community-maintained MDBList).",
|
||
Icon: "🏰",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/garycrawfordgc/disney-movies/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_disney_shows",
|
||
Title: "Disney+ Shows",
|
||
Description: "TV shows currently available on Disney+ (community-maintained MDBList).",
|
||
Icon: "🏰",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaTV,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/garycrawfordgc/disney-shows/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_hbo_shows",
|
||
Title: "HBO Shows",
|
||
Description: "TV shows currently on HBO/Max (community-maintained MDBList).",
|
||
Icon: "🎭",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaTV,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/garycrawfordgc/hbo-shows/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_amazon_movies",
|
||
Title: "Amazon Prime Movies",
|
||
Description: "Movies on Amazon Prime Video (community-maintained MDBList).",
|
||
Icon: "📦",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/garycrawfordgc/amazon-prime-movies/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_amazon_shows",
|
||
Title: "Amazon Prime Shows",
|
||
Description: "TV shows on Amazon Prime Video (community-maintained MDBList).",
|
||
Icon: "📦",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaTV,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/garycrawfordgc/amazon-prime-shows/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_hulu_shows",
|
||
Title: "Hulu Shows",
|
||
Description: "TV shows on Hulu (community-maintained MDBList).",
|
||
Icon: "🟢",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaTV,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/garycrawfordgc/hulu-shows/json"},
|
||
},
|
||
|
||
// ── Top Rated (MDBList: IMDb Top 250) ──────────────────────────────────
|
||
{
|
||
ID: "mdblist_imdb_top_250_movies",
|
||
Title: "IMDb Top 250 Movies",
|
||
Description: "The IMDb Top 250 movies list, kept in sync from MDBList.",
|
||
Icon: "🥇",
|
||
Category: CategoryTopRated,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: 250,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/snoak/imdb-top-250-movies/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_imdb_top_250_shows",
|
||
Title: "IMDb Top 250 Shows",
|
||
Description: "The IMDb Top 250 TV shows list, kept in sync from MDBList.",
|
||
Icon: "🥇",
|
||
Category: CategoryTopRated,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaTV,
|
||
DefaultLimit: 250,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/snoak/imdb-top-250-shows/json"},
|
||
},
|
||
|
||
// ── Editorial (MDBList: hand-picked themes) ────────────────────────────
|
||
{
|
||
ID: "mdblist_mindfuck_movies",
|
||
Title: "Mindfuck Movies",
|
||
Description: "Twist-heavy and reality-bending movies, curated on MDBList by hdlists.",
|
||
Icon: "🌀",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/hdlists/mindfuck-movies/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_top_documentaries",
|
||
Title: "Top Documentary Movies",
|
||
Description: "Top-rated documentaries from 1980 to today (MDBList by hdlists).",
|
||
Icon: "🎥",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
MDBList: &MDBListSpec{
|
||
URL: "https://mdblist.com/lists/hdlists/latest-hd-documentary-movies-1980-to-today/json",
|
||
},
|
||
},
|
||
{
|
||
ID: "mdblist_top_horror",
|
||
Title: "Top Horror Movies",
|
||
Description: "Top-rated horror from 1980 to today (MDBList by hdlists).",
|
||
Icon: "👻",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
MDBList: &MDBListSpec{
|
||
URL: "https://mdblist.com/lists/hdlists/latest-hd-horror-movies-top-rated-from-1980-to-today/json",
|
||
},
|
||
},
|
||
|
||
// ── Streaming Originals (MDBList, Kometa-curated) ──────────────────────
|
||
// Phase-1 templates that mirror the PMM `movies_streaming` and
|
||
// `shows_streaming` originals sets. Lists come from MDBList user
|
||
// `k0meta` (the Kometa team) so the data ages well alongside PMM users
|
||
// who already trust that source. Default sort orders land in the 4000s
|
||
// band, sequenced alphabetically by service name so the gallery shows a
|
||
// predictable column ordering.
|
||
{
|
||
ID: "mdblist_streaming_apple_tv_plus",
|
||
Title: "Apple TV+",
|
||
Description: "Apple TV+ originals across films and series, curated by the Kometa team on MDBList.",
|
||
Icon: "🍎",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMixed,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 4001,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/k0meta/appletv-originals/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_streaming_disney_plus_originals",
|
||
Title: "Disney+ Originals",
|
||
Description: "Disney+ originals across films and series, curated by the Kometa team on MDBList.",
|
||
Icon: "🏰",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMixed,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 4002,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/k0meta/disney-originals/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_streaming_hbo_max_originals",
|
||
Title: "HBO Max Originals",
|
||
Description: "Max (formerly HBO Max) originals across films and series, curated by the Kometa team on MDBList.",
|
||
Icon: "🎭",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMixed,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 4003,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/k0meta/max-originals/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_streaming_hulu_originals",
|
||
Title: "Hulu Originals",
|
||
Description: "Hulu originals across films and series, curated by the Kometa team on MDBList.",
|
||
Icon: "🟢",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMixed,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 4004,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/k0meta/hulu-originals/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_streaming_netflix_originals",
|
||
Title: "Netflix Originals",
|
||
Description: "Netflix-produced films and series, curated by the Kometa team on MDBList.",
|
||
Icon: "🅽",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMixed,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 4005,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/k0meta/netflix-originals/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_streaming_peacock_originals",
|
||
Title: "Peacock Originals",
|
||
Description: "Peacock originals across films and series, curated by the Kometa team on MDBList.",
|
||
Icon: "🦚",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMixed,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 4006,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/k0meta/peacock-originals/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_streaming_prime_video_originals",
|
||
Title: "Prime Video Originals",
|
||
Description: "Amazon Prime Video originals across films and series, curated by the Kometa team on MDBList.",
|
||
Icon: "📦",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMixed,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 4007,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/k0meta/amazon-originals/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_streaming_shudder",
|
||
Title: "Shudder",
|
||
Description: "Recent horror and thriller titles available on Shudder (MDBList by snoak).",
|
||
Icon: "🩸",
|
||
Category: CategoryStreaming,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 4008,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/snoak/latest-shudder-movies/json"},
|
||
},
|
||
|
||
// ── Awards (MDBList) ───────────────────────────────────────────────────
|
||
// Sorted within the 3000s band so awards land between Best-of-Year
|
||
// (2000s) and Streaming Originals (4000s) in apply-time sort_order.
|
||
{
|
||
ID: "mdblist_awards_oscar_winners",
|
||
Title: "Oscar Winners",
|
||
Description: "Academy Award winners across categories, sourced from MDBList (atalante421).",
|
||
Icon: "🏆",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 3001,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"awards", "oscars"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/atalante421/oscar-winners/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_awards_golden_globes_winners",
|
||
Title: "Golden Globes Winners",
|
||
Description: "Golden Globe winning films across categories, sourced from MDBList (atalante421).",
|
||
Icon: "🏆",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 3002,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"awards", "golden-globes"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/atalante421/golden-globe-winners/json"},
|
||
},
|
||
|
||
// ── Best of Year (MDBList) ─────────────────────────────────────────────
|
||
// Year-specific best-of lists drawn from siskourso's Rotten-Tomatoes
|
||
// roll-ups. Only the years with active public lists ship; older years
|
||
// (2018-2022) had no maintained equivalent on MDBList at template
|
||
// authoring time and are intentionally skipped — see Phase-1 report.
|
||
{
|
||
ID: "mdblist_best_of_2023",
|
||
Title: "Best of 2023",
|
||
Description: "Top-rated 2023 releases from Rotten Tomatoes' end-of-year picks (MDBList by siskourso).",
|
||
Icon: "📅",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 2023,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"best-of-year"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/siskourso/rotten-tomatoes-best-of-2023/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_best_of_2024",
|
||
Title: "Best of 2024",
|
||
Description: "Top-rated 2024 releases from Rotten Tomatoes' end-of-year picks (MDBList by siskourso).",
|
||
Icon: "📅",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 2024,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"best-of-year"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/siskourso/rotten-tomatoes-best-of-2024-ed84tni24k/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_best_of_2025",
|
||
Title: "Best of 2025",
|
||
Description: "Top-rated 2025 releases from Rotten Tomatoes' end-of-year picks (MDBList by siskourso).",
|
||
Icon: "📅",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 2025,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"best-of-year"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/siskourso/rotten-tomatoes-best-of-2025/json"},
|
||
},
|
||
|
||
// ── Charts (MDBList) ───────────────────────────────────────────────────
|
||
// 1000s band. "Top Rated Movies" is already covered by the existing
|
||
// `mdblist_imdb_top_250_movies` template under CategoryTopRated, so this
|
||
// chart only contributes the MovieMeter entry. Its title must NOT be
|
||
// "Popular Movies": bundle apply dedupes by slugified title per library,
|
||
// and `tmdb_popular_movies` already owns the popular-movies slug — a
|
||
// duplicate title would make this template silently skip in all_defaults.
|
||
{
|
||
ID: "mdblist_charts_popular_movies",
|
||
Title: "IMDb MovieMeter Top 100",
|
||
Description: "IMDb MovieMeter's most-popular movies right now, kept in sync from MDBList (linaspurinis).",
|
||
Icon: "📊",
|
||
Category: CategoryPopular,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 1001,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"chart"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/linaspurinis/imdb-moviemeter-top-100/json"},
|
||
},
|
||
|
||
// ── Seasonal / Holiday (MDBList) ───────────────────────────────────────
|
||
// 8000s band. Most entries source from `fuzi0n` for a consistent
|
||
// curatorial style across the holidays they cover. Heritage-month
|
||
// entries come from `k0meta`. Several PMM seasonal entries
|
||
// (St. Patrick's Day, Independence Day, Black History Month, Women's
|
||
// History Month) had no MDBList equivalent and are skipped — see
|
||
// Phase-1 report.
|
||
{
|
||
ID: "mdblist_seasonal_halloween",
|
||
Title: "Halloween",
|
||
Description: "A deep cut of Halloween-coded horror and family fright (MDBList by fuzi0n).",
|
||
Icon: "🎃",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 8001,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"seasonal", "holiday"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/fuzi0n/halloween-movies/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_seasonal_christmas",
|
||
Title: "Christmas",
|
||
Description: "Christmas-themed movies for the holiday season (MDBList by fuzi0n).",
|
||
Icon: "🎄",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 8002,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"seasonal", "holiday"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/fuzi0n/christmas-movies/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_seasonal_valentines_day",
|
||
Title: "Valentine's Day",
|
||
Description: "Romance films for Valentine's Day viewing (MDBList by fuzi0n).",
|
||
Icon: "❤️",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 8003,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"seasonal", "holiday"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/fuzi0n/valentines-day-movies/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_seasonal_easter",
|
||
Title: "Easter",
|
||
Description: "Easter-season films across family and reflective titles (MDBList by fuzi0n).",
|
||
Icon: "🐣",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 8004,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"seasonal", "holiday"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/fuzi0n/easter-movies/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_seasonal_thanksgiving",
|
||
Title: "Thanksgiving",
|
||
Description: "Thanksgiving-themed films for the long-weekend rotation (MDBList by fuzi0n).",
|
||
Icon: "🦃",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 8005,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"seasonal", "holiday"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/fuzi0n/thanksgiving-movies/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_seasonal_new_year",
|
||
Title: "New Year",
|
||
Description: "Films set around New Year's Eve and the turn of the year (MDBList by fuzi0n).",
|
||
Icon: "🎆",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 8006,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"seasonal", "holiday"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/fuzi0n/new-years-movies/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_seasonal_aapi_heritage_month",
|
||
Title: "AAPI Heritage Month",
|
||
Description: "Films and series highlighting Asian American and Pacific Islander voices (MDBList by k0meta).",
|
||
Icon: "🌸",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMixed,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 8007,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"seasonal", "heritage"},
|
||
MDBList: &MDBListSpec{
|
||
URL: "https://mdblist.com/lists/k0meta/asian-american-pacific-islander-heritage-month/json",
|
||
},
|
||
},
|
||
{
|
||
ID: "mdblist_seasonal_latinx_heritage_month",
|
||
Title: "Latinx Heritage Month",
|
||
Description: "Films and series celebrating Latinx storytellers and themes (MDBList by k0meta).",
|
||
Icon: "🌶️",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMixed,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 8008,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"seasonal", "heritage"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/k0meta/latinx-heritage-month/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_seasonal_pride_month",
|
||
Title: "Pride Month",
|
||
Description: "Recent LGBTQ-led films and series — the closest available MDBList proxy for Pride Month (by apollocat).",
|
||
Icon: "🏳️🌈",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMixed,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 8009,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"seasonal", "heritage", "pride"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/apollocat/new-in-lgbtq/json"},
|
||
},
|
||
|
||
// ── Editorial / Misc (MDBList) ─────────────────────────────────────────
|
||
// 9000s band. Studio and distributor catalogs the operator's PMM
|
||
// `movies_misc` set typically includes.
|
||
{
|
||
// Repointed 2026-07: the original shtluck list was deleted on MDBList.
|
||
ID: "mdblist_misc_criterion_collection",
|
||
Title: "Criterion Collection",
|
||
Description: "The Criterion Collection of films, kept in sync from MDBList (reptauros).",
|
||
Icon: "🎞️",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
// No limit: this is a catalog list (~1000 entries) — the collection
|
||
// should hold every Criterion title the library owns, not a top-N.
|
||
DefaultLimit: 0,
|
||
DefaultSortOrder: 9001,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"editorial", "studio"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/reptauros/the-criterion-collection/json"},
|
||
},
|
||
{
|
||
// Repointed 2026-07: the original irvingbeano list was deleted on MDBList.
|
||
ID: "mdblist_misc_a24",
|
||
Title: "A24",
|
||
Description: "Films distributed by A24, kept in sync from MDBList (InShaneMagic).",
|
||
Icon: "🎬",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
// No limit: catalog list (~150 entries) — hold every owned A24 film.
|
||
DefaultLimit: 0,
|
||
DefaultSortOrder: 9002,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"editorial", "studio"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/inshanemagic/a24-films/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_misc_ifc_films",
|
||
Title: "IFC Films",
|
||
Description: "IFC Films movie catalog (MDBList by notamongo5).",
|
||
Icon: "🎬",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 9003,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"editorial", "studio"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/notamongo5/ifc/json"},
|
||
},
|
||
{
|
||
ID: "mdblist_misc_studio_ghibli",
|
||
Title: "Studio Ghibli",
|
||
Description: "Studio Ghibli's animated feature catalog, kept in sync from MDBList (jukebox8786).",
|
||
Icon: "🐉",
|
||
Category: CategoryEditorial,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 9004,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"editorial", "studio"},
|
||
MDBList: &MDBListSpec{URL: "https://mdblist.com/lists/jukebox8786/studio-ghibli-anime/json"},
|
||
},
|
||
|
||
// ── Custom MDBList ─────────────────────────────────────────────────────
|
||
// "Bring your own URL" template that opens the standard MDBList import
|
||
// form so admins can paste any public list URL. Operators who want their
|
||
// own curated MDBList templates can register additional Template values
|
||
// against the Default registry at startup.
|
||
{
|
||
ID: "mdblist_custom",
|
||
Title: "Custom MDBList",
|
||
Description: "Paste any public MDBList JSON URL to seed a synced collection.",
|
||
Icon: "📋",
|
||
Category: CategoryCustom,
|
||
Source: SourceMDBList,
|
||
MediaKind: MediaMixed,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSyncSchedule: "0 6 * * *",
|
||
MDBList: &MDBListSpec{URL: ""},
|
||
},
|
||
|
||
// ── Popular by Genre (TMDB Discover) ─────────────────────────────────────
|
||
// 5000s band. Each entry runs TMDB's /discover/movie endpoint sorted by
|
||
// popularity.desc with a 300-vote floor to keep emerging-but-thin titles
|
||
// from polluting the top of the list. Daily refresh at 04:00 matches the
|
||
// existing tmdb_popular_* cadence.
|
||
{
|
||
ID: "tmdb_discover_popular_action",
|
||
Title: "Popular Action",
|
||
Description: "Crowd-pleasing action films sorted by current TMDB popularity.",
|
||
Icon: "💥",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5001,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{28},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_adventure",
|
||
Title: "Popular Adventure",
|
||
Description: "Trending adventure movies driving the most TMDB attention right now.",
|
||
Icon: "🗺️",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5002,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{12},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_animation",
|
||
Title: "Popular Animation",
|
||
Description: "Animated features riding high on TMDB popularity, from family fare to adult animation.",
|
||
Icon: "🎨",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5003,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{16},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_comedy",
|
||
Title: "Popular Comedy",
|
||
Description: "Comedies pulling the most viewers across TMDB this week.",
|
||
Icon: "😂",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5004,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{35},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_crime",
|
||
Title: "Popular Crime",
|
||
Description: "Heists, mobsters, and procedurals dominating TMDB's crime charts.",
|
||
Icon: "🕵️",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5005,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{80},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_documentary",
|
||
Title: "Popular Documentary",
|
||
Description: "Most-watched documentary features on TMDB right now.",
|
||
Icon: "🎥",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5006,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{99},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_drama",
|
||
Title: "Popular Drama",
|
||
Description: "Drama films riding the top of TMDB's popularity rankings.",
|
||
Icon: "🎭",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5007,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{18},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_family",
|
||
Title: "Popular Family",
|
||
Description: "Family-friendly hits with the biggest current TMDB audience.",
|
||
Icon: "👨👩👧",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5008,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{10751},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_fantasy",
|
||
Title: "Popular Fantasy",
|
||
Description: "Magic, myths, and quests — the fantasy slate trending on TMDB.",
|
||
Icon: "🧙",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5009,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{14},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_history",
|
||
Title: "Popular History",
|
||
Description: "Historical dramas and period pieces ranked by TMDB popularity.",
|
||
Icon: "🏛️",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5010,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{36},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_horror",
|
||
Title: "Popular Horror",
|
||
Description: "The horror titles drawing the biggest TMDB crowds right now.",
|
||
Icon: "👻",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5011,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{27},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_music",
|
||
Title: "Popular Music",
|
||
Description: "Music biopics, concert films, and musicals climbing TMDB's charts.",
|
||
Icon: "🎵",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5012,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{10402},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_mystery",
|
||
Title: "Popular Mystery",
|
||
Description: "Whodunits and puzzlers with the most active TMDB audience.",
|
||
Icon: "🔍",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5013,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{9648},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_romance",
|
||
Title: "Popular Romance",
|
||
Description: "Love stories pulling the most viewers across TMDB's romance shelf.",
|
||
Icon: "💞",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5014,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{10749},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_science_fiction",
|
||
Title: "Popular Science Fiction",
|
||
Description: "Sci-fi blockbusters and cult favourites sorted by TMDB heat.",
|
||
Icon: "🚀",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5015,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{878},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_thriller",
|
||
Title: "Popular Thriller",
|
||
Description: "Tense, fast-moving thrillers ranked by current TMDB popularity.",
|
||
Icon: "🗡️",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5016,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{53},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_war",
|
||
Title: "Popular War",
|
||
Description: "War films and combat dramas trending on TMDB this week.",
|
||
Icon: "⚔️",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5017,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{10752},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_popular_western",
|
||
Title: "Popular Western",
|
||
Description: "Westerns drawing the most TMDB attention, from classics to revisionist tales.",
|
||
Icon: "🤠",
|
||
Category: CategoryPopular,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 5018,
|
||
DefaultSyncSchedule: "0 4 * * *",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{37},
|
||
SortBy: "popularity.desc",
|
||
VoteCountGte: 300,
|
||
},
|
||
},
|
||
|
||
// ── Top Rated by Genre (TMDB Discover) ───────────────────────────────────
|
||
// 6000s band. Sorted by vote_average.desc with a 1000-vote floor — high
|
||
// enough to filter out fluke perfect scores while still leaving room for
|
||
// well-regarded mid-tier titles. Refresh weekly on Sunday at 05:00.
|
||
{
|
||
ID: "tmdb_discover_top_rated_action",
|
||
Title: "Top Rated Action",
|
||
Description: "The highest-scoring action films on TMDB with enough votes to count.",
|
||
Icon: "💥",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6001,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{28},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_adventure",
|
||
Title: "Top Rated Adventure",
|
||
Description: "Best-reviewed adventure films across TMDB, weighted by user votes.",
|
||
Icon: "🗺️",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6002,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{12},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_animation",
|
||
Title: "Top Rated Animation",
|
||
Description: "The animated films TMDB users score highest, from Pixar to anime.",
|
||
Icon: "🎨",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6003,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{16},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_comedy",
|
||
Title: "Top Rated Comedy",
|
||
Description: "The best-rated comedies on TMDB, surfacing classics over flash-in-the-pan hits.",
|
||
Icon: "😂",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6004,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{35},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_crime",
|
||
Title: "Top Rated Crime",
|
||
Description: "The most acclaimed crime films on TMDB, gathered by user vote.",
|
||
Icon: "🕵️",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6005,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{80},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_documentary",
|
||
Title: "Top Rated Documentary",
|
||
Description: "Documentaries with the strongest TMDB scores and a solid vote count.",
|
||
Icon: "🎥",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6006,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{99},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_drama",
|
||
Title: "Top Rated Drama",
|
||
Description: "TMDB's best-rated dramas — character-led, story-first cinema.",
|
||
Icon: "🎭",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6007,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{18},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_family",
|
||
Title: "Top Rated Family",
|
||
Description: "Family films that earn TMDB's highest user scores.",
|
||
Icon: "👨👩👧",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6008,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{10751},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_fantasy",
|
||
Title: "Top Rated Fantasy",
|
||
Description: "Fantasy films with the best TMDB ratings across the genre.",
|
||
Icon: "🧙",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6009,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{14},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_history",
|
||
Title: "Top Rated History",
|
||
Description: "The most acclaimed historical films on TMDB, sorted by vote average.",
|
||
Icon: "🏛️",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6010,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{36},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_horror",
|
||
Title: "Top Rated Horror",
|
||
Description: "The best-rated horror films on TMDB, vote-weighted to keep the bar honest.",
|
||
Icon: "👻",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6011,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{27},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_music",
|
||
Title: "Top Rated Music",
|
||
Description: "Music films that earn TMDB's strongest user reception, from biopics to musicals.",
|
||
Icon: "🎵",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6012,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{10402},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_mystery",
|
||
Title: "Top Rated Mystery",
|
||
Description: "Mystery films with the highest TMDB scores and a healthy vote base.",
|
||
Icon: "🔍",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6013,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{9648},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_romance",
|
||
Title: "Top Rated Romance",
|
||
Description: "Romance films with TMDB's best-loved ratings and a real audience behind them.",
|
||
Icon: "💞",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6014,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{10749},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_science_fiction",
|
||
Title: "Top Rated Science Fiction",
|
||
Description: "Science fiction films at the very top of TMDB's vote averages.",
|
||
Icon: "🚀",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6015,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{878},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_thriller",
|
||
Title: "Top Rated Thriller",
|
||
Description: "Thrillers that crowd the upper end of TMDB's vote averages.",
|
||
Icon: "🗡️",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6016,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{53},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_war",
|
||
Title: "Top Rated War",
|
||
Description: "The most acclaimed war films on TMDB, sorted by user vote average.",
|
||
Icon: "⚔️",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6017,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{10752},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
{
|
||
ID: "tmdb_discover_top_rated_western",
|
||
Title: "Top Rated Western",
|
||
Description: "Westerns with the best TMDB scores, from classic horse operas to modern revisions.",
|
||
Icon: "🤠",
|
||
Category: CategoryTopRated,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 6018,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{37},
|
||
SortBy: "vote_average.desc",
|
||
VoteCountGte: 1000,
|
||
},
|
||
},
|
||
|
||
// ── Kids Movies (TMDB Discover) ──────────────────────────────────────────
|
||
// 9000s band (Misc/Kids slot). Combines TMDB's Family genre with a PG
|
||
// certification ceiling so the result tracks something an actual kid can
|
||
// watch, not just a soft-PG-13 family-marketed action film.
|
||
{
|
||
ID: "tmdb_discover_kids_movies",
|
||
Title: "Kids Movies",
|
||
Description: "Family-genre films capped at a PG certification — safe picks for younger viewers.",
|
||
Icon: "🧸",
|
||
Category: CategoryEditorial,
|
||
Source: SourceTMDBDiscover,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 9050,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
TMDBDiscover: &TMDBDiscoverSpec{
|
||
MediaType: "movie",
|
||
WithGenres: []int{10751},
|
||
SortBy: "popularity.desc",
|
||
CertificationLte: "PG",
|
||
VoteCountGte: 100,
|
||
},
|
||
},
|
||
|
||
// ── Franchises (TMDB Collection) ─────────────────────────────────────────
|
||
// 7000s band. Curated movie franchises that resolve to a TMDB
|
||
// `/collection/{id}` payload. Sort orders are sparsely allocated so
|
||
// future franchise additions can slot in without disturbing existing
|
||
// entries. The placeholder template at 7099 ships with CollectionID=0
|
||
// (a permitted sentinel — see validateTMDBCollection) and an empty sync
|
||
// schedule so applying it produces a collection the admin can edit
|
||
// before any sync runs.
|
||
//
|
||
// Two plan-listed franchises are intentionally absent because TMDB has
|
||
// no usable umbrella collection for them:
|
||
// - Marvel Cinematic Universe (plan ID 86311 resolves to "The
|
||
// Avengers Collection" — a 6-film subset, not the full MCU).
|
||
// - DC Extended Universe (plan ID 573436 resolves to "Spider-Man:
|
||
// Spider-Verse Collection" — completely unrelated; no DCEU
|
||
// umbrella exists on TMDB).
|
||
// Both are best surfaced via TMDB Discover company filters or MDBList
|
||
// in a follow-up; shipping a wrong ID would mis-populate the
|
||
// resulting collection.
|
||
{
|
||
ID: "tmdb_franchise_star_wars",
|
||
Title: "Star Wars Saga",
|
||
Description: "The Skywalker-era Star Wars feature films as catalogued by TMDB.",
|
||
Icon: "⚔️",
|
||
Category: CategoryEditorial,
|
||
Source: SourceTMDBCollection,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 7002,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"franchise"},
|
||
TMDBCollection: &TMDBCollectionSpec{CollectionID: 10},
|
||
},
|
||
{
|
||
ID: "tmdb_franchise_james_bond",
|
||
Title: "James Bond",
|
||
Description: "Six decades of Eon Productions' James Bond films, tracked through TMDB's collection.",
|
||
Icon: "🕴️",
|
||
Category: CategoryEditorial,
|
||
Source: SourceTMDBCollection,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 7003,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"franchise"},
|
||
TMDBCollection: &TMDBCollectionSpec{CollectionID: 645},
|
||
},
|
||
{
|
||
ID: "tmdb_franchise_wizarding_world",
|
||
Title: "Wizarding World",
|
||
Description: "The Harry Potter octalogy — TMDB's canonical Wizarding World grouping (Fantastic Beasts lives in a separate collection).",
|
||
Icon: "🪄",
|
||
Category: CategoryEditorial,
|
||
Source: SourceTMDBCollection,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 7004,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"franchise"},
|
||
TMDBCollection: &TMDBCollectionSpec{CollectionID: 1241},
|
||
},
|
||
{
|
||
ID: "tmdb_franchise_fast_furious",
|
||
Title: "Fast & Furious",
|
||
Description: "Dom's family and every quarter-mile of the Fast & Furious main series.",
|
||
Icon: "🏎️",
|
||
Category: CategoryEditorial,
|
||
Source: SourceTMDBCollection,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 7006,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"franchise"},
|
||
TMDBCollection: &TMDBCollectionSpec{CollectionID: 9485},
|
||
},
|
||
{
|
||
ID: "tmdb_franchise_lord_of_the_rings",
|
||
Title: "The Lord of the Rings",
|
||
Description: "Peter Jackson's three-part adaptation of Tolkien's Middle-earth epic.",
|
||
Icon: "💍",
|
||
Category: CategoryEditorial,
|
||
Source: SourceTMDBCollection,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 7007,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"franchise"},
|
||
TMDBCollection: &TMDBCollectionSpec{CollectionID: 119},
|
||
},
|
||
{
|
||
ID: "tmdb_franchise_hobbit",
|
||
Title: "The Hobbit",
|
||
Description: "The Hobbit prequel trilogy, set in Middle-earth before the One Ring.",
|
||
Icon: "🗡️",
|
||
Category: CategoryEditorial,
|
||
Source: SourceTMDBCollection,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 7008,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"franchise"},
|
||
TMDBCollection: &TMDBCollectionSpec{CollectionID: 121938},
|
||
},
|
||
{
|
||
ID: "tmdb_franchise_jurassic_park",
|
||
Title: "Jurassic Park",
|
||
Description: "Every entry in the Jurassic Park and Jurassic World dinosaur saga.",
|
||
Icon: "🦖",
|
||
Category: CategoryEditorial,
|
||
Source: SourceTMDBCollection,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 7009,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"franchise"},
|
||
TMDBCollection: &TMDBCollectionSpec{CollectionID: 328},
|
||
},
|
||
{
|
||
ID: "tmdb_franchise_pirates_of_the_caribbean",
|
||
Title: "Pirates of the Caribbean",
|
||
Description: "Captain Jack Sparrow's swashbuckling Disney pirate cycle.",
|
||
Icon: "🏴☠️",
|
||
Category: CategoryEditorial,
|
||
Source: SourceTMDBCollection,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 7010,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"franchise"},
|
||
TMDBCollection: &TMDBCollectionSpec{CollectionID: 295},
|
||
},
|
||
{
|
||
ID: "tmdb_franchise_mission_impossible",
|
||
Title: "Mission: Impossible",
|
||
Description: "Ethan Hunt and the IMF across the Mission: Impossible film series.",
|
||
Icon: "💼",
|
||
Category: CategoryEditorial,
|
||
Source: SourceTMDBCollection,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 7011,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"franchise"},
|
||
TMDBCollection: &TMDBCollectionSpec{CollectionID: 87359},
|
||
},
|
||
{
|
||
ID: "tmdb_franchise_monsterverse",
|
||
Title: "MonsterVerse",
|
||
Description: "Legendary's MonsterVerse Godzilla titles — the closest TMDB collection to the Titans cycle.",
|
||
Icon: "👹",
|
||
Category: CategoryEditorial,
|
||
Source: SourceTMDBCollection,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 7012,
|
||
DefaultSyncSchedule: "0 5 * * 0",
|
||
Tags: []string{"franchise"},
|
||
TMDBCollection: &TMDBCollectionSpec{CollectionID: 535313},
|
||
},
|
||
{
|
||
ID: "tmdb_franchise_placeholder",
|
||
Title: "TMDB Franchise",
|
||
Description: "Placeholder for any TMDB collection ID — apply this template via a bundle, then edit the resulting collection's source config to set the franchise ID.",
|
||
Icon: "🎞️",
|
||
Category: CategoryEditorial,
|
||
Source: SourceTMDBCollection,
|
||
MediaKind: MediaMovie,
|
||
DefaultLimit: builtinDefaultLimit,
|
||
DefaultSortOrder: 7099,
|
||
DefaultSyncSchedule: "",
|
||
Tags: []string{"franchise", "placeholder"},
|
||
TMDBCollection: &TMDBCollectionSpec{CollectionID: 0},
|
||
},
|
||
}
|
||
|
||
var builtinBundles = withAllDefaultsBundle([]Bundle{
|
||
{
|
||
ID: "core_defaults",
|
||
Title: "Core Defaults",
|
||
Description: "A focused starter set of movie and TV collections inspired by common Kometa libraries.",
|
||
TemplateIDs: []string{
|
||
"tmdb_trending_movies_week",
|
||
"tmdb_popular_movies",
|
||
"tmdb_top_rated_movies",
|
||
"tmdb_now_playing",
|
||
"tmdb_upcoming",
|
||
"mdblist_imdb_top_250_movies",
|
||
"mdblist_top_documentaries",
|
||
"mdblist_top_horror",
|
||
"mdblist_mindfuck_movies",
|
||
"tmdb_trending_tv_week",
|
||
"tmdb_popular_tv",
|
||
"tmdb_top_rated_tv",
|
||
"tmdb_airing_today",
|
||
"tmdb_on_the_air",
|
||
"mdblist_imdb_top_250_shows",
|
||
},
|
||
},
|
||
{
|
||
ID: "streaming_expanded",
|
||
Title: "Streaming Originals",
|
||
Description: "Provider-specific originals and specialty streaming shelves.",
|
||
TemplateIDs: []string{
|
||
"mdblist_streaming_apple_tv_plus",
|
||
"mdblist_streaming_disney_plus_originals",
|
||
"mdblist_streaming_hbo_max_originals",
|
||
"mdblist_streaming_hulu_originals",
|
||
"mdblist_streaming_netflix_originals",
|
||
"mdblist_streaming_peacock_originals",
|
||
"mdblist_streaming_prime_video_originals",
|
||
"mdblist_streaming_shudder",
|
||
},
|
||
},
|
||
{
|
||
ID: "awards_and_years",
|
||
Title: "Awards & Yearly Picks",
|
||
Description: "Oscar, Golden Globe, yearly best-of, and movie chart collections.",
|
||
TemplateIDs: []string{
|
||
"mdblist_awards_oscar_winners",
|
||
"mdblist_awards_golden_globes_winners",
|
||
"mdblist_best_of_2023",
|
||
"mdblist_best_of_2024",
|
||
"mdblist_best_of_2025",
|
||
"mdblist_charts_popular_movies",
|
||
},
|
||
},
|
||
{
|
||
ID: "seasonal_collections",
|
||
Title: "Seasonal Collections",
|
||
Description: "Holiday, observance, and calendar-driven collection shelves.",
|
||
TemplateIDs: []string{
|
||
"mdblist_seasonal_halloween",
|
||
"mdblist_seasonal_christmas",
|
||
"mdblist_seasonal_valentines_day",
|
||
"mdblist_seasonal_easter",
|
||
"mdblist_seasonal_thanksgiving",
|
||
"mdblist_seasonal_new_year",
|
||
"mdblist_seasonal_aapi_heritage_month",
|
||
"mdblist_seasonal_latinx_heritage_month",
|
||
"mdblist_seasonal_pride_month",
|
||
},
|
||
},
|
||
{
|
||
ID: "studio_collections",
|
||
Title: "Studios & Labels",
|
||
Description: "Curated studio, label, and collection-brand shelves.",
|
||
TemplateIDs: []string{
|
||
"mdblist_misc_criterion_collection",
|
||
"mdblist_misc_a24",
|
||
"mdblist_misc_ifc_films",
|
||
"mdblist_misc_studio_ghibli",
|
||
},
|
||
},
|
||
{
|
||
ID: "popular_genres",
|
||
Title: "Popular Genres",
|
||
Description: "TMDB Discover genre shelves sorted by current popularity.",
|
||
TemplateIDs: []string{
|
||
"tmdb_discover_popular_action",
|
||
"tmdb_discover_popular_adventure",
|
||
"tmdb_discover_popular_animation",
|
||
"tmdb_discover_popular_comedy",
|
||
"tmdb_discover_popular_crime",
|
||
"tmdb_discover_popular_documentary",
|
||
"tmdb_discover_popular_drama",
|
||
"tmdb_discover_popular_family",
|
||
"tmdb_discover_popular_fantasy",
|
||
"tmdb_discover_popular_history",
|
||
"tmdb_discover_popular_horror",
|
||
"tmdb_discover_popular_music",
|
||
"tmdb_discover_popular_mystery",
|
||
"tmdb_discover_popular_romance",
|
||
"tmdb_discover_popular_science_fiction",
|
||
"tmdb_discover_popular_thriller",
|
||
"tmdb_discover_popular_war",
|
||
"tmdb_discover_popular_western",
|
||
"tmdb_discover_kids_movies",
|
||
},
|
||
},
|
||
{
|
||
ID: "top_rated_genres",
|
||
Title: "Top Rated Genres",
|
||
Description: "TMDB Discover genre shelves sorted by vote average with vote floors.",
|
||
TemplateIDs: []string{
|
||
"tmdb_discover_top_rated_action",
|
||
"tmdb_discover_top_rated_adventure",
|
||
"tmdb_discover_top_rated_animation",
|
||
"tmdb_discover_top_rated_comedy",
|
||
"tmdb_discover_top_rated_crime",
|
||
"tmdb_discover_top_rated_documentary",
|
||
"tmdb_discover_top_rated_drama",
|
||
"tmdb_discover_top_rated_family",
|
||
"tmdb_discover_top_rated_fantasy",
|
||
"tmdb_discover_top_rated_history",
|
||
"tmdb_discover_top_rated_horror",
|
||
"tmdb_discover_top_rated_music",
|
||
"tmdb_discover_top_rated_mystery",
|
||
"tmdb_discover_top_rated_romance",
|
||
"tmdb_discover_top_rated_science_fiction",
|
||
"tmdb_discover_top_rated_thriller",
|
||
"tmdb_discover_top_rated_war",
|
||
"tmdb_discover_top_rated_western",
|
||
},
|
||
},
|
||
{
|
||
ID: "franchise_collections",
|
||
Title: "Franchise Collections",
|
||
Description: "TMDB franchise and saga collections for major movie series.",
|
||
TemplateIDs: []string{
|
||
"tmdb_franchise_star_wars",
|
||
"tmdb_franchise_james_bond",
|
||
"tmdb_franchise_wizarding_world",
|
||
"tmdb_franchise_fast_furious",
|
||
"tmdb_franchise_lord_of_the_rings",
|
||
"tmdb_franchise_hobbit",
|
||
"tmdb_franchise_jurassic_park",
|
||
"tmdb_franchise_pirates_of_the_caribbean",
|
||
"tmdb_franchise_mission_impossible",
|
||
"tmdb_franchise_monsterverse",
|
||
"tmdb_franchise_placeholder",
|
||
},
|
||
},
|
||
})
|
||
|
||
func withAllDefaultsBundle(bundles []Bundle) []Bundle {
|
||
seen := make(map[string]struct{})
|
||
allTemplateIDs := make([]string, 0)
|
||
for _, bundle := range bundles {
|
||
for _, id := range bundle.TemplateIDs {
|
||
if _, ok := seen[id]; ok {
|
||
continue
|
||
}
|
||
seen[id] = struct{}{}
|
||
allTemplateIDs = append(allTemplateIDs, id)
|
||
}
|
||
}
|
||
|
||
allDefaults := Bundle{
|
||
ID: "all_defaults",
|
||
Title: "All Defaults",
|
||
Description: "Every default bulk-add template, including core, streaming, awards, seasonal, genre, and franchise collections.",
|
||
TemplateIDs: allTemplateIDs,
|
||
}
|
||
|
||
out := make([]Bundle, 0, len(bundles)+1)
|
||
out = append(out, allDefaults)
|
||
out = append(out, bundles...)
|
||
return out
|
||
}
|
||
|
||
func init() {
|
||
for _, t := range builtinTemplates {
|
||
if t.PosterPath == "" {
|
||
t.PosterPath = defaultPosterPath(t.ID)
|
||
}
|
||
Default.Register(t)
|
||
}
|
||
for _, b := range builtinBundles {
|
||
Default.RegisterBundle(b)
|
||
}
|
||
}
|
||
|
||
func defaultPosterPath(templateID string) string {
|
||
if templateID == "" {
|
||
return ""
|
||
}
|
||
return "/images/collection-templates/" + templateID + ".jpg"
|
||
}
|