Software Freedom Law Center

Changeset 9

Show
Ignore:
Timestamp:
12/07/07 13:45:05 (1 year ago)
Author:
bkuhn
Message:
  • Initial mass changes to make it work for updating loblaw-test
    Mercurial repository.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/dev-tools/update-loblaw-test.plx

    r7 r9  
    11#!/usr/bin/perl 
    22 
    3 # This script is designed to be run from svn's post hooks.  It generally lives in 
    4 #  douglas:~svn/bin and called from the Calendaring repository post hooks 
    5  
    6 #  After a private calendar commit is completed, this script is called to 
    7 #  make the public version and committed. 
    8  
     3# This script is designed to be run launched by svn's post hooks under the 
     4# uid of the Mercurial repository.  It generally lives in ~svn/bin 
     5# and called from the repository post hooks 
    96 
    107# The sub's "safe_read_from_pipe" and read_from_process are: 
     
    4441use warnings; 
    4542 
    46 my $CAL_CHECKOUT = "/home/svn/Calendars-Checkout"; 
     43my $LOBLAW_TRUNK_CHECKOUT = "/home/hg/SVNCheckouts/loblaw-trunk"; 
    4744my $SVN = "/usr/bin/svn"; 
    48 my $EMACS = "/usr/bin/emacs-snapshot"; 
    4945my $SVNLOOK = "/usr/bin/svnlook"; 
    50 my $PIPE_FILE = "/home/svn/pipes/public-calendar-build"; 
     46my $PIPE_FILE = "/home/svn/pipes/loblaw-update"; 
    5147 
    5248use POSIX ":sys_wait_h"; 
     
    188184############################################################################### 
    189185############################################################################### 
    190 sub BinarySearchForTZEntry { 
    191 # $tzList is assumed to be sorted, $dateTime is  
    192   my($tzList, $dateTime) = @_; 
    193   my ($l, $u) = (0, @$tzList - 1);  # lower, upper end of search interval 
    194   my $i;                       # index of probe 
    195   my $final = 0; 
    196   while ($l <= $u) { 
    197     $i = int(($l + $u)/2); 
    198     my $compareVal = DateTime->compare($tzList->[$i]{date}, $dateTime); 
    199     if ($compareVal < 0) { 
    200       $l = $i+1; 
    201       $final = $i; 
    202     } elsif ($compareVal > 0) { 
    203       $u = $i-1; 
    204     } else { 
    205       return $tzList->[$i]; # found, won't happen often 
    206     } 
    207   } 
    208   return  $tzList->[$final];         # not found, go down one lower 
    209 } 
    210 ############################################################################### 
    211 sub PrivatizeMergeAndTZIcalFile ($$$$$$) { 
    212   my($icsPrivate, $icsPublic, $icsFull, $tzList, $user, $errorUser) = @_; 
    213  
    214   my %calendar; 
    215   $calendar{private} = Data::ICal->new(filename => $icsPrivate); 
    216   $calendar{public} = Data::ICal->new(filename => $icsPublic); 
    217   my $newCalendar = Data::ICal->new(data => <<END_ICAL 
    218 BEGIN:VCALENDAR 
    219 VERSION:2.0 
    220 PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.0//EN 
    221 END:VCALENDAR 
    222 END_ICAL 
    223 ); 
    224   my $type = "public"; 
    225   while (1) { 
    226     my $entries = (defined $calendar{$type}) ? $calendar{$type}->entries : []; 
    227     foreach my $entry (@{$entries}) { 
    228       $entry->add_property(class => "PRIVATE") if ($type eq "private"); 
    229  
    230       # Let's shift some timezones around. 
    231       foreach my $dateType (qw/DTSTART DTEND/) { 
    232         my $datePropList = $entry->property($dateType); 
    233         next unless @$datePropList > 0; 
    234  
    235         WarnLog($errorUser, "Strange that the entry below for $icsFull had more " . 
    236                       "than one $dateType:\n" . Data::Dumper->Dumper($entry) ) 
    237           unless @$datePropList == 1; 
    238  
    239         my $dateProp = $datePropList->[0]; 
    240         # Only continue processing date if we have this property.  (Duh) 
    241         next unless defined $dateProp; 
    242         my $params = $dateProp->parameters(); 
    243  
    244         # Only continue if it is a DATE-TIME property.  This is a bit of a 
    245         # judgement call but I think it's the right one.  When someone 
    246         # creates an all-day event, we don't want to allow it to drift to 
    247         # antoher day merely because the user has moved time zones. 
    248  
    249         next unless defined $params and defined $params->{VALUE} 
    250                                     and $params->{VALUE} =~ /DATE\-TIME/i; 
    251         my $nyTime = DateTime::Format::ICal->parse_datetime($dateProp->value); 
    252         my $newDate = DateTime::Format::ICal->parse_datetime($dateProp->value); 
    253         $nyTime->set_time_zone("America/New_York") 
    254           if $nyTime->time_zone->name =~ /floating/; 
    255         my $val = BinarySearchForTZEntry($tzList, $nyTime); 
    256         $newDate->set_time_zone($val->{newTZ}); 
    257         $newDate->set_time_zone("America/New_York"); 
    258         $newDate->set_time_zone("floating"); 
    259         my $newICalDate = DateTime::Format::ICal->format_datetime($newDate); 
    260         $dateProp->value($newICalDate); 
    261  
    262       } 
    263       $newCalendar->add_entry($entry); 
    264     } 
    265     last if ($type eq "private"); 
    266     $type = "private"; 
    267   } 
    268   foreach my $tzEntry (@$tzList) { $tzEntry->{date}->set_time_zone("floating"); } 
    269   for (my $ii = 0; $ii < @$tzList; $ii++) { 
    270     my $tzEntry = $tzList->[$ii]; 
    271  
    272     next unless defined $tzEntry->{location} and 
    273                 $tzEntry->{location} !~ /^\s*NYC\s*$/i; 
    274  
    275     my $startDate = DateTime::Format::ICal->format_datetime($tzEntry->{date}); 
    276  
    277  
    278     my $nextDate = ($ii+1 < @$tzList) ? 
    279       DateTime::Format::ICal->format_datetime($tzList->[$ii+1]{date}) : $startDate; 
    280  
    281     $nextDate =~ s/T\d+Z?$//; $startDate =~ s/T\d+Z?$//; 
    282  
    283     my $whereEvent = Data::ICal::Entry::Event->new(); 
    284     $whereEvent->add_properties(summary     => "$user Travel: ". $tzEntry->{location}, 
    285                                 description => $tzEntry->{location}, 
    286                                 dtstart     => [ $startDate, { VALUE => 'DATE' } ], 
    287                                 dtend       => [ $nextDate,{ VALUE => 'DATE' } ], 
    288                                 uid         => 'bkuhnScript' . (time() + $ii)); 
    289     $newCalendar->add_entry($whereEvent); 
    290   } 
    291   open(MERGED_CAL, ">$icsFull") or 
    292     DieLog("Unable to overwrite $icsFull: $!", $LOCK_CLEANUP_CODE); 
    293   print MERGED_CAL $newCalendar->as_string; 
    294   close MERGED_CAL; 
    295   DieLog("Error when writing $icsFull: $!", $LOCK_CLEANUP_CODE) 
    296     unless $? == 0; 
    297 } 
    298 ############################################################################### 
    299 sub FilterEmacsToICal ($$$$$) { 
    300   my ($publicCalendarFile, $privateCalendarFile, $outputFile, 
    301       $emacsSettings, $user) = @_; 
    302  
    303   my @tzList = BuildTZList($emacsSettings->{reportProblems}, 
    304                            $publicCalendarFile, $privateCalendarFile); 
    305  
    306   my($elispFH, $elispFile) = tempfile(); 
    307   my $icsWillBePrivatizedFile = tmpnam(); 
    308   my $icsPublicFile = tmpnam(); 
    309   print $elispFH "(setq-default european-calendar-style t)\n" 
    310     if $emacsSettings->{calendarStyle} =~  /european/i; 
    311   print $elispFH <<ELISP_END 
    312 (icalendar-export-file "$privateCalendarFile" "$icsWillBePrivatizedFile") 
    313 (icalendar-export-file "$publicCalendarFile" "$icsPublicFile") 
    314 ELISP_END 
    315 ; 
    316   $elispFH->close(); 
    317   my @emacsOutput = read_from_process($EMACS, '--no-windows', 
    318                  '--batch', '--no-site-file', '-l', $elispFile); 
    319   DieLog("Emacs process for exporting $privateCalendarFile and " . 
    320          "$publicCalendarFile exited with non-zero exit status of " . 
    321          "$? ($!), and output of:\n    " . join("\n   ", @emacsOutput), 
    322          $LOCK_CLEANUP_CODE) 
    323     if ($? != 0); 
    324   my $goodCount =0; 
    325   foreach my $line (@emacsOutput) { 
    326     $goodCount++  
    327       if $line =~ /^\s*Wrote\s+($icsPublicFile|$icsWillBePrivatizedFile)\s*$/; 
    328   } 
    329   DieLog("Unexpected Emacs output: " . join("\n   ", @emacsOutput), 
    330          $LOCK_CLEANUP_CODE) 
    331     if ($goodCount != 2); 
    332  
    333   my $icsFullFile = tmpnam(); 
    334   PrivatizeMergeAndTZIcalFile($icsWillBePrivatizedFile, $icsPublicFile, 
    335                             $icsFullFile, \@tzList, $user, 
    336                               $emacsSettings->{reportProblems}); 
    337  
    338   PrivacyFilterICalFile($icsFullFile, $outputFile); 
    339   DieLog("Unable to remove temporary files") 
    340     unless unlink($icsPublicFile, $icsWillBePrivatizedFile, $icsFullFile) == 3; 
    341 } 
    342186############################################################################### 
    343187# Take a list of keys and a list of values and insersperse them and 
     
    354198} 
    355199############################################################################### 
    356 sub BuildTZList ($$$) { 
    357   my($user, $pubEmacsFile, $privEmacsFile) = @_; 
    358  
    359   my @tzList; 
    360  
    361   foreach my $file ($pubEmacsFile, $privEmacsFile) { 
    362     open(DATA, "<$file") or DieLog("unable to read $file: $!", 
    363                                    $LOCK_CLEANUP_CODE); 
    364     while (my $line = <DATA>) { 
    365       if ($line =~ /^\s*;[;\s]*TZ\s*=([^\s,]+)\s*(?:,+\s*LOCA?T?I?O?N?\s*=\"([^"]+)\")? 
    366                     \s+(?:at|on)\s*(.*)\s+in\s+(\S+)\s*$/ix) { 
    367         my($newTZstr, $location, $dateStartStr, $dateStartTZstr) = ($1, $2, $3, $4); 
    368         my $newTZ; 
    369         eval { $newTZ = DateTime::TimeZone->new( name => $newTZstr ); }; 
    370         if ($@ or not defined $newTZ) { 
    371           WarnLog($user, 
    372                   "Invalid time zone of \"$newTZstr\" in $line from $file: $@"); 
    373           next; 
    374         } 
    375         my $dateStartTZ; 
    376         eval { 
    377           $dateStartTZ = DateTime::TimeZone->new( name => $dateStartTZstr ); }; 
    378         if ($@ or not defined $dateStartTZ) { 
    379           WarnLog($user, 
    380            "Invalid time zone of \"$dateStartTZstr\" in $line from $file: $@"); 
    381           next; 
    382         } 
    383         my(@data) = UnixDate("$dateStartStr", qw(%Y %m %d %H %M %S)); 
    384         if (@data != 6) { 
    385           WarnLog($user, "Unparseable date string of \"$dateStartStr\"" . 
    386                    "in $line from $file"); 
    387           next; 
    388         } 
    389         my @args = MergeLists([qw( year month day hour minute second)], \@data); 
    390         my $startDate; 
    391         eval { 
    392           $startDate = DateTime->new(@args, time_zone => $dateStartTZstr); 
    393         }; 
    394         if ($@ or not defined $startDate) { 
    395           WarnLog($user, "Trouble parsing \"$dateStartStr $dateStartTZstr\" " . 
    396                   "in $line from $file\n\n" . 
    397                   "Most likely $dateStartTZstr was a bad time zone.: $@ "); 
    398           next; 
    399         } 
    400         push(@tzList, { date => $startDate, newTZ => $newTZ, location => $location}); 
    401       } 
    402     } 
    403   } 
    404   # If we found nothing, everything is NYC 
    405   if (@tzList == 0) { 
    406     push(@tzList, { date => DateTime->new(year => 2006,  month => 11, day => 03, 
    407                                           hour =>  11, minute => 00,  second => 00, 
    408                                           time_zone => "America/New_York"), 
    409                     newTZ => "America/New_York", location => undef }); 
    410  
    411   } 
    412   return sort { DateTime->compare($a->{date}, $b->{date}); } @tzList; 
    413 } 
    414 ############################################################################### 
    415 sub PrivacyFilterICalFile ($$) { 
    416   my($inputFile, $outputFile) = @_; 
    417  
    418   my $oldCalendar = Data::ICal->new(filename => $inputFile); 
    419   my $newCalendar = Data::ICal->new(data => <<END_ICAL 
    420 BEGIN:VCALENDAR 
    421 VERSION:2.0 
    422 PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.0//EN 
    423 END:VCALENDAR 
    424 END_ICAL 
    425 ); 
    426   my $entries = (defined $oldCalendar) ? $oldCalendar->entries : []; 
    427   my $x =0; 
    428   foreach my $entry (@{$entries}) { 
    429     my @newSubEntries; 
    430     foreach my $subEntry (@{$entry->{entries}}) { 
    431       my $refVal = ref $subEntry; 
    432       if (defined $refVal and $refVal =~ /Alarm/i) { 
    433         # Don't put it in the list in the public version if is an alarm 
    434       } else { 
    435         push(@newSubEntries, $subEntry); 
    436       } 
    437     } 
    438     $entry->{entries} = \@newSubEntries; 
    439  
    440     my $classes = $entry->property('class'); 
    441     my $class; 
    442     foreach my $classProp (@{$classes}) { 
    443       $class = $classProp->value; 
    444       last if defined $class and 
    445         $class =~ /^\s*(?:PUBLIC|PRIVATE|CONFIDENTIAL)\s*/i; 
    446     } 
    447     if (defined $class and $class  =~ /CONFIDENTIAL/i) { 
    448       # do not put this event in the output at all 
    449       next; 
    450     } elsif (defined $class and $class =~ /PRIVATE/i){ 
    451       foreach my $prop (qw/location summary description/) { 
    452         my $propList = $entry->property($prop); 
    453         $entry->add_property($prop => "Private") 
    454           if (defined $propList and @{$propList} > 0); 
    455       } 
    456     } 
    457     $newCalendar->add_entry($entry); 
    458   } 
    459   open(SCRUBBED_CAL, ">$outputFile") or 
    460     DieLog("Unable to overwrite $outputFile: $!", $LOCK_CLEANUP_CODE); 
    461   print SCRUBBED_CAL $newCalendar->as_string; 
    462   close SCRUBBED_CAL; 
    463   DieLog("Error when writing $outputFile: $!", $LOCK_CLEANUP_CODE) 
    464     unless $? == 0; 
    465 } 
    466 ############################################################################### 
    467200sub DoUpdate ($) { 
    468201  my ($revision) = @_; 
    469202 
    470   chdir $CAL_CHECKOUT or 
    471     DieLog("unable to change directory to $CAL_CHECKOUT: $!", 
     203  chdir $LOBLAW_TRUNK_CHECKOUT or 
     204    DieLog("unable to change directory to $LOBLAW_TRUNK_CHECKOUT: $!", 
    472205           $LOCK_CLEANUP_CODE); 
    473206 
     
    490223my %CAUGHT_REVISIONS; 
    491224 
    492 my %EMACS_USER_KEY = (eben  => { calendarStyle => 'plain', 
    493                                  reportProblems => 'sullivan'}, 
    494                       bkuhn => { calendarStyle => 'european', 
    495                                  reportProblems => 'bkuhn'}, 
    496                       sullivan => { calendarStyle => 'plain', 
    497                                  reportProblems => 'sullivan'}, 
    498                       vasile => { calendarStyle => 'european', 
    499                                  reportProblems => 'vasile'}); 
    500  
    501225sub ProcessRevision ($$) { 
    502226  my($repository, $revision) = @_; 
     
    504228  return unless $repository =~ m|Repository/Calendars\s*$|; 
    505229 
    506   chdir $CAL_CHECKOUT or 
    507     DieLog("unable to change directory to $CAL_CHECKOUT: $!"); 
     230  chdir $LOBLAW_TRUNK_CHECKOUT or 
     231    DieLog("unable to change directory to $LOBLAW_TRUNK_CHECKOUT: $!"); 
    508232 
    509233  my @svnLookChangedLines = 
     
    554278    if ($type eq "ics") { 
    555279      my $dir = $file;  $dir =~ s|/Private/[^/]+\s*$||; 
    556       $filteredFile = "$CAL_CHECKOUT/$dir/${user}.ics"; 
    557  
    558       PrivacyFilterICalFile("$CAL_CHECKOUT/$file", $filteredFile); 
     280      $filteredFile = "$LOBLAW_TRUNK_CHECKOUT/$dir/${user}.ics"; 
     281 
     282      PrivacyFilterICalFile("$LOBLAW_TRUNK_CHECKOUT/$file", $filteredFile); 
    559283    } elsif ($type eq "emacs") { 
    560284      my($publicFile, $privateFile) = 
    561285      ("${user}/${user}-public.diary", "${user}/Private/${user}-private.diary"); 
    562       $filteredFile = "$CAL_CHECKOUT/${user}/${user}.ics"; 
    563       FilterEmacsToICal("$CAL_CHECKOUT/$publicFile", 
    564                         "$CAL_CHECKOUT/$privateFile", $filteredFile,  
     286      $filteredFile = "$LOBLAW_TRUNK_CHECKOUT/${user}/${user}.ics"; 
     287      FilterEmacsToICal("$LOBLAW_TRUNK_CHECKOUT/$publicFile", 
     288                        "$LOBLAW_TRUNK_CHECKOUT/$privateFile", $filteredFile,  
    565289                       $EMACS_USER_KEY{$user}, $user); 
    566290    } else { 
     
    693417    } 
    694418    # give a chance for the FIFO to recover 
    695     #    DieLog("Error encountered closing $PIPE_FILE: $!") unless ($? == 0); 
    696   } 
    697 } 
    698 ############################################################################### 
    699  
    700 open(PID, ">/home/svn/pids/public-cal.pid") or  
     419    #    DieLog("Error encountered closing $PIPE_FILE: $!") unless ($? == n0); 
     420  } 
     421} 
     422############################################################################### 
     423 
     424open(PID, ">/home/hg/pids/loblaw-test-update.pid") or  
    701425  DieLog("Unable to open PID file: $!"); 
    702426print PID "$$\n"; 

SFLC Main Page

[frdm] Support SFLC