| 141 | | sub get_sbsnews_data |
| 142 | | { |
| 143 | | my $file = "WNC-Schedule.html"; |
| 144 | | |
| 145 | | my $data; |
| 146 | | print "Old webpage no longer exists. Retrieving cache if available. Need new parser.\n"; |
| 147 | | # 7 days in one URL: http://www.sbs.com.au/whatson/WNC-Schedule.html |
| 148 | | # my $data = &Shepherd::Common::get_url( url => "http://www.sbs.com.au/whatson/WNC-Schedule.html", |
| 149 | | # stats => \%stats, |
| 150 | | # retries => 4, |
| 151 | | # debug => $opt->{debug} ? 3 : 1, |
| 152 | | # retry_delay => 120, |
| 153 | | # # the website doesn't support 'If-Modified-Since' headers but we can live in hope |
| 154 | | # mirror => $file); |
| 155 | | |
| 156 | | $data = &Shepherd::Common::get_mirror_file($file, 84) if (!$data); |
| 157 | | |
| 158 | | exit 22 unless ($data); |
| 159 | | |
| 160 | | my %day_range_names = (sunday=>0,monday=>1,tuesday=>2,wednesday=>3,thursday=>4,friday=>5,saturday=>6); |
| 161 | | |
| 162 | | # |
| 163 | | # parse html using the following state machine: |
| 164 | | # 0 = looking for first time tag |
| 165 | | # 1 = got first time tag |
| 166 | | # 2 = reading programmes |
| 167 | | # 3 = end of programmes |
| 168 | | # |
| 169 | | my $state_machine = 0; |
| 170 | | my @time_column; |
| 171 | | my $tree = HTML::TreeBuilder->new_from_content($data); |
| 172 | | my $time_tag_count = 0; |
| 173 | | my $tr_count = 0; |
| 174 | | |
| 175 | | my @seen_day_tag, my @column_is_day, my @column_maps_to_time; |
| 176 | | my @time_column_wrapped_over_midnight; |
| 177 | | my @prev_row_prog_tag; |
| 178 | | |
| 179 | | my $seen_time_tag_column = -1; |
| 180 | | &log("state machine is 0, looking for start of table") if $opt->{debug}; |
| 181 | | |
| 182 | | foreach my $tr1 ($tree->look_down('_tag' => 'tr')) { |
| 183 | | my $td_count = 0; |
| 184 | | my @row; |
| 185 | | |
| 186 | | foreach my $td1 ($tr1->look_down('_tag' => 'td')) { |
| 187 | | if ($td1->as_text() =~ /^Time$/) { |
| 188 | | if ($state_machine < 2) { |
| 189 | | &log("found time tag $time_tag_count in column $td_count") if $opt->{debug}; |
| 190 | | $time_column[$time_tag_count] = $td_count; |
| 191 | | $seen_time_tag_column = $time_tag_count; |
| 192 | | if ($time_tag_count == 0) { |
| 193 | | $state_machine = 1; |
| 194 | | &log("advanced state machine to 1, looking for day names") if $opt->{debug}; |
| 195 | | } |
| 196 | | |
| 197 | | # if this is a new time tag & we have existing unprocessed |
| 198 | | # columns, fix em up now |
| 199 | | for my $col (0..($#column_maps_to_time)) { |
| 200 | | if ((defined $column_maps_to_time[$col]) && |
| 201 | | ($column_maps_to_time[$col] == -1)) { |
| 202 | | $column_maps_to_time[$col] = $td_count; |
| 203 | | &log("fixed up column $col to map to time in column $td_count") if $opt->{debug}; |
| 204 | | } |
| 205 | | } |
| 206 | | $time_tag_count++; |
| 207 | | } else { |
| 208 | | $state_machine = 3; |
| 209 | | } |
| 210 | | } elsif ($td1->as_text() =~ /^\S$/) { |
| 211 | | if ($state_machine == 1) { |
| 212 | | $time_tag_count++; |
| 213 | | &log("blank column in $td_count, incremented time_tag to $time_tag_count") if $opt->{debug}; |
| 214 | | |
| 215 | | # blank column clears out our time column |
| 216 | | $seen_time_tag_column = -1; |
| 217 | | } |
| 218 | | } else { |
| 219 | | next if ($state_machine == 0); |
| 220 | | |
| 221 | | # parse day name |
| 222 | | if (($state_machine == 1) && ($td1->as_text() =~ /day$/)) { |
| 223 | | # got a day name.. |
| 224 | | my $dname = lc($td1->as_text()); |
| 225 | | if (defined $day_range_names{$dname}) { |
| 226 | | my $dnum = $day_range_names{$dname}; |
| 227 | | die "saw day tag for $dname more than once. has the HTML format changed?" |
| 228 | | if (defined $seen_day_tag[$dnum]); |
| 229 | | $seen_day_tag[$dnum]++; |
| 230 | | $column_is_day[$td_count] = $dnum; |
| 231 | | $column_maps_to_time[$td_count] = $seen_time_tag_column; |
| 232 | | &log("column $td_count is day $dnum ($dname) epoch time column $seen_time_tag_column") |
| 233 | | if $opt->{debug}; |
| 234 | | } else { |
| 235 | | die "expected day name, got '$dname'. has the HTML format changed?"; |
| 236 | | } |
| 237 | | } elsif ($state_machine == 2) { |
| 238 | | # soak up the data! |
| 239 | | $row[$td_count] = $td1->as_text(); |
| 240 | | $row[$td_count] =~ s/(^\s+|\s+$)//g; |
| 241 | | &log((sprintf "stored row data %d: '%s'", $td_count, $td1->as_text())) if $opt->{debug}; |
| 242 | | } else { |
| 243 | | &log((sprintf "got other text: state_machine=%d, td_count=%d, got: '%s'", |
| 244 | | $state_machine,$td_count,$td1->as_text())) if $opt->{debug}; |
| 245 | | } |
| 246 | | } |
| 247 | | $td_count++; |
| 248 | | } |
| 249 | | if ($state_machine == 1) { |
| 250 | | $state_machine = 2; |
| 251 | | &log("advanced state machine to 2, now looking for programmes") if $opt->{debug}; |
| 252 | | next; |
| 253 | | } elsif ($state_machine == 2) { |
| 254 | | # process row |
| 255 | | # 1. loop through $time_column ... |
| 256 | | foreach my $tcount (0..($time_tag_count-1)) { |
| 257 | | next if (!defined $time_column[$tcount]); |
| 258 | | my $tcol = $time_column[$tcount]; |
| 259 | | next if (!defined $row[$tcol]); |
| 260 | | |
| 261 | | # parse time from $row[$tcol] ... format is "13:30-13:50" |
| 262 | | my $start_time = -1, my $stop_time = -1; |
| 263 | | if ($row[$tcol] =~ /^(\d{1,2}):(\d{1,2})\s*\-\s*(\d{1,2}):(\d{1,2})$/) { |
| 264 | | $start_time = ($1*60*60)+($2*60); |
| 265 | | $stop_time = ($3*60*60)+($4*60); |
| 266 | | } else { |
| 267 | | &log("couldn't match start/stop time from '".$row[$tcol]."' in column $tcol") if $opt->{debug}; |
| 268 | | } |
| 269 | | |
| 270 | | # sometimes-subtitle-line (but not always) |
| 271 | | # if previous line had a programme in this slot and can't match a time, |
| 272 | | # use this row data as a sub-title for the programme |
| 273 | | if (($start_time == -1) || ($stop_time == -1)) { |
| 274 | | foreach my $col (0..$td_count) { |
| 275 | | if ((defined $column_is_day[$col]) && |
| 276 | | (defined $column_maps_to_time[$col]) && |
| 277 | | ($column_maps_to_time[$col] == $tcol) && |
| 278 | | (defined $prev_row_prog_tag[$col])) { |
| 279 | | if ($row[$col] ne "") { |
| 280 | | &log("added subtitle '".$row[$col]."' from col $col to previous-row prog '". |
| 281 | | $tv_guide->{$prev_row_prog_tag[$col]}->{title}->[0]->[0]."'") if $opt->{debug}; |
| 282 | | |
| 283 | | $tv_guide->{$prev_row_prog_tag[$col]}->{'sub-title'} = [[ $row[$col], $opt->{lang} ]]; |
| 284 | | &Shepherd::Common::cleanup($tv_guide->{$prev_row_prog_tag[$col]}->{'sub-title'}); |
| 285 | | } |
| 286 | | $prev_row_prog_tag[$col] = undef; |
| 287 | | } |
| 288 | | } |
| 289 | | next; |
| 290 | | } |
| 291 | | |
| 292 | | # wrapping over midnight for the first time |
| 293 | | if ($stop_time < $start_time) { |
| 294 | | $time_column_wrapped_over_midnight[$tcol] = 1; |
| 295 | | $stop_time += (24*60*60); |
| 296 | | &log("detected wrap-around-midnight for time '$row[$tcol]' in column $tcol") if $opt->{debug}; |
| 297 | | } |
| 298 | | |
| 299 | | # loop through all programmes which match this time column |
| 300 | | foreach my $col (0..$td_count) { |
| 301 | | if ((defined $column_is_day[$col]) && |
| 302 | | (defined $column_maps_to_time[$col]) && |
| 303 | | ($column_maps_to_time[$col] == $tcol)) { |
| 304 | | next if ($row[$col] eq ""); |
| 305 | | |
| 306 | | my $prog; |
| 307 | | $prog->{channel} = $channels->{'SBS News'}; |
| 308 | | $prog->{title} = [[ $row[$col], $opt->{lang} ]]; |
| 309 | | &Shepherd::Common::cleanup($prog->{title}); |
| 310 | | $prog->{start} = $start_time; |
| 311 | | $prog->{stop} = $stop_time; |
| 312 | | |
| 313 | | $prog->{category} = [[ 'News', undef ]] if ($progname =~ /News/i); |
| 314 | | my $wday = $column_is_day[$col]; |
| 315 | | if (defined $time_column_wrapped_over_midnight[$tcol] and $stop_time < (24*60*60)) { |
| 316 | | $wday = ($wday + 1) % 7; |
| 317 | | } |
| 318 | | $prog->{wday} = $wday; |
| 319 | | |
| 320 | | $prev_row_prog_tag[$col] = $wday*(24*60*60) + $start_time; |
| 321 | | $tv_guide->{$prev_row_prog_tag[$col]} = $prog; |
| 322 | | $tv_guide_by_wday->{$wday}->{$start_time} = $prog; |
| 323 | | |
| 324 | | &log((sprintf "got prog col %d: start=%s, stop=%s, '%s', day=%d (%d)", |
| 325 | | $col,&print_time($start_time),&print_time($stop_time),$row[$col],$column_is_day[$col],$wday)) |
| 326 | | if $opt->{debug}; |
| 327 | | |
| 328 | | $stats{seen_progs}++; |
| 329 | | } |
| 330 | | } |
| 331 | | } |
| 332 | | } |
| 333 | | $tr_count++; |
| 334 | | &log("advanced tr_count to $tr_count") if $opt->{debug}; |
| 335 | | } |
| 336 | | |
| 337 | | $tree->delete; |
| 338 | | |
| 339 | | die "didn't find 'time' tag in HTML table. has the HTML format changed?\n" |
| 340 | | if ($state_machine == 0); |
| 341 | | |
| 342 | | die "didn't find any programmes! has the HTML format changed?\n" |
| 343 | | if ($stats{seen_progs} == 0); |
| 344 | | } |
| 345 | | |
| 346 | | ###################################################################################################### |
| 347 | | |
| 348 | | # sbsnews data from http://www.sbs.com.au/whatson/WNC-Schedule.html has 5 or 10 |
| 349 | | # minute holes in it. this fills in those holes by extending programs over holes. |
| 350 | | # it also adds in "Station Close" programs for long overnight gaps. |
| 351 | | |
| 352 | | sub adjust_stop_times |
| 353 | | { |
| 354 | | &log("Extending stop times to fill in small guide data holes."); |
| 355 | | |
| 356 | | my @day_names = ("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"); |
| 357 | | |
| 358 | | # reverse-sort thru list to adjust prog stop times |
| 359 | | my @list = sort {$b <=> $a} keys %$tv_guide; |
| 360 | | my $prev_start = $tv_guide->{$list[$#list]}->{start} + (7*24*60*60); |
| 361 | | foreach my $key (@list) { |
| 362 | | my $stop = $tv_guide->{$key}->{wday}*(24*60*60) + $tv_guide->{$key}->{stop}; |
| 363 | | if ($stop != $prev_start) { |
| 364 | | my $diff = $prev_start - $stop; |
| 365 | | $stop = $tv_guide->{$key}->{stop}; |
| 366 | | my $new_wday = $tv_guide->{$key}->{wday}; |
| 367 | | if ($stop >= (24*60*60)) { |
| 368 | | $stop -= (24*60*60); |
| 369 | | $new_wday = ($new_wday + 1) % 7; |
| 370 | | } |
| 371 | | |
| 372 | | # Gaps of at least 30 minutes before 7am are Station Closes |
| 373 | | if ($diff / 60 >= 30 and (($prev_start % (24*60*60)) <= (7*60*60))) { |
| 374 | | my $new_prog = { title => [[ 'Station Close', $opt->{lang} ]], |
| 375 | | channel => $channels->{'SBS News'}, |
| 376 | | start => $stop, |
| 377 | | stop => $prev_start % (24*60*60) }; |
| 378 | | &log(sprintf "Inserting \"Station Close\" on %s between %s to %s", |
| 379 | | $day_names[$new_wday], |
| 380 | | &print_time($new_prog->{start}), |
| 381 | | &print_time($new_prog->{stop})); |
| 382 | | $tv_guide_by_wday->{$new_wday}->{$stop} = $new_prog; |
| 383 | | |
| 384 | | # Gaps of 15 or more minutes in other times are genuine holes |
| 385 | | # If the gap is a weekday, fill it with whatever was in |
| 386 | | # that timeslot tommorow (we have Monday holes for some reason) |
| 387 | | } elsif ($diff / 60 >= 15) { |
| 388 | | if ($new_wday > 0 and $new_wday < 6) { |
| 389 | | my $copy_wday = $new_wday + 1; |
| 390 | | $copy_wday = 1 if $copy_wday >= 6; |
| 391 | | |
| 392 | | if ($tv_guide_by_wday->{$copy_wday}->{$stop}) { |
| 393 | | my $new_prog = { %{$tv_guide_by_wday->{$copy_wday}->{$stop}}}; |
| 394 | | delete $new_prog->{wday} if $new_prog->{wday}; |
| 395 | | &log(sprintf "Filling weekday gap on %s at %s with next day's schedule \"%s\".", |
| 396 | | $day_names[$new_wday], &print_time($stop), $new_prog->{title}[0][0]); |
| 397 | | $tv_guide_by_wday->{$new_wday}->{$stop} = $new_prog; |
| 398 | | } else { |
| 399 | | &log(sprintf "Unable to find suitable program to copy to fill " . |
| 400 | | "weekday gap on %s at %s.", $day_names[$new_wday], &print_time($stop)); |
| 401 | | } |
| 402 | | } else { |
| 403 | | &log(sprintf "Can't fill gap on %s at %s after \"%s\" for %d mins.", |
| 404 | | $day_names[$new_wday], |
| 405 | | &print_time($stop), |
| 406 | | $tv_guide->{$key}->{title}[0][0], |
| 407 | | $diff/60); |
| 408 | | } |
| 409 | | |
| 410 | | # Gaps of <15 minutes shall be filled in |
| 411 | | } else { |
| 412 | | &log(sprintf "Extending stop time of \"%s\" by %d mins, from %s to %s on %s.", |
| 413 | | $tv_guide->{$key}->{title}[0][0], |
| 414 | | $diff/60, |
| 415 | | &print_time($tv_guide->{$key}->{stop}), |
| 416 | | &print_time($tv_guide->{$key}->{stop} + $diff), |
| 417 | | $day_names[$tv_guide->{$key}->{wday}]) if ($opt->{debug}); |
| 418 | | $tv_guide->{$key}->{stop} += $diff; |
| 419 | | $stats{extended_stops}++ |
| 420 | | } |
| 421 | | } |
| 422 | | delete $tv_guide->{$key}->{wday}; |
| 423 | | $prev_start = $key; |
| 424 | | } |
| 425 | | } |
| 426 | | |
| 427 | | ###################################################################################################### |
| 428 | | |
| | 178 | sub cook_data |
| | 179 | { |
| | 180 | my $raw = shift; |
| | 181 | my $time_column = shift; |
| | 182 | my $title_column = shift; |
| | 183 | my $week = shift; |
| | 184 | my $day = shift; |
| | 185 | |
| | 186 | my $row = 0; my $started = 0; |
| | 187 | my $previous_time = 0; |
| | 188 | while (1) { |
| | 189 | #print $raw->{$time_column}->{$row}->{title} . "\n"; |
| | 190 | #print $raw->{$title_column}->{$row}->{title} . "\n"; |
| | 191 | |
| | 192 | my ($start_time, $stop_time); |
| | 193 | if ($raw->{$time_column}->{$row}->{title} && |
| | 194 | $raw->{$time_column}->{$row}->{title} =~ |
| | 195 | /^(\d{1,2})[:.](\d{1,2})\s*\-\s*(\d{1,2})[:.](\d{1,2})$/) { |
| | 196 | $started=1; |
| | 197 | |
| | 198 | $start_time = ($1*60*60)+($2*60); |
| | 199 | $stop_time = ($3*60*60)+($4*60); |
| | 200 | if ($start_time > $stop_time) { |
| | 201 | $stop_time += (24*60*60); |
| | 202 | } elsif ($previous_time > $start_time) { |
| | 203 | $day = ($day + 1) % 7 |
| | 204 | } |
| | 205 | $previous_time = $stop_time; |
| | 206 | } else { |
| | 207 | $row += 1; |
| | 208 | if (!$started) { |
| | 209 | next; |
| | 210 | } else { |
| | 211 | last; |
| | 212 | } |
| | 213 | } |
| | 214 | |
| | 215 | #print "$day ".&print_time($start_time)." ".&print_time($stop_time)."\n"; |
| | 216 | |
| | 217 | my $prog; |
| | 218 | $prog->{channel} = $channels->{'SBS News'}; |
| | 219 | $prog->{start} = $start_time; |
| | 220 | $prog->{stop} = $stop_time; |
| | 221 | $prog->{title} = [[ $raw->{$title_column}->{$row}->{title}, $opt->{lang} ]]; |
| | 222 | $prog->{'sub-title'} = [[ $raw->{$title_column}->{$row}->{subtitle}, $opt->{lang} ]] |
| | 223 | if $raw->{$title_column}->{$row}->{subtitle}; |
| | 224 | $prog->{category} = [[ 'News', undef ]] |
| | 225 | if ($raw->{$title_column}->{$row}->{title} =~ /News/i); |
| | 226 | &Shepherd::Common::cleanup($prog); |
| | 227 | |
| | 228 | $week->{$day}->{$start_time} = $prog; |
| | 229 | |
| | 230 | #warn Dumper($prog); |
| | 231 | |
| | 232 | $row += 1; |
| | 233 | }; |
| | 234 | #print "$day = $row\n"; |
| | 235 | |
| | 236 | return $week; |
| | 237 | } |
| | 238 | |
| | 239 | sub get_sbsnews_data |
| | 240 | { |
| | 241 | my $file = "WNC-Schedule.html"; |
| | 242 | |
| | 243 | # 7 days in one URL: http://www.sbs.com.au/whatson/WNC-Schedule.html |
| | 244 | my $data = &Shepherd::Common::get_url( url => "http://www.sbs.com.au/schedule/digital", |
| | 245 | stats => \%stats, |
| | 246 | retries => 4, |
| | 247 | debug => $opt->{debug} ? 3 : 1, |
| | 248 | retry_delay => 120, |
| | 249 | # the website doesn't support 'If-Modified-Since' headers but we can live in hope |
| | 250 | mirror => $file); |
| | 251 | |
| | 252 | $data = &Shepherd::Common::get_mirror_file($file, 14) if (!$data); |
| | 253 | |
| | 254 | exit 22 unless ($data); |
| | 255 | |
| | 256 | # read html |
| | 257 | my $tree = HTML::TreeBuilder->new_from_content($data); |
| | 258 | my $table = $tree->look_down('_tag' => 'div', id => 'digital_list'); |
| | 259 | die "Format has changed can't find digital_list\n" unless ($table); |
| | 260 | my $raw; |
| | 261 | my ($column, $row) = (0,0); |
| | 262 | foreach my $ul ($table->look_down('_tag' => 'ul')) { |
| | 263 | foreach my $li ($ul->look_down('_tag' => 'li')) { |
| | 264 | my $title = $li->as_trimmed_text(); |
| | 265 | my $subtitle = $li->look_down('_tag' => 'span'); |
| | 266 | if (defined $subtitle) { |
| | 267 | $subtitle = $subtitle->as_trimmed_text(); |
| | 268 | $title =~ s/$subtitle//; |
| | 269 | } else { |
| | 270 | $subtitle = ""; |
| | 271 | } |
| | 272 | #print "$title<$subtitle\t"; |
| | 273 | $raw->{$column}->{$row}->{title} = $title; |
| | 274 | $raw->{$column}->{$row}->{subtitle} = $subtitle; |
| | 275 | $row += 1; |
| | 276 | } |
| | 277 | #print "\n"; |
| | 278 | $row = 0; |
| | 279 | $column += 1; |
| | 280 | } |
| | 281 | $tree->delete; |
| | 282 | die "didn't find any programmes! has the HTML format changed?\n" unless ($column==9); |
| | 283 | |
| | 284 | # make ideal week |
| | 285 | #my %day_range_names = (sunday=>0,monday=>1,tuesday=>2,wednesday=>3,thursday=>4,friday=>5,saturday=>6); |
| | 286 | my $week; |
| | 287 | foreach my $day (0 .. 6) { |
| | 288 | if ($day == 0) { |
| | 289 | $week = cook_data($raw, 8, 7, $week, $day) |
| | 290 | } else { |
| | 291 | $week = cook_data($raw, 0, $day, $week, $day) |
| | 292 | } |
| | 293 | } |
| | 294 | |
| | 295 | return $week; |
| | 296 | } |
| | 297 | |
| | 298 | ###################################################################################################### |
| | 299 | |
| | 300 | sub fix_gaps |
| | 301 | { |
| | 302 | my $week = shift; |
| | 303 | |
| | 304 | &log("Extending stop times to fill in small guide data holes."); |
| | 305 | |
| | 306 | my @day_names = ("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"); |
| | 307 | |
| | 308 | my @list = sort {$b <=> $a} keys %{$week->{0}}; |
| | 309 | my $prev_start = $list[$#list] + (24*60*60); |
| | 310 | |
| | 311 | for (my $day=6; $day >= 0; $day--) { |
| | 312 | @list = sort {$b <=> $a} keys %{$week->{$day}}; |
| | 313 | |
| | 314 | foreach my $start (@list) { |
| | 315 | my $stop = $week->{$day}->{$start}->{stop}; |
| | 316 | |
| | 317 | if ($stop != $prev_start) { |
| | 318 | my $diff = $prev_start - $stop; |
| | 319 | my $new_day = $day; |
| | 320 | if ($stop >= (24*60*60)) { |
| | 321 | $stop -= (24*60*60); |
| | 322 | $prev_start -= (24*60*60); |
| | 323 | $new_day = ($day + 1) % 7; |
| | 324 | } |
| | 325 | |
| | 326 | # Gaps of at least 30 minutes before 7am are Station Closes |
| | 327 | if ($diff / 60 >= 30 and (($prev_start % (24*60*60)) <= (7*60*60))) { |
| | 328 | my $new_prog = { title => [[ 'Station Close', $opt->{lang} ]], |
| | 329 | channel => $channels->{'SBS News'}, |
| | 330 | start => $stop, |
| | 331 | stop => $prev_start }; |
| | 332 | &log(sprintf "Inserting \"Station Close\" on %s between %s to %s", |
| | 333 | $day_names[$new_day], |
| | 334 | &print_time($new_prog->{start}), |
| | 335 | &print_time($new_prog->{stop})); |
| | 336 | $week->{$new_day}->{$stop} = $new_prog; |
| | 337 | $stats{gap_add_close}++ |
| | 338 | |
| | 339 | # Gaps of 15 or more minutes in other times are genuine holes |
| | 340 | } elsif ($diff / 60 >= 15) { |
| | 341 | my $new_prog = { title => [[ 'Gap', $opt->{lang} ]], |
| | 342 | channel => $channels->{'SBS News'}, |
| | 343 | start => $stop, |
| | 344 | stop => $prev_start }; |
| | 345 | &log(sprintf "Inserting \"Gap\" on %s between %s to %s", |
| | 346 | $day_names[$new_day], |
| | 347 | &print_time($new_prog->{start}), |
| | 348 | &print_time($new_prog->{stop})); |
| | 349 | $week->{$new_day}->{$stop} = $new_prog; |
| | 350 | $stats{gap_add_gap}++ |
| | 351 | |
| | 352 | # Gaps of <15 minutes shall be filled in |
| | 353 | } else { |
| | 354 | &log(sprintf "Extending stop time of \"%s\" by %d mins, from %s to %s on %s.", |
| | 355 | $week->{$day}->{$start}->{title}[0][0], |
| | 356 | $diff/60, |
| | 357 | &print_time($week->{$day}->{$start}->{stop}), |
| | 358 | &print_time($week->{$day}->{$start}->{stop} + $diff), |
| | 359 | $day_names[$day]) if ($opt->{debug}); |
| | 360 | $week->{$day}->{$start}->{stop} += $diff; |
| | 361 | $stats{gap_extended_stops}++ |
| | 362 | } |
| | 363 | } |
| | 364 | $prev_start = $start; |
| | 365 | } |
| | 366 | $prev_start += (24*60*60); |
| | 367 | } |
| | 368 | return $week; |
| | 369 | } |
| | 370 | |
| | 371 | ###################################################################################################### |
| | 372 | |