Annotation of ConnorCalendar/calendar.pl, revision 1.7

1.1       nick        1: #!/usr/bin/perl -wT
                      2: 
                      3: =begin comment info
                      4: +------------------------------------------------------------------------------
                      5: |
                      6: | See end of script for comments and 'pod2man $NAME | nroff -man' to
                      7: | view man page or pod2text $NAME for plain text.
                      8: |
                      9: |   Nicholas DeClario <nick@demandred.dyndns.org>
                     10: |   March 2009
1.7     ! nick       11: |      $Id: calendar.pl,v 1.6 2013-05-29 03:27:02 nick Exp $
1.1       nick       12: |
                     13: +------------------------------------------------------------------------------
                     14: =end comment
                     15: =cut
                     16: BEGIN {
                     17:         delete @ENV{ qw(IFS CDPATH ENV BASH_ENV PATH) };
                     18:         $ENV{'PATH'} = "/bin:/usr/bin";
                     19:       }
                     20: 
                     21: use strict;
                     22: use Getopt::Long;
                     23: use Pod::Usage;
                     24: use Data::Dumper;
                     25: use Calendar::Simple;
                     26: use Date::Calendar::Year qw( :all );
                     27: use Date::Calendar::Profiles qw( $Profiles );
                     28: 
1.7     ! nick       29: my $VERSION  = q/$Id: calendar.pl,v 1.6 2013-05-29 03:27:02 nick Exp $/;
1.1       nick       30: my $DEBUG    = "";
1.2       nick       31: my $URL             = "http://demandred.dyndns.org/cgi-bin/ConnorCalendar/index.cgi";
1.1       nick       32: my %post_in  = ( );
                     33: my %opts     = &fetchOptions( );
1.3       nick       34: my @list     = ( );
1.1       nick       35: my @months   = qw/ January February March April May June July 
1.5       nick       36:                   August September October November December /;
1.1       nick       37: my %holidays = ( 
1.7     ! nick       38:                 "Easter Sunday"        => 'even',
1.1       nick       39:                 "Christmas Day"        => 'even',
                     40:                 "Christmas Eve"        => 'odd',
                     41:                 "Father's Day"         => 'all',
                     42:                 "Independence Day"     => 'even',
                     43:                 "Labor Day"            => 'even',
                     44:                 "Memorial Day"         => 'odd',
                     45:                 "New Year's Day"       => 'even',
1.7     ! nick       46:                 "New Year's Eve"       => 'even',
1.1       nick       47:                 "Thanksgiving Day"     => 'odd', 
                     48:               );
                     49: 
                     50: my %specials = (
                     51:                "11/28"                 => "even",
                     52:                "5/6"                   => "odd",
                     53:                );
1.3       nick       54: my @weekend  = qw/ 2011 8 12 /;
                     55: my %weekends = &calcWeekends( @weekend );
1.1       nick       56: 
                     57: &ReadParse( );
                     58: 
                     59: my $yr =  sprintf( "%d", $post_in{'cy'} ) || ( ( localtime )[5] + 1900 );
                     60: my $YEAR = sprintf( "%d", $yr );
1.7     ! nick       61: push @list, 'Easter Sunday' if ( ! $YEAR % 2 );
1.1       nick       62: 
                     63: print "Content-type: text/html\n\n";
1.5       nick       64: print &header( );
                     65: print &css( );
1.1       nick       66: my $year_us = Date::Calendar::Year->new( $YEAR, $Profiles->{'US-FL'} );
                     67: my @hdays = $year_us->labels( );
                     68: 
1.7     ! nick       69: print "<h1><center><a href=\"$URL?cy=" . ( $YEAR - 1 ) .
        !            70:       "\">&lt;--</a> " .
        !            71:       "Calendar Days Connor Visits for $YEAR" .
        !            72:        "<a href=\"$URL?cy=" . ( $YEAR + 1 ) . "\">--&gt;</a></h1>";
