Warning, /pim/korganizer/src/data/ical2vcal.in is written in an unsupported language. File is not indexed.

0001 #! @PERL@
0002 # THE ABOVE LINE SHOULD POINT TO YOUR PERL EXECUTABLE!
0003 # ical2vcal
0004 # (c) 1998 Preston Brown
0005 # Part of the KOrganizer Project
0006 #
0007 # This utility will read ~/.calendar in the ical format as input, and output 
0008 # a file in the versit vCalendar format with a .vcs extension.
0009 #
0010 # This code is covered by the GNU Public License.  Please see the file
0011 # COPYING for more information.
0012 #
0013 # MINIMAL ERROR CHECKING!  HIGHLY PRIMITIVE!  YOU HAVE BEEN WARNED!
0014 
0015 # open the calendar.
0016 $home = $ENV{"HOME"};
0017 $pcount = 0;
0018 
0019 $exitstatus = 0;
0020 
0021 $filename = "$home/.calendar";
0022 
0023 if (defined($ARGV[0]) && defined($ARGV[1])) {
0024     $filename = $ARGV[0];
0025     $outfilename = $ARGV[1];
0026 } elsif (defined($ARGV[0])) {
0027     $outfilename = $ARGV[0];
0028 } else {
0029     exit -1;
0030 }
0031 
0032 if (!open(ICALFILE, $filename)) {
0033     exit -1;
0034 }
0035 if (!open(VCALFILE, ">$outfilename")) {
0036     exit -1;
0037 }
0038 
0039 $line = <ICALFILE>;
0040 
0041 &write_header;
0042 
0043 if ($line =~ /Calendar(\s+)\[v/) {
0044     while ($line = &getLine) {
0045         if (($line =~ /^Appt/) || ($line =~ /^Note/)) {
0046             &process_appointment;
0047             &write_appointment;
0048         } else {
0049             # silently skip line
0050         }
0051     }
0052 } else {
0053     # not a ical file?!
0054     exit -2;
0055 }
0056 
0057 close(ICALFILE);
0058 close(VCALFILE);
0059 
0060 sub getLine
0061 {
0062     $_ = <ICALFILE>;
0063     if (!defined($_)) {
0064         &write_footer;
0065         exit $exitstatus;
0066     }
0067     s/\\\[/\(/g;
0068     s/\\\]/\)/g;
0069     $pcount += tr/\[//;
0070     $pcount -= tr/\]//;
0071     return $_;
0072 }
0073 
0074 sub process_appointment
0075 {
0076     undef(%curappt);
0077 
0078     # this is a count of the total # of parentheses.
0079     while ($pcount) {
0080         $line = &getLine;
0081         
0082         # check to see if more is left to be processed.
0083         if ($pcount > 0) {
0084             # process the line.
0085 
0086             if ($line =~ /^Start/) {
0087                 # start time (minutes since midnight)
0088                 $_ = $line;
0089                 ($totalmin) = /\[(\d+)\]/;
0090                 $min = $totalmin % 60;
0091                 $hour = int ($totalmin / 60);
0092                 $curappt{"starthour"} = $hour;
0093                 $curappt{"startmin"} = $min;
0094                 
0095             } elsif ($line =~ /^Length/) {
0096                 # time length (minutes)
0097                 $_ = $line;
0098                 ($lengthmin) = /\[(\d+)\]/;
0099                 $min = $lengthmin % 60;
0100                 $hour = int ($lengthmin / 60);
0101                 $curappt{"endhour"} = $hour;
0102                 $curappt{"endmin"} = $min;
0103             } elsif ($line =~ /^Uid/) {
0104                 # unique identifier
0105                 $_ = $line;
0106                 ($uid) = /\[(.+)\]/;
0107                 $curappt{"uid"} = $uid ;
0108             } elsif ($line =~ /^Owner/) {
0109                 # appointment's owner
0110                 $_ = $line;
0111                 ($attendee) = /\[(\w+)\]/;
0112                 $curappt{"attendee"} = $attendee;
0113             } elsif ($line =~ /^Contents/) {
0114                 # description
0115                 $description = "";
0116                 $_ = $line;
0117                 # special case where it's all in one place:
0118                 if (/\[(.*)\]/) {
0119                     $summary = $1;
0120                 } else {
0121                     ($summary) = /\[(.*)/;
0122                     $_ = &getLine;
0123                     while (!(/\]$/)) {
0124                         chop;
0125                         $description = $description . " " . $_;
0126                         $_ = &getLine;
0127                     }
0128                     /(.*)\]$/;
0129                     $description = $description . $1;
0130                 }
0131                 $curappt{"summary"} = $summary;
0132                 if (length($description) > 0) {
0133                     $summary = $summary . "...";
0134                     $curappt{"description"} = $description;
0135                 }
0136             } elsif ($line =~ /^Text/) {
0137                 $description = "";
0138                 $_ = $line;
0139                 if (/\[\d+\s+\[(.*)\]\]/) {
0140                     $summary = $1;
0141                 } else {
0142                     ($summary) = /\[\d+\s+\[(.*)$/;
0143                     $_ = &getLine;
0144                     while (!(/\]$/)) {
0145                         chop;
0146                         $description = $description . " " . $_;
0147                         $_ = &getLine;
0148                     }
0149                     /^(.*)\]\]/;
0150                     $description = $description . $1;
0151                 }
0152                 $curappt{"summary"} = $summary;
0153                 if (length($description) > 0) {
0154                     $summary = $summary . "...";
0155                     $curappt{"description"} = $description;
0156                 }
0157             } elsif ($line =~ /^Alarms/) {
0158                 $_ = $line;
0159                 ($alarm) = /(\d+)\]/;
0160                 $curappt{"alarmtime"} = $alarm;
0161             } elsif ($line =~ /^Todo/) {
0162                 $curappt{"todo"} = 1;
0163             } elsif ($line =~ /^Dates/) {
0164                 # dates to occur on
0165                 &process_dates;
0166             } elsif ($line =~ /^\]/) {
0167                 # do nothing
0168             } elsif ($line =~ /^Hilite/) {
0169                 # do nothing
0170             } elsif ($line =~ /^Remind/) {
0171                 # do nothing
0172             } elsif ($line =~ /^Done/) {
0173                 $curappt{"done"}=1;
0174             } else {
0175                 # do nothing
0176                 ;
0177             }
0178 
0179         } # if $pcount > 0
0180 
0181     } # while pcount
0182 
0183     if (defined($curappt{"starthour"})) {
0184         # fix up end time, just peg it at the end of the day
0185         $endhour = $curappt{"starthour"} + $curappt{"endhour"};
0186         $endmin = $curappt{"startmin"} + $curappt{"endmin"};
0187         $endhour = $endhour + int ($endmin / 60);
0188         $endmin = $endmin % 60;
0189         $curappt{"endhour"} = $endhour;
0190         $curappt{"endmin"} = $endmin;
0191         if ($endhour >= 24) {
0192             $curappt{"endhour"} = 23;
0193             $curappt{"endmin"} = 55;
0194         }
0195     }
0196 }
0197 
0198 sub output
0199 {
0200     $outline = shift(@_);
0201     print VCALFILE $outline;
0202     print VCALFILE "\n";
0203 #    print($outline);
0204 #    print("\n");
0205 }
0206 
0207 sub write_header
0208 {
0209     output("BEGIN:VCALENDAR");
0210     output("PRODID:-//K Desktop Environment//NONSGML KOrganizer//EN");
0211     output("VERSION:1.0");
0212 }
0213 
0214 sub write_footer
0215 {
0216     output("END:VCALENDAR");
0217 }
0218 
0219 sub write_appointment
0220 {
0221     if (defined($curappt{"tossme"})) {
0222         return;
0223     }
0224 
0225     if (defined($curappt{"todo"})) {
0226         output("BEGIN:VTODO");
0227     } else {
0228         output("BEGIN:VEVENT");
0229     }
0230     $tmpstr = &date_to_str($curappt{"startyear"},
0231                            $curappt{"startmonth"},
0232                            $curappt{"startday"});
0233     if (defined($curappt{"starthour"})) {
0234         $tmpstr = $tmpstr . &time_to_str($curappt{"starthour"},
0235                                $curappt{"startmin"});
0236     } else {
0237         $tmpstr = $tmpstr . &time_to_str("0","0");
0238     }
0239     output("DCREATED:" . $tmpstr);
0240     output("UID:" . $curappt{"uid"});
0241     output("SEQUENCE:0");
0242     output("LAST-MODIFIED:$tmpstr");
0243     output("DTSTART:$tmpstr");
0244     if (defined($curappt{"starthour"})) {
0245         $tmpstr = &date_to_str($curappt{"startyear"},
0246                               $curappt{"startmonth"},
0247                               $curappt{"startday"}) . 
0248                                   &time_to_str($curappt{"endhour"},
0249                                                $curappt{"endmin"});
0250     } 
0251     output("DTEND:$tmpstr");
0252     if (defined($curappt{"summary"})) {
0253         $summary = $curappt{"summary"};
0254         output("SUMMARY:$summary");
0255     }
0256     if (defined($curappt{"description"})) {
0257         $description = $curappt{"description"};
0258         output("DESCRIPTION:$description");
0259     }
0260     if (defined($curappt{"attendee"})) {
0261         $attendee = "ATTENDEE;ROLE=OWNER:" . $curappt{"attendee"};
0262         output($attendee);
0263     }
0264     
0265     if (defined($curappt{"alarm"})) {
0266         
0267     }
0268 
0269     if (defined($curappt{"repeats"})) {
0270         # wow what a mess
0271         $rule = "RRULE:";
0272         if ($curappt{"repeats"} eq "DAILY") {
0273             $rule = $rule . "D" . $curappt{"period"};
0274         } elsif ($curappt{"repeats"} eq "WEEKLY") {
0275             $rule = $rule . "W1" . " ";
0276             $rule = $rule . $curappt{"weekdays"};
0277                 
0278         } elsif ($curappt{"repeats"} eq "MONTHLY") {
0279             $rule = $rule . "MD" . $curappt{"period"};
0280             $rule = $rule . " " . $curappt{"startday"};
0281         }
0282         if ($curappt{"endrepeat"} && ($curappt{"endrepeat"} =~ /T/)) {
0283             $rule = $rule . " " . $curappt{"endrepeat"};
0284         } elsif ($curappt{"endrepeat"}) {
0285             $rule = $rule . " \#" . $curappt{"endrepeat"};
0286         } else {
0287             $rule = $rule . " \#0";
0288         }
0289         output($rule);
0290     }
0291     if (defined($curappt{"exceptions"})) {
0292         $exceptions = "EXDATE:" . $curappt{"exceptions"};
0293         chop($exceptions);
0294         output($exceptions);
0295     }
0296     if (defined($curappt{"todo"})) {
0297         if (defined($curappt{"done"})) {
0298             output("STATUS:COMPLETED");
0299         } else {
0300             output("STATUS:NEEDS ACTION");
0301         }
0302     }
0303     output("CLASS:PUBLIC");
0304     output("PRIORITY:0");
0305     output("TRANSP:0");
0306     output("RELATED-TO:0");
0307     if (defined($curappt{"todo"})) {
0308         output("END:VTODO\n");
0309     } else {
0310         output("END:VEVENT\n");
0311     }
0312 }
0313 
0314 sub date_to_str
0315 {
0316     $year = shift(@_);
0317     $month = shift(@_);
0318     $day = shift(@_);
0319     my($datestr);
0320     $datestr = sprintf("%04d%02d%02d",$year,$month,$day);
0321     return $datestr;
0322 }
0323 
0324 sub time_to_str
0325 {
0326     $hour = shift(@_);
0327     $min = shift(@_);
0328     my($timestr);
0329 
0330     $timestr = sprintf("T%02d%02d00",$hour,$min);
0331     return $timestr;
0332 }
0333 
0334 sub process_dates
0335 {
0336     # first, test for single
0337     $_ = $line;
0338     if (/\[Single/)  {
0339         &repeat_none;
0340     } elsif (/\[Days/) {
0341         &repeat_daily;
0342     } elsif (/\[WeekDays/) {
0343         &repeat_weekly;
0344     } elsif (/\[Months/) {
0345         &repeat_monthly;
0346     } elsif (/\[ComplexMonths/) {
0347         $exitstatus = 1;
0348         #printf("WARNING: complex repeating month entry detected, we don't support.\n");
0349         #printf("converting to a single occurrence on the original start date.\n");
0350         $line = &getLine;
0351         &repeat_none;
0352     } elsif (/\[Empty/) {
0353         # silently toss
0354         $curappt{"tossme"} = "TRUE";
0355     } else {
0356         $exitstatus = 1;
0357         #print "didn't understand line: $_";
0358     }
0359     while ($line = &getLine) {
0360         if ($line =~ /^\]/) {
0361             return;
0362         } elsif ($line =~ /^Finish/) {
0363             ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
0364             $curappt{"endrepeat"} = &date_to_str($year, $month, $day);
0365             $curappt{"endrepeat"} = $curappt{"endrepeat"} . &time_to_str("0","0");
0366         } elsif ($line =~ /^Deleted/) {
0367             ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
0368             if (defined($curappt{"exceptions"})) {
0369                 $curappt{"exceptions"} = $curappt{"exceptions"} .
0370                     &date_to_str($year, $month, $day) . ";";
0371             } else {
0372                 $curappt{"exceptions"} = &date_to_str($year, $month, $day) .
0373                     ";";
0374             }
0375         } else {
0376             $exitstatus = 1;
0377             #print "trashed line: $line";
0378         }
0379     }
0380 }
0381 
0382 sub repeat_none
0383 {
0384     # just a one time shot
0385     ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
0386     $curappt{"startmonth"} = $month;
0387     $curappt{"startday"} = $day;
0388     $curappt{"startyear"} = $year;
0389 }
0390 
0391 sub repeat_daily
0392 {
0393     # repeats on a daily basis
0394     $curappt{"repeats"} = "DAILY";
0395     ($skip) = /(\d+)$/;
0396     $curappt{"period"} = $skip;
0397     $line = &getLine;
0398     ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
0399     $curappt{"startmonth"} = $month;
0400     $curappt{"startday"} = $day;
0401     $curappt{"startyear"} = $year;
0402 }
0403 
0404 sub repeat_weekly
0405 {
0406     # repeats on a weekly basis, a few days a week
0407     $curappt{"repeats"} = "WEEKLY";
0408     $startofdates = index($_,"WeekDays") + length("WeekDays");
0409     $endofdates = index($_,"Months");
0410     $datestr = substr($_,$startofdates,($endofdates-$startofdates));
0411     $datestr =~ s/^\s+//;
0412     @days = split(/\s+/,$datestr);
0413     $datestr = "";
0414     foreach $date (@days) {
0415         if ($date == 1) {
0416             $datestr = $datestr . "SU ";
0417         } elsif ($date == 2) {
0418             $datestr = $datestr . "MO ";
0419         } elsif ($date == 3) {
0420             $datestr = $datestr . "TU ";
0421         } elsif ($date == 4) {
0422             $datestr = $datestr . "WE ";
0423         } elsif ($date == 5) {
0424             $datestr = $datestr . "TH ";
0425         } elsif ($date == 6) {
0426             $datestr = $datestr . "FR ";
0427         } elsif ($date == 7) {
0428             $datestr = $datestr . "SA ";
0429         }
0430     }
0431     # remove one trailing whitespace
0432     chop($datestr);
0433     $curappt{"weekdays"} = $datestr;
0434     $line = &getLine;
0435     ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
0436     $curappt{"startmonth"} = $month;
0437     $curappt{"startday"} = $day;
0438     $curappt{"startyear"} = $year;
0439 }
0440 
0441 sub repeat_monthly
0442 {
0443     # repeats on a daily basis
0444     $curappt{"repeats"} = "MONTHLY";
0445     ($skip) = /(\d+)$/;
0446     $curappt{"period"} = $skip;
0447     $line = &getLine;
0448     ($day, $month, $year) = /(\d+)\/(\d+)\/(\d+)/;
0449     $curappt{"startmonth"} = $month;
0450     $curappt{"startday"} = $day;
0451     $curappt{"startyear"} = $year;
0452 }
0453 
0454