#!/usr/bin/perl -wT use strict; # Demonstration code. Please edit the path. my $self = $ENV{SCRIPT_NAME} || "ENV ERROR"; # Used in link destination, but you can easily change that. print "Content-type: text/html\n\nOld Maps Index"; # Edit this path! &calendar("/path/to/files") or print "Could not read the directory."; print ""; ############################################################################################################# # # calendar(path) # # Runs under strict, taint mode, and generates no warnings. # # # # Print a really cool calendar of available files with dates in their names. # Suggested usage: index (log)files generated by some program that generates files. # See it in action at http://odin.prohosting.com/dakkalot/archive.pl # # Recognises files according to two regexps, which you will need to change to suit your situation, and provides # links behind the dates in the calendar, with customizable destinations. # Doesn't require a four-digit year, will ignore months outside of (1..12), but doesn't know how many days each # month has, so it'll gladly swallow and display the 32nd day of a month. # That is no problem, of course, unless your software actually generates files with such dates, then it might # look odd, but it won't screw up anything. Another effect of not knowing how many days each month has, is that # it won't display much for months that have only the first few files. Again, it won't screw up the calendar. # # Requires: Time::Local (standard module) to determine day-of-week of the first day of each relevant month. # Parameter: path to the maze directory. # Returns: true (and HTML output on STDOUT) on success, false on failure (cannot read directory). # Example call: # &calendar("/path/to/files") or print "Could not read directory."; # # How to customise: # I've marked the points you will need to customize with capital letters in the comments, so they're easy to # find. Points A and B need similar changes, since the regexps must look like eachother. # Point C isn't that important, but it gets rid of leading zeroes, which might be undesirable. # Point D determines the contents of the links for each day, and point E indicates you're ready to run it. ############################################################################################################# sub calendar { require Time::Local; # To determine day-of-week my $dir = shift; # The path to the directory to be indexed my @months = qw(January February March April May June July August September October November December); my @dow = qw(Sun Mon Tue Wed Thu Fri Sat); # Short names look better my $monthsperline = 2; # Number of months to display on a line my %CALENDAR; my ($year, $month, $day); ##### # A # ##### # The regexp in the grep block is designed to filter the directory contents to only relevant files. # This regexp finds files that look like "2001-5-30.mz", but of course you can change it to suit # Your situation. There is a similar regexp at point B, which captures these numbers. opendir DIR, $dir or return 0; my @files = grep { /^\d+-\d\d?-\d\d?\.mz$/ } readdir DIR; closedir DIR or return 0; foreach (@files) { ##### # B # ##### # This is the second regexp that must look like the first one. # year - month - day ($year, $month, $day) = $_ =~ /^(\d+)-(\d\d?)-(\d\d?)\.mz$/; ##### # C # ##### # Convert to numbers, eliminating leading zeroes. This might be a problem if your files do use them, # So comment it out if necessary. $year += 0; $month += 0; $day += 0; ##### # D # ##### # What is put in this HoHoA (or something ;-) is what the calendar cells will link to. Modify at will. $CALENDAR{$year}->{$month}->[$day] = "$self?map=$year-$month-$day"; } ##### # E # ##### # After this, there is nothing that you need to adjust for your situation, but you can do so to change the calendar's appearance. # If you've successfully changed points A and B, you should be ready to go, but for actual functionality, you'll need to modify # point D and possibly point C. # Start the actual calendar foreach $year (sort keys %CALENDAR) { my $thisyear = \%{$CALENDAR{$year}}; my $lastmonth = 0; print ""; foreach $month (1..12) { # foreach $month (sort { $a <=> $b } keys %$thisyear) { if(exists $thisyear->{$month}) { print ""; } else { print ""; } print "" if $month % $monthsperline == 0; } print "
$year
"; print ""; my $thismonth = \@{$CALENDAR{$year}->{$month}}; my $thisdow = (localtime Time::Local::timelocal(0,0,0,1,$month-1,$year))[6]; # dow for 1st day of month my $currentdow = 0; if($currentdow ne $thisdow) { # Don't do this if the month start on a Sunday! foreach (1..$thisdow) { print ""; $currentdow++; } } foreach $day (1..$#$thismonth) { my $contents = $CALENDAR{$year}->{$month}->[$day]; print ""; $currentdow++; if($currentdow == 7) { $currentdow = 0; print ""; } } print "
$months[$month-1]
"; print join "", @dow; print "
"; if($contents) { print "$day"; } else { # You can change this if you don't like the gray "N/A" in cells that exist but have no file print "N/A"; } print "
\n"; print "
\n" } return 1; }