easyplaytv-service/…/providers/blaze_vod.py — Blaze TV catalogue
The full catalogue scraper ships in the shared runtime at easyplaytv-service/src/easyplaytv_service/vod_sync/providers/blaze_vod.py (and the vendored copy inside service.easyplaytv). The video addon keeps only the playback half (resources/lib/blaze_vod.py: resolve_vod). Functions and line numbers below refer to the runtime copy.
Role
Blaze has no JSON API. Everything is page-scraped HTML. This module covers the catalogue (list of shows), seasons, episodes. Blaze is the smallest of the addon's providers — only ~30 series — so the inefficiency of HTML scraping is acceptable.
Constants
The URL roots. The per-episode streams/api/replay/stream/…
playback endpoint is built by the addon's blaze.py
resolver at play time using the stream_key /
stream_uvid values list_episodes scrapes.
Listing functions
No pagination — Blaze returns the entire series catalogue in one HTML page. The function:
- Fetches
URL_SERIES. - Iterates over each col-auto layout-carousel-column div (a Bootstrap carousel card). Each card describes one show.
- For each card takes an 8 000-char chunk starting at the div's match position (line 14) — small enough to avoid matching into the next card, big enough to capture all the meta we need.
- Pulls the show's URL out of the href: 'https://watch.blaze.tv/shows/...' JSON-ish attribute that the Blaze page injector emits.
- The card-img-top img alt=… attribute is the title (filters out the Logo title that's the brand image).
- Episode count pulled from the data-content-type="episodes" tag's
adjacent
N Episodesspan text.
Returns a flat list with title, f_name (the per-show URL), image, description, episodes count.
The resolver is entirely regex-driven. If Blaze's HTML team changes their carousel class names or HTML shape, this breaks silently — you'll see empty catalogues. No fallback path; no JSON API to fall back to.
Fetches a per-show page (the f_name stored in list_shows), finds
id="season- elements (Bootstrap tab pattern), and
builds a seasons list. If no seasons are found on the page, fabricates a
synthetic "Episodes" season with season_id=0 (the Kodi specials block) to
avoid empty listings for single-season shows Blaze didn't bother to flag.
Triple-returns (seasons, html, stream_base) from the show page
so a caller that then needs to enumerate episodes doesn't
have to re-fetch the page. Sizes of HTML
are bounded by list_seasons' fetch and reused downstream
(list_episodes(html, …) consumes the already-fetched markup).
Consumes the already-fetched html from list_seasons
— does NO additional HTTP fetch. Walks the
id="seasonsContent" section in the HTML, parses per-episode
cards. Filters by season_number when supplied. Each episode dict has
title, image, stream_key (per-episode
data-key) and stream_uvid (per-episode
data-uvid) — the pair Blaze's replay endpoint requires for VOD
playback, plus parsed season_number/episode_number and
duration.
Same "streams":"…" JSON config pattern that blaze.py uses for live — extracts the Blaze streams base URL the per-episode player uses. Without it the VOD episodes would resolve to the wrong (default) streams endpoint.