%3 ::nx::Object ::nx::Object ::xo::ical::VCALITEM ::xo::ical::VCALITEM add_recurrence as_ical edit_recurrence get ical_body parse RRULE start_end tag ::xo::ical::VCALITEM->::nx::Object ::xo::ical::VEVENT ::xo::ical::VEVENT finish ::xo::ical::VEVENT->::xo::ical::VCALITEM ::xo::ical::VTODO ::xo::ical::VTODO ::xo::ical::VTODO->::xo::ical::VCALITEM

Class ::xo::ical::VCALITEM

::xo::ical::VCALITEM[i] create ... \
           [ -creation_date creation_date ] \
           [ -description description ] \
           [ -dtstamp dtstamp ] \
           [ -dtstart dtstart ] \
           [ -geo geo ] \
           [ -is_day_item (default "false") ] \
           [ -last-modified last-modified ] \
           [ -last_modified last_modified ] \
           [ -location location ] \
           [ -priority priority ] \
           [ -status status ] \
           [ -summary summary ] \
           [ -uid uid ] \
           [ -url url ]

VCALITEM is the superclass of a VTODO and a VEVENT, intended as an abstract class.
Defined in packages/xotcl-core/tcl/ical-procs.tcl

Class Relations

  • class: ::nx::Class[i]
  • superclass: ::nx::Object[i]
  • subclass: ::xo::ical::VEVENT[i], ::xo::ical::VTODO[i]
::nx::Class create ::xo::ical::VCALITEM \
     -superclass ::nx::Object

