File:  [Local Repository] / ConnorCalendar / calendar.pl
Revision 1.14: download - view: text, annotated - select for diffs
Fri Nov 13 18:07:40 2020 UTC (3 years, 6 months ago) by nick
Branches: MAIN
CVS tags: HEAD
Added school calendar days for 2020/2021 school year.

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

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