def getICal(self): """get iCal data """ start_str, end_str = event_util.dateStringsForEvent(self.context) out = StringIO() map = { 'dtstamp' : rfc2445dt(DateTime()), 'created' : rfc2445dt(DateTime(self.context.CreationDate())), 'uid' : self.context.UID(), 'modified' : rfc2445dt(DateTime(self.context.ModificationDate())), 'summary' : vformat(self.context.Title()), 'startdate' : start_str, 'enddate' : end_str, } out.write(ICS_EVENT_START % map) description = self.context.Description() if description: out.write(foldline('DESCRIPTION:%s\n' % vformat(description))) location = self.context.getLocation() if location: out.write('LOCATION:%s\n' % vformat(location)) subject = self.context.Subject() if subject: out.write('CATEGORIES:%s\n' % ','.join(subject)) # TODO -- NO! see the RFC; ORGANIZER field is not to be used for non-group-scheduled entities #ORGANIZER;CN=%(name):MAILTO=%(email) #ATTENDEE;CN=%(name);ROLE=REQ-PARTICIPANT:mailto:%(email) cn = [] contact = self.context.contact_name() if contact: cn.append(contact) phone = self.context.contact_phone() if phone: cn.append(phone) email = self.context.contact_email() if email: cn.append(email) if cn: out.write('CONTACT:%s\n' % vformat(', '.join(cn))) url = self.context.event_url() if url: out.write('URL:%s\n' % url) # allow derived event types to inject additional data for iCal try: self.context.getICalSupplementary(out) except AttributeError: pass out.write(ICS_EVENT_END) return out.getvalue()
def test_rfc2445dt(self): dt = DateTime('2005/07/20 18:00:00 Brazil/East') self.assertEqual(rfc2445dt(dt), '20050720T210000Z') dt = DateTime('2010/08/31 20:15:00 GMT+1') self.assertEqual(rfc2445dt(dt), '20100831T191500Z') # we need a DateTime-object as input dt = datetime.datetime.now() self.assertRaises(AttributeError, rfc2445dt, dt)
def dateStringsForEvent(event): # Smarter handling for whole-day events data_dict = toDisplay(event) if event.getWholeDay(): # For all-day events we must not include the time within # the date-time string start_str = _dateForWholeDay(event.start())[:8] if data_dict["same_day"]: # one-day events end with the timestamp of the next day # (which is the start data plus 1 day) end_str = _dateForWholeDay(event.start() + 1)[:8] else: # all-day events lasting several days end at the next # day after the end date end_str = _dateForWholeDay(event.end() + 1)[:8] else: # default (as used in Plone) start_str = rfc2445dt(event.start()) end_str = rfc2445dt(event.end()) return start_str, end_str