Methods (to be applied on instances)

  • add_recurrence (scripted, public)

     <instance of xo::ical::VCALITEM[i]> add_recurrence \
        [ -cal_item_id cal_item_id ]

    Call calendar::item::add_recurrence with the options calculated by "parse RRULE"

    Switches:
    -cal_item_id
    (optional)

    Partial Call Graph (max 5 caller/called nodes):
    %3 calendar::item::add_recurrence calendar::item::add_recurrence (public) xo::ical::VCALITEM instproc add_recurrence xo::ical::VCALITEM instproc add_recurrence xo::ical::VCALITEM instproc add_recurrence->calendar::item::add_recurrence

    Testcases:
    No testcase defined.
    if { [info exists :recurrence_options] } {
      calendar::item::add_recurrence  -cal_item_id $cal_item_id  {*}${:recurrence_options}
    }
  • as_ical (scripted, public)

     <instance of xo::ical::VCALITEM[i]> as_ical

    Output a VCALITEM (VTODO or VEVENT) "object" in ical notation.

    Partial Call Graph (max 5 caller/called nodes):
    %3

    Testcases:
    No testcase defined.
    set item_type [namespace tail [:info class]]
    append t "BEGIN:$item_type\r\n"  [:ical_body]  "END:$item_type\r\n"
    return $t
  • edit_recurrence (scripted, public)

     <instance of xo::ical::VCALITEM[i]> edit_recurrence \
        [ -cal_item_id cal_item_id ] [ -recurrence_id recurrence_id ]

    We might or might not have a recurrence on the old entry. In case we have one, the old one might have started earlier, so we try to terminate it.

    Switches:
    -cal_item_id
    (optional)
    -recurrence_id
    (optional)

    Partial Call Graph (max 5 caller/called nodes):
    %3 calendar::item::add_recurrence calendar::item::add_recurrence (public) xo::ical::VCALITEM instproc edit_recurrence xo::ical::VCALITEM instproc edit_recurrence xo::ical::VCALITEM instproc edit_recurrence->calendar::item::add_recurrence

    Testcases:
    No testcase defined.
    :debug "do we have a recurrence? [info exists :recurrence_options]"
    if { [info exists :recurrence_options] } {
      if {$recurrence_id ne ""} {
    
        #
        # The current implementation of calendar::item::edit_recurrence is
        # just built for the interface of the calendar package, which does
        # not allow one to change multiple attributes. We have to assume, that a
        # calendar client allows this.
        #
        # When the old start date is the same as the new start date,
        # we could delete the recurrence and add a new one.
        #
        # calendar::item::delete_recurrence -recurrence_id $recurrence_id
    
        lassign [::xo::dc list -prepare integer get_old_start_date_and_event_id {
          select start_date, e.event_id
          from  acs_events e, timespans t, time_intervals i
          where recurrence_id = :recurrence_id
          and   e.timespan_id = t.timespan_id
          and   i.interval_id = t.interval_id
          order by 1 limit 1
        }] old_start_date old_event_id
    
        :debug "recurrence_id $recurrence_id old_event_id $old_event_id cal_item_id $cal_item_id  old_start_date $old_start_date new start_date ${:dtstart} opts ${:recurrence_options}"
    
        ::xo::db::sql::acs_event recurrence_timespan_edit  -event_id $old_event_id  -start_date $old_start_date  -end_date ${:dtstart}
      }
      calendar::item::add_recurrence  -cal_item_id $cal_item_id  {*}${:recurrence_options}
    }
  • get (scripted, public)

     <instance of xo::ical::VCALITEM[i]> get property [ default ]

    Return a certain property of an ical items. In case, the item has no such property, return the default value.

    Parameters:
    property
    default (optional)

    Partial Call Graph (max 5 caller/called nodes):
    %3

    Testcases:
    No testcase defined.
    if {[info exists :$property]} {
        return [set :$property]
    }
    return $default
  • ical_body (scripted, public)

     <instance of xo::ical::VCALITEM[i]> ical_body

    The method ical_body returns the ical-formatted content of the variables. All variables of VEVENTs and VTODOs are listed below, since the names are distinct, and no methods are used. So far there is no handling for the repetition fields (which might occur more than once). An option would be to handle these as lists. All date/time stamps are provided either by the ANSI date (from postgres) or by a date which can be processed via clock scan

    Partial Call Graph (max 5 caller/called nodes):
    %3 xo::db::tcl_date xo::db::tcl_date (public) xo::ical::VCALITEM instproc ical_body xo::ical::VCALITEM instproc ical_body xo::ical::VCALITEM instproc ical_body->xo::db::tcl_date

    Testcases:
    No testcase defined.
    if {![info exists :dtstamp]}       {set :dtstamp ${:creation_date}}
    if {![info exists :last_modified]} {set :last_modified ${:dtstamp}}
    
    set tcl_stamp         [::xo::db::tcl_date ${:dtstamp} tz]
    set tcl_creation_date [::xo::db::tcl_date ${:creation_date} tz]
    set tcl_last_modified [::xo::db::tcl_date ${:last_modified} tz]
    
    # status values:
    #    VEVENT:   TENTATIVE, CONFIRMED, CANCELLED
    #    VTODO:    NEEDS-ACTION, COMPLETED, IN-PROCESS, CANCELLED
    #    VJOURNAL: DRAFT, FINAL, CANCELLED
    
    append t   [:tag -conv tcl_time_to_utc -value $tcl_creation_date created]  [:tag -conv tcl_time_to_utc -value $tcl_last_modified last-modified]  [:tag -conv tcl_time_to_utc -value $tcl_stamp dtstamp]  [:start_end]  [:tag -conv tcl_time_to_utc completed]  [:tag -conv tcl_time_to_utc percent-complete]  [:tag transp]  [:tag uid]  [:tag url]  [:tag geo]  [:tag priority]  [:tag sequence]  [:tag CLASS]  [:tag -conv text_to_ical location]  [:tag status]  [:tag -conv text_to_ical description]  [:tag -conv text_to_ical summary]  [:tag -conv tcl_time_to_utc due]
    
    if {[info exists :formatted_recurrences]} {
      append t ${:formatted_recurrences}
    }
    return $t
  • parse RRULE (scripted, public)

     <instance of xo::ical::VCALITEM[i]> parse RRULE recurrule

    parse recurrence rule provided in cal syntax. This method assumes that the instance variable dtstart is already set, before this method is called.

    Parameters:
    recurrule

    Partial Call Graph (max 5 caller/called nodes):
    %3

    Testcases:
    No testcase defined.
    set r_freq ""
    set every_n 1
    set r_error 0
    set r_until ""
    set days_of_week ""
    set r_count 0
    foreach rval [split $recurrule ";"] {
      if { [regexp {^FREQ\=+(.*)$} $rval _ freqval] } {
        switch $freqval {
          DAILY   { set r_freq "day" }
          WEEKLY  { set r_freq "week" }
          MONTHLY { set r_freq "month_by_day"}
          YEARLY  { set r_freq "year"}
          default { set r_error 1 }
        }
      } elseif { [regexp {^COUNT=(.*)$} $rval _ countval] } {
        set r_count $countval
      } elseif { [regexp {^UNTIL=([0-9]+)(T([0-9]+)Z?)?$} $rval _ untildate untiltime] } {
        if {$untiltime eq ""} {
          set untiltime 000000
        }
        append r_until  "[string range $untildate 0 3]-[string range $untildate 4 5]-[string range $untildate 6 7]"  " "  "[string range $untiltime 0 1]:[string range $untiltime 2 3]"
      } elseif { [regexp {^INTERVAL\=+(.*)$} $rval _ intval] } {
        set every_n $intval
      } elseif { [regexp {^BYDAY\=+(.*)$} $rval _ bydayval] } {
        #
        # build days_of_week list
        #
        foreach dayval [split $bydayval ","] {
          switch $dayval {
            SU { lappend days_of_week "0" }
            MO { lappend days_of_week "1" }
            TU { lappend days_of_week "2" }
            WE { lappend days_of_week "3" }
            TH { lappend days_of_week "4" }
            FR { lappend days_of_week "5" }
            SA { lappend days_of_week "6" }
          }
        }
      } elseif { [regexp {^BYMONTHDAY\=+(.*)$} $rval _ bymonthdayval] } {
        set r_freq "month_by_date"
      } else {
        # other rules don't work with OpenACS recurrence model
        :debug "ignore recurrence rule <$rval> of <$recurrule>"
      }
      #check we can make this rule, else ignore
    }
    
    #
    # We should have now 'r_freq' computed.  If 'r_until' is not
    # provided, calculate it based on 'r_count' (COUNT is not
    # directly supported by OpenACS).  If both UNTIL and COUNT are
    # not set, it is an unlimited event and skipped.
    #
    if { $r_until eq "" && $r_freq ne "" && $r_count > 0 } {
      # current date + r_count * r_freq * every_n (/ num_days)
      # set num seconds per frequency
      switch $r_freq {
        day           { set r_freq_amount 86400 }
        week          { set r_freq_amount 604800 }
        month_by_day  { set r_freq_amount 2419200 }
        month_by_date { set r_freq_amount 2678400 }
        year          { set r_freq_amount 31449600 }
      }
      # start date is count=1, so adjust count
      set r_count [expr {$r_count - 1}]
      set r_extra [expr {$r_count * $r_freq_amount * $every_n}]
      if { $r_freq eq "week" && [llength $days_of_week] > 0} {
        set r_extra [expr {$r_extra / [llength $days_of_week]}]
      }
      set r_until [::xo::ical clock_to_oacstime [expr {[clock scan ${:dtstart}] + $r_extra}]]
    }
    
    #
    # If we have no errors, and 'r_freq' is computed, then keep the
    # computed values in form of a parameter list for
    # calendar::item::add_recurrence
    #
    if { !$r_error && $r_freq ne ""} {
      set :recurrence_options [list -interval_type $r_freq -every_n $every_n]
      if {$days_of_week ne ""} {
        lappend :recurrence_options -days_of_week $days_of_week
      }
      if {$r_until ne ""} {
        lappend :recurrence_options -recur_until $r_until
      }
    }