Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

HTML Calendar Index for Files

by orkysoft (Friar)
on May 01, 2001 at 06:35 UTC ( [id://76860]=sourcecode: print w/replies, xml ) Need Help??
Category: CGI stuff
Author/Contact Info orkysoft
See it in action at the Mapster archive.
Description:

This subroutine indexes files that contain a date in their name, and displays them as a neat HTML calendar. It uses Time::Local to determine the day of week for the first day of each month, but doesn't know how many days a month has, and will happily index a file whose name indicates it's from the 32nd day of a given month. The number of months is hardwired, but it is flexible about years.

The months are displayed two in a row (easily changeable) and if there are no files for a given month, it's no problem. This calendar will make sure it gives a sane display. If there are no files for only some days in a month, it's not a problem either. If the missing days are between 1 and an existing file, they'll be marked as N/A, otherwise, not at all.

This calendar is designed to only find one file for a particular day.

Call it with the path to the directory to be indexed as a parameter. You might need to tweak the code for some hardwired things, but they're marked.

More information is included in comments in the code, but they're hard to miss.

Update: I changed the HTML in the two lines that start the tables for the years and the months, so it will display correctly in Netscape 4.7x, which it did not before.

#!/usr/bin/perl -wT
use strict;

# Demonstration code. Please edit the path.
my $self = $ENV{SCRIPT_NAME} || "ENV ERROR";    # Used in link destina
+tion, but you can easily change that.

print "Content-type: text/html\n\n<html><head><title>Old Maps Index</t
+itle></head><body>";

# Edit this path!
&calendar("/path/to/files") or print "Could not read the directory.";

print "</body></html>";



######################################################################
+#######################################
#
# 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 gen
+erates files.
# See it in action at http://odin.prohosting.com/dakkalot/archive.pl
#
# Recognises files according to two regexps, which you will need to ch
+ange to suit your situation, and provides
# links behind the dates in the calendar, with customizable destinatio
+ns.
# 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 mon
+th.
# That is no problem, of course, unless your software actually generat
+es files with such dates, then it might
# look odd, but it won't screw up anything. Another effect of not know
+ing 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 failu
+re (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 lette
+rs in the comments, so they're easy to
# find. Points A and B need similar changes, since the regexps must lo
+ok like eachother.
# Point C isn't that important, but it gets rid of leading zeroes, whi
+ch 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 b
+etter
    my $monthsperline = 2;                # Number of months to displa
+y on a line

    my %CALENDAR;
    my ($year, $month, $day);


#####
# A #
#####
# The regexp in the grep block is designed to filter the directory con
+tents 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 b
+e 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 cale
+ndar 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 situat
+ion, but you can do so to change the calendar's appearance.
# If you've successfully changed points A and B, you should be ready t
+o 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 "<table border=1 cols=$monthsperline width=100%><tr><th 
+colspan=$monthsperline align=center bgcolor=#aaaaaa>$year</th></tr><t
+r>";
        foreach $month (1..12) {            # foreach $month (sort { $
+a <=> $b } keys %$thisyear) {
            if(exists $thisyear->{$month}) {
                print "<td>";
                print "<table border=1 cols=7 width=100%><tr><th colsp
+an=7 align=center bgcolor=#cccccc>$months[$month-1]</th></tr><tr><th>
+";
                print join "</th><th>", @dow;
                print "</th></tr><tr>";
                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 d
+o this if the month start on a Sunday!
                    foreach (1..$thisdow) { print "<td></td>"; $curren
+tdow++; }
                }
                foreach $day (1..$#$thismonth) {
                    my $contents = $CALENDAR{$year}->{$month}->[$day];
                    print "<td>";
                    if($contents) {
                        print "<a href='$contents'>$day</a>";
                    } else {
                        # You can change this if you don't like the gr
+ay "N/A" in cells that exist but have no file
                        print "<font color=gray>N/A";
                    }
                    print "</td>";
                    $currentdow++;
                    if($currentdow == 7) {
                        $currentdow = 0;
                        print "</tr><tr>";
                    }
                }
                print "</tr></table>\n";
                print "</td>";
            } else {
                print "<td></td>";
            }
            print "</tr><tr>" if $month % $monthsperline == 0;
        }
        print "</tr></table>\n"
    }
    return 1;
}
Replies are listed 'Best First'.
(Vortacist) Re: HTML Calendar Index for Files
by Vortacist (Pilgrim) on May 02, 2001 at 03:01 UTC

    I think this is a neat idea, although if you wanted to add date-checking (to make sure you do have a valid date for the given month and refuse things like the 32nd day), Date::Calc would be just the module. It might have a few more features than you would need, but the documentation is good and I've found it easy to use.

      I see the printing of 32nd days and stuff (it'll even accept years like 1 and 40000) as a feature. If there are files with semi-legal names, it won't crash, screw up the display, or ignore the files, it'll extend the calendar to display them anyway.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://76860]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (6)
As of 2024-04-23 18:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found