1.1       nick       73: my $row = 0;
1.5       nick       74: print "<table align=center border=0><tr>";
1.1       nick       75: for( my $month = 1; $month <= 12; $month++ )
                     76: {
                     77:        if ( $row >= 3 ) 
                     78:        {
                     79:                $row = 0;
                     80:                print "</tr><tr>";
                     81:        }
                     82:        print "<td align=center valign=top>";
                     83:        print "<b>$months[($month - 1)]</b>\n";
                     84:        print "<pre>Su Mo Tu We Th Fr Sa\n";
                     85:        my @CALS = calendar( $month, $YEAR );
                     86:        foreach my $cal ( @CALS ) 
                     87:        {
                     88:                foreach my $day ( @$cal ) 
                     89:                {
                     90:                        if( defined $day ) 
                     91:                        {
                     92:                                my $h_day = ( $year_us->labels( $YEAR, $month, $day ) )[1];
                     93:                                if( &IHaveConnor( $h_day ) ) {
1.3       nick       94:                                        push @list, $h_day;
1.1       nick       95:                                        print sprintf "<font color=red><b>%2d</b> </font>", $day;
                     96:                                } elsif ( &isSpecial( $YEAR, $month, $day ) || 
                     97:                                          &isWeekend( $YEAR, $month, $day ) ) {
                     98:                                        print sprintf "<font color=green><b>%2d</b> </font>", $day;
                     99:                                } elsif ( &isToday( $YEAR, $month, $day ) ) {
                    100:                                        print sprintf "<font color=blue><b>%2d</b> </font>", $day;
                    101:                                } else {
                    102:                                        print sprintf "%2d ", $day;
                    103:                                }
                    104:                        } else {
                    105:                                print '   ';
                    106:                        }       
                    107:                }
                    108:                print "\n";
                    109:        }
                    110:        print "</pre></td>";
                    111:        $row++;
                    112: }
                    113: print "</tr></table>";
1.6       nick      114: print "<p class=\"Legend\">Holidays I have Connor are in <font color=red>Red</font>\n</br>";
                    115: print "Today is <font color=blue>Blue</font>\n</br>";
                    116: print "Weekends and special days I have Connor are in <font color=green>Green</font>\n</p>";
                    117: 
                    118: 
1.7     ! nick      119: print "<table width=35% align=center border=0><tr><td>List of Special/Holidays " .
        !           120:       "I have Connor:<br /><p class=Legend>";
        !           121: print map { $_ . "<br />\n" } sort @list;
        !           122: print "</p></td></tr></table>\n";
1.6       nick      123: print "</pre><p class=\"footer\">Version: <font color=green>$VERSION</font><br />";
                    124: print "CVS: <a target=\"_new\" href=\"http://demandred.dyndns.org/cgi-bin/cvsweb/ConnorCalendar/\">http://demandred.dyndns.org/cgi-bin/cvsweb/ConnorCalendar/</a>";
                    125: print "</center></p>";
1.3       nick      126: 
1.1       nick      127: 
                    128: ###############################################################################
                    129: ###############################################################################
                    130: sub IHaveConnor 
                    131: {
                    132:        my $holiday = shift || return 0;
                    133:        my $y = ( $YEAR % 2 ) ? "odd" : "even";
                    134: 
                    135:        if ( defined $holidays{$holiday} )
                    136:        {
                    137:                return 1 if ( $holidays{$holiday} eq "all" );
                    138:                return 1 if ( $holidays{$holiday} eq $y );
                    139:        }
                    140: 
                    141:        return 0;
                    142: }
                    143: 
                    144: sub isSpecial
                    145: {
                    146:         my $y = shift || return 0;
                    147:         my $m = shift || return 0;
                    148:         my $d = shift || return 0;
                    149:        my $yr = ( $YEAR % 2 ) ? "odd" : "even";
                    150: 
                    151:        my $ref = "$m/$d";
                    152:        
                    153:        if ( defined $specials{$ref} )
                    154:        {
1.3       nick      155:                if ( $specials{$ref} eq "all" ||
                    156:                     $specials{$ref} eq $yr ) {
                    157:                        push @list, $ref;
                    158:                        return 1;
                    159:                }
1.1       nick      160:        }
                    161: 
                    162:        return 0;
                    163: }
                    164: 
                    165: sub isWeekend
                    166: {
1.3       nick      167:        my $y = shift || return 0;
1.1       nick      168:         my $m = shift || return 0;
                    169:         my $d = shift || return 0;
                    170: 
1.3       nick      171:        $m--;
                    172:        my $ds = sprintf( "$y/$months[$m]/%02d", $d );
                    173: 
                    174:        return 1 if ( defined $weekends{$ds} );
                    175: 
1.1       nick      176:        return 0;
                    177: }
                    178: 
                    179: sub isToday
                    180: {
                    181:        my $y = shift || return 0;
                    182:        my $m = shift || return 0;
                    183:        my $d = shift || return 0;
                    184: 
                    185:        return 1 if ( $y eq ( ( localtime )[5] + 1900 ) &&
                    186:             $m eq ( ( localtime )[4] + 1 ) &&
                    187:             $d eq ( ( localtime )[3] ) );
                    188:        return 0;
                    189: }
                    190: 
