caldav::calendars proc parse (public)
caldav::calendarsparse text
Defined in packages/xotcl-core/tcl/01-debug-procs.tcl
Parse the ical file passed in as string and output a list of CalItem objects. The attributes specified in opaque_tags are passed as opaque values. Opaque attributes are not shown in OpenACS, but output when the calendar item is requested in ical format.
- Parameters:
- text (required)
- the text do be parsed TODO: this should go into ical-procs..... but first check dependencies - $item add_ical_var .... - ::caldav::calitem new
- Testcases:
- No testcase defined.
Source code: # # Parse the ical file passed in as string and output a list of # CalItem objects. The attributes specified in opaque_tags are # passed as opaque values. Opaque attributes are not shown in # OpenACS, but output when the calendar item is requested in # ical format. # # @param text the text do be parsed # # TODO: this should go into ical-procs..... but first check dependencies # - $item add_ical_var .... # - ::caldav::calitem new set parse_error 0 set in_valarm 0 set in_vevent 0 set item_list {} #opaque_tags are the tags that will be persisted in ical_vars set opaque_re ^([join ${:opaque_tags} |]):(.*)$ :debug opaque_re=$opaque_re set prefix "" regsub -all "\n " $text "" text regsub -all "\r" $text "" text foreach line [split $text \n] { ns_log notice "======== <$line>" if {$in_valarm} { # # treat everything in an VALARM as opaque for the time being # append :OPAQUE-VALARM $line\r\n if { $line eq "END:VALARM"} { # end of valarm section set in_valarm 0 $item add_ical_var OPAQUE-VALARM "" [set :OPAQUE-VALARM] } } elseif { $in_vevent && [regexp $opaque_re $line _ tag value] } { $item add_ical_var $tag "" [::xo::ical ical_to_text $value] } elseif { $line eq "BEGIN:VEVENT" } { # reset values set in_valarm 0 set in_vevent 1 set r_error 0 # #setting a creation date is only needed for debugging # # GN TODO: DO NOT HARDCODE calitem HERE! # set item [::caldav::calitem new -description "" -creation_date [xo::ical clock_to_utc [clock seconds]]] $item destroy_on_cleanup #$item set description "" #$item set creation_date [xo::ical clock_to_utc [clock seconds]] lappend item_list $item } elseif { $line eq {BEGIN:VALARM} } { # begin of VALARM section set in_valarm 1 set :OPAQUE-VALARM $line\r\n } elseif { $in_vevent && [regexp {^LOCATION[^:]*:(.*)$} $line _ location] } { $item location set [::xo::ical ical_to_text $location] } elseif { $in_vevent && [regexp {^SUMMARY[^:]*:(.*)$} $line _ title] } { $item summary set [::xo::ical ical_to_text $title] } elseif { $in_vevent && [regexp {^(DTSTAMP|UID|LAST-MODIFIED)[^:]*:(.*)$} $line _ field entry] } { $item [string tolower $field] set $entry } elseif { $in_vevent && [regexp {^DTSTART(\;TZID.*)?:([0-9]+)T+([0-9]+)(Z?).*$} $line _ tz date time utc] } { if {[string length $date] != 8 || [string length $time] != 6} { set parse_error 1 } else { $item dtstart set [:set_date_time $date $time [expr {$utc ne ""}] $tz] } } elseif { $in_vevent && [regexp {^DTSTART.+DATE[^:]*:([0-9]+).*$} $line _ date] } { if {[string length $date] != 8} { set parse_error 1 } else { $item dtstart set [:set_date_time $date "0000" 0 ""] } } elseif { $in_vevent && [regexp {^DTEND(\;TZID.*)?[^:]*:([0-9]+)T+([0-9]+)(Z?).*$} $line _ tz date time utc] } { if {[string length $date] != 8 || [string length $time] != 6} { set parse_error 1 } else { $item dtend set [:set_date_time $date $time [expr {$utc ne ""}] $tz] } } elseif { $in_vevent && [regexp {^DTEND.+?DATE[^:]*:([0-9]+).*$} $line _ date ] } { if {[string length $date] != 8} { set parse_error 1 } else { $item dtend set [:set_date_time $date "0000" 0 ""] } } elseif {$in_vevent && [regexp {^DURATION[^:]*:P(.*)$} $line _ duration] } { $item duration set 0 if {[regexp {^([0-9]+)W(.*)$} $duration _ units duration]} { $item incr duration [expr {[util::trim_leading_zeros $units]*24*3600*7}] } if {[regexp {([0-9]+)D(.*)$} $duration _ units duration]} { $item incr duration [expr {[util::trim_leading_zeros $units]*24*3600}] } if {[regexp {([0-9]+)H(.*)$} $duration _ units duration]} { $item incr duration [expr {[util::trim_leading_zeros $units]*3600}] } if {[regexp {([0-9]+)M(.*)$} $duration _ units duration]} { $item incr duration [expr {[util::trim_leading_zeros $units]*60}] } if {[regexp {([0-9]+)S(.*)$} $duration _ units duration]} { $item incr duration [util::trim_leading_zeros $units] } } elseif {$in_vevent && [regexp {^DESCRIPTION[^:]*:(.*)$} $line _ desc] } { $item description set [::xo::ical ical_to_text $desc] } elseif {$in_vevent && [regexp {^URL[^:]*:(.*)$} $line _ desc] } { $item add_ical_var URL "" [::xo::ical ical_to_text $desc] } elseif { $in_vevent && [regexp {^RRULE[^:]*:(.*)$} $line _ recurrule] } { $item parse RRULE $recurrule } elseif { $in_vevent && $line eq "END:VEVENT" } { set in_vevent 0 $item finish $parse_error } elseif {$in_vevent && [regexp {^X-APPLE-STRUCTURED-LOCATION(\;[^:]+|):(.*)$} $line . params value]} { # # Special handling for Apple ical implementations # $item add_ical_var X-APPLE-STRUCTURED-LOCATION $params $value } else { # Ignore unused ical lines :debug "ical parse ignores <$line>" } } return $item_listXQL Not present: Generic, PostgreSQL, Oracle