[ Index ]
 

Code source de WebCalendar 1.0.5

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables | Statistiques

title

Body

[fermer]

/tools/ -> palm_datebook.pl (source)

   1  #!/usr/bin/perl
   2  
   3  =head1 NAME
   4  palm_datebook.pl
   5  
   6  =head1 SYNOPSIS
   7  Reads the events from a Palm Desktop DateBook.dat
   8  
   9  =head1 DESCRIPTION
  10  This file reads a Palm Desktop DateBook file (datebook.dat) and prints
  11  all the non-expired entries (can return all, see below) to STDOUT.  It prints a pipe
  12  separated value list by default.
  13  
  14  =head1 USAGE
  15  The script is set up to be used with the webcalendar and doesn't need to be
  16  altered.  If you want to use it some other way, then change the variables in
  17  the config section to suit your needs and edit the main program (bottom of script).
  18  You can uncomment the $outfile config to print to a file.  The default program 
  19  will not include expired events and takes 2 arguments:
  20  
  21    1. $DateBookFileName - The name/location of the datebook.dat
  22    2. $exc_private - If a 1 is passed private records will be skipped
  23  
  24  The following data is available in $Entry:
  25  
  26  $Entry->{RecordID}           =  Record ID in the Palm
  27  $Entry->{Status}             =  Identifies new and deleted records (status in datebook)
  28  $Entry->{Position}           =  Position in list?
  29  $Entry->{StartTime}          =  In seconds since 1970
  30  $Entry->{EndTime}            =  In seconds since 1970
  31  $Entry->{Description}        =  Description of event (string)
  32  $Entry->{Duration}           =  How long the event lasts (in minutes)
  33  $Entry->{Note}               =  Note (string)
  34  $Entry->{Untimed}            =  1 = true  0 = false
  35  $Entry->{Private}            =  1 = true  0 = false
  36  $Entry->{Category}           =  useless for Palm
  37  $Entry->{AlarmSet}           =  1 = true  0 = false
  38  $Entry->{AlarmAdvanceAmount} =  How many units in AlarmAdvanceType (-1 means not set)
  39  $Entry->{AlarmAdvanceType}   =  Units: (0=minutes, 1=hours, 2=days)
  40  $Entry->{Repeat}             =  Array containing repeat information (if repeat)
  41  $Entry->{Repeat}->{Interval}   =  1=daily,2=weekly,3=MonthlyByDay,4=MonthlyByDate,5=Yearly
  42  $Entry->{Repeat}->{Frequency}  =  How often event occurs. (1=every, 2=every other,etc.)
  43  $Entry->{Repeat}->{EndTime}    =  When the repeat ends (In seconds since 1970)
  44  $Entry->{Repeat}->{Exceptions} =  An exception to the repeat (In seconds since 1970)
  45  $Entry->{Repeat}->{RepeatDays} =  For Weekly: What days to repeat on (7 characters...y or n for each day)
  46  $Entry->{Repeat}->{DayNum}     =  For MonthlyByDay: Day of week (1=sun,2=mon,3=tue,4=wed,5=thu,6=fri,7=sat)
  47  $Entry->{Repeat}->{WeekNum}    =  For MonthlyByDay: Week number (1=first,2=second,3=third,4=fourth,5=last)
  48  
  49  =head1 CONTRIBUTERS
  50  Eduard Martinescu - Provided patch to parse category list.
  51  
  52  =cut
  53  
  54  use CGI qw (:standard);
  55  my $q = new CGI;
  56  my ($Year, $Month, $Day);
  57  my $DATA;
  58  
  59  # -----------------------  Config if necessary  ----------------------------
  60  my $DateBookFileName = $ARGV[0];  # The name of the file
  61  my $exc_private = $ARGV[1];       # Do we want private entries? (1 = skip private)
  62  my $inc_expired = 0;              # Do we want expired entries? (1 = include expired)
  63  my $sep = "|";                    # what to separate the output with
  64  #my $outfile = "/tmp/datebook_dump.txt";  # uncomment to print to file
  65  #---------------------------------------------------------------------------
  66  
  67  #=================
  68  sub ReadDateBook {
  69  #=================
  70  # ReadDateBook opens the file we passed (datebook.dat) and reads the entries.
  71  
  72    my ($FileName, $Filter) = @_;
  73    my (@Fields, @Entries, $FieldCount, $NumberOfEntries);
  74    my ($Entry, $i, $Header, $Tag);
  75    my ($NextFree, $CategoryCount, $Category, @Categories, $ResourceID);
  76    my ($FieldsPerRow, $RecordIdPos, $RecordStatusPos, $RecordPlacementPos);
  77  
  78    open DATEBOOK, "<".$FileName;
  79    binmode DATEBOOK;
  80  
  81    local $/ = undef;
  82    $_ = <DATEBOOK>;
  83    $GlobalPos = 0;
  84    close DATEBOOK;
  85  
  86    # First, check the initial 4 byte "tag" field.
  87    $Tag = ReadByteString(4);
  88  
  89    # Next, read the header information.
  90    $FileName = ReadPilotString();
  91    $Header   = ReadPilotString();
  92    $NextFree = ReadLong();
  93  
  94    # Read the category information
  95    $CategoryCount = ReadLong();
  96    for ($i=0; $i<$CategoryCount; $i++) {
  97      $Category = ReadCategory();
  98      push (@Categories,$Category) if ($Category ne 0);
  99    }
 100  
 101    $ResourceID         = ReadLong();
 102    $FieldsPerRow       = ReadLong();
 103    $RecordIdPos        = ReadLong();
 104    $RecordStatusPos    = ReadLong();
 105    $RecordPlacementPos = ReadLong();
 106  
 107    # Read the field list.
 108    $FieldCount = ReadShort();
 109    for ($i=0; $i<$FieldCount; $i++)
 110       {push @Fields, ReadShort();}
 111  
 112    # Figure out how many entries to read
 113    $NumberOfEntries = ReadLong() / $FieldCount;
 114  
 115    # Read the entries.
 116    for ($i=0; $i<$NumberOfEntries; $i++) {
 117      $Entry = ReadEntry();
 118      if ($Entry ne 0){
 119        if (!$Filter or &$Filter($Entry)){push @Entries, $Entry;}
 120      }
 121    }
 122  
 123    return @Entries;
 124  }
 125  
 126  #==============
 127  sub ReadEntry {
 128  #==============
 129  # ReadPalmEntry reads a single entry from the datebook, stores it in a local
 130  # hash, and returns a reference to that hash.  The reference can safely
 131  # be stored in an array for later use.
 132  
 133    my (%Entry);
 134  
 135    $Entry{RecordID}           = ReadPilotField();
 136    $Entry{Status}             = ReadPilotField();
 137    $Entry{Position}           = ReadPilotField();
 138    $Entry{StartTime}          = ReadPilotField();
 139    $Entry{EndTime}            = ReadPilotField();
 140    $Entry{Description}        = ReadPilotField();
 141    $Entry{Duration}           = ReadPilotField();
 142    $Entry{Note}               = ReadPilotField();
 143    $Entry{Untimed}            = ReadPilotField();
 144    $Entry{Private}            = ReadPilotField();
 145    $Entry{Category}           = ReadPilotField();
 146    $Entry{AlarmSet}           = ReadPilotField();
 147    $Entry{AlarmAdvanceAmount} = ReadPilotField();
 148    $Entry{AlarmAdvanceType}   = ReadPilotField();
 149    $Entry{Repeat}             = ReadPilotField();
 150  
 151    #Should return as -1 if not set, but is returning as 4294967295
 152    $Entry{AlarmAdvanceAmount} = "-1" if ($Entry{AlarmAdvanceAmount} eq '4294967295');
 153  
 154    # Remove Crap from the DateBook5 Application
 155    $Entry{Note} = '' if ($Entry{Note} =~ /^\#\#[fcdxX\@]/);
 156  
 157    # Filter single quotes, \n\r
 158    $Entry{Description} = &filter_quotes($Entry{Description});
 159    $Entry{Note} = &filter_quotes($Entry{Note});
 160  
 161    # Calculate duration in minutes
 162    $Entry{Duration} = ($Entry{EndTime} - $Entry{StartTime}) / 60;
 163  
 164    # Skip private records if $exc_private
 165    if (($exc_private) && ($Entry{Private} == 1)) {
 166      return 0;
 167    # Skip Record if not in Palm (no RecordID) or marked for deletion
 168    } elsif (($Entry{RecordID} == 0) || ($Entry{Status} == 129) || ($Entry{Status} == 4)){
 169      return 0;
 170    # Skip events that are past endtime (except repeats that aren't expired) unless $inc_expired
 171    } elsif (($Entry{EndTime} < time()) && (!$Entry{Repeat}) && (!$inc_expired)){
 172      return 0;
 173    } elsif (($Entry{Repeat}) && ($Entry{Repeat}{EndTime} < time())&& ($Entry{Repeat}{EndTime} != 0) && (!$inc_expired)){
 174      return 0;
 175    } else {
 176  #print $Entry{RecordID} . "\n";
 177      return \%Entry;
 178    }
 179  }
 180  
 181  #===================
 182  sub ReadPilotField {
 183  #===================
 184  # ReadPilotField returns a single field from the datebook file.
 185    my ($Type, $N, $sun, $mon, $tue, $wed, $thu, $fri, $sat);
 186    my ($i, $DatesToSkip, $Repeat, $Interval, $Frequency, $Duration, $Position, $EndTime, $exceptions, @E);
 187    my (%RA);
 188  
 189    $Type = ReadLong();
 190  
 191    if ($Type == 1 or $Type == 3 or $Type == 6) {
 192      return ReadLong();
 193    } elsif ($Type == 5) {
 194       ReadLong();  # Skip the long of all zeroes
 195       return ReadPilotString();
 196    } elsif ($Type == 8) {
 197       $DatesToSkip = ReadShort();
 198       for ($i=1; $i<=$DatesToSkip; $i++)
 199          {$exceptions .= ReadLong().":";}
 200       chop $exceptions;
 201       $Repeat = ReadShort();
 202       if ($Repeat == 0xFFFF) {
 203         ReadShort();
 204         $Skip = ReadShort();
 205         SkipBytes($Skip);
 206       } elsif ($Repeat and $Repeat != 0x8001) { #($Repeat == 0x1a40 or $Repeat == 0xb3c0 or $Repeat == 0xe750)
 207  #         print "       DEBUG: Repeat is $Repeat\n";
 208  #         ReadLong();
 209       }
 210       if ($Repeat) {
 211         $Interval   = ReadLong();
 212         $Frequency  = ReadLong();
 213         $EndTime    = ReadLong();
 214         if ($EndTime eq 1956542399) {       # No EndTime
 215           $EndTime = '';
 216         }
 217  
 218           ReadLong();
 219         $DayNum =  ReadLong();
 220         if ($Interval == 2) {
 221           $Position = ReadByte();
 222         } elsif ($Interval == 3) {
 223           $Position = ReadLong();
 224         } elsif ($Interval == 5) {
 225           $Position = ReadLong();
 226         } else {
 227           $Position == 0;
 228         }
 229  
 230         # Build the Repeat array to return
 231         $RA{Interval} = $Interval;
 232         $RA{Frequency} = $Frequency;
 233         $RA{EndTime}  = $EndTime;
 234         if ($exceptions){ $RA{Exceptions} = $exceptions;}
 235  
 236         if ($Interval == 2) {            # Weekly repeat
 237           # $Position is an integer that tells what days of the week
 238           # to repeat on. (sun=1,mon=2,tue=4,wed=8,thu=16,fri=32,sat=64)
 239           # The numbers are added together to give a unique integer.
 240           # We will break it down since the WebCalendar doesn't use this format.
 241           $N = $Position;
 242  
 243            # Check for Saturday
 244            if ($N - 64 >= 0) {
 245              $sat = 'y';
 246              $N -= 64;
 247            } else {
 248              $sat = 'n';
 249            }
 250  
 251            # Check for Friday
 252            if ($N - 32 >= 0) {
 253              $fri = 'y';
 254              $N -= 32;
 255            } else {
 256              $fri = 'n';
 257            }
 258  
 259            # Check for Thursday
 260            if ($N - 16 >= 0) {
 261              $thu = 'y';
 262              $N -= 16;
 263            } else {
 264              $thu = 'n';
 265            }
 266  
 267            # Check for Wednesday
 268            if ($N - 8 >= 0) {
 269              $wed = 'y';
 270              $N -= 8;
 271            } else {
 272              $wed = 'n';
 273            }
 274  
 275            # Check for Tuesday
 276            if ($N - 4 >= 0) {
 277              $tue = 'y';
 278              $N -= 4;
 279            } else {
 280              $tue = 'n';
 281            }
 282  
 283            # Check for Monday
 284            if ($N - 2 >= 0) {
 285              $mon = 'y';
 286              $N -= 2;
 287            } else {
 288              $mon = 'n';
 289            }
 290  
 291            # Check for Sunday
 292            if ($N - 1 >= 0) {
 293              $sun = 'y';
 294              $N -= 1;
 295            } else {
 296              $sun = 'n';
 297            }
 298            $RA{RepeatDays} = $sun.$mon.$tue.$wed.$thu.$fri.$sat;
 299         } elsif ($Interval == 3) {      # Monthlybyday repeat
 300           $RA{DayNum} = $DayNum + 1;    # Day of week (1=sun,2=mon,3=tue,4=wed,5=thu,6=fri,7=sat)
 301           $RA{WeekNum} = $Position + 1; # Week number (1=first,2=second,3=third,4=fourth,5=last)
 302         }
 303         return \%RA;
 304       } else {
 305         return 0;  # No repeat
 306       }
 307    } else {
 308  #      print STDERR "There's a problem with this pilot field of type $Type\n";
 309     return undef;
 310    }
 311  }
 312  
 313  
 314  #===================
 315  sub ReadByteString {
 316  #===================
 317  # ReadByteString reads the number of bytes passed to it as a parameter
 318  # and returns it as a character string.
 319  
 320     my ($Count) = @_;
 321     $GlobalPos += $Count;
 322     return substr ($_, $GlobalPos-$Count, $Count);
 323  }
 324  
 325  #====================
 326  sub ReadPilotString {
 327  #====================
 328  # ReadPilotString reads a pilot formatted string, which is a size (one
 329  # byte, unless the byte is 0xFF, then it's the two bytes after the 0xFF),
 330  # followed by that many bytes, and returns a Perl string.
 331  
 332    my ($String) = "";
 333    my ($Length, $i);
 334  
 335    $Length = unpack ('C', substr ($_, $GlobalPos, 1));
 336    $GlobalPos++;
 337    if ($Length == 255) {
 338      $Length = ReadShort();
 339    }
 340  
 341    $GlobalPos += $Length;
 342    return substr ($_, $GlobalPos-$Length, $Length);
 343  }
 344  
 345  #==============
 346  sub SkipBytes {
 347  #==============
 348  # SkipBytes is just like ReadByteString, except it throws away the data,
 349  # rather than returning it.
 350  
 351    my ($Count) = @_;
 352    $GlobalPos += $Count;
 353  }
 354  
 355  #=============
 356  sub ReadByte {
 357  #=============
 358  # ReadByte reads a single byte, and returns it as an integer.
 359  
 360    $GlobalPos++;
 361    return unpack ('C', substr($_, $GlobalPos-1, 1));
 362  }
 363  
 364  #==============
 365  sub ReadShort {
 366  #==============
 367  # ReadShort reads two bytes, and returns them as an integer (low order
 368  # byte is the first one read).
 369  
 370    $GlobalPos+=2;
 371    return unpack ('S', substr($_, $GlobalPos-2, 2));
 372  }
 373  
 374  #=============
 375  sub ReadLong {
 376  #=============
 377  # ReadLong reads four bytes, and returns them as an integer (low order
 378  # byte is the first one read).
 379  
 380    $GlobalPos+=4;
 381    return unpack ('L', substr($_, $GlobalPos-4, 4));
 382  }
 383  
 384  #====================
 385  sub ByDateAscending {
 386  #====================
 387  # Sort records by StartTime
 388  
 389    return $a->{StartTime} <=> $b->{StartTime};
 390  }
 391  
 392  #==================
 393  sub filter_quotes {
 394  #==================
 395  # Filter newline/return
 396     
 397    my $temp = $_[0];
 398  #  $temp =~ s/'/\\'/g;
 399    $temp =~ s/\n|\r/ /g; # Remove newline
 400    return ($temp);
 401  }
 402  
 403  #=================
 404  sub ReadCategory {
 405  #=================
 406  # ReadCategory reads a single category entry from the datebook,
 407  # stores it in a local hash, and returns a reference to that hash.
 408  # The reference can safely be stored in an array for later use.
 409  
 410    my (%Entry);
 411  
 412    $Entry{Index}         = ReadLong();
 413    $Entry{CategoryID}    = ReadLong();
 414    $Entry{DirtyFlag}     = ReadLong();
 415    $Entry{LongName}      = ReadPilotString();
 416    $Entry{ShortName}     = ReadPilotString();
 417    return \%Entry;
 418  }
 419  
 420  #-----------------------------  Main Program -------------------------------
 421  
 422  foreach $Entry (sort ByDateAscending ReadDateBook($DateBookFileName)) {
 423    $DATA .=  $Entry->{RecordID}. $sep;
 424    $DATA .=  $Entry->{StartTime}. $sep;
 425    $DATA .=  $Entry->{EndTime}. $sep;
 426    $DATA .=  $Entry->{Description}. $sep;
 427    $DATA .=  $Entry->{Duration}. $sep;
 428    $DATA .=  $Entry->{Note}. $sep;
 429    $DATA .=  $Entry->{Untimed}. $sep;
 430    $DATA .=  $Entry->{Private}. $sep;
 431    $DATA .=  $Entry->{Category}. $sep;
 432    $DATA .=  $Entry->{AlarmSet}. $sep;
 433    $DATA .=  $Entry->{AlarmAdvanceAmount}. $sep;
 434    $DATA .=  $Entry->{AlarmAdvanceType}. $sep;
 435    $DATA .=  $Entry->{Repeat}->{Interval}. $sep;
 436    $DATA .=  $Entry->{Repeat}->{Frequency}. $sep;
 437    $DATA .=  $Entry->{Repeat}->{EndTime}. $sep;
 438    $DATA .=  $Entry->{Repeat}->{Exceptions}. $sep;
 439    $DATA .=  $Entry->{Repeat}->{RepeatDays}. $sep;
 440  #  $DATA .=  $Entry->{Repeat}->{DayNum}. $sep;
 441    $DATA .=  $Entry->{Repeat}->{WeekNum}. $sep;
 442    $DATA .=  "\n";
 443  }
 444  
 445  if ($outfile) {
 446    die "Couldn't open $outfile: $!" if ((open OUT, ">$outfile") eq undef);
 447    flock (OUT, 2);print OUT $DATA;flock (OUT, 8);close OUT;
 448  } else {
 449    print STDOUT $DATA;
 450  }
 451  exit;


Généré le : Fri Nov 30 19:09:19 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics