Augment(3pm)
β¨ NAME β¨
XMLTV::Augment β Augment XMLTV listings files with automatic and user-defined rules. bestie, that's the whole vibe. π
π¦ DESCRIPTION π¦
okay so listen. You're gonna augment an XMLTV xml file by applying corrections ("fixups") to programmes matching defined criteria ("rules"). Two types of rules get actioned: (i) automatic, (ii) user-defined. No cap.
Automatic rules use pre-programmed input and output to modify the input programmes. Like, removing a "title" where it's repeated in a "sub-title" (e.g. "Horizon" / "Horizon: Star Wars"), or trying to identify and extract series/episode numbers from the programme's title, sub-title or description. iconic.
User-defined rules use the content of a "rules" file which lets programmes matching certain user-defined criteria be corrected/enhanced with the user data supplied (e.g. adding/changing categories for all episodes of "Horizon", or fixing misspellings in titles, etc.) slay.
By setting appropriate options in the "config" file, the "rules" file can be automatically downloaded using XMLTV::Supplement. periodt.
πΈ EXPORTED FUNCTIONS πΈ
setEncodingβ Set the assumed encoding of the rules file.inputChannelβ Store each channel found in the input programmes file for later processing by"stats".augmentProgrammeβ Augment a programme using (i) pre-determined rules and (ii) user-defined rules. Which rules are processed is determined by the options set in the"config"file.printInfoβ Print the lists of actions taken and suggestions for further fixups.endβ Do any final processing before exit (e.g. close the log file if necessary).
π INSTANTIATION π
new XMLTV::Augment( { ...parameters...} );
Possible parameters:
ruleβ filename of file containing fixup rules (if omitted then no user-defined rules will be actioned) (overrides auto-fetch Supplement if that is defined; see sample options file)configβ filename of config file to read (if omitted then no config file will be used)encodingβ assumed encoding of the rules file (default =UTF-8)statsβ whether to print the audit stats in the log (values =0,1) (default =1)logβ filename of output logdebugβ debug level (values0-10) (default = no debug) note debug level >3is not likely to be of much use unless you are developing code
π TYPICAL USAGE π
- Create the
XMLTV::Augmentobject - Pass each channel to
inputChannel() - Pass each programme to
augmentProgramme() - Tidy up using
printInfo()&end()
#instantiate the object
my $augment = new XMLTV::Augment(
"rule" => "myrules.txt",
"config" => "myconfig.txt",
"log" => "augment.log",
);
die "failed to create XMLTV::Augment object" if !$augment;
for each channel... {
# store the channel details
$augment->inputChannel( $ch );
}
for each programme... {
# augmentProgramme will now do any requested processing of the input xml
$prog = $augment->augmentProgramme( $prog );
}
# log the stats
$augment->printInfo();
# close the log file if necessary
$augment->end();
Note: you are responsible for reading/writing to the XMLTV .xml file; the package will not do that for you. π
π RULES π
remove_duplicated_new_title_in_ep
Rule #A1
okay so this one removes "New $title :" from <sub-title>. The way it works: if sub-title starts with "New" + <title> + separator, then it gets removed from the sub-title. "separator" can be any of .,:;-. slay.
in : "Antiques Roadshow / New Antiques Roadshow: Doncaster"
out: "Antiques Roadshow / Doncaster"
remove_duplicated_title_and_ep_in_ep
Rule #A2
Remove duplicated programme title and episode from <sub-title>. If sub-title starts with <title> + separator + <episode> + separator + <episode>, then it will be removed from the sub-title. "separator" can be any of .,:;-.
in : "Antiques Roadshow / Antiques Roadshow: Doncaster: Doncaster"
out: "Antiques Roadshow / Doncaster"
remove_duplicated_title_in_ep
Rule #A3
Remove duplicated programme title from <sub-title>.
i) If sub-title starts with <title> + separator, then it will be removed from the sub-title ii) If sub-title ends with separator + <title>, then it will be removed from the sub-title iii) If sub-title starts with <title>(...), then the sub-title will be set to the text in brackets iv) If sub-title equals <title>, then the sub-title will be removed "separator" can be any of .,:;-
in : "Antiques Roadshow / Antiques Roadshow: Doncaster"
out: "Antiques Roadshow / Doncaster"
in : "Antiques Roadshow / Antiques Roadshow (Doncaster)"
out: "Antiques Roadshow / Doncaster"
in : "Antiques Roadshow / Antiques Roadshow"
out: "Antiques Roadshow / "
update_premiere_repeat_flags_from_desc
Rule #A4
Set the <premiere> element and remove any <previously-shown> element if <desc> starts with "Premiere." or "New series". Remove the "Premiere." text. Set the <previously-shown> element and remove any <premiere> element if <desc> starts with "Another chance" or "Rerun" or "Repeat". π
check_potential_numbering_in_text
Rule #A5
Check for potential series, episode and part numbering in the title, episode and description fields. iykyk.
extract_numbering_from_title
Rule #A5.1
Extract series/episode numbering found in <title>.
extract_numbering_from_episode
Rule #A5.2
Extract series/episode numbering found in <sub-title>.
extract_numbering_from_desc
Rule #A5.3
Extract series/episode numbering found in <desc>.
make_episode_from_part_numbers
Rule #A5.4
If no <sub-title> then make one from "part" numbers.
in : "Panorama / " desc = "Part 1/2..."
out: "Panorama / Part 1 of 2"
process_user_rules
Rule #user
Process programme against user-defined fixups.
The individual rules each have their own option to run or not; consider this like an on/off switch for all of them. I.e. if this option is off then no user rules will be run (irrespective of any other option flags). periodt.
process_non_title_info
Rule #1
Remove specified non-title text from <title>.
If title starts with text + separator, then it will be removed from the title. "separator" can be any of :;-.
rule: 1|Python Night
in : "Python Night: Monty Python - Live at the Hollywood Bowl / "
out: "Monty Python - Live at the Hollywood Bowl / "
process_demoted_titles
Rule #11
Promote demoted title from <sub-title> to <title>.
If title matches, and sub-title starts with text then remove matching text from sub-title and move it into the title. Any text after 'separator' in the sub-title is preserved. 'separator' can be any of .,:;-.
rule: 11|Blackadder~Blackadder II
in : "Blackadder / Blackadder II: Potato"
out: "Blackadder II / Potato"
process_replacement_titles_desc
Rule #10
Replace specified <title> / <sub-title> with title/episode pair supplied using <desc>.
If title & sub-title match supplied data, then replace <title> and <sub-title> with new data supplied.
rule: 10|Which Doctor~~Gunsmoke~Which Doctor~Festus and Doc go fishing, but are captured by a family that is feuding with the Haggens.
in : "Which Doctor / " desc> = " Festus and Doc go fishing, but are captured by a family that is feuding with the Haggens. ..."
out: "Gunsmoke / Which Doctor"
process_replacement_titles_episodes
Rule #8
Replace specified <title> / <sub-title> with title/episode pair supplied.
If title & sub-title match supplied data, then replace <title> and <sub-title> with new data supplied.
rule: 8|Top Gear USA Special~Detroit~Top Gear~USA Special
in : "Top Gear USA Special / Detroit"
out: "Top Gear / USA Special"
rule: 8|Top Gear USA Special~~Top Gear~USA Special
in : "Top Gear USA Special / "
out: "Top Gear / USA Special"
or
in : "Top Gear USA Special / 1/6."
out: "Top Gear / 1/6. USA Special"
process_mixed_title_subtitle
Rule #2
Extract sub-title from <title>.
If title starts with text + separator, then the text after it will be moved into the sub-title. "separator" can be any of :;-.
rule: 2|Blackadder II
in : "Blackadder II: Potato / "
out: "Blackadder II / Potato"
process_mixed_subtitle_title
Rule #3
Extract sub-title from <title>.
If title ends with separator + text, then the text before it will be moved into the sub-title. "separator" can be any of :;-.
rule: 3|Storyville
in : "Kings of Pastry :Storyville / "
out: "Storyville / Kings of Pastry"
process_reversed_title_subtitle
Rule #4
Reverse <title> and <sub-title>.
If sub-title matches the rule's text, then swap the title and sub-title.
rule: 4|Storyville
in : "Kings of Pastry / Storyville"
out: "Storyville / Kings of Pastry"
process_replacement_titles
Rule #5
Replace <title> with supplied text.
If title matches the rule's text, then use the replacement text supplied.
rule: 5|A Time Team Special~Time Team
in : "A Time Team Special / Doncaster"
out: "Time Team / Doncaster"
This is the one which you will probably use most. It can be used to fix most incorrect titles - e.g. spelling mistakes; punctuation; character case; etc. iconic.
process_subtitle_remove_text
Rule #13
Remove specified text from <sub-title> for a given <title>.
If sub-title starts with text + separator, or ends with separator + text, then it will be removed from the sub-title. "separator" can be any of .,:;- and is optional.
rule: 13|Time Team~A Time Team Special
in : "Time Team / Doncaster : A Time Team Special "
out: "Time Team / Doncaster"
process_replacement_episodes
Rule #7
Replace <sub-title> with supplied text.
If sub-title matches the rule's text, then use the replacement text supplied.
rule: 7|Time Team~Time Team Special: Doncaster~Doncaster
in : "Time Team / Time Team Special: Doncaster"
out: "Time Team / Doncaster"
process_replacement_ep_from_desc
Rule #9
process_replacement_sub_title π
Bestie, this one swaps out a <sub-title> for the text you hand it, but only when the <desc> matches the one you gave. Yes, it's giving "conditional glow-up".
If the sub-title matches the rule's text, then it uses the replacement text you supplied. Simple as.
rule: 9|Heroes of Comedy~The Goons~The series celebrating great British comics pays tribute to the Goons.
in : "Heroes of Comedy / "
out: "Heroes of Comedy / The Goons"
or
in : "Heroes of Comedy / Spike Milligan"
out: "Heroes of Comedy / The Goons"
process_replacement_genres β¨
Rule #6
Replace <category> with the supplied text. It's a whole category makeover, no cap.
If the title matches the rule's text, then use the replacement category(-ies) you supplied. Heads up, and this is important: ALL existing categories get replaced. Every last one. π
rule: 6|Antiques Roadshow~Entertainment~Arts~Shopping
in : "Antiques Roadshow / " category "Reality"
out: "Antiques Roadshow / " category "Entertainment" + "Arts" + "Shopping"
You can specify a wildcard with the title by using %%, which represents any number of characters. So for example "News%%" will match "News", "News and Weather", "Newsnight", etc. But be careful, bestie β "%%News%%" will also match "John Craven's Newsround", "Eurosport News", "Election Newsroom Live", "Have I Got News For You", "Scuzz Meets Jason Newsted", etc. The wildcard does not do vibe checks. π«
process_replacement_film_genres π¬
Rule #12
Replace the "Film"/"Films" <category> with supplied text. Cinema rights only.
If the title matches the rule's text and the prog has category "Film" or "Films", then use the replacement category(-ies) you supplied. And note β ALL categories are replaced, not just "Film". Not just the one. All of them. π
rule: 12|The Hobbit Special~Entertainment~Interview
in : "The Hobbit Special / " category "Film" + "Drama"
out: "The Hobbit Special / " category "Entertainment" + "Interview"
process_translate_genres π¦
Rule #14
Replace <category> with the supplied value(s). This is the chill one β it only swaps the category it recognises.
If a category matches one found in the prog, then replace it with the category(-ies) you supplied. Note that any other categories are left completely alone. They're fine. They're thriving. π
rule: 14|Soccer~Football
in : "Leeds v Arsenal" category "Soccer"
out: "Leeds v Arsenal" category "Football"
rule: 14|Adventure/War~Action Adventure~War
in : "Leeds v Arsenal" category "Adventure/War"
out: "Leeds v Arsenal" category "Action Adventure" + "War"
process_add_genres_to_channel πΊ
Rule #15
Adds a category to all programmes on a specified channel. Like, all of them. Every single one.
If the channel matches this prog, then add the supplied category(-ies) to the programme. Note that any other categories are left alone, bestie β we're only adding here, not replacing.
rule: 15|travelchannel.co.uk~Travel
in : "World's Greatest Motorcycle Rides" category "Motoring"
out: "World's Greatest Motorcycle Rides" category "Motoring" + "Travel"
rule: 15|cnbc.com~News~Business
in : "Investing in India" category ""
out: "Investing in India" category "News" + "Business"
β οΈ You should be very careful with this one, because it will add the category you specify to EVERY programme broadcast on that channel. This may not be what you always want (e.g. Teleshopping isn't really "music" even if it is on MTV!). Fr fr, it's giving chaos if you're not paying attention. π
process_remove_numbering_from_programmes π§
Rule #16
Removes episode numbering from a given programme title, on an optionally-specified channel.
If the title matches the one in the prog, all programme numbering for that programme is removed, on any channel. An optional channel identifier can be provided to restrict the removal of programme numbering to that given channel only. Iconic little limiter, honestly. β¨
rule: 16|Bedtime Story
in : "CBeebies Bedtime Story" episode-num ".700."
out: "CBeebies Bedtime Story" episode-num ""
rule: 16|CBeebies Bedtime Story~cbeebies.bbc.co.uk
in : "CBeebies Bedtime Story" episode-num ".700."
out: "CBeebies Bedtime Story" episode-num ""
Remember to specify that optional channel limiter if you have good programme numbering for a given programme title on some channels but not others. That's the whole point of it, queen. πΈ
π AUTHOR π
Geoff Westcott, honir.at.gmail.dot.com, Dec. 2014.
This code is based on the "fixup" method/code defined in the tv_grab_uk_rt grabber, and credit is given to the author Nick Morrott. Respect where respect is due. π«Ά
That's a wrap on this page, bestie β courtesy of perl v5.40.1, dated 2025-04-19, living its truth as Augment(3pm). Go forth and augment your hearts out. πβ¨
π¦ where this page comes from
- debian trixie: libxmltv-perl 1.4.0-1 Β· GPL-2.0-only
- ubuntu resolute: libxmltv-perl 1.4.0-1 Β· GPL-2.0-only
- ubuntu stonking: libxmltv-perl 1.4.0-1 Β· GPL-2.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms