form auto-disabling, support for multiple parties
authorTroy Sankey <sankeytms@gmail.com>
Sat, 8 Feb 2014 07:06:45 +0000 (23:06 -0800)
committerTroy Sankey <sankeytms@gmail.com>
Sat, 8 Feb 2014 07:06:45 +0000 (23:06 -0800)
index.pl

index 23df7a8..a1e3397 100755 (executable)
--- a/index.pl
+++ b/index.pl
@@ -75,25 +75,27 @@ if ($q->param) {
 
 
 ###############################################################################
-# Function: print_rsvp
-# Parameters:
+# Function: print_rsvp_form
+# Parameters: bool to disable the form
 # Description: Print the rsvp form as an html form in an html table.
 ###############################################################################
-sub print_rsvp {
+sub print_rsvp_form {
+  my $disabled = $_[0];
   print $q->start_form();
-
   print $q->start_table(),
         "<tr>",
         "<td style=\"text-align:right;\">", "<em>Full Name: </em>", "</td>",
         "<td>", $q->textfield(-name=>'full_name',
                               -size=>30,
-                              -maxlength=>80), "</td>",
+                              -maxlength=>80,
+                              -disabled=>$disabled), "</td>",
         "</tr>\n",
         "<tr>",
         "<td style=\"text-align:right;\">", "<em>Email: </em>", "</td>",
         "<td>", $q->textfield(-name=>'email',
                               -size=>30,
-                              -maxlength=>80), " <em>(must be one of the emails in your key)</em>", "</td>",
+                              -maxlength=>80,
+                              -disabled=>$disabled), " <em>(must be one of the emails in your key)</em>", "</td>",
         "</tr>\n",
         "<tr>",
         "<td style=\"text-align:right;\">", "<em>Your PGP Key Fingerprint: </em>", "</td>",
@@ -101,12 +103,15 @@ sub print_rsvp {
                               -default=>'',
                               -override=>1,
                               -size=>50,
-                              -maxlength=>50), "</td>",
+                              -maxlength=>50,
+                              -disabled=>$disabled), "</td>",
         "</tr>\n",
         "<tr>",
         "<td></td>",
         "<td>", $q->submit(-name=>'submit',
-                           -value=>'Submit'), "</td>",
+                           -value=>'Submit',
+                           -disabled=>$disabled), " <em>(registration disabled 24h before the event)</em></td>",
+        "</tr>",
         $q->end_table();
 
   print $q->end_form;
@@ -191,6 +196,52 @@ sub get_next_party {
 }
 
 ###############################################################################
+# Function: get_previous_parties
+# Parameters:
+# Return: array of dates of all previous parties.
+# Description:
+#   Get the dates of all the previous parties.
+###############################################################################
+sub get_previous_parties {
+  my $sth = $dbh->prepare("SELECT idx,EXTRACT(EPOCH FROM datetime) FROM party WHERE datetime < now() ORDER BY datetime DESC")
+    or die "Couldn't prepare statement: " . $dbh->errstr;
+  $sth->execute()
+    or die "Couldn't execute statement: " . $dbh->errstr;
+  my @parties;
+  my $finished = 0;
+  while (!$finished) {
+    my @row = $sth->fetchrow_array();
+    if (defined @row) {
+      push (@parties, DateTime->from_epoch(epoch => $row[1], time_zone => 'local'));
+    } else {
+      $finished = 1;
+    }
+  }
+  return @parties;
+}
+
+###############################################################################
+# Function: get_party
+# Parameters: date string in ISO format (e.g. '2014-02-08')
+# Return: tuple contianing the party index and datetime.
+# Description:
+#   Get the index and date of any party.
+###############################################################################
+sub get_party {
+  my $date = $_[0];
+  my $sth = $dbh->prepare("SELECT idx,EXTRACT(EPOCH FROM datetime) FROM party WHERE date_trunc('day', datetime) = ?")
+    or die "Couldn't prepare statement: " . $dbh->errstr;
+  $sth->execute("$date 00:00:00")
+    or die "Couldn't execute statement: " . $dbh->errstr;
+  my @row = $sth->fetchrow_array(); # should just be one row
+  if (!defined @row) {
+    return undef;
+  }
+  $row[1] = DateTime->from_epoch(epoch => $row[1], time_zone => 'local');
+  return @row;
+}
+
+###############################################################################
 # Functions: render_keylist, get_keylist
 # Parameters: database, party index
 # Description:
@@ -414,14 +465,13 @@ sub print_body_home {
     print $q->end_html;
     return;
   }
