1 #!/usr/bin/perl -Tw 2 use strict; 3 $|++; 4 5 use CGI qw(:standard); 6 use GD; 7 8 use constant CRLF => "\015\012"; 9 use constant SLEEPYTIME => 5; 10 use constant MAX_UPDATE => 60; 11 12 ## perl -MDate::Manip -e 'print &UnixDate(ParseDate("1/1/2000 12:00am GMT"),"%s")' 13 use constant Y2K_GMT => 946684800; 14 my @TIME_UNITS = ( 15 [ year => 365.25 * 24 * 60 * 60 ], 16 [ week => 7 * 24 * 60 * 60 ], 17 [ day => 24 * 60 * 60 ], 18 [ hour => 60 * 60 ], 19 [ minute => 60 ], 20 [ second => 1 ], 21 ); 22 23 my $tz = param('tz') || 0; 24 25 my $font = gdLargeFont; 26 my $char_x = $font->width; 27 my $char_y = $font->height; 28 29 print "HTTP/1.0 200 OK" . CRLF; 30 31 my $BOUNDARY = "the-time"; 32 print map($_ . CRLF, 33 "Content-Type: multipart/x-mixed-replace; boundary=$BOUNDARY", 34 "", 35 "--$BOUNDARY"); 36 for (my $count = 1; $count < MAX_UPDATE; $count++) { 37 my $gif = time_gif(); 38 print header(-type => 'image/gif', 39 -content_length => length($gif), 40 -expires => 'now', 41 ); 42 print $gif; 43 print CRLF . "--$BOUNDARY" . CRLF; 44 sleep SLEEPYTIME; 45 } 46 47 exit 0; 48 49 sub time_gif { 50 my $time = time - 3600 * $tz; 51 my $left = Y2K_GMT - $time; 52 my $string = "no time at all"; 53 if ($left >= 0) { 54 my @items = map { 55 my ($unit, $secs) = @$_; 56 my $count = int($left/$secs); 57 $left -= $count * $secs; 58 $count ? $count == 1 ? "1 $unit" : "$count ${unit}s" : (); 59 } @TIME_UNITS; 60 $string = 61 @items > 2 ? join(", ", @items[0..$#items-1], "and $items[-1]") : 62 @items > 1 ? "$items[0] and $items[1]" : 63 $items[0]; 64 } 65 66 my $picture_x = $char_x * length($string); 67 my $picture_y = $char_y; 68 69 my $image = GD::Image->new($picture_x, $picture_y); 70 my $background = $image->colorAllocate(127,127,127); 71 $image->transparent($background); 72 $image->interlaced('true'); 73 my $red = $image->colorAllocate(255,0,0); 74 $image->string($font, 0, 0, $string, $red); 75 $image->gif; 76 }