#!c:\perl\bin\perl.exe #!/usr/bin/perl ################################################################################ # # File: roster.pl # RCS: $Header: $ # Description: Generates a dynamic page for displaying and editing # the current roster. Depends on two files: # tfile.txt - contains the roster items # pw.txt - contains the password on its only line # The pages will only contain items that are current, i.e., # the schedule always begins today (or later). # Author: Staal Vinterbo # Created: Tue May 13 11:41:24 2003 # Modified: Wed Mar 31 20:43:13 2004 (Staal Vinterbo) svinterb@dsg.bwh.harvard.edu # Language: Perl # Package: N/A # Status: Experimental (Do Not Distribute) # # (c) Copyright 2003, Staal Vinterbo, all rights reserved. # ################################################################################ use CGI; use CGI::Carp 'fatalsToBrowser'; use CGI::FormBuilder; use Time::Local 'timegm_nocheck'; ### Globals my $tfile = "data/tfile.txt"; my ($sec,$min,$hour,$day,$mon,$tyear,$wday,$yday,$isdst) = localtime(time); my $year = 1900 + $tyear; $mon += 1; my $defdate = $year.sprintf("%02d%02d",$mon,$day); my $defstime = "18:00"; my $defetime = "20:00"; my $pfile = "data/pw.txt"; my $pw; my $addform; my $delform; my @trans; # used in delform my @ids = (); # used in delform my %lh = (); # used in delform # init cgi my $cgi = CGI->new; #### Subs # helpers sub initpw { if(!open(pfd, "$pfile")){ print "could not open password file.\n"; die "could not open password file $pfile.\n"; } $pw = ; close(pfd); chomp($pw); } sub loadlist { local($fname) = @_; if(!open(tf, "$fname")){ print "could not open file\n"; die "could not open $tfile\n"; } my(@trans) = ; close(tf); $i = 0; sort { ($aname, $adate, $ast, $rest) = split(/;/,$a); ($bname, $bdate, $bst, $rest) = split(/;/,$b); $adate <=> $bdate || $ast cmp $bst; } map { chomp; $_ .= ";$i"; $i++; $_; } @trans; } sub selnewer { local(@strans) = @_; my @olist = (); for(@strans){ my($name, $date, $st, $et, $id, $rest) = split(/;/); /([0-9]{4})([0-9]{2})([0-9]{2})/ =~ $date; if($1 >= $year && ($2 >= $mon || $1 > $year) && ($3 >= $day || $1 > $year || $2 > $mon)){ push(@olist, $_); } } @olist; } sub stringtime { local($string) = @_; my @da = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"); my($name, $date, $st, $et, $id, $rest) = split(/;/, $string); /([0-9]{4})([0-9]{2})([0-9]{2})/ =~ $date; $unixtime = timegm_nocheck(0,0,0,$3 + 1,$2 - 1,$1 - 1900); @a = localtime($unixtime); "$da[$a[6]] $1/$2/$3 $st - $et\t$name"; } sub printformheader { local($title) = @_; print $cgi->header(); print $cgi->start_html(-title=>$title, -style=>{ 'src'=> 'dsg.css'}); print $cgi->h1($title); } sub getid { local($string) = @_; my($name, $date, $st, $et, $id, $rest) = split(/;/, $string); $id; } # page/form displaying sub doshow { local($all) = @_; printformheader("Staff Schedule"); # print the motd if(open(IN, "motd.txt")){ # print $cgi->hr; print ; close(IN); # print $cgi->hr, $cgi->p, "\n"; } print "To add entries click ", $cgi->a({-href => $cgi->url."?mode=addform"}, "add."),$cgi->br, "To delete entries click ", $cgi->a({-href => $cgi->url."?mode=delform"}, "delete."),$cgi->hr,$cgi->p; print "The ", $all ? "registered" : "current", " entries are:",$cgi->br; print "
";
    my @lines = loadlist($tfile);
    if(!$all){
	@lines = selnewer(@lines);
    }
    for(@lines){
	print stringtime($_), "\n";
    }
    print $cgi->hr,"
