Legend:
- Unmodified
- Added
- Removed
-
shepherd
r4 r5 3 3 # "Shepherd" 4 4 5 my $version = '0.2. 5ng';5 my $version = '0.2.6'; 6 6 7 7 # A wrapper for various Aussie TV guide data grabbers … … 19 19 # 0.2.2 : --check 20 20 # 0.2.3 : Bugfix: archives correctly 21 # 0.2.5ng : multi-grabber (potentially with partial data) & postprocessor support 21 # 0.2.5 : multi-grabber (potentially with partial data) 22 # 0.2.6 : postprocessor support 22 23 # 23 24 # ToDo: … … 28 29 # --desc or --ready 29 30 # * --ready option that says whether config is required? 30 # * "Last Data" column in status31 31 32 32 use strict; … … 39 39 use XMLTV::Ask; 40 40 use DateTime::Format::Strptime; 41 use POSIX qw(strftime); 41 42 42 43 # --------------------------------------------------------------------------- … … 58 59 59 60 my $GRABBER_DIR = "$CWD/grabbers"; 61 my $POSTPROCESSOR_DIR = "$CWD/postprocessors"; 60 62 my $ARCHIVE_DIR = "$CWD/archive"; 61 my $timeslot_size = (15 * 60); # 15 minute slots 62 my $channel_ok_threshold_percent = 90; 63 64 my $timeslot_size = (15 * 60); # 15 minute slots 65 my $channel_ok_threshold_percent = 90; # 90% these may need to be tweaked but look ok for now 66 my $postprocessor_ok_threshold_percent = 80; # 80% these may need to be tweaked but look ok for now 67 my $postprocessor_disable_failure_threshold = 5; # number of times a postprocessor has to fail in a row before it is automatically disabled 63 68 64 69 my $opt; 70 my $pref_order; 71 my $made_changes = 0; 65 72 my $debug = 1; 66 73 my $grabbers = { }; 74 my $postprocessors = { }; 67 75 my $preferred; # obsolete but may still exist in shepherd.conf 68 76 my $region; … … 75 83 my $langs = [ 'en' ]; 76 84 my $num_timeslots; 77 my $ grabber_data = { };85 my $plugin_data = { }; 78 86 my $channel_data = { }; 79 87 my $starttime, my $endtime; 88 my $input_postprocess_files = ""; 89 my $insufficient_grabber_data = 0; 80 90 81 91 # --------------------------------------------------------------------------- … … 123 133 } 124 134 125 &set_order($opt->{setorder}) if ($opt->{setorder}); 126 127 if ($opt->{check}) 128 { 129 check(); 130 } 135 &set_order(0,$opt->{setorder}) if ($opt->{setorder}); 136 &check() if ($opt->{check}); 131 137 132 138 if ($opt->{enable} or $opt->{disable} or $opt->{setorder} or $opt->{check}) 133 139 { 134 write_config_file(); 140 set_order(1) if $made_changes; 141 write_config_file() if $made_changes; 135 142 status(); 136 143 exit; … … 160 167 calc_date_range(); 161 168 grab_data(); 169 postprocess_data(); 170 output_data(); 162 171 } 163 172 … … 165 174 166 175 status(); 176 write_config_file(); 167 177 168 178 # --------------------------------------------------------------------------- … … 184 194 $used_grabbers++; 185 195 186 $grabber_data->{$grabber}->{last_grabbed} = time; 196 $grabbers->{$grabber}->{lastdata} = time; 197 $grabbers->{$grabber}->{laststatus} = "unknown"; 187 198 188 199 printf "SHEPHERD: Using grabber: (%d) %s\n",$grabbers->{$grabber}->{order},$grabber; 189 200 190 201 my $output = "$GRABBER_DIR/$grabber/output.xmltv"; 202 $input_postprocess_files .= "$output "; 203 191 204 my $comm = "$GRABBER_DIR/$grabber/$grabber " . 192 205 "--region $region " . … … 208 221 209 222 # soak up the data we just collected 210 &soak_up_grabber_data($grabber, $output); 223 &soak_up_data($grabber, $output); 224 $grabbers->{$grabber}->{laststatus} = $plugin_data->{$grabber}->{laststatus}; 211 225 212 226 # check to see if we have all the data we want 213 $need_more_data = &analyze_ grabber_data();227 $need_more_data = &analyze_plugin_data($channel_ok_threshold_percent); 214 228 215 229 last if (!$need_more_data); … … 226 240 { 227 241 print "SHEPHERD: Ran through ALL grabbers but still missing data!!! :(\n"; 242 $insufficient_grabber_data = 1; 228 243 return; 229 244 } … … 231 246 232 247 233 # interpret xmltv data from this grabber 234 sub soak_up_ grabber_data248 # interpret xmltv data from this grabber/postprocessor 249 sub soak_up_data 235 250 { 236 251 my ($grabber, $output) = @_; 237 eval { $ grabber_data->{$grabber}->{xmltv} = XMLTV::parsefiles($output); };238 239 if (defined $ grabber_data->{$grabber}->{xmltv}) {240 $ grabber_data->{$grabber}->{valid} = 1;241 242 my $xmltv = $ grabber_data->{$grabber}->{xmltv};252 eval { $plugin_data->{$grabber}->{xmltv} = XMLTV::parsefiles($output); }; 253 254 if (defined $plugin_data->{$grabber}->{xmltv}) { 255 $plugin_data->{$grabber}->{valid} = 1; 256 257 my $xmltv = $plugin_data->{$grabber}->{xmltv}; 243 258 my ($encoding, $credits, $chan, $progs) = @$xmltv; 244 $ grabber_data->{$grabber}->{total_duration} = 0;245 $ grabber_data->{$grabber}->{programmes} = 0;259 $plugin_data->{$grabber}->{total_duration} = 0; 260 $plugin_data->{$grabber}->{programmes} = 0; 246 261 247 262 my $strptime = new DateTime::Format::Strptime( pattern => "%Y%m%d%H%M %z"); … … 261 276 262 277 # store grabber-specific stats 263 $ grabber_data->{$grabber}->{programmes}++;264 $ grabber_data->{$grabber}->{total_duration} += ($t2->epoch - $t1->epoch);278 $plugin_data->{$grabber}->{programmes}++; 279 $plugin_data->{$grabber}->{total_duration} += ($t2->epoch - $t1->epoch); 265 280 $seen_progs_on_this_channel++; 266 $ grabber_data->{$grabber}->{earliest_data_seen} = $t1->epoch if (!defined $grabber_data->{$grabber}->{earliest_data_seen});267 $ grabber_data->{$grabber}->{earliest_data_seen} = $t1->epoch if ($t1->epoch < $grabber_data->{$grabber}->{earliest_data_seen});268 $ grabber_data->{$grabber}->{latest_data_seen} = $t2->epoch if (!defined $grabber_data->{$grabber}->{latest_data_seen});269 $ grabber_data->{$grabber}->{latest_data_seen} = $t2->epoch if ($t2->epoch > $grabber_data->{$grabber}->{latest_data_seen});281 $plugin_data->{$grabber}->{earliest_data_seen} = $t1->epoch if (!defined $plugin_data->{$grabber}->{earliest_data_seen}); 282 $plugin_data->{$grabber}->{earliest_data_seen} = $t1->epoch if ($t1->epoch < $plugin_data->{$grabber}->{earliest_data_seen}); 283 $plugin_data->{$grabber}->{latest_data_seen} = $t2->epoch if (!defined $plugin_data->{$grabber}->{latest_data_seen}); 284 $plugin_data->{$grabber}->{latest_data_seen} = $t2->epoch if ($t2->epoch > $plugin_data->{$grabber}->{latest_data_seen}); 270 285 271 286 # store channel-specific stats … … 299 314 300 315 # print some stats about what we saw! 301 my $earlist_data_seen = localtime($grabber_data->{$grabber}->{earliest_data_seen}); 302 my $latest_data_seen = localtime($grabber_data->{$grabber}->{latest_data_seen}); 303 printf "SHEPHERD: Grabber '%s' returned data for %d channels (%d programmes, %dd%02dh%02dm%02ds duration, earliest %s, latest %s)\n", 304 $grabber, $seen_channels_with_data, $grabber_data->{$grabber}->{programmes}, 305 int($grabber_data->{$grabber}->{total_duration} / 86400), # days 306 int(($grabber_data->{$grabber}->{total_duration} % 86400) / 3600), # hours 307 int(($grabber_data->{$grabber}->{total_duration} % 3600) / 60), # mins 308 int($grabber_data->{$grabber}->{total_duration} % 60), # sec 309 $earlist_data_seen, $latest_data_seen; 316 printf "SHEPHERD: Grabber '%s' returned data for %d channels, %d programmes, %dd%02dh%02dm%02ds duration, %s%s\n", 317 $grabber, $seen_channels_with_data, $plugin_data->{$grabber}->{programmes}, 318 int($plugin_data->{$grabber}->{total_duration} / 86400), # days 319 int(($plugin_data->{$grabber}->{total_duration} % 86400) / 3600), # hours 320 int(($plugin_data->{$grabber}->{total_duration} % 3600) / 60), # mins 321 int($plugin_data->{$grabber}->{total_duration} % 60), # sec 322 (defined $plugin_data->{$grabber}->{earliest_data_seen} ? (strftime "%a %e %b %H:%M - ", localtime($plugin_data->{$grabber}->{earliest_data_seen})) : 'no data'), 323 (defined $plugin_data->{$grabber}->{latest_data_seen} ? (strftime "%a %e %b %H:%M", localtime($plugin_data->{$grabber}->{latest_data_seen})) : ''); 324 $plugin_data->{$grabber}->{laststatus} = sprintf "%dch/%dpr/%dhrs %s-%s", 325 $seen_channels_with_data, $plugin_data->{$grabber}->{programmes}, 326 int($plugin_data->{$grabber}->{total_duration} / 3600), 327 (defined $plugin_data->{$grabber}->{earliest_data_seen} ? (strftime "%a%d%b%H:%M", localtime($plugin_data->{$grabber}->{earliest_data_seen})) : 'no'), 328 (defined $plugin_data->{$grabber}->{latest_data_seen} ? (strftime "%a%d%b%H:%M", localtime($plugin_data->{$grabber}->{latest_data_seen})) : 'data'); 329 310 330 } else { 311 printf "WARNING: Grabber%s didn't seem to return any valid XMLTV!\n",$grabber;312 delete $ grabber_data->{$grabber}->{valid};331 printf "WARNING: Plugin %s didn't seem to return any valid XMLTV!\n",$grabber; 332 delete $plugin_data->{$grabber}->{valid}; 313 333 } 314 334 } … … 317 337 # analyze grabber data - do we have all the data we want? 318 338 # returns 1 if we need more data, 0 if we have all we want 319 sub analyze_grabber_data 320 { 339 sub analyze_plugin_data 340 { 341 my $threshold = shift; 321 342 my $retval = 0; # until proven otherwise 322 343 my $total_data_percent = 0, my $total_channels = 0; … … 329 350 my $data_in_channel = 0; 330 351 for my $slotnum (0..($num_timeslots-1)) { 331 $data_in_channel++ if ( $channel_data->{$ch}->{timeslots}[$slotnum] > 0);352 $data_in_channel++ if ((defined $channel_data->{$ch}->{timeslots}[$slotnum]) && ($channel_data->{$ch}->{timeslots}[$slotnum] > 0)); 332 353 } 333 354 334 355 # do we have enough data for this channel? 335 356 my $data_in_channel_percent = $data_in_channel / ($num_timeslots-1) * 100; 336 if ($data_in_channel_percent >= $ channel_ok_threshold_percent) {357 if ($data_in_channel_percent >= $threshold) { 337 358 $statusstring .= sprintf "%s: %0.1f%% [complete], ",$ch,$data_in_channel_percent; 338 359 } else { … … 381 402 382 403 # ----------------------------------------- 404 # Subs: Postprocessing 405 # ----------------------------------------- 406 407 sub postprocess_data 408 { 409 # for our first postprocessor, we feed it ALL of the XMLTV files we have 410 # as each postprocessor runs, we feed in the output from the previous one 411 # Shepherd checks the "completeness" of the data that comes out of a postprocessor & automatically 412 # reverts back to the previous postprocessor if it was shown to be bad 413 414 # first time around: feed in $input_postprocess_files 415 my $need_more_data; 416 417 foreach my $postprocessor (sort { $postprocessors->{$a} <=> $postprocessors->{$b} } keys %$postprocessors) { 418 next if ($postprocessors->{$postprocessor}->{disabled}); 419 420 $postprocessors->{$postprocessor}->{lastdata} = time; 421 $postprocessors->{$postprocessor}->{laststatus} = "unknown"; 422 423 printf "SHEPHERD: Using postprocessor: %s\n",$postprocessor; 424 425 my $output = "$POSTPROCESSOR_DIR/$postprocessor/output.xmltv"; 426 my $comm = "$POSTPROCESSOR_DIR/$postprocessor/$postprocessor " . 427 "--region $region " . 428 "--channels_file $channels_file " . 429 "--output $output"; 430 $comm .= " --days $days" if ($days); 431 $comm .= " --offset $opt->{offset}" if ($opt->{offset}); 432 $comm .= " --debug" if ($debug); 433 $comm .= " @ARGV" if (@ARGV); 434 $comm .= " $input_postprocess_files"; 435 print "SHEPHERD: Excuting command: $comm\n"; 436 437 chdir "$POSTPROCESSOR_DIR/$postprocessor/"; 438 system($comm); 439 chdir $CWD; 440 441 # 442 # soak up the data we just collected and check it 443 # YES - these are the SAME routines we used in the previous 'grabber' phase 444 # but the difference here is that we clear out our 'channel_data' beforehand 445 # so we can independently analyze the impact of this postprocessor. 446 # if it clearly returns bad data, don't use that data (go back one step) and 447 # flag the postprocessor as having failed. after 3 consecutive failures, disable it 448 # 449 450 # clear out channel_data 451 foreach my $ch (keys %{$channels}) { 452 delete $channel_data->{$ch}; 453 } 454 455 # process and analyze it! 456 &soak_up_data($postprocessor, $output); 457 $need_more_data = &analyze_plugin_data($postprocessor_ok_threshold_percent); 458 459 $postprocessors->{$postprocessor}->{laststatus} = $plugin_data->{$postprocessor}->{laststatus}; 460 461 if (($need_more_data) && (!$insufficient_grabber_data)) { 462 # urgh. this postprocessor did a bad bad thing ... 463 printf "SHEPHERD: XML data from postprocessor %s rejected, using XML from previous stage\n",$postprocessor; 464 465 if (defined $postprocessors->{$postprocessor}->{conescutive_failures}) { 466 $postprocessors->{$postprocessor}->{conescutive_failures}++; 467 } else { 468 $postprocessors->{$postprocessor}->{conescutive_failures} = 1; 469 } 470 printf "SHEPHERD: Postprocessor \"%s\" has now failed %d times in a row. %d more and it will be automatically disabled.\n", 471 $postprocessor, 472 $postprocessors->{$postprocessor}->{conescutive_failures}, 473 $postprocessor_disable_failure_threshold; 474 475 if ($postprocessors->{$postprocessor}->{conescutive_failures} >= $postprocessor_disable_failure_threshold) { 476 printf "SHEPHERD: Disabling Postprocessor \"%s\".\n",$postprocessor; 477 $postprocessors->{$postprocessor}->{disabled} = 1; 478 } 479 } else { 480 # accept what this postprocessor did to our output ... 481 printf "SHEPHERD: accepting output from postprocessor %s, feeding it into next stage\n",$postprocessor; 482 $input_postprocess_files = $output; 483 delete $postprocessors->{$postprocessor}->{conescutive_failures} if (defined $postprocessors->{$postprocessor}->{conescutive_failures}); 484 } 485 } 486 } 487 488 489 sub output_data 490 { 491 # $input_postprocess_files (hopefully just one file now) contains our final output 492 # send it to whereever --output told us to! 493 494 if ($opt->{output}) { 495 open(F,">$opt->{output}") || die "could not open outputfile $opt->{output} for writing: $!\n"; 496 } 497 498 foreach my $infile (split(/ /,$input_postprocess_files)) { 499 if (!(open(INFILE,"<$infile"))) { 500 printf "WARNING: could not open input file \"%s\": %s\n", $infile, $!; 501 printf "Output XMLTV data may be damanged as a result!\n"; 502 } else { 503 while (<INFILE>) { 504 if ($opt->{output}) { 505 print F $_ if ($opt->{output}); 506 } else { 507 print $_; 508 } 509 } 510 close(INFILE); 511 } 512 } 513 close(F) if ($opt->{output}); 514 } 515 516 # ----------------------------------------- 383 517 # Subs: Updates & Installations 384 518 # ----------------------------------------- … … 395 529 396 530 my %glist = %$grabbers; 397 while ($data =~ /(.*):(.*)/g) 398 { 399 update_component($1, $2); 400 delete $glist{$1}; 401 } 402 foreach (keys %glist) 403 { 404 unless ($grabbers->{$_}->{disabled}) 405 { 531 my %plist = %$postprocessors; 532 while ($data =~ /(.*):(.*):(.*)/g) 533 { 534 my ($proggy, $latestversion, $progtype) = ($1,$2,$3); 535 update_component($proggy, $latestversion, $progtype); 536 delete $glist{$proggy} if ($progtype eq "grabber"); 537 delete $plist{$proggy} if ($progtype eq "postprocessor"); 538 } 539 540 # work out what grabbers disappeared (if any) 541 foreach (keys %glist) { 542 unless ($grabbers->{$_}->{disabled}) { 406 543 print "\nDeleted grabber: $_.\n"; 407 disable($_); 544 disable($_,"grabber"); 545 $made_changes = 1; 546 } 547 } 548 549 # work out what postprocessors disappeared (if any) 550 foreach (keys %plist) { 551 unless ($postprocessors->{$_}->{disabled}) { 552 print "\nDeleted Postprocessor: $_.\n"; 553 disable($_,"postprocessor"); 554 $made_changes = 1; 408 555 } 409 556 } … … 412 559 sub update_component 413 560 { 414 my ($proggy, $latestversion ) = @_;561 my ($proggy, $latestversion, $progtype) = @_; 415 562 416 563 print "\n"; 417 564 418 if ($proggy eq $progname)419 {420 if(! -e "$CWD/$progname")421 {565 # handle new installs.. 566 if (($$proggy eq $progname) && ($progtype eq "shepherd")) { 567 # shepherd itself.. 568 if(! -e "$CWD/$progname") { 422 569 print "Missing: $CWD/$progname\n"; 423 install($progname, $latestversion );570 install($progname, $latestversion, $progtype); 424 571 return; 425 572 } 426 } 427 else 428 { 429 if (!$grabbers->{$proggy} or ! -e "$GRABBER_DIR/$proggy/$proggy") 430 { 573 } elsif ($progtype eq "grabber") { 574 if (!$grabbers->{$proggy} or ! -e "$GRABBER_DIR/$proggy/$proggy") { 431 575 print "New grabber: $proggy.\n"; 432 install($proggy, $latestversion );576 install($proggy, $latestversion, $progtype); 433 577 return; 434 578 } 435 if ($grabbers->{$proggy}->{disabled}) 436 { 437 print "Warning: $proggy disabled by config file.\n"; 438 } 439 } 440 441 # Compare versions 442 my $ver = ($proggy eq $progname ? $version : $grabbers->{$proggy}->{ver}); 579 print "Warning: grabber $proggy disabled by config file.\n" if ($grabbers->{$proggy}->{disabled}); 580 } elsif ($progtype eq "postprocessor") { 581 if (!$postprocessors->{$proggy} or ! -e "$POSTPROCESSOR_DIR/$proggy/$proggy") { 582 print "New postprocessor: $proggy.\n"; 583 install($proggy, $latestversion, $progtype); 584 return; 585 } 586 print "Warning: postprocessor $proggy disabled by config file.\n" if ($postprocessors->{$proggy}->{disabled}); 587 } 588 589 # upgrade/downgrades 590 my $ver; 591 if ($progtype eq "grabber") { 592 $ver = ($proggy eq $progname ? $version : $grabbers->{$proggy}->{ver}); 593 } elsif ($progtype eq "postprocessor") { 594 $ver = ($proggy eq $progname ? $version : $postprocessors->{$proggy}->{ver}); 595 } elsif (($$proggy eq $progname) && ($progtype eq "shepherd")) { 596 $ver = $version; 597 } else { 598 print "Warning: unknown type of programme: prog '$proggy' progtype '$progtype' not installed.\n"; 599 return; 600 } 443 601 444 602 my $result = versioncmp($ver, $latestversion); 445 if ($result == -1) 446 { 603 if ($result == -1) { 447 604 print "Upgrading $proggy from v$ver to v$latestversion.\n"; 448 } 449 elsif ($result == 1) 450 { 605 } elsif ($result == 1) { 451 606 print "Downgrading $proggy from v$ver to v$latestversion.\n"; 452 } 453 else 454 { 607 } else { 455 608 print "Already have latest version of $proggy: v$ver.\n"; 456 609 return; 457 610 } 458 install($proggy, $latestversion );611 install($proggy, $latestversion, $progtype); 459 612 } 460 613 461 614 sub install 462 615 { 463 my ($proggy, $latestversion ) = @_;616 my ($proggy, $latestversion, $progtype) = @_; 464 617 465 618 print "Downloading $proggy v$latestversion.\n"; … … 469 622 my $ver = $version; 470 623 471 if ($proggy ne $progname) 472 { 473 -d $GRABBER_DIR or mkdir $GRABBER_DIR 474 or die "Cannot create directory $GRABBER_DIR: $!"; 475 624 if (($$proggy eq $progname) && ($progtype eq "shepherd")) { 625 $rdir = $HOME; 626 $ldir = $CWD; 627 $ver = $version; 628 } elsif ($progtype eq "grabber") { 629 $rdir = $HOME . "/grabbers"; 476 630 $ldir = "$GRABBER_DIR/$proggy"; 477 -d $ldir or mkdir $ldir or die "Cannot create directory $ldir: $!";478 $rdir = "$rdir/grabbers";479 631 $ver = $grabbers->{$proggy}->{ver}; 480 } 632 -d $GRABBER_DIR or mkdir $GRABBER_DIR or die "Cannot create directory $GRABBER_DIR: $!"; 633 } elsif ($progtype eq "postprocessor") { 634 $rdir = $HOME . "/postprocessors"; 635 $ldir = "$POSTPROCESSOR_DIR/$proggy"; 636 $ver = $postprocessors->{$proggy}->{ver}; 637 -d $POSTPROCESSOR_DIR or mkdir $POSTPROCESSOR_DIR or die "Cannot create directory $POSTPROCESSOR_DIR: $!"; 638 } else { 639 print "Warning: unknown type of programme: prog '$proggy' progtype '$progtype' not installed.\n"; 640 return; 641 } 642 -d $ldir or mkdir $ldir or die "Cannot create directory $ldir: $!"; 481 643 482 644 my $newfile = "$ldir/$proggy-$latestversion"; 483 484 645 my $rc = LWP::Simple::getstore("$rdir/$proggy-$latestversion", $newfile); 485 646 … … 493 654 system('chmod u+x ' . $newfile); 494 655 495 -d $ARCHIVE_DIR or mkdir $ARCHIVE_DIR 496 or die "Cannot create directory $ARCHIVE_DIR: $!"; 656 -d $ARCHIVE_DIR or mkdir $ARCHIVE_DIR or die "Cannot create directory $ARCHIVE_DIR: $!"; 497 657 498 658 if (-e "$ldir/$proggy") … … 504 664 print "Installed $proggy v$latestversion.\n" if ($debug); 505 665 506 if ($proggy eq $progname)507 {666 # if the update was for shepherd itself, restart it 667 if (($$proggy eq $progname) && ($progtype eq "shepherd")) { 508 668 print "\n*** Restarting ***\n\n"; 509 669 exec("$ldir/$proggy"); … … 512 672 513 673 print "Testing $proggy...\n" if ($debug); 514 my $result = test_grabber($proggy); 515 516 # Update grabbers list 517 my $disabled = $grabbers->{$proggy}->{disabled}; 518 $grabbers->{$proggy} = 519 { 520 'ver' => $latestversion, 521 'disabled' => $disabled, 522 'ready' => $result 523 }; 524 } 525 526 sub test_grabber 527 { 528 my $proggy = shift; 529 530 chdir("$GRABBER_DIR/$proggy"); 531 system("$GRABBER_DIR/$proggy/$proggy --ready"); 674 my $result = test_proggy($ldir,"$ldir/$proggy"); 675 676 if ($progtype eq "grabber") { 677 $grabbers->{$proggy}->{ver} = $latestversion; 678 $grabbers->{$proggy}->{ready} = $result; 679 $grabbers->{$proggy}->{laststatus} = sprintf "updated to %s on %s", $latestversion, (strftime "%a%d%b%y",localtime(time)); 680 } elsif ($progtype eq "postprocessor") { 681 $postprocessors->{$proggy}->{ver} = $latestversion; 682 $postprocessors->{$proggy}->{ready} = $result; 683 $postprocessors->{$proggy}->{laststatus} = sprintf "updated to %s on %s", $latestversion, (strftime "%a%d%b%y",localtime(time)); 684 } 685 686 $made_changes = 1; 687 } 688 689 sub test_proggy 690 { 691 my ($testdir,$proggyexec) = @_; 692 693 chdir($testdir); 694 system("$proggyexec --ready"); 532 695 chdir ($CWD); 533 696 … … 535 698 print "Return value: $result\n" if ($debug); 536 699 537 if ($result) 538 { 539 print "\nGrabber $proggy did not exit cleanly!\n" . 540 "It may require configuration.\n\n"; 541 } 542 700 print "\nprogramme $proggyexec did not exit cleanly!\n" . 701 "It may require configuration.\n\n" if ($result); 543 702 return !$result; 544 703 } … … 548 707 my $proggy = shift; 549 708 709 # confirm it exists first 710 if ((!$grabbers->{$proggy}) && (!$postprocessors->{$proggy})) { 711 printf "No such grabber/postprocessor: \"%s\".\n",$proggy; 712 return; 713 } 550 714 print "Enabling $proggy.\n"; 551 if (!$grabbers->{$proggy}) 552 { 553 print "No such grabber: \"$proggy\".\n"; 554 } 555 else 556 { 557 delete $grabbers->{$proggy}->{disabled}; 558 } 715 716 delete $grabbers->{$proggy}->{disabled} if ($grabbers->{$proggy}); 717 delete $postprocessors->{$proggy}->{disabled} if ($postprocessors->{$proggy}); 718 $made_changes = 1; 559 719 } 560 720 … … 563 723 my $proggy = shift; 564 724 725 # confirm it exists first 726 if ((!$grabbers->{$proggy}) && (!$postprocessors->{$proggy})) { 727 printf "No such grabber/postprocessor: \"%s\".\n",$proggy; 728 return; 729 } 565 730 print "Disabling $proggy.\n"; 566 $grabbers->{$proggy}->{disabled} = 1; 731 732 $grabbers->{$proggy}->{disabled} = 1 if ($grabbers->{$proggy}); 733 $postprocessors->{$proggy}->{disabled} = 1 if ($postprocessors->{$proggy}); 734 $made_changes = 1; 567 735 } 568 736 569 737 sub set_order 570 738 { 571 my $order = shift; 572 my $all_ok = 1; 573 574 # first check that user supplied a valid list of grabbers 575 if ($order) { 576 foreach my $proggy (split(/,/,$order)) { 577 next if !$proggy; 578 if (!$grabbers->{$proggy}) { 579 $all_ok = 0; 580 print "Invalid grabber: \"$proggy\".\n"; 581 } 582 } 583 } 584 if ($all_ok) { 585 # if list was ok then first reset current order to zero 586 foreach my $proggy (keys %$grabbers) { 587 $grabbers->{$proggy}->{order} = 0; 588 } 589 590 # and now set order 591 my $order_num = 1; 592 if ($order) { 593 foreach my $proggy (split(/,/,$order)) { 739 my ($quiet,$order) = @_; 740 $pref_order = $order if ($order); 741 742 # reset current order to zero 743 foreach my $proggy (keys %$grabbers) { 744 $grabbers->{$proggy}->{order} = 0; 745 } 746 747 # and now set order 748 my $order_num = 1; 749 if ($pref_order) { 750 foreach my $proggy (split(/,/,$pref_order)) { 751 if (defined $grabbers->{$proggy}) { 594 752 $grabbers->{$proggy}->{order} = $order_num; 595 753 $order_num++; 596 754 } 597 755 } 598 599 # set order of any grabbers not specified in a random manner 600 foreach my $proggy (sort keys %$grabbers) { 601 if ($grabbers->{$proggy}->{order} == 0) {602 $grabbers->{$proggy}->{order} = $order_num+int(rand(100)); 603 }604 } 605 606 # .. and finally normalize the order (& show the user the order we chose) 607 print "Grabber order set as follows:\n"; 608 $order_num = 0;609 $opt->{setorder} = "";610 foreach my $proggy (sort { $grabbers->{$a}->{order} <=> $grabbers->{$b}->{order} } keys %$grabbers) {611 $order_num++;612 $grabbers->{$proggy}->{order} = $order_num;613 $opt->{setorder} .= "$proggy" . ",";614 printf " #%d. %s%s\n",$grabbers->{$proggy}->{order},$proggy,($grabbers->{$proggy}->{disabled} ? " [disabled]" : ""); 615 } 616 }756 } 757 758 # set order of any grabbers not specified in a random manner 759 foreach my $proggy (sort keys %$grabbers) { 760 if ((!defined $grabbers->{$proggy}->{order}) || ($grabbers->{$proggy}->{order} == 0)) { 761 $grabbers->{$proggy}->{order} = $order_num+int(rand(1000)); 762 } 763 } 764 765 # .. and finally normalize the order (& show the user the order we chose) 766 print "Grabber order set as follows:\n" unless $quiet; 767 $order_num = 0; 768 foreach my $proggy (sort { $grabbers->{$a}->{order} <=> $grabbers->{$b}->{order} } keys %$grabbers) { 769 $order_num++; 770 $grabbers->{$proggy}->{order} = $order_num; 771 printf " #%d. %s%s\n",$grabbers->{$proggy}->{order},$proggy,($grabbers->{$proggy}->{disabled} ? " [disabled]" : "") unless $quiet; 772 } 773 774 $made_changes = 1; 617 775 } 618 776 … … 620 778 { 621 779 my $result; 622 foreach (keys %$grabbers) 623 { 624 $result = test_grabber($_); 625 print "Grabber $_: " . 626 ($result ? "OK" : "Failed") . "\n\n"; 627 if (!$result ne !$grabbers->{$_}->{ready}) 628 { 629 $grabbers->{$_}->{ready} = $result; 780 foreach my $proggy (keys %$grabbers) { 781 $result = test_proggy("$GRABBER_DIR/$proggy","$GRABBER_DIR/$proggy/$proggy"); 782 printf "Grabber %s: %s\n",$proggy,($result ? "OK" : "Failed"); 783 if (!$result ne !$grabbers->{$proggy}->{ready}) { 784 $grabbers->{$proggy}->{ready} = $result; 785 $made_changes = 1; 786 } 787 } 788 789 foreach my $proggy (keys %$postprocessors) { 790 $result = test_proggy("$POSTPROCESSOR_DIR/$proggy","$POSTPROCESSOR_DIR/$proggy/$proggy"); 791 printf "Postprocessor %s: %s\n",$proggy,($result ? "OK" : "Failed"); 792 if (!$result ne !$postprocessors->{$proggy}->{ready}) { 793 $postprocessors->{$proggy}->{ready} = $result; 794 $made_changes = 1; 630 795 } 631 796 } … … 651 816 # at least one 'order' was missing .. we need to put it in! 652 817 printf "Legacy shepherd.conf file didn't contain any grabber order! Automatically updating using a random order, use --setorder to manually set this if you care.\n"; 653 &set_order(); 654 $opt->{setorder} = ""; 818 &set_order(1); 655 819 } 656 820 } … … 691 855 open(CONF, ">$config_file") or die "cannot write to $config_file: $!"; 692 856 print CONF Data::Dumper->Dump( 693 [$region, $ grabbers],694 ["region", " grabbers" ]);857 [$region, $pref_order, $grabbers, $postprocessors ], 858 ["region", "pref_order", "grabbers", "postprocessors" ]); 695 859 close CONF; 696 860 print "\nUpdated configuration file $config_file.\n" if ($debug); … … 710 874 'help' => \$opt->{help}, 711 875 'configure' => \$opt->{configure}, 876 'output' => \$opt->{output}, 712 877 'debug' => \$debug); 713 878 } … … 802 967 803 968 print "\nRandomly selecting grabber order.\n\n"; 804 set_order( );969 set_order(0); 805 970 806 971 show_channels(); … … 882 1047 sub status 883 1048 { 884 print " Grabber Version Enabled Ready Last Data\n" . 885 " -----------------------------------------------------------------\n"; 886 my $star; 887 foreach (sort { $grabbers->{$a}->{order} <=> $grabbers->{$b}->{order} } keys %$grabbers) 888 { 1049 print " Grabber Version Enabled Ready Last Run Status\n" . 1050 " ----------------- ------- ------- ----- ---------- ---------------------------\n"; 1051 foreach (sort { $grabbers->{$a}->{order} <=> $grabbers->{$b}->{order} } keys %$grabbers) { 889 1052 my $h = $grabbers->{$_}; 890 printf " %- 26s %8s %5s %7s %10s\n",1053 printf " %-16s %8s %4s %6s %11s %s\n", 891 1054 "$h->{order}. $_", 892 1055 $h->{ver}, 893 1056 $h->{disabled} ? '' : 'Y', 894 1057 $h->{ready} ? 'Y' : '', 895 $h->{lastdata} ? localtime($h->{lastdata}) : ''; 896 } 897 898 printf "Grabbers shown in order of preference.\n"; 1058 $h->{lastdata} ? (strftime "%a%d%b%y", localtime($h->{lastdata})) : '', 1059 $h->{laststatus} ? $h->{laststatus} : ''; 1060 } 1061 printf "Grabbers shown in order of preference.\n\n"; 1062 1063 print " Postprocessor Version Enabled Ready Last Run Status\n" . 1064 " ----------------- ------- ------- ----- ---------- ---------------------------\n"; 1065 foreach (sort { $postprocessors->{$a} <=> $postprocessors->{$b} } keys %$postprocessors) { 1066 my $h = $postprocessors->{$_}; 1067 printf " %-16s %8s %4s %6s %11s %s\n", 1068 $_, 1069 $h->{ver}, 1070 $h->{disabled} ? '' : 'Y', 1071 $h->{ready} ? 'Y' : '', 1072 $h->{lastdata} ? (strftime "%a%d%b%y", localtime($h->{lastdata})) : '', 1073 $h->{laststatus} ? $h->{laststatus} : ''; 1074 } 1075 printf "Postprocessors shown in order of execution.\n\n"; 899 1076 } 900 1077 … … 912 1089 913 1090 --setorder <s> Set order of grabbers to <s> (comma-seperated list of grabbers) 914 --disable <s> Don't ever use grabber <s> 1091 1092 --disable <s> Don't ever use grabber/postprocessor <s> 915 1093 --enable <s> Okay, maybe use it again then 916 --uninstall <s> Remove a disabled grabber 1094 --uninstall <s> Remove a disabled grabber/postprocessor 917 1095 918 1096 --noupdate Do not attempt to update before running 919 1097 --update Update only; do not grab data 920 1098 921 --check Check status of all grabbers 1099 --check Check status of all grabbers and postprocessors 922 1100 }; 923 1101 exit 0;
