Repository navigation
feat(xmltv): a title's episode numbering is read off it - #32
Merged
Merged
Conversation
Many sources give no episode number of their own and write it into the
title instead: "Duel S01E99", "Komisár Rex III (13)", "Robogobo: Season 1".
A guide built from them shows the numbering as part of the series' name, and
homepi carries a parser for it in three of its sites.
`parseTitleNumbering(title, { patterns? })` takes it off, as `{ title,
season?, seasons?, episode?, episodes?, part?, parts?, subTitle? }`. The
built-in forms are English or need no language: the `onscreen` grammar
`parseOnscreenEpisodeNum` reads, with the season required; "Season 4
Episode 5" and "Episode 4"; a Roman season before "(13)"; "(6/12)"; and
": Season 1". A source's own words are patterns, regular expressions with
named groups matched against the whole title, tried before the built-in
ones. The guards are as much the point as the forms: "Spinal Tap II",
"(2019)", "(2023/24)", "Poprask na silnici E4", "CIVIL (2)" and "Malcolm X
(2)" stay as they are. `stripTitleSeason(title, season)` takes off a season
a source also gives apart, a bare numeral included.
`programme(start, title, { numbered: true })` does it as a programme is
built. The title is rewritten, and the numbers and the sub-title are written
where the site gives none of its own. An `.episode()` call fills in what it
leaves out from the title's numbers, each where the call agrees with what it
belongs to: the season for a call naming none, the episode only for a call
naming no other season. `fromTitle: false`, on `numbered` or on one call,
has a call's numbers stand alone. A builder without `numbered` does no more
than it did.
`.episode()` given a part and no total of parts writes the part with no
total, rather than "part 2 of 1".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Many sources write the episode number into the title instead of a field of its own: "Duel S01E99", "Komisár Rex III (13)", "Robogobo: Season 1". The guide then shows the numbering as part of the series' name. homepi has a parser for this in three of its sites. This PR moves it into
epg-tools/xmltv, with English built-in forms and room for a source's own.What's added
parseTitleNumbering(title, { patterns? })returns{ title, season?, seasons?, episode?, episodes?, part?, parts?, subTitle? }.onscreengrammarparseOnscreenEpisodeNumreads, with the season required (S01E02,S01 Ep 5,S1/3E2/10,S01E02 P1/2);Season 4 Episode 5andEpisode 4;(13);(6/12);: Season 1.titlegroup throws the first time it's used.stripTitleSeason(title, season, { patterns? })removes a season the source also gives in a field, including a bare trailing numeral ("Zločin III" with season 3 gives "Zločin").programme(start, title, { numbered })onProgrammeBuilderandctx.programme:build()returns where the site gives none of its own..episode()call fills in what it leaves out from the title's numbers, each only where the call agrees with what that number belongs to.fromTitle: false, onnumberedor on a single call, makes a call's numbers stand alone.TitleNumbering,TitleNumberingOptionsandNumberedOptions.Guards
What the parser leaves alone matters as much as what it reads. These stay as they are:
.+?\s+backtracking is quadratic on long runs of whitespace.Known misreadings, documented: "Louis XIV (3)" (a regnal number), "Star Wars: Episode 1 - …" (a film named as an episode), a bracketed age rating "(18)", and a daily soap's "(1999)". A source can read the soap's number with its own pattern, since those are tried first.
How the builder fills in from the title
.episode(113)on "Komisár Rex III (13)` gives S03E113..episode(null, 4)gives season 4 alone, not season 4's episode 13.build()unless an.episode()call wrote numbers or the site added its ownxmltv_nsoronscreenentry. They were taken off the title, so a call that wrote nothing doesn't lose them.build()doesn't change the builder: it adds these to a copy, so a.subTitle()or.episode()after one build still wins at the next.Other changes
.episode()given a part and no total now writes the part with no total. It used to write "part 2 of 1", which is invalidxmltv_ns. This was a bug before this branch.onscreengrammar inepisode-num.tsis split into two fragments, so the title form reuses it instead of keeping a second, narrower copy.NumberedOptionsis exported as a type from the root and fromepg-tools/grabber, next toProgrammeOptions.Performance
A builder without
numberedkeeps all title state in one field that staysundefined, and itsbuild()returns straight away. Benchmarked withmain's builder and this one loaded in the same process and run alternately, 100k programmes with.episode()and.build(): the medians are the same within noise (142.8 ms onmainagainst 140.6 ms here).Testing
test/title-numbering.test.tsports homepi's cases. Its Slovak and Hungarian forms run as custom patterns, which also shows the built-in forms leave them alone.fromTitle, building more than once, sub-titles and parts. A grabber test checks thatnumberedpasses throughctx.programme.test/readme-examples.ts.Not in this PR
A site-level
numberedoption, which would also cover Xtream, Schedules Direct and plain programme objects. That's new public API and is left for a separate decision.