#!/local/bin/perl # ------------------------------------------------------------------ # ical2vcs V0.4 # Perl translator for Apple Ical (.ics) to Palm Vcal (.vcs) format # # J. Touch # touch@isi.edu # http://www.isi.edu/touch # # USC Information Sciences Institute (USC/ISI) # Marina del Rey, California 90292, USA # Copyright (c) 2004-2007 # # Revision date: Jun. 2, 2007 # ------------------------------------------------------------------ # # Copyright (c) 2004-2007 by the University of Southern California. # All rights reserved. # # Permission to use, copy, modify, and distribute this software and # its documentation in source and binary forms for non-commercial # purposes and without fee is hereby granted, provided that the # above copyright notice appear in all copies and that both the # copyright notice and this permission notice appear in supporting # documentation, and that any documentation, advertising materials, # and other materials related to such distribution and use # acknowledge that the software was developed by the University of # Southern California, Information Sciences Institute. The name of # the University may not be used to endorse or promote products # derived from this software without specific prior written # permission. # # THE UNIVERSITY OF SOUTHERN CALIFORNIA MAKES NO REPRESENTATIONS # ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. THIS # SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. # ------------------------------------------------------------------ # # usage: # ics2vcs2.pl [inputfile.ics] > [outputfile.vcs] # # Converts ical calendars to vcs # Intended primarily to convert Apple-generated IETF ical schedules # to be importable into Palm Desktop # # WARNING - tested on IETF-61.ics and IETF-64.ics files only # # replace codes: # ics vcs (quoted-printable) # --------------------------------------------------- # \n =0D=0A # \N =0D=0A # \, , # \; ; # \\ \ # \(other) ERROR # # Also changes some command strings: # ics vcs # ------------------------------------------------- # VERSION:2.0 VERSION:1.0 # SUMMARY: SUMMARY;ENCODING=QUOTED-PRINTABLE: # DESCRIPTION: DESCRIPTION;ENCODING=QUOTED-PRINTABLE: # PRODID:-//Apple... PRODID:ics2vcs... (prefixed) # DURATION DTEND (now allows DURATION before DTSTART) # # Unfolds the lines first - vcs doesn't have a line length limit, # but ics folds on ?? chars/line (what is this, the 1970's?) # inserting # # returns: # 0 on no illegal characters found (no error) # 1 if any illegal characters found (error) # ------------------------------------------------------------------ #################################################################### # unfold the file - folding is so 1970's ;-( @wholefile = <>; $wholefileline = join('XXJDTXX',@wholefile); $wholefileline =~ s/\nXXJDTXX //g; @cleanfile = split(/XXJDTXX/,$wholefileline); while ($line = shift(@cleanfile)) { ################################################################## # substitutions: ################################################################## # eat the windows carriage returns "^M"s $line =~ s/\r//g; # printed quotable doesn't react well to '=' $line =~ s/=/-/g; # eat the trailing carriage returns $line =~ s/\\n$//i; # convert carriage returns and tabs to quoted printable equivalent $line =~ s/\\n/=0D=0A/gi; # case insensitive $line =~ s/\t/=0D=0A/g; # this isn't quite right, but works OK for now # omit unneeded escapes $line =~ s/\\,/,/g; $line =~ s/\\;/;/g; $line =~ s/\\\\/\\/g; # print warning later for unrecognized backslashes if ($line =~ /(\\.*)/) { print "ics2vcsERROR: unrecogized backslash escape = >>$1<<\n"; $errorfound = 1; } ################################################################## # translate portions from ical-speak to vcal-speak ################################################################## $line =~ s/^VERSION\:2\.0/VERSION\:1\.0/; $line =~ s/^SUMMARY\:/SUMMARY\;ENCODING\=QUOTED\-PRINTABLE\:/; $line =~ s/^DESCRIPTION\:/DESCRIPTION\;ENCODING\=QUOTED\-PRINTABLE\:/; # label output as coming from this software $line =~ s/^PRODID\:(.*)/PRODID: ics2vcs 0.4 Joe Touch from $1/; # omit time zones on entries; supported in later versions of PalmOS $line =~ s/^DTSTART;.*:/DTSTART:/; $line =~ s/^DTEND;.*:/DTEND:/; ################################################################## # look for begin of events to clear out variables ################################################################## if ($line =~ /^BEGIN:VEVENT/) { $startfound = 0; $durfound = 0; } if ($line =~ /^DTSTART:(.*)/) { $starttime = $1; $starttime =~ /([0-9]+)T([0-9][0-9])([0-9][0-9])([0-9]*)/; $syrday = $1; $shour = $2; $smin = $3; $sextra = $4; $startfound = 1; } if ($line =~ /^DURATION:(.*)/) { $dur = $1; $dur =~ s/PT(([0-9]+)H)?(([0-9]+)M)?//; $dhour = $2; $dmin = $4; if ($dur != "") { print $line; print "ics2vcsERROR ONLY HOURS AND MINUTES DURATIONS ARE SUPPORTED\n"; $errorfound = 1; } $durfound = 1; # eat the line - it's not printed out in vcs $line = ""; } if (($startfound == 1) && ($durfound == 1)) { # once you find both start and duration, write DTEND $shour += $dhour; $smin += $dmin; if ($smin > 60) { $smin -= 60; $shour++; } $hrmin = sprintf "%0.2d%0.2d",$shour, $smin; # append line here $line .= "DTEND:" . $syrday . "T" . $hrmin . $sextra . "\n"; $startfound = 0; $durfound = 0; } ################################################################## # omit blank lines to compress entries ################################################################## if ($line !~ /^\s+$/) { print $line; } if ($line =~ /^DTEND/) { if (($starttime == 0) && ($durfound == 1)) { print "ics2vcsERROR INVALID DURATION BEFORE START TIME\n"; $errorfound = 1; } if (($starttime == 1) && ($durfound == 0)) { print "ics2vcsERROR INVALID START TIME WITHOUT DTEND OR DURATION\n"; $errorfound = 1; } } } if ($errorfound == 1) { printf STDERR "ERROR FOUND - see \'ics2vcsERROR\' inside output file\n"; } exit($errorfound);