1.3       nick      191: sub calcWeekends 
                    192: {
                    193:        my $y = shift;
                    194:        my $m = shift;
                    195:        my $d = shift;
                    196:        my %weekends = ( );
                    197: 
                    198:        print "Weekends I have Connor:\n";
                    199: 
                    200:        use Calendar;
                    201:        my $date = Calendar->new_from_Gregorian( $m, $d, $y );
                    202:                
                    203:        $weekends{$date->date_string( "%Y/%M/%d" )} = 1;
                    204:        &twoMore( $date );
                    205:        while ( $date->date_string( "%Y" ) <= 2026 ) 
                    206:        {
                    207:                $date += 14;
                    208:                $weekends{$date->date_string( "%Y/%M/%d" )} = 1;
                    209:                &twoMore( $date );
                    210:        }
                    211: 
                    212:        return %weekends;
                    213: 
                    214:        sub twoMore 
                    215:        {
                    216:                my $td = shift;
                    217:                
                    218:                $td++;
                    219:                $weekends{$td->date_string( "%Y/%M/%d" )} = 1;
                    220:                $td++;
                    221:                $weekends{$td->date_string( "%Y/%M/%d" )} = 1;
                    222:        }
                    223: }
                    224: 
1.1       nick      225: ###############################################################################
                    226: ###############################################################################
                    227: sub ReadParse
                    228: {
                    229:         my $a = $_[0] ? $_[0] : \%post_in;
                    230:         my ( $i, $in );
                    231:         my @in = ( );
                    232: 
                    233:         if ( defined $ENV{'SERVER_NAME'} ) {
                    234:                 my $SERVER = $ENV{'SERVER_NAME'};
                    235:         }
                    236: 
                    237:         if ( ( defined $ENV{'REQUEST_METHOD'} ) &&
                    238:              ($ENV{'REQUEST_METHOD'} eq 'POST') )
                    239:         {
                    240:                 read(STDIN, $in, $ENV{'CONTENT_LENGTH'});
                    241:         }
                    242:         else
                    243:         {
                    244:                 $in = $ENV{'QUERY_STRING'} || "";
                    245:         }
                    246: 
                    247:         @in = split(/\&/, $in);
                    248: 
                    249:         foreach $i (@in)
                    250:         {
                    251:                 my ($k, $v) = split(/=/, $i, 2);
                    252:                 $k =~ s/\+/ /g; $k =~ s/%(..)/pack("c",hex($1))/ge;
                    253:                 $v =~ s/\+/ /g; $v =~ s/%(..)/pack("c",hex($1))/ge;
                    254:                 $a->{$k} = defined($a->{$k}) ? $a->{$k}."\0".$v : $v;
                    255:         }
                    256: 
                    257: }
                    258: 
                    259: ###############################################################################
                    260: ##
                    261: ## &fetchOptions( );
                    262: ##
                    263: ##      Grab our command line arguments and toss them in to a hash
                    264: ##
                    265: ###############################################################################
                    266: sub fetchOptions {
                    267:         my %opts;
                    268: 
                    269:         &GetOptions(
                    270:                         "help|?"        => \$opts{'help'},
                    271:                         "man"           => \$opts{'man'},
                    272:                    ) || &pod2usage( );
                    273:         &pod2usage( ) if defined $opts{'help'};
                    274:         &pod2usage( { -verbose => 2, -input => \*DATA } ) if defined $opts{'man'};
                    275: 
                    276:         return %opts;
                    277: }
                    278: 
