File Coverage

blib/lib/SlideShow.pm
Criterion Covered Total %
statement 19 240 7.9
branch 0 98 0.0
condition 0 9 0.0
subroutine 7 15 46.6
pod 4 7 57.1
total 30 369 8.1


line stmt bran cond sub pod time code
1             package SlideShow;
2              
3 1     1   694 use strict;
  1         2  
  1         37  
4 1     1   5 use vars qw($VERSION @ISA);
  1         1  
  1         82  
5              
6             $VERSION = '2.0_02';
7              
8             @SlideShow::ISA = qw(HTML::Parser);
9              
10 1     1   3047 use CGI qw/:standard/;
  1         17259  
  1         7  
11 1     1   5510 use LWP::UserAgent;
  1         60348  
  1         33  
12 1     1   1015 use HTML::Parser;
  1         6398  
  1         38  
13 1     1   10 use URI::Escape;
  1         2  
  1         90  
14              
15             BEGIN {
16 1     1   2740 $SlideShow::last_marker = '';
17             }
18              
19             sub new {
20 0     0 1   my $class = shift;
21              
22 0           my $self = HTML::Parser->new();
23 0           bless $self, $class;
24              
25 0           while (my $X = shift) {
26 0           my $Y = shift;
27 0           $self->{$X} = $Y;
28             }
29              
30 0 0         die "SlideShow::Master missing required parameter 'master_cgi'"
31             unless exists $self->{master_cgi};
32              
33 0 0         $self->{start_title} = "SlideShow Startup"
34             unless exists $self->{start_title};
35 0 0         $self->{tmp_dir} = "/tmp"
36             unless exists $self->{tmp_dir};
37 0 0         $self->{view_file} = "$self->{tmp_dir}/viewfile.html"
38             unless exists $self->{view_file};
39 0 0         $self->{log_file} = "$self->{tmp_dir}/surflog.last"
40             unless exists $self->{tmp_log};
41 0 0         $self->{tmp_log} = "$self->{tmp_dir}/surf.tmp"
42             unless exists $self->{tmp_log};
43              
44 0 0         $self->{url_list} = [ "http://www.perl.com/CPAN/" ]
45             unless exists $self->{url_list};
46              
47 0 0         $self->{commentary} = "Presented using SlideShow, a Perl module"
48             . " for remote browser control available at"
49             ." www.perl.com/CPAN/"
50             unless exists $self->{commentary};
51              
52 0           $self->{redirect} = "$self->{master_cgi}?URL=";
53 0           $self->{inside} = 0;
54              
55 0           $self->{ua} = new LWP::UserAgent;
56 0           $self->{ua}->agent("SlideShow/2.0");
57              
58 0           $self;
59             }
60              
61             sub run {
62 0     0 0   my $self = shift;
63              
64 0 0         if (not param()) {
65             # no URL given
66 0           print
67             header,
68             start_html(-title => $self->{start_title},
69             -BGCOLOR => "#FFFFFF"),
70             h1($self->{start_title}),
71             start_form,
72             submit('Show URL'),
73             textfield('URL'),
74             end_form;
75              
76 0 0         if ($self->{url_list}) {
77 0           print hr;
78 0           print h2('presets');
79 0           print "
    \n";
80 0           for my $url (@{$self->{url_list}}) {
  0            
81 0           print "
  • {master_cgi}?URL=$url\">$url\n";
  • 82             }
    83 0           print "\n";
    84             }
    85            
    86 0 0         if ($self->{commentary}) {
    87 0           print hr;
    88 0           print $self->{commentary};
    89             }
    90              
    91 0           print end_html;
    92              
    93             } else {
    94 0           my $current_http_dir = param('URL');
    95 0           $current_http_dir =~ s/\s+$//;
    96              
    97 0 0         if (substr($current_http_dir, -1, 1) ne '/') {
    98 0           $current_http_dir =~ s!^(http://.*/).*!$1!;
    99             }
    100              
    101 0           $self->{current_dir} = $current_http_dir;
    102              
    103 0           print header;
    104              
    105 0           my $item = param('URL');
    106              
    107 0           unlink($self->{view_file});
    108              
    109 0 0         if (not open VIEWFILE, ">$self->{view_file}") {
    110 0           print "

    can't create $self->{view_file}: $!

    \n";
    111             } else {
    112 0           print VIEWFILE $$."\n";
    113              
    114 0 0         if ($item =~ /^\s*last\s*$/) {
    115 0           print VIEWFILE $SlideShow::last_marker."\n"; # send the termination
    116 0           close VIEWFILE;
    117              
    118 0 0         if (-e $self->{tmp_log}) {
    119 0           unlink ($self->{log_file});
    120 0           rename ($self->{tmp_log}, $self->{log_file});
    121             }
    122              
    123             print
    124 0           start_html(-title => "Session finished",
    125             -BGCOLOR => "#FFFFFF"),
    126             h1("Session finished");
    127              
    128 0           print "{master_cgi}\">New Session",p;
    129              
    130 0 0         if ($self->{log_file}) {
    131 0           print "
    \n";
    132 0           print "The pages were visited in this order:

    \n";

    133            
    134 0           open(LOG, $self->{log_file});
    135            
    136 0           while() {
    137 0           print "
  • ".$_;
  • 138             }
    139 0           close(LOG);
    140 0           print "
    \n";
    141 0           print "Save this document locally if you'd like to"
    142             . " keep a record.\n";
    143             }
    144              
    145 0           sleep(4); # sleep longer than the update time for clients
    146 0           unlink ($self->{view_file});
    147 0           exit 0;
    148             }
    149              
    150 0           my $req = new HTTP::Request 'GET' => $item;
    151 0           my $res = $self->{ua}->request($req);
    152              
    153 0 0         if (not $res->is_success) {
    154 0           print "Error: " . $res->status_line . "\n";
    155             } else {
    156 0           my $item = $res->as_string;
    157 0           print $self->rewrite($item, "master");
    158 0           print VIEWFILE $self->rewrite($item, "viewer");
    159 0 0         if ($self->{log_file}) {
    160 0 0         open LOG, ">>$self->{tmp_log}"
    161             or die "can't open $self->{tmp_log}: $!";
    162 0           print LOG param('URL')."\n";
    163 0           close LOG;
    164             }
    165             }
    166 0           close VIEWFILE;
    167              
    168             }
    169 0           print end_html;
    170             }
    171             }
    172              
    173             sub start {
    174 0     0 1   my $self = shift ;
    175 0           my ($tag, $attr, $attrseq, $origtext) = @_;
    176              
    177 0           $self->{result} .= '<' . $tag;
    178              
    179 0 0         if (lc($tag) eq 'html') {
    180 0           $self->{inside} = 1;
    181             }
    182              
    183 0 0         return unless $self->{inside};
    184 0           my $dirpref = $self->{current_dir};
    185              
    186 0           my $hostpref = $dirpref;
    187 0           $hostpref =~ s!^((?:ht|f)tp://[^\/]+).*!$1/!;
    188              
    189 0 0         if (defined $dirpref) {
    190 0 0         $dirpref .= '/' unless
    191             substr($dirpref, -1, 1) eq '/';
    192             }
    193              
    194 0 0         if (defined $attr->{'src'}) {
    195             # fully qualify any relative IMG paths
    196             # perhaps this should get the images locally and
    197             # serve them up, too, but for now it still points
    198             # to the original sites.
    199 0 0         if ($attr->{'src'} !~ m!^(?:ht|f)tp://!i) {
    200 0 0         if (substr($attr->{'src'}, 0, 1) eq '/') {
    201 0           $attr->{'src'} = $hostpref . $attr->{'src'};
    202             } else {
    203 0           print STDERR "$attr->{'src'} -> ";
    204 0           $attr->{'src'} = $dirpref . $attr->{'src'};
    205 0           print STDERR "$attr->{'src'}\n";
    206             }
    207             }
    208 0           $attr->{'src'} =~ s|/+$|/|;
    209             }
    210              
    211 0 0         if (defined $attr->{'href'}) {
    212 0 0         if ($attr->{'href'} !~ m!^(ht|f)tp://!i) {
    213 0 0         if (substr($attr->{'href'}, 0, 1) eq '/') {
    214 0           $attr->{'href'} = $hostpref . $attr->{'href'};
    215             } else {
    216 0           $attr->{'href'} = $dirpref . $attr->{'href'};
    217             }
    218             }
    219 0           $attr->{'href'} =~ s!/+$!/!;
    220             }
    221              
    222 0 0         if ($tag eq 'a') {
    223 0 0         if ($attr->{'href'}) {
    224              
    225 0 0         if ($self->{'which'} eq 'master') {
    226             # redirect HREFs on the master back into the CGI
    227 0           my $h = $self->{redirect} . $attr->{'href'};
    228 0           $attr->{'href'} = $h;
    229             } else {
    230             # convert the viewer's HREFs to some style
    231             # change so that aren't as easily tempted
    232             # to click off the path
    233 0           delete $attr->{'href'};
    234              
    235 0           $attr->{'color'} = 'red';
    236              
    237 0 0         push @$attrseq, 'color'
    238             unless grep $_ eq 'color', @$attrseq;
    239             }
    240             }
    241             }
    242              
    243 0           for my $m (@$attrseq) {
    244 0           $self->{result} .= " $m=\"$attr->{$m}\"";
    245             }
    246              
    247 0           $self->{result} .= '>';
    248 0 0 0       if ($tag eq 'body' and $self->{which} eq 'master') {
    249 0           $self->{result} .= "

    \n";

    250 0           $self->{result} .= "\nSlideShow: ";
    251 0           $self->{result} .= "{master_cgi}\">Top | ";
    252 0           $self->{result} .= "{master_cgi}?URL=last\">Quit ";
    253 0           $self->{result} .= "

    \n";
    254             }
    255            
    256 0           $self->{result};
    257             }
    258              
    259             sub text {
    260 0     0 1   my $self = shift ;
    261 0           my $text = shift;
    262              
    263 0 0         return unless $self->{inside};
    264              
    265 0           $self->{result} .= $text;
    266             }
    267              
    268             sub comment {
    269 0     0     my $self = shift ;
    270 0           my $comment = shift;
    271 0 0         return unless $self->{inside};
    272 0           $self->{result} .= "";
    273             }
    274              
    275             sub end {
    276 0     0 1   my $self = shift ;
    277 0 0         return unless $self->{inside};
    278              
    279 0           my ($tag, $origtext) = @_;
    280 0 0         if (lc($tag) eq 'html') {
    281 0           $self->{inside} = 0;
    282             }
    283 0 0 0       if (lc($tag) eq 'body' and $self->{which} eq 'master') {
    284 0           $self->{result} .= "\n";
    285              
    286 0           $self->{result} .= start_form
    287             . submit('Next Slide:')
    288             . textfield(-name => 'URL', -size=>40, -default=>param('URL'))
    289             . end_form;
    290             }
    291 0           $self->{result} .= $origtext;
    292             }
    293              
    294             sub rewrite {
    295 0     0 0   my $self = shift;
    296 0           my $html = shift;
    297 0           my $which = shift;
    298              
    299 0           $html =~ s/^.*?(
    300              
    301 0 0         if (lc($which) eq 'viewer') {
    302 0           $self->{which} = 'viewer';
    303             } else {
    304 0           $self->{which} = 'master';
    305             }
    306              
    307 0           $self->{result} = '';
    308              
    309 0           $self->parse($html);
    310              
    311 0           return $self->{result};
    312             }
    313              
    314             sub client {
    315 0     0 0   my %p;
    316 0           while (shift) {
    317 0           $p{$_} = shift;
    318             }
    319              
    320 0 0         $p{view_file} = "/tmp/viewfile.html"
    321             unless $p{view_file};
    322              
    323 0 0         $p{log_file} = "/tmp/surflog.last"
    324             unless $p{log_file};
    325             # $DEBUG = 1;
    326              
    327             # Unbuffer STDOUT
    328 0           $|=1;
    329              
    330 0           print "HTTP/1.0 200 OK\n";
    331 0           print "Content-type: multipart/x-mixed-replace;boundary=ThisRandomString\n";
    332 0           print "\n";
    333 0           print "--ThisRandomString\n";
    334              
    335 0           my $prev_surf_id = "-1";
    336 0           my $done = 0;
    337 0           my $count = 0;
    338 0           my $TIMEOUT = 60 * 4; # (browser timeout is typically 5 minutes)
    339              
    340             #
    341             # wait for the file to show up
    342             # present the startup message until it does
    343             #
    344 0           while (!-r $p{view_file}) {
    345 0           print "Content-type: text/html\n\n";
    346              
    347 0           print "\n";
    348 0           print "Waiting for session\n";
    349 0           print "\n";
    350 0           print "

    Presentation view

    \n";
    351              
    352 0           print "time: ".`date`."

    \n";

    353 0           print "Waiting for session to begin...
    \n\n";
    354              
    355 0           print "\n";
    356 0           print "\n";
    357              
    358 0           print "--ThisRandomString\n";
    359 0           sleep(5);
    360             }
    361              
    362             #
    363             # Once we've seen the file, we're in a presentation.
    364             #
    365 0           my ($line, $surf_id);
    366 0   0       while(($count < $TIMEOUT) && !$done) {
    367 0           $count++;
    368 0           $line = 0;
    369 0 0         if (open(ITEM, $p{view_file})) {
    370 0           while (my $item = ) {
    371 0           $line++;
    372 0 0         if ($line == 1) {
    373 0           chop $item;
    374 0           $surf_id = $item;
    375              
    376 0 0         if ($prev_surf_id eq $surf_id) {
    377 0           last;
    378             } else {
    379 0           $prev_surf_id = $surf_id;
    380 0           print "Content-type: text/html\n\n";
    381              
    382             ## Reset the presentation counter
    383 0           $count = 0;
    384              
    385 0           next;
    386             }
    387             }
    388              
    389 0 0         if ($item =~ /^$SlideShow::last_marker$/) {
    390 0           print "\n";
    391 0           print "Session finished\n";
    392 0           print "\n";
    393              
    394 0           print '
    395            

    Thank you

    396              
    397             The session has finished.
    398             ';
    399 0 0         if ($p{log_file}) {
    400 0           print "
    \n";
    401 0           print "The pages were visited in this order:

    \n";

    402            
    403 0           open(LOG, $p{log_file});
    404            
    405 0           while() {
    406 0           print "
  • ".$_;
  • 407             }
    408 0           close(LOG);
    409 0           print "
    \n";
    410 0           print "Save this document locally if you'd like to"
    411             . " keep a record.\n";
    412             }
    413 0           $done = 1;
    414 0           next;
    415             }
    416              
    417 0           print $item;
    418             }
    419 0           close(ITEM);
    420 0 0         print "\n--ThisRandomString\n" if ($line > 1);
    421             }
    422 0           sleep(1);
    423             }
    424              
    425 0 0         if ($count >= $TIMEOUT) {
    426 0           print "--ThisRandomString\n";
    427              
    428 0           print "Content-type: text/html\n\n";
    429 0           print "\n";
    430 0           print '',"\n";
    431 0           print "

    Timed out.

    \n";
    432 0           print "
    \n";
    433 0           print "This session has been active without update for too long.
    \n";
    434 0           print "Hit Reload if you think the session is still in progress.\n";
    435 0           print "\n";
    436             }
    437              
    438 0           print "--ThisRandomString--\n";
    439             }
    440              
    441              
    442             1;
    443             __END__