Annotation of ConnorCalendar/calendar.pl, revision 1.14
1.10 nick 1: #!/usr/bin/perl -w
1.1 nick 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.14 ! nick 11: | $Id: calendar.pl,v 1.13 2018/10/30 13:53:00 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;
1.10 nick 26: use Date::Pcalendar::Year qw( :all );
27: use Date::Pcalendar::Profiles qw( $Profiles );
1.1 nick 28:
1.14 ! nick 29: my $VERSION = '$Id: calendar.pl,v 1.13 2018/10/30 13:53:00 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.12 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',
1.8 nick 45: "New Year's Day" => 'odd',
46: "New Year's Eve" => 'odd',
1.1 nick 47: "Thanksgiving Day" => 'odd',
1.14 ! nick 48: );
1.1 nick 49:
50: my %specials = (
51: "11/28" => "even",
52: "5/6" => "odd",
53: );
1.12 nick 54:
1.14 ! nick 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:
1.12 nick 76: print "Content-type: text/html\n\n";
77: print &header( );
78:
79:
1.10 nick 80: ## Change this @weekend to 'qw/ 2011 8 12 /' for original schedule
81: my @weekend = qw/ 2011 8 19 /;
1.3 nick 82: my %weekends = &calcWeekends( @weekend );
1.1 nick 83:
84: &ReadParse( );
85:
1.12 nick 86: my $yr = sprintf( "%d", $post_in{'cy'} || ( localtime )[5] + 1900 );
1.1 nick 87: my $YEAR = sprintf( "%d", $yr );
1.9 nick 88: push @list, 'Easter Sunday' if ( $YEAR % 2 == 0 );
1.1 nick 89:
1.5 nick 90: print &css( );
1.10 nick 91: my $year_us = Date::Pcalendar::Year->new( $YEAR, $Profiles->{'US-FL'} );
1.1 nick 92: my @hdays = $year_us->labels( );
93:
1.7 nick 94: print "<h1><center><a href=\"$URL?cy=" . ( $YEAR - 1 ) .
95: "\"><--</a> " .
96: "Calendar Days Connor Visits for $YEAR" .
1.10 nick 97: "<a href=\"$URL?cy=" . ( $YEAR + 1 ) . "\"> --></a></h1>";
1.1 nick 98: my $row = 0;
1.5 nick 99: print "<table align=center border=0><tr>";
1.1 nick 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 ) ) {
1.3 nick 119: push @list, $h_day;
1.1 nick 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;
1.14 ! nick 126: } elsif ( &isSchoolClosed( $YEAR, $month, $day ) ) {
! 127: print sprintf "<font color=orange><b>%2d</b> </font>", $day;
1.1 nick 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>";
1.13 nick 141: print "<p class=\"Legend\">Holidays Connor visits are in <font color=red>Red</font>\n</br>";
1.6 nick 142: print "Today is <font color=blue>Blue</font>\n</br>";
1.14 ! nick 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";
1.13 nick 144: print "Weekends and special days Connor visits are in <font color=green>Green</font>\n</p>";
1.6 nick 145:
146:
1.7 nick 147: print "<table width=35% align=center border=0><tr><td>List of Special/Holidays " .
1.13 nick 148: "Connor Visits:<br /><p class=Legend>";
1.7 nick 149: print map { $_ . "<br />\n" } sort @list;
150: print "</p></td></tr></table>\n";
1.6 nick 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>";
1.3 nick 154:
1.1 nick 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: {
1.14 ! nick 174: my $y = shift || return 0;
! 175: my $m = shift || return 0;
! 176: my $d = shift || return 0;
1.1 nick 177: my $yr = ( $YEAR % 2 ) ? "odd" : "even";
178:
179: my $ref = "$m/$d";
180:
181: if ( defined $specials{$ref} )
182: {
1.3 nick 183: if ( $specials{$ref} eq "all" ||
184: $specials{$ref} eq $yr ) {
185: push @list, $ref;
186: return 1;
187: }
1.1 nick 188: }
189:
190: return 0;
191: }
192:
1.14 ! nick 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:
1.1 nick 208: sub isWeekend
209: {
1.3 nick 210: my $y = shift || return 0;
1.10 nick 211: my $m = shift || return 0;
212: my $d = shift || return 0;
1.1 nick 213:
1.3 nick 214: $m--;
215: my $ds = sprintf( "$y/$months[$m]/%02d", $d );
216:
217: return 1 if ( defined $weekends{$ds} );
218:
1.1 nick 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:
1.3 nick 234: sub calcWeekends
235: {
236: my $y = shift;
237: my $m = shift;
238: my $d = shift;
239: my %weekends = ( );
240:
1.13 nick 241: print "Weekends Connor Visits:\n";
1.3 nick 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:
1.1 nick 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:
1.5 nick 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;
1.7 nick 350: background: #eeeeee;
1.5 nick 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:
1.6 nick 364: p.Legend {
365: color: #000000;
366: font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif;
367: font-size: 8pt;
368: margin: auto;
1.7 nick 369: width: 300px;
1.6 nick 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:
1.5 nick 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;
1.6 nick 386: background-color : transparent;
387: margin-left: 20px;
388: margin-right: 20px;
389: border-top: 1px solid black;
390: border-bottom: 1px solid black;
1.5 nick 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:
1.6 nick 433: p.footer {
434: color: #000000;
435: font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif;
436: font-size: 8pt;
437: margin: auto;
1.7 nick 438: width: 500px;
1.6 nick 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;
1.5 nick 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:
1.1 nick 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>