"; if($all){ print "Show only ", $cgi->a({-href=>$cgi->url()}, "current"); }else{ print "Show ", $cgi->a({-href=>$cgi->url()."?mode=showall"}, "all"); } print $cgi->p(), $cgi->a({-href=>'./'}, "Back"), $cgi->p(),$cgi->end_html; } sub createaddform { ($cgi->Vars)->{mode} = 'adddo'; # overwrite value $addform = CGI::FormBuilder->new(method=>'POST', title => 'Add Staff Time', text => 'To add a new schedule item, fill in the form and press submit.', fields => [name, date, stime, etime,password, mode], values => ['', $defdate, $defstime, $defetime, '', 'adddo'], labels => {stime => 'Start time', etime => 'End time'}, required => 'ALL', validate=>{name => '/^[0-9a-zA-Z.@() ]+$/', date => '/^[0-9]{8}$/', starttime => 'TIME', endtime => 'TIME', password => '/^\S{3,10}$/' }, params=>$cgi ); $addform->field(name => 'password', type=>'password'); $addform->field(name => 'date', comment=>'(YYYYMMDD)', size=>'8', maxlength=>'8'); $addform->field(name => 'stime', size=>'5', maxlength=>'5', comment => '(HH:MM, 24 hour)'); $addform->field(name => 'etime', size=>'5', maxlength=>'5', comment => '(HH:MM, 24 hour)'); $addform->field(name => 'mode', type=>'hidden', value => 'adddo', required => 0); } sub createdelform { ($cgi->Vars)->{mode} = 'deldo'; # overwrite value @trans = selnewer(loadlist($tfile)); my @l = (); @ids = (); %lh = (); for(@trans){ my $id = getid($_); my $label = stringtime($_); push(@l, $label); push(@ids, $id); $lh{$id} = $label; } $delform = CGI::FormBuilder->new(method=>'POST', title => 'Delete Staff Times', fields => ['mode','select','password'], text => 'Select the entries you want to delete, fill in password and then press submit.', params => $cgi, validate=>{password => '/^\S{3,10}$/'}); $delform->field(name => 'select', type => 'select', options => \@ids, multiple => 1, required => 'ALL', labels => \%lh); $delform->field(name => 'password', type=>'password', required => 1); $delform->field(name => 'mode', type=>'hidden', value => 'deldo', required => 0); } #### main program unless($cgi->param){ # no parameters doshow(0); } else { $mode = $cgi->param('mode'); if($mode eq 'showall'){ # create and show add form doshow(1); } elsif($mode eq 'addform'){ # create and show add form createaddform; printformheader("Add Staff Schedule Form"); print $addform->render(header => 0); } elsif($mode eq 'delform'){ # create and show del form createdelform; printformheader("Delete Staff Schedule Form"); if(@trans){ print $delform->render(header => 0); } else { print "Nothing to delete."; } } elsif($mode eq 'adddo'){ # process add form data createaddform; printformheader("Add Staff Schedule Form"); if($addform->submitted() && $addform->validate()) { initpw; my $f = $addform->field; unless($f->{password} eq $pw){ print "Sorry, invalid password."; } else { $s .= "$f->{name};$f->{date};$f->{stime};$f->{etime}"; if(!open(tfd, ">>$tfile")){ print "opening file error\n"; die "could not open $tfile for appending\n"; } print tfd "$s\n"; close(tfd); print $addform->confirm; #### print $cgi->p, $cgi->hr, "Staff: please remember to register for the VHB-forum, our bulletin board.", "After registering, please send a pm (on the board) to staal so he can add you to the", " keyholders list. This will give you access to a private forum where we can discuss", " adminstrative things. Thank you.", $cgi->br, $cgi->hr; #### } } } elsif($mode eq 'deldo'){ # process del form data createdelform; printformheader("Delete Staff Schedule Form"); if ($delform->submitted() && $delform->validate()) { initpw; my @selected = $delform->field('select'); my $f = $delform->field; unless($f->{password} eq $pw){ print "Sorry, invalid password.", $cgi->p(); } else { if(@selected){ %sh = map { $_ => 1 } @selected; if(!open(tf, "$tfile")){ print "could not open file\n"; die "could not open $tfile\n"; } @trans = ; close(tf); if(!open(tf, ">$tfile")){ print "could not open file for writing\n"; die "could not open $tfile for writing\n"; } $i = 0; for(@trans){ unless(defined($sh{$i++})){ print tf "$_"; } } close(tf); } print $delform->confirm; } } } print $cgi->p(), $cgi->a({-href=>$cgi->url}, "Back to schedule"), $cgi->p(),$cgi->end_html; }