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