]> pere.pagekite.me Git - homepage.git/commitdiff
Add support for importing ical files, and do some cleanup.
authorPetter Reinholdtsen <pere@hungry.com>
Mon, 23 Jan 2006 22:58:00 +0000 (22:58 +0000)
committerPetter Reinholdtsen <pere@hungry.com>
Mon, 23 Jan 2006 22:58:00 +0000 (22:58 +0000)
linux/plan2icalendar

index 92ef801561d794a6d71d15a3846df8c383c61b25..d22965dd67ffa7b486f86378e1fd7dbb074a064a 100755 (executable)
@@ -3,21 +3,43 @@
 # Author: Petter Reinholdtsen <pere@hungry.com>
 # Date:   2002-01-10
 #
-# Convert plan calender data to icalender format.
+# Convert plan calender data to/from icalender format.
 #
 # plan, <URL:http://www.bitrot.de/>
 # icalendar, RFC 2445, <URL:http://www.faqs.org/rfcs/rfc2445.html">iCalendar>
 
+use warnings;
+use strict;
+
+use Getopt::Std;
 use Date::Parse;
 use Date::Format;
+use Date::ICal;
 
 my @events;
+my %opts;
+my $debug = 0;
+unless (getopts('if:o:', \%opts)) {
+    usage();
+    exit 1;
+}
 
-my $mailto = "pere\@hungry.com";
+my $input  = $opts{f};
+my $output = $opts{o};
 
-read_planfile(".plan.dir/dayplan");
-write_icalendar();
+if ($opts{i}) { # Import
+    read_icalendar($input   || "test.ical");
+    write_planfile($output  || $ENV{HOME}."/.plan.dir/fromical");
+} else { # Default is to export
+    read_planfile($input    || $ENV{HOME}."/.plan.dir/dayplan");
+    write_icalendar($output || "-");
+}
+exit 0;
 
+sub usage {
+    print <<EOF
+EOF
+}
 sub read_planfile {
     my ($planfile) = @_;
     open(PLAN, "<$planfile") || die "Unable to read $planfile";
@@ -30,22 +52,22 @@ sub read_planfile {
             my $info = <PLAN>;
             chomp $info;
             my ($dontknow, $msg) = $info =~ m/^(.)\t(.+)$/;
-            print STDERR "E: $date $start $duration $msg\n";
+            print STDERR "E: $date $start $duration $msg\n" if $debug;
 
             my $timestamp = str2time("$date $start");
-            $isostartstamp  = time2str("%Y%m%dT%H%M%S", $timestamp);
+            my $isostartstamp  = time2str("%Y%m%dT%H%M%S", $timestamp);
+            my $icalstartstamp = Date::ICal->new( epoch => $timestamp );
 
             my @f = split(/:/, $duration);
             $timestamp += ($f[0]*60*60 + $f[1]*60 +$f[2]);
-            $isoendstamp  = time2str("%Y%m%dT%H%M%S", $timestamp);
+            my $isoendstamp  = time2str("%Y%m%dT%H%M%S", $timestamp);
+            my $icalendstamp = Date::ICal->new( epoch => $timestamp );
 
-            print STDERR "IE: $isostartstamp $isoendstamp\n";
+            print STDERR "IE: $isostartstamp $isoendstamp\n" if $debug;
             push(@events, {
-                organizer => "$mailto",
                 summary   => $msg,
-                dtstart   => $isostartstamp,
-                dtend     => $isoendstamp,
-                priority  => '1'
+                dtstart   => $icalstartstamp->ical,
+                dtend     => $icalendstamp->ical,
                 });
         }
     }