-  my ($party_idx,$party_datetime) = get_next_party();
-  if (defined $party_idx) {
-    my $delta_party = $party_datetime->clone()
-                                     ->add(days => 1)  # i don't know why
-                                     ->delta_days(DateTime->today())
-                                     ->delta_days();
+  my ($next_party_idx,$next_party_datetime) = get_next_party();
+  if (defined $next_party_idx) {
+    my $delta_party = $next_party_datetime->clone();
+    $delta_party->truncate( to => 'day' );
+    $delta_party = $delta_party->delta_days(DateTime->today( time_zone => 'local' ))->delta_days();
     print "<p>Next keysigning party: <ins>" .
-          $party_datetime->strftime("%F %R %z") .
+          $next_party_datetime->strftime("%F %R %z") .
           "</ins> (" .
           ($delta_party == 0 ? "today!" :
            $delta_party == 1 ? "$delta_party day from now" :
@@ -430,11 +480,21 @@ sub print_body_home {
   } else {
     print "<p>Next keysigning party: <ins>none planned yet :-(</ins></p>";
   }
-  print "<p>If you would like to attend, please RSVP by filling in the form below.",
-        "<br>For instructions and more information, see the ",
+  print "<p>If you would like to attend, please RSVP by filling in the form below. You may attend even if registration has been closed!</p>";
+  my $registration_closed;
+  if (!defined $next_party_idx) {
+    $registration_closed = 1;
+  } else {
+    # registration is closed if now + 24h > next party.
+    $registration_closed =
+      (-1 == DateTime->compare(DateTime->now( time_zone => 'local' )
+                                       ->add_duration( DateTime::Duration->new( days => 1 ) ),
+                               $next_party_datetime));
+  }
+  print_rsvp_form($registration_closed);
+  print "<p>For instructions and more information, see the ",
         "<a href=\"https://linux.ucla.edu/wiki/index.php/Keysigning_party\">Keysigning party</a> ",
         "page on the wiki.</p>";
-  print_rsvp();
   print_tail();
   print $q->end_html;
 }
@@ -450,17 +510,22 @@ sub print_body_keylists {
     print $q->end_html;
     return;
   }
-  my ($party_idx,$party_datetime) = get_next_party();
+  my ($next_party_idx,$next_party_datetime) = get_next_party();
+  my @previous_parties = get_previous_parties();
   if ($rel_url =~ /^keylist(_.*)?\.txt$/) {
+    my $keylist_date_str = substr($1, 1);
     print $q->header(-type => 'text/plain', -charset=>"utf-8");
     if ($rel_url =~ /^keylist\.txt$/) {
-      print get_keylist($party_idx);
+      print get_keylist($next_party_idx);
     } else {
-      print "some other list...\n";
+      my ($party_idx,$party_datetime) = get_party($keylist_date_str);
+      print get_keylist($party_idx);
     }
   } elsif ($rel_url =~ /^keylist(_.*)?\.txt\.sha(1|224|256|384|512)$/) {
+    my $keylist_date_str = substr($1, 1);
+    my $shanum = $2;
     print $q->header(-type => 'text/plain');
-    print get_sha(get_keylist($party_idx),$2);
+    print get_sha(get_keylist($next_party_idx), $shanum);
     print "  keylist.txt";
   } elsif ($rel_url =~ /^keylist(_.*)?\.pdf$/) {
     binmode STDOUT, ':raw';  # this is binary PDF output, so don't use utf-8
@@ -468,25 +533,45 @@ sub print_body_keylists {
                      -type=>'application/pdf',
                      -content_disposition=>"inline; filename=keylist.pdf",
                      -charset=>"utf-8");
-    print get_pdf($party_idx);
+    print get_pdf($next_party_idx);
+  } elsif ($rel_url =~ /^(....-..-..)$/) {
+    print $q->header(-type=>"text/html", -charset=>"utf-8");
+    print $q->start_html(-title=>$page_title, -encoding=>"UTF-8");
+    print_head();
+    print "<p>Keylist from $1</p>";
+    my $kl_name = "keylist_$1";
+    print_keylist_links($kl_name);
+    print_tail();
+    print $q->end_html;
   } else {
     print $q->header(-type=>"text/html", -charset=>"utf-8");
     print $q->start_html(-title=>$page_title, -encoding=>"UTF-8");
     print_head();
-    print "<p style=\"font-family:monospace; font-size:1.2em;\">";
-    print "<a href=\"$base_url/lists/keylist.txt\">keylist.txt</a>.{",
-          "<a href=\"$base_url/lists/keylist.txt.sha1\">sha1</a>,",
-          "<a href=\"$base_url/lists/keylist.txt.sha224\">sha224</a>,",
-          "<a href=\"$base_url/lists/keylist.txt.sha256\">sha256</a>,",
-          "<a href=\"$base_url/lists/keylist.txt.sha384\">sha384</a>,",
-          "<a href=\"$base_url/lists/keylist.txt.sha512\">sha512</a>}", "<br>";
-    print "<a href=\"$base_url/lists/keylist.pdf\">keylist.pdf</a>";
-    print "</p>";
+    if (defined $next_party_idx) {
+      print "<p>Keylist for upcoming party:</p>";
+      print_keylist_links("keylist");
+    }
+    if (defined @previous_parties) {
+      print "<p>keylists from previous parties:</p>";
+    }
     print_tail();
     print $q->end_html;
   }
 }
 
+sub print_keylist_links {
+  my $kl_name = $_[0];
+  print "<p style=\"font-family:monospace; font-size:1.2em;\">";
+  print "<a href=\"$base_url/lists/$kl_name.txt\">$kl_name.txt</a>.{",
+        "<a href=\"$base_url/lists/$kl_name.txt.sha1\">sha1</a>,",
+        "<a href=\"$base_url/lists/$kl_name.txt.sha224\">sha224</a>,",
+        "<a href=\"$base_url/lists/$kl_name.txt.sha256\">sha256</a>,",
+        "<a href=\"$base_url/lists/$kl_name.txt.sha384\">sha384</a>,",
+        "<a href=\"$base_url/lists/$kl_name.txt.sha512\">sha512</a>}", "<br>";
+  print "<a href=\"$base_url/lists/$kl_name.pdf\">$kl_name.pdf</a>";
+  print "</p>";
+}
+
 sub print_body_keyrings {
   print $q->header(-type=>"text/html", -charset=>"utf-8");
   print $q->start_html(-title=>$page_title, -encoding=>"UTF-8");