async def report(self, environ, body, resources_by_hrefs, properties, base_href, base_resource, depth): requested = None for el in body: if el.tag == '{urn:ietf:params:xml:ns:caldav}time-range': requested = el else: raise AssertionError("unexpected XML element") tz = get_calendar_timezone(base_resource) def tzify(dt): return as_tz_aware_ts(dt, tz).astimezone(pytz.utc) (start, end) = _parse_time_range(requested) assert start.tzinfo assert end.tzinfo ret = ICalendar() ret['VERSION'] = '2.0' ret['PRODID'] = PRODID fb = FreeBusy() fb['DTSTAMP'] = vDDDTypes(tzify(datetime.datetime.now())) fb['DTSTART'] = vDDDTypes(start) fb['DTEND'] = vDDDTypes(end) fb['FREEBUSY'] = [item async for item in iter_freebusy( webdav.traverse_resource(base_resource, base_href, depth), start, end, tzify)] ret.add_component(fb) return webdav.Response(status='200 OK', body=[ret.to_ical()])
def as_vevent(self): revent = self.source.copy() revent["DTSTART"] = vDDDTypes(self.start) revent["DTEND"] = vDDDTypes(self.stop) for attribute in self.ATTRIBUTES_TO_DELETE_ON_COPY: if attribute in revent: del revent[attribute] for subcomponent in self.source.subcomponents: revent.add_component(subcomponent) return revent
def convert_error(self, error, url, tb_s): """Create an error which can be used by the dhtmlx scheduler.""" event = Event() event["DTSTART"] = event["DTEND"] = vDDDTypes(datetime.datetime.now()) event["SUMMARY"] = type(error).__name__ event["DESCRIPTION"] = str(error) + "\n\n" + tb_s event["UID"] = "error" + str(id(error)) if url: event["URL"] = url return event
def str_to_exdate_list(value): """This is a hack to create valid time date ranges""" # This would create something like ``EXDATE;VALUE=DATE:yyyymmdd``. # It might be what we need, or not. Currently, the other alternative below # serves us better, so this is not used. # exdate_list = [vDate(item) for item in vDDDLists.from_ical(value)] exdate_list = [ vDDDTypes(item).to_ical() for item in vDDDLists.from_ical(value) ] return exdate_list
def match_indexes(self, indexes, tzify): vs = {} for name, value in indexes.items(): if name and name[2:] in self.all_props: if value and value[0]: if not isinstance(value[0], vDDDTypes): vs[name[2:]] = vDDDTypes(vDatetime.from_ical(value[0])) else: vs[name[2:]] = value[0] try: component_handler = self.component_handlers[self.comp] except KeyError: logging.warning('unknown component %r in time-range filter', self.comp) return False return component_handler(self.start, self.end, vs, tzify)
def set_event_info_from_vevent(instance, ev, kw_map, do_action=True): # Make sure a subtransaction happens. We might end up renaming the # event, and we don't really know if it was existing or new. transaction.savepoint(optimistic=True) info = {} for k, v in kw_map.items(): value = ev.get(k, None) if value is None: # Ugh, special case for dtend if k in ('dtend', ): # dtstart and duration *must* exist. dtstart = ev.get('dtstart') params = getattr(dtstart, 'params', {}) duration = ev.get('duration') if duration is None: dtend = dtstart.dt else: dtend = dtstart.dt + duration.dt value = vDDDTypes(dtend) value.params = Parameters(dict(params)) else: continue value = convert(value) info[v] = value instance.update(**info) uid = ev.decoded('uid', None) if uid is None: uid = generateUID(instance) setattr(instance, UID_ATTR, uid) if do_action: # XXX NAAAAASTY Code. We need to create a special # workflow for Event. This assumes the default Plone workflow. wf = getToolByName(instance, 'portal_workflow') state = wf.getInfoFor(instance, 'review_state') status = ev.get('status', 'CONFIRMED') if not re_status_mapping.get(state, 'CONFIRMED') == status: set_event_state_from_status(instance, status, wf) instance.reindexObject()
def set_event_info_from_vevent(instance, ev, kw_map, do_action=True): # Make sure a subtransaction happens. We might end up renaming the # event, and we don't really know if it was existing or new. transaction.savepoint(optimistic=True) info = {} for k, v in kw_map.items(): value = ev.get(k, None) if value is None: # Ugh, special case for dtend if k in ('dtend',): # dtstart and duration *must* exist. dtstart = ev.get('dtstart') params = getattr(dtstart, 'params', {}) duration = ev.get('duration') if duration is None: dtend = dtstart.dt else: dtend = dtstart.dt + duration.dt value = vDDDTypes(dtend) value.params = Parameters(dict(params)) else: continue value = convert(value) info[v] = value instance.update(**info) uid = ev.decoded('uid', None) if uid is None: uid = generateUID(instance) setattr(instance, UID_ATTR, uid) if do_action: # XXX NAAAAASTY Code. We need to create a special # workflow for Event. This assumes the default Plone workflow. wf = getToolByName(instance, 'portal_workflow') state = wf.getInfoFor(instance, 'review_state') status = ev.get('status', 'CONFIRMED') if not re_status_mapping.get(state, 'CONFIRMED') == status: set_event_state_from_status(instance, status, wf) instance.reindexObject()
def match_indexes(self, prop, tzify): return any( self.match(vDDDTypes(vDatetime.from_ical(p)), tzify) for p in prop[None])