@@ -55,7 +77,7 @@ sub read_planfile {
 
 # BEGIN:VCALENDAR
 # PRODID
-#  :-//K Desktop Environment//NONSGML KOrganizer//EN
+#  :-//test environment//NONSGML plan2icalendar//EN
 # VERSION
 #  :2.0
 # BEGIN:VEVENT
@@ -69,12 +91,8 @@ sub read_planfile {
 #  :20020110T153939
 # DTSTAMP
 #  :20020110T153952
-# ORGANIZER
-#  :MAILTO:pre@diskless.uio.no
 # SUMMARY
 #  :SL-veiledning
-# PRIORITY
-#  :1
 # DTSTART
 #  :20020114T151500
 # DTEND
@@ -82,41 +100,102 @@ sub read_planfile {
 # END:VEVENT
 # END:VCALENDAR
 sub write_icalendar {
-    print <<EOF;
+    my $filename = shift;
+    open(PLAN, ">$filename") || die "Unable to write to $filename";
+    print PLAN <<EOF;
 BEGIN:VCALENDAR
-PRODID
- :-//K Desktop Environment//NONSGML KOrganizer//EN
-VERSION
- :2.0
+CALSCALE:GREGORIAN
+PRODID:-//test environment//NONSGML plan2icalender//EN
+VERSION:2.0
 EOF
     my $count = 0;
-    my $event;
-    for $event (@events) {
-        print <<EOF;
+    for my $event (@events) {
+        $event->{uid} = "plan2icalendar-$count" unless $event->{uid};
+        $event->{dtstamp} = "20020110T153952" unless $event->{dtstamp};
+        $event->{'last-modified'} = "20020110T153939" unless $event->{'last-modified'};
+        $event->{sequence} = $count unless $event->{sequence};
+        $event->{created} = "20020110T153939" unless $event->{created};
+        print PLAN <<EOF;
 BEGIN:VEVENT
-CREATED
- :20020110T153939
-UID
- :plan2icalendar-$count
-SEQUENCE
- :$count
-LAST-MODIFIED
- :20020110T153939
-DTSTAMP
- :20020110T153952
-ORGANIZER
- :MAILTO:$event->{organizer}
-SUMMARY
- :$event->{summary}
-PRIORITY
- :$event->{priority}
-DTSTART
- :$event->{dtstart}
-DTEND
- :$event->{dtend}
+CREATED:$event->{created}
+UID:$event->{uid}
+SEQUENCE:$count
+LAST-MODIFIED:$event->{'last-modified'}
+DTSTAMP:$event->{dtstamp}
+SUMMARY:$event->{summary}
+DTSTART:$event->{dtstart}
+DTEND:$event->{dtend}
 END:VEVENT
+
 EOF
         $count++;
     }
-    print "END:VCALENDAR\n";
+    print PLAN "END:VCALENDAR\n";
+    close PLAN;
+}
+
+#
+# Should probably leave this task to Net::ICal.  But it is not
+# available in debian/sarge, so I make a quick-n-dirty solution
+# instead.
+#
+sub read_icalendar {
+    my $filename = shift;
+    open (ICALENDAR, "<$filename") or die "Unable to read from $filename";
+    my $oldval = $/;
+    $/ = "\r\n";
+    while (<ICALENDAR>) {
+       chomp;
+       if (m/^BEGIN:VEVENT/) {
+           my %event;
+           while (<ICALENDAR>) {
+               chomp;
+               last if (m/END:VEVENT/);
+               $event{description} = $1 if (m/^DESCRIPTION\s*:\s*(.+)$/);
+               $event{created} = $1 if (m/^CREATED\s*:\s*(.+)$/);
+               $event{dtend} = $1 if (m/^DTEND\s*:\s*(.+)$/);
+               $event{dtstamp} = $1 if (m/^DTSTAMP\s*:\s*(.+)$/);
+               $event{dtstart} = $1 if (m/^DTSTART\s*:\s*(.+)$/);
+               $event{last-modified} = $1 if (m/^LAST-MODIFIED\s*:\s*(.+)$/);
+               $event{sequence} = $1 if (m/^SEQUENCE\s*:\s*(.+)$/);
+               $event{summary} = $1 if (m/^SUMMARY\s*:\s*(.+)$/);
+               $event{uid} = $1 if (m/^UID\s*:\s*(.+)$/);
+           }
+           push @events, \%event;
+       }
+    }
+    close (ICALENDAR);
+    $/ = $oldval;
+}
+
+# Simple version covering the chars I need.
+sub utf8tolocalmap {
+    my $string = shift;
+    $string =~ s/ø/ø/g;
+    $string =~ s/æ/æ/g;
+    $string =~ s/Ã¥/å/g;
+    return $string;
+}
+
+sub write_planfile {
+    my $filename = shift;
+    open(PLAN, ">$filename") or die "Unable to write to $filename";
+    for my $event (@events) {
+        # offset = 0 -- assume all timestamps in local time zone
+        my $ical = Date::ICal->new( ical => $event->{dtstart}, offset => 0 );
+        my $date = join("/", $ical->month, $ical->day, $ical->year);
+        my $start = join(":", $ical->hour, $ical->min, $ical->sec);
+
+        my $icalstop = Date::ICal->new( ical => $event->{dtend}, offset => 0 );
+        my $icalduration = $icalstop - $ical;
+        my $duration = join(":",
+                            $icalduration->hours   || "0",
+                            $icalduration->minutes || "0",
+                            $icalduration->seconds || "0");
+
+        my $code = "N";
+        my $summary = utf8tolocalmap($event->{summary});
+        print PLAN "$date  $start  $duration  0:0:0  0:0:0  ---------- 0 0\n";
+        print PLAN "$code\t$summary\n";
+    }
 }