--- program/xmltv.pl 2009/10/31 14:47:07 25 +++ program/xmltv.pl 2009/10/31 21:34:40 26 @@ -5,6 +5,9 @@ use XML::Simple; use Data::Dump qw(dump); +use DateTime; + +my $step = 1; # min my $tv = XMLin( 'tv.xml', ContentKey => '-content', @@ -25,7 +28,11 @@ background: #eee; } -th,odd { +td.blank { + background: #fff; +} + +th.odd { background: #eef; } @@ -39,6 +46,11 @@ float: right; } +span.date { + color: #fff; + font-size: 150%; +} + @@ -59,57 +71,125 @@ my $programs; -sub hh { substr $_[0], 8, 2 } -sub mm { substr $_[0], 10, 2 } +my $date; + +sub iso_to_dt { + my ( $date, $timezone ) = split(/\s/,shift); + DateTime->new( + year => substr($date, 0, 4), + month => substr($date, 4, 2), + day => substr($date, 6, 2), + hour => substr($date, 8, 2), + minute => substr($date, 10, 2), + second => substr($date, 12, 2), +# timezone => $timezone, + ); +} + +sub duration_min { + my $dt = shift; + return + $dt->hours * 60 + + $dt->minutes +# + $dt->seconds + ; +} + +sub dt_hhmm { + sprintf( '%02d:%02d', $_[0]->hour, $_[0]->minute ); +} -sub in_mins { hh($_[0]) * 60 + mm($_[0]) } +foreach my $p ( sort { $a->{start} cmp $b->{start} } @{ $tv->{programme} } ) { -foreach my $p ( @{ $tv->{programme} } ) { warn "# p ",dump $p; - my $t_start = in_mins $p->{start}; - my $t_stop = in_mins $p->{stop}; + my $dt_start = iso_to_dt $p->{start}; + my $dt_stop = iso_to_dt $p->{stop}; + + my $t_diff = $dt_stop - $dt_start; + my $duration = duration_min( $dt_stop - $dt_start ); + + warn "# t $dt_start - $dt_stop [$duration]\n"; - warn "# t $t_start - $t_stop\n"; - if ( ! defined $programs->{ $p->{channel} } ) { - push @{ $programs->{ $p->{channel} } }, [ 0, $t_start ]; + if ( ! $date ) { + $date = $dt_start->clone; } - push @{ $programs->{ $p->{channel} } }, [ $t_start, $t_stop - $t_start, $p ]; + + push @{ $programs->{ $p->{channel} } }, [ $dt_start, $duration, $p ]; } warn "# programs ", dump $programs; -foreach my $hh ( 0 .. 23 ) { - foreach my $mm ( 0 .. 59 ) { +warn "# date $date\n"; + +#$date->set_hour( 0 ); +$date->set_minute( 0 ); +$date->set_second( 0 ); + +print qq|$date\n|; +foreach my $c ( @channels ) { + my $start = $programs->{$c}->[0]->[0] || die "no first $c in ", dump $programs->{$c}; + my $duration = duration_min( $start - $date ); + warn "# padding $c $start $duration\n"; + unshift @{ $programs->{$c} }, [ $date, $duration ]; +} + +my $more = 1; + +while ( $more ) { + + my @td; + + $more = 0; + + foreach my $c ( @channels ) { + + next unless defined $programs->{$c}->[0]; + $more++ unless $more; - my $hhmm = sprintf '%02d:%02d', $hh, $mm; + my $first_start = $programs->{$c}->[0]->[0]; - print "\n"; +warn "# first_start $c $first_start $date\n"; - my @td; + if ( $first_start <= $date ) { - foreach my $c ( @channels ) { - if ( $programs->{$c}->[0]->[0] == $hh * 60 + $mm ) { - my $p = shift @{ $programs->{$c} }; - my $span = $p->[1]; # - 1; + my $p = shift @{ $programs->{$c} }; - my $html = ''; - $html = join("\n" - , qq|$hhmm
$span
| + my $td_attr = 'rowspan=' . int( $p->[1] / $step ); + + my $hhmm = dt_hhmm $p->[0]; + + my $html = ''; + if ( $p->[2] ) { + $html .= join("\n" + , qq|$hhmm
$p->[1]
| , $p->[2]->{title}->{content} , "" - ) if $p->[2]; - - push @td, qq|$html|; + ); + } else { + $td_attr .= ' class=blank'; } + + push @td, qq|$html|; } + } - my $class = $hh % 2 == 0 ? 'even' : 'odd'; - my $th = ''; - $th = qq|$hh| if $mm == 0; + my $th = ''; + if ( $date->minute == 0 ) { + $th = $date->hour; + $th = qq|| . $date->day . qq|
$th| if $th == 0; + + my $span = 60 / $step; + my $class = $date->hour % 2 == 0 ? 'even' : 'odd'; + $th = qq|$th|; - print qq|$th|, join('', @td), qq|\n|; } + + print "\n"; + print qq|$th|, join('', @td), qq|\n|; + + $date->add( minutes => $step ); + } print qq|