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   }