1.5       nick      279: sub header {
                    280:        return <<EOF;
                    281: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                    282: 
                    283: <html xmlns="http://www.w3.org/1999/xhtml">
                    284: <head>
                    285: <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
                    286:     <title>Calendar Days Connor Visits</title>
                    287:   </head>
                    288: <body bgcolor="#FFFFFF">
                    289: EOF
                    290: }
                    291: 
                    292: sub css {
                    293:        return <<EOF;
                    294: <style type="text/css">
                    295: body {
                    296: 
                    297: padding-top: 0px;
                    298: padding-left: 0px;
                    299: padding-right: 0px;
                    300: padding-bottom: 0px;
                    301: 
                    302:  text-align:left;
                    303:  margin:0;
                    304:  font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif;
                    305:  #font-family: Geneva, Arial, Helvetica, sans-serif;
                    306:  font-size: 12pt;
1.7     ! nick      307:  background: #eeeeee;
1.5       nick      308:  color:#000000;
                    309: 
                    310: 
                    311: }
                    312: 
                    313: .name { 
                    314:  color: #191970; 
                    315:  font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif;
                    316:  #font-family: Verdana, Arial, sans-serif;
                    317:  font-size: 18pt; font-weight: bold; line-height: 38pt;
                    318:  text-align: center;
                    319: }
                    320: 
1.6       nick      321: p.Legend {
                    322:  color: #000000;
                    323:  font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif;
                    324:  font-size: 8pt;
                    325:  margin: auto;
1.7     ! nick      326:  width: 300px;
1.6       nick      327:  background-color : transparent;
                    328:  border-top: 1px solid #888888;
                    329:  border-left: 1px solid #888888;
                    330:  border-right: 1px solid #888888;
                    331:  border-bottom: 1px solid #888888;
                    332:  padding-top: 3px;
                    333:  padding-bottom: 3px;
                    334:  padding-left: 3px;
                    335:  padding-right: 3px;
                    336: }
                    337: 
1.5       nick      338: h1 { 
                    339:  color: #191970; 
                    340:  font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif;
                    341:  #font-family: Verdana, Arial, sans-serif;
                    342:  font-size: 12pt; font-weight: bold; line-height: 15pt;
1.6       nick      343:  background-color : transparent;
                    344:  margin-left: 20px;
                    345:  margin-right: 20px;
                    346:  border-top: 1px solid black;
                    347:  border-bottom: 1px solid black;
1.5       nick      348: }
                    349: 
                    350: 
                    351: h2 {
                    352:  color: #191970; 
                    353:  font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif;
                    354:         font-weight: bold;
                    355:         font-size: 18px;
                    356: }
                    357:         
                    358: h3 {
                    359:  color: #191970; 
                    360:  font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif;
                    361:         font-weight: bold;
                    362:         font-size: 14px;
                    363: }
                    364: 
                    365: 
                    366: textarea { width:100%; }
                    367: 
                    368: .gallery {
                    369: padding-top: 80px;
                    370: padding-left: 60px;
                    371: padding-right: 50px;
                    372: line-height: 120%;
                    373: background:url('topleft.jpg') no-repeat top left;
                    374: }
                    375: .browse {
                    376: padding-top: 80px;
                    377: padding-left: 60px;
                    378: padding-right: 50px;
                    379: line-height: 120%;
                    380: background:url(topleft.jpg) no-repeat top left;
                    381: }
                    382: .content, .rc {
                    383: padding-top: 100px;
                    384: padding-left: 80px;
                    385: padding-right: 50px;
                    386: line-height: 120%;
                    387: }
                    388: 
                    389: 
1.6       nick      390: p.footer {
                    391:  color: #000000;
                    392:  font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif;
                    393:  font-size: 8pt;
                    394:  margin: auto;
1.7     ! nick      395:  width: 500px;
1.6       nick      396:  background-color : transparent;
                    397:  border-top: 1px solid #888888;
                    398:  padding-top: 3px;
                    399:  padding-bottom: 3px;
                    400:  padding-left: 3px;
                    401:  padding-right: 3px;
                    402:  text-align: center;
1.5       nick      403: }
                    404: 
                    405: 
                    406: .header {
                    407: float: right;
                    408: margin-top: 30px;
                    409: margin-right: 50px;
                    410: padding: 10px;
                    411: padding-top: 10px,10px,10px,10px;
                    412: 
                    413: }
                    414: pre {
                    415:     border: #777777 1px dashed;
                    416:     padding: 0.5em;
                    417:     margin-left: 1em;
                    418:     margin-right: 2em;
                    419:     white-space: pre;
                    420:     background-color: #fbfdff;
                    421:     color: black;
                    422:     font-size:12px;
                    423: }
                    424: 
                    425: .refer {
                    426:        padding-left: 60px;
                    427:        padding-right: 50px;
                    428:        margin-right: 50px;
                    429:        margin-left: 50px;
                    430:        font-size:80%;
                    431: }
                    432: 
                    433: .gotobar {
                    434:        color: #191970; 
                    435:        font-size:10px;
                    436: }
                    437: 
                    438: .edit bar {
                    439:        color: #949ce5; 
                    440: }
                    441: 
                    442: .contactInfo {
                    443:        font-size:12px;
                    444:        text-align:center;
                    445: }
                    446: 
                    447: .workHeader {
                    448:        text-align:left;
                    449:        font-size:13px;
                    450:        text-decoration:none;
                    451:        font-weight:normal;
                    452: }
                    453: 
                    454: .workHeaderDate {
                    455:        float: right;
                    456: }
                    457: 
                    458: .workHeaderStrong {
                    459:        font-size:15px;
                    460:        text-decoration:none;
                    461:        font-weight:bolder;
                    462: }
                    463: 
                    464: .jobDescription {
                    465:        padding-top:15px;
                    466:        font-size:13px;
                    467: }
                    468: 
                    469: .bulletContent {
                    470:        font-size:13px;
                    471: }
                    472: 
                    473: .leftCol {
                    474:        width:10.2em;
                    475:        position:absolute;
                    476:        top:0;
                    477:        font-size:13px;
                    478:        padding-left:1%;
                    479:        padding-right:1%;
                    480: }
                    481: 
                    482: .rightCol {
                    483:        width:10.2em;
                    484:        position:absolute;
                    485:        top:0;
                    486:        font-size:13px;
                    487:        padding-left:1%;
                    488:        padding-right:1%;
                    489: }
                    490: 
                    491: a:link {color:#082e58;  text-decoration: none; font-weight:bolder;}
                    492: a:visited {color:#7795b7; font-weight:normal; text-decoration:none;}
                    493: a:hover {color:#949ce5;}
                    494: 
                    495: 
                    496: a.definition:before { content:"[::"; }
                    497: a.definition:after { content:"]"; }
                    498: a.alias { text-decoration:none; border-bottom: thin dashed; }
                    499: a.near:link { color:#093; }
                    500: a.near:visited { color:#550; }
                    501: a.upload:before { content:"<"; }
                    502: a.upload:after { content:">"; }
                    503: a.outside:before { content:"["; }
                    504: a.outside:after { content:"]"; }
                    505: img.logo { float: right; clear: right; border-style:none; }
                    506: div.diff { padding-left:5%; padding-right:5%; }
                    507: div.old { background-color:#FFFFAF; }
                    508: div.new { background-color:#CFFFCF; }
                    509: div.message { background-color:#FEE; }
                    510: div.journal h1 { font-size:large; }
                    511: table.history { border-style:none; }
                    512: td.history { border-style:none; }
                    513: span.result { font-size:larger; }
                    514: span.info { font-size:smaller; font-style:italic; }
                    515: div.rss { background-color:#EEF; }
                    516: div.sister { float:left; margin-right:1ex; background-color:#FFF; }
                    517: div.sister p { margin-top:0; }
                    518: div.sister img { border:none; }
                    519: div.near { background-color:#EFE; }
                    520: div.near p { margin-top:0; }
                    521: </style>
                    522: EOF
                    523: 
                    524: }
                    525: 
1.1       nick      526: __END__
                    527: 
                    528: =head1 NAME
                    529: 
                    530: masterbuild.pl - blurb
                    531: 
                    532: =head1 SYNOPSIS
                    533: 
                    534: masterbuild.pl [options]
                    535: 
                    536:  Options:
                    537:         --help,?        Display the basic help menu
                    538:         --man,m         Display the detailed man page
                    539: 
                    540: =head1 DESCRIPTION
                    541: 
                    542: =head1 HISTORY
                    543: 
                    544: =head1 AUTHOR
                    545: 
                    546: Nicholas DeClario <nick@declario.com>
                    547: 
                    548: =head1 BUGS
                    549: 
                    550: This is a work in progress.  Please report all bugs to the author.
                    551: 
                    552: =head1 SEE ALSO
                    553: 
                    554: =head1 COPYRIGHT
                    555: 
                    556: =cut

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>