#!/usr/bin/perl -w # # add_time_info # # Quick kludge for testing output from two different grabbers. # Sometimes one listings source will be more informative than another # about the timing of programmes. Whereas the old source gave two # programmes sharing a clump from 11:00 to 12:00, the new one tells # you that one runs from 11:00 to 11:35 and the second from 11:35 to # 12:00. So the new listings source gives more information, but when # diffing the results there will be a discrepancy and seeming 'error'. # The answer is to patch up the old results where they agree with, but # are less detailed than, the new. # # Usage: reads 'less detailed' listings from stdin and 'more detailed' # given as a filename argument, outputs fixed-up version of 'less # detailed' to stdout. use strict; use XMLTV; # Use Log::TraceMessages if installed. BEGIN { eval { require Log::TraceMessages }; if ($@) { *t = sub {}; *d = sub { '' }; } else { *t = \&Log::TraceMessages::t; *d = \&Log::TraceMessages::d; } } # Use 'old' to mean the listings read from stdin, 'new' for those # given as an argument. Just as a shorthand. # my $old_data = XMLTV::parsefile('-'); my $new_data = XMLTV::parsefile(shift @ARGV); #$Log::TraceMessages::On = 1; my %interested; foreach (@{$old_data->[3]}) { next unless defined $_->{clumpidx} and $_->{clumpidx} ne '0/1'; push @{$interested{$_->{channel}}->{$_->{start}}}, $_; } t '\%interested=' . d \%interested; my (%new, %new_channels); foreach (@{$new_data->[3]}) { my $ch = $_->{channel}; push @{$new{$ch}->{$_->{start}}}, $_; $new_channels{$ch} = 1; } my %warned_ch; foreach my $ch (keys %interested) { if (not $new_channels{$ch}) { warn "unable to process channel $ch since not included in more detailed output\n" unless $warned_ch{$ch}++; next; } my $s = $interested{$ch}; my $n = $new{$ch}; t "doing channel $ch"; t 'fixing up: ' . d $s; t 'based on: ' . d $n; START: foreach my $start (keys %$s) { my @to_replace = @{$s->{$start}}; die "funny clump size at $start on $ch" if @to_replace < 2; t 'clump to replace: ' . d \@to_replace; my $r = $n->{$start}; die "no programmes to replace with at $start on $ch" if not defined $r; die if ref $r ne 'ARRAY'; my @replacement = @$r; die "no programmes to replace with at $start on $ch" if not @replacement; t 'replacement: ' . d \@replacement; my $i = 0; REPLACE: die "too many programmes to replace with" if @replacement > @to_replace; foreach (@replacement) { my $old = $to_replace[$i]; t 'updating: ' . d $old; t '...based on: ' . d $_; foreach my $key (qw(start stop clumpidx)) { if (exists $_->{$key}) { $old->{$key} = $_->{$key}; } else { delete $old->{$key}; } } t 'new version: ' . d $old; ++ $i; t "so far replaced $i programmes"; } die if $i > @to_replace; if ($i == @to_replace) { t 'end of clump'; next START; } t 'still some to replace, move forward in time'; my $prev = $replacement[-1]; die if not $prev; my $follow_on_start = $prev->{stop}; die "can't find follow-on replacement: no stop time in prev ($prev->{start}, $prev->{channel})" if not defined $follow_on_start; t "looking for programme in new listings at $follow_on_start"; my $follow_on = $n->{$follow_on_start}; die "can't find follow-on replacement: none at $follow_on_start on $ch" if not defined $follow_on; @replacement = @$follow_on; die if not @replacement; goto REPLACE; } } XMLTV::write_data($old_data);