strm.py — removed (pre-split URL builders & show fetchers)
The strm.py module was deleted in the 3-package split. Its
responsibilities were absorbed into the shared runtime:
- Provider show aggregation +
_nav_*tagging now happens in library_sync.py's per-provider sync branches (_sync_movies/_sync_series). - The
plugin://URL synthesis is folded into_insert_movie/_insert_episodein library_sync.py. - Provider catalogue scrapers ship in
easyplaytv-service/src/easyplaytv_service/vod_sync/providers/.
The detail below is retained purely as historical record of the pre-split architecture — none of the functions documented exist anymore.
Role
Two responsibilities (the module name strm is historical —
the addon does not write .strm files on disk; all episode and
movie files live as plugin:// URLs in
PLUGIN_SOURCE_PATH rows in the Kodi DB):
- Show aggregation — call every provider's
list_showsfor every unified genre and return a single flat list withprovider,_genre_id,_nav_mode, and the provider-specific_nav_*fields baked in. - URL synthesis — given one of those show dicts (or a
single episode dict from
list_episodes), build aplugin://plugin.video.easyplaytv/?action=resolve_vod&provider=…&episode_id=…&…URL that Kodi's plugin entry point can route to the right resolver.
Module-level constants (lines 11–15)
STRM_MOVIES_DIR and STRM_SERIES_DIR are
defined at module load but never referenced by any function in this
module — the addon does not write .strm files on disk;
all episode and movie file rows live as plugin://… URLs
under PLUGIN_SOURCE_PATH in the Kodi DB.
STATE_FILE points at strm_state.json, but the
live state file the sync engine reads is
library_sync_state.json + series_sync_state.json
(see library_sync.py).
The three constants exist purely for historical traceability — safe to
delete them in a refactor.
STRM_DIR (line 12) is still used — through
_plugin_lib at line 17 it sets up sys.path so
the bare-name from genres import … at line 23 resolves
whether the module is imported from inside Kodi or run standalone.
Provider import dispatcher
Lazy-imports the right *_vod module for a provider name.
The try/except pattern handles two import conventions — Kodi's
resources.lib.bbc_vod vs. the same module imported bare
(bbc_vod) for tests run outside Kodi.
Films / series fetchers
The movie catalog aggregator. Iterates UNIFIED_GENRES for
the films genre only, then per-provider per-genre call lists
the films with provider-appropriate pagination:
| Provider | Pagination |
|---|---|
| BBC | Page-based loop until cur_page >= total_pages |
| My5 | Offset-based with 100-row limit, stops when offset >= total_entries |
| ITVX | Single call — ITVX paginates internally and returns the full category payload |
| C4 | Single call with limit=9999 — C4's API caps at ~10k rows |
| STV | Filters to show.standalone == True only (single-film programmes) |
Each show dict gets s["provider"] = " added so
downstream code knows where it came from.
The series equivalent — iterates every unified genre except
films. More importantly, it tags each show with
_nav_mode (either "playable" for
standalone/movie-like shows or "series" for shows with multiple
episodes) and the provider-specific _nav_* fields that
_sync_series uses to
fetch seasons/episodes:
| Provider | Series mode fields | Playable mode condition |
|---|---|---|
| BBC | _nav_pid | show.get("standalone") and show.get("episode_id") |
| My5 | _nav_f_name | show.get("standalone") |
| ITVX | _nav_prog_id, _nav_slug | show.get("standalone") and show.get("episode_id") |
| C4 | _nav_f_name | always series (C4 doesn't tag standalone at API level) |
| STV | _nav_f_name | show.get("standalone") |
The _nav_* pre-pass meant the sync layer didn't have to know
each provider's id-field naming.
Movie URL builder
Builds a play URL for a movie show. Returns None if the
show isn't standalone (it's actually a series — movies that are
multi-episode specials shouldn't be treated as a single-play movie). For
providers where every film needs an episode lookup (C4, STV),
this function does a live season-list call to find the single
episode:
- BBC:
resolve_vod&provider=bbc&episode_id=&title=… - My5:
resolve_vod&provider=my5&episode_id=&standalone=1&title=… - ITVX:
resolve_vod&provider=itvx&episode_id=…&title=…&playlist_url= - C4: calls
c4_vod.list_seasons(f_name), requires exactly 1 episode, builds URL with bothprogramme_idandasset_id - STV: iterates
stv_vod.list_seasons(), then iterates the result for the firstvideo_idit finds with a DRM flag
Note: All URLs are URL-encoded via safe_filename(show["title"])
for the title parameter.
The STV branch references episodes at line 173 without
defining it — looks like a refactor removed
episodes = vod.list_episodes(...) but missed the
if not episodes: return None guard. The code will throw a
NameError on first STV movie. In practice nobody's noticed
because STV's "films" catalogue is mostly empty in the production library.
Worth fixing; tag a one-liner episodes = vod.list_episodes(f_name, series_guid=series_guid)
back in.
Episode URL builder
Builds a play URL for a single episode within a series. Always includes
the season + episode numbers in the URL via the _se() helper
(lines 216-222) — even though the resolver doesn't strictly need them, the
plugin entry-point reads them onto the listitem's setInfo
so Kodi caches consistent SxxExx metadata for the played file. Without
them, the displayed 1x01. prefix disappears after playback
because the player's metadata overwrites the folder's listitem metadata
(see the inline comment at line 205).
| Provider | Extra params beyond episode_id, title, season, episode |
|---|---|
| BBC | show_title (extracted via _bbc_ep_title) |
| My5 | standalone=0/1, show_f_name, f_name (if different) |
| ITVX | playlist_url (URL-encoded) |
| C4 | asset_id |
| STV | drm_enabled=0/1 |
Helper for BBC episode titles. BBC programmes often have a "Series N:"
subtitle pattern; this strips that prefix and falls back to the bare
subtitle or just "Episode N". Used only inside
_build_episode_strm_url for BBC.
Cross-file interactions
- Importing
safe_filenamefor title normalisation across all URL builders. - Calling
c4_vod.list_seasons()andstv_vod.list_seasons()inline within_build_strm_url— these were sync-time HTTP fetches, so the cost was folded into the slower of the two paths (movie catalog fetch). - Returning flat lists that the sync layer filtered by
_nav_mode == "series"andprovider.