Changeset View
Standalone View
pykolab/xml/event.py
Show First 20 Lines • Show All 146 Lines • ▼ Show 20 Lines | def add_attendee(self, email_or_attendee, name=None, rsvp=False, role=None, participant_status=None, cutype="INDIVIDUAL", params=None): | ||||
# apply update to self and all exceptions | # apply update to self and all exceptions | ||||
self.update_attendees([attendee], True) | self.update_attendees([attendee], True) | ||||
def add_category(self, category): | def add_category(self, category): | ||||
self._categories.append(ustr(category)) | self._categories.append(ustr(category)) | ||||
self.event.setCategories(self._categories) | self.event.setCategories(self._categories) | ||||
def add_recurrence_date(self, _datetime): | |||||
valid_datetime = False | |||||
if isinstance(_datetime, datetime.date): | |||||
valid_datetime = True | |||||
if isinstance(_datetime, datetime.datetime): | |||||
# If no timezone information is passed on, make it UTC | |||||
if _datetime.tzinfo is None: | |||||
_datetime = _datetime.replace(tzinfo=pytz.utc) | |||||
valid_datetime = True | |||||
if not valid_datetime: | |||||
raise InvalidEventDateError, _("Rdate needs datetime.date or datetime.datetime instance, got %r") % (type(_datetime)) | |||||
self.event.addRecurrenceDate(xmlutils.to_cdatetime(_datetime, True)) | |||||
def add_exception_date(self, _datetime): | def add_exception_date(self, _datetime): | ||||
valid_datetime = False | valid_datetime = False | ||||
if isinstance(_datetime, datetime.date): | if isinstance(_datetime, datetime.date): | ||||
valid_datetime = True | valid_datetime = True | ||||
if isinstance(_datetime, datetime.datetime): | if isinstance(_datetime, datetime.datetime): | ||||
# If no timezone information is passed on, make it UTC | # If no timezone information is passed on, make it UTC | ||||
if _datetime.tzinfo == None: | if _datetime.tzinfo == None: | ||||
▲ Show 20 Lines • Show All 313 Lines • ▼ Show 20 Lines | def get_date_text(self, date_format=None, time_format=None): | ||||
if all_day: | if all_day: | ||||
time_format = '' | time_format = '' | ||||
if start_date == end_date: | if start_date == end_date: | ||||
return start.strftime(date_format) | return start.strftime(date_format) | ||||
return "%s - %s" % (start.strftime(date_format + " " + time_format), end.strftime(end_format)) | return "%s - %s" % (start.strftime(date_format + " " + time_format), end.strftime(end_format)) | ||||
def get_recurrence_dates(self): | |||||
return map(lambda _: xmlutils.from_cdatetime(_, True), self.event.recurrenceDates()) | |||||
def get_exception_dates(self): | def get_exception_dates(self): | ||||
return map(lambda _: xmlutils.from_cdatetime(_, True), self.event.exceptionDates()) | return map(lambda _: xmlutils.from_cdatetime(_, True), self.event.exceptionDates()) | ||||
def get_exceptions(self): | def get_exceptions(self): | ||||
return self._exceptions | return self._exceptions | ||||
def has_exceptions(self): | def has_exceptions(self): | ||||
return len(self._exceptions) > 0 | return len(self._exceptions) > 0 | ||||
▲ Show 20 Lines • Show All 168 Lines • ▼ Show 20 Lines | class Event(object): | ||||
def get_ical_rrule(self): | def get_ical_rrule(self): | ||||
result = [] | result = [] | ||||
rrule = self.get_recurrence() | rrule = self.get_recurrence() | ||||
if rrule.isValid(): | if rrule.isValid(): | ||||
result.append(rrule.to_ical()) | result.append(rrule.to_ical()) | ||||
return result | return result | ||||
def get_ical_rdate(self): | |||||
rdates = self.get_recurrence_dates() | |||||
for i in range(len(rdates)): | |||||
rdates[i] = icalendar.prop.vDDDLists(rdates[i]) | |||||
return rdates | |||||
def get_location(self): | def get_location(self): | ||||
return self.event.location() | return self.event.location() | ||||
def get_lastmodified(self): | def get_lastmodified(self): | ||||
try: | try: | ||||
_datetime = self.event.lastModified() | _datetime = self.event.lastModified() | ||||
if _datetime == None or not _datetime.isValid(): | if _datetime == None or not _datetime.isValid(): | ||||
self.__str__() | self.__str__() | ||||
▲ Show 20 Lines • Show All 148 Lines • ▼ Show 20 Lines | def set_end(self, _datetime): | ||||
raise InvalidEventDateError, _("Event end needs datetime.date or datetime.datetime instance, got %r") % (type(_datetime)) | raise InvalidEventDateError, _("Event end needs datetime.date or datetime.datetime instance, got %r") % (type(_datetime)) | ||||
self.event.setEnd(xmlutils.to_cdatetime(_datetime, True)) | self.event.setEnd(xmlutils.to_cdatetime(_datetime, True)) | ||||
def set_exception_dates(self, _datetimes): | def set_exception_dates(self, _datetimes): | ||||
for _datetime in _datetimes: | for _datetime in _datetimes: | ||||
self.add_exception_date(_datetime) | self.add_exception_date(_datetime) | ||||
def set_recurrence_dates(self, _datetimes): | |||||
for _datetime in _datetimes: | |||||
self.add_recurrence_date(_datetime) | |||||
def add_custom_property(self, name, value): | def add_custom_property(self, name, value): | ||||
if not name.upper().startswith('X-'): | if not name.upper().startswith('X-'): | ||||
raise ValueError, _("Invalid custom property name %r") % (name) | raise ValueError, _("Invalid custom property name %r") % (name) | ||||
props = self.event.customProperties() | props = self.event.customProperties() | ||||
props.append(kolabformat.CustomProperty(name.upper(), value)) | props.append(kolabformat.CustomProperty(name.upper(), value)) | ||||
self.event.setCustomProperties(props) | self.event.setCustomProperties(props) | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | def set_ical_sequence(self, sequence): | ||||
self.set_sequence(sequence) | self.set_sequence(sequence) | ||||
def set_ical_summary(self, summary): | def set_ical_summary(self, summary): | ||||
self.set_summary(ustr(summary)) | self.set_summary(ustr(summary)) | ||||
def set_ical_uid(self, uid): | def set_ical_uid(self, uid): | ||||
self.set_uid(str(uid)) | self.set_uid(str(uid)) | ||||
def set_ical_rdate(self, rdate): | |||||
rdates = [] | |||||
# rdate here can be vDDDLists or a list of vDDDLists, why?! | |||||
if isinstance(rdate, icalendar.prop.vDDDLists): | |||||
rdate = [rdate] | |||||
for _rdate in rdate: | |||||
if isinstance(_rdate, icalendar.prop.vDDDLists): | |||||
tzid = None | |||||
if hasattr(_rdate, 'params') and 'TZID' in _rdate.params: | |||||
vanmeeuwen: Does the existence of an `_rdate.params` attribute imply that the 'TZID' key is set? | |||||
Not Done Inline ActionsYes, it does. According to icalendar code, but I'll add additional check. machniak: Yes, it does. According to icalendar code, but I'll add additional check. | |||||
tzid = _rdate.params['TZID'] | |||||
dts = icalendar.prop.vDDDLists.from_ical(_rdate.to_ical(), tzid) | |||||
for datetime in dts: | |||||
rdates.append(datetime) | |||||
self.set_recurrence_dates(rdates) | |||||
def set_ical_recurrenceid(self, value, params): | def set_ical_recurrenceid(self, value, params): | ||||
try: | try: | ||||
self.thisandfuture = params.get('RANGE', '') == 'THISANDFUTURE' | self.thisandfuture = params.get('RANGE', '') == 'THISANDFUTURE' | ||||
self.set_recurrence_id(value, self.thisandfuture) | self.set_recurrence_id(value, self.thisandfuture) | ||||
except InvalidEventDateError, e: | except InvalidEventDateError, e: | ||||
pass | pass | ||||
def set_lastmodified(self, _datetime=None): | def set_lastmodified(self, _datetime=None): | ||||
▲ Show 20 Lines • Show All 354 Lines • ▼ Show 20 Lines | def to_message_itip(self, from_address, method="REQUEST", participant_status="ACCEPTED", subject=None, message_text=None): | ||||
# attendees being reduced to the replying attendee above | # attendees being reduced to the replying attendee above | ||||
if attendees is not None: | if attendees is not None: | ||||
self._attendees = attendees | self._attendees = attendees | ||||
self.event.setAttendees(self._attendees) | self.event.setAttendees(self._attendees) | ||||
return msg | return msg | ||||
def is_recurring(self): | def is_recurring(self): | ||||
return self.event.recurrenceRule().isValid() | return self.event.recurrenceRule().isValid() or len(self.get_recurrence_dates()) > 0 | ||||
Not Done Inline ActionsShould not both clauses in this || statement evaluate to True? It seems that for a recurring event, .isValid() should be true as well as (implicitly) a positive number of occurrences should exist. Note also that a "recurring" event with only one occurrence would validate len() > 0, which may not yield the expected results. Also note that self.event (the lower-level XML level) and self.get_recurrence_dates() work on two different in-memory representations of the event, allowing for race-conditions. Perhaps it is best to ensure the complete event is read and parsed, which should logically lead to two equals copies. vanmeeuwen: Should not both clauses in this `||` statement evaluate to True? It seems that for a recurring… | |||||
Not Done Inline ActionsRDATE specified additional occurrences. So if there's one RDATE it is recurring event. There can be an event with RDATE but no recurrence rule. So, I think this is correct. I don't get the last paragraph. get_recurrence_dates() also uses self.event. machniak: RDATE specified additional occurrences. So if there's one RDATE it is recurring event. There… | |||||
def to_event_cal(self): | def to_event_cal(self): | ||||
from kolab.calendaring import EventCal | from kolab.calendaring import EventCal | ||||
return EventCal(self.event) | return EventCal(self.event) | ||||
def get_next_occurence(self, _datetime): | def get_next_occurence(self, _datetime): | ||||
if not hasattr(self, 'eventcal'): | if not hasattr(self, 'eventcal'): | ||||
self.eventcal = self.to_event_cal() | self.eventcal = self.to_event_cal() | ||||
▲ Show 20 Lines • Show All 134 Lines • Show Last 20 Lines |
Does the existence of an _rdate.params attribute imply that the 'TZID' key is set?