def from_ical(cls, st, multiple=False): """Populates the component recursively from a string. """ stack = [] # a stack of components comps = [] previous_line = None for line in Contentlines.from_ical(st): # raw parsing if not line: continue try: name, params, vals = line.parts() previous_line = line except ValueError as err: # if unable to parse a line within a component # that ignores exceptions, mark the component # as broken and skip the line. otherwise raise. try: if previous_line and name in NEWLINE_FIX_NAMES: try: #Try to generate line from last name key (fix malformed line breaks) new_line = Contentline.from_ical( previous_line + escape_char('\n') + line) name, params, vals = new_line.parts() component = stack[-1] component.pop(name) previous_line = new_line except: raise else: raise except ValueError as err: component = stack[-1] if stack else None if not component or not component.ignore_exceptions: raise component.is_broken = True print "Broken: " + str(component) continue uname = name.upper() # check for start of component if uname == 'BEGIN': # try and create one of the components defined in the spec, # otherwise get a general Components for robustness. c_name = vals.upper() c_class = component_factory.get(c_name, cls) component = c_class() if not getattr(component, 'name', ''): # undefined components component.name = c_name stack.append(component) # check for end of event elif uname == 'END': # we are done adding properties to this component # so pop it from the stack and add it to the new top. component = stack.pop() if not stack: # we are at the end comps.append(component) else: if not component.is_broken: stack[-1].add_component(component) # we are adding properties to the current top of the stack else: factory = types_factory.for_property(name) component = stack[-1] datetime_names = ('DTSTART', 'DTEND', 'RECURRENCE-ID', 'DUE', 'FREEBUSY', 'RDATE', 'EXDATE') try: if name in datetime_names and 'TZID' in params: vals = factory(factory.from_ical(vals, params['TZID'])) else: vals = factory(factory.from_ical(vals)) except ValueError: if not component.ignore_exceptions: raise component.is_broken = True else: vals.params = params component.add(name, vals, encode=0) if multiple: return comps if len(comps) > 1: raise ValueError('Found multiple components where ' 'only one is allowed: {st!r}'.format(**locals())) if len(comps) < 1: #Fix missing END:VCALENDAR flag problem if len(stack)==1 and stack[-1].name == u'VCALENDAR': component = stack.pop() comps.append(component) else: raise ValueError('Found no components where ' 'exactly one is required: ' '{st!r}'.format(**locals())) return comps[0]
def extract_attendees(output): evt_attendees = {} for line in Contentlines.from_ical(output): # raw parsing try: name, params, vals = line.parts() if name == 'UID': uid = vals if name == 'ATTENDEE': if uid not in evt_attendees: evt_attendees[str(uid)] = [] vals = vals.replace('mailto:', '') if re.match( r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)", vals): evt_attendees[str(uid)].append({ 'email': vals, 'CN': params['CN'], 'PARTSTAT': params['PARTSTAT'] }) except: """""" return evt_attendees
def from_ical(cls, st, multiple=False): """Populates the component recursively from a string. """ stack = [] # a stack of components comps = [] for line in Contentlines.from_ical(st): # raw parsing if not line: continue name, params, vals = line.parts() uname = name.upper() # check for start of component if uname == 'BEGIN': # try and create one of the components defined in the spec, # otherwise get a general Components for robustness. c_name = vals.upper() c_class = component_factory.get(c_name, cls) component = c_class() if not getattr(component, 'name', ''): # undefined components component.name = c_name stack.append(component) # check for end of event elif uname == 'END': # we are done adding properties to this component # so pop it from the stack and add it to the new top. component = stack.pop() if not stack: # we are at the end comps.append(component) else: if not component.is_broken: stack[-1].add_component(component) # we are adding properties to the current top of the stack else: factory = types_factory.for_property(name) component = stack[-1] datetime_names = ('DTSTART', 'DTEND', 'RECURRENCE-ID', 'DUE', 'FREEBUSY', 'RDATE', 'EXDATE') try: if name in datetime_names and 'TZID' in params: vals = factory(factory.from_ical(vals, params['TZID'])) else: vals = factory(factory.from_ical(vals)) except ValueError: if not component.ignore_exceptions: raise component.is_broken = True else: vals.params = params component.add(name, vals, encode=0) if multiple: return comps if len(comps) > 1: raise ValueError('Found multiple components where ' 'only one is allowed: {st!r}'.format(**locals())) if len(comps) < 1: raise ValueError('Found no components where ' 'exactly one is required: ' '{st!r}'.format(**locals())) return comps[0]
def test_main(self, lines): cl = Contentlines() for key, params, value in lines: params = Parameters(**params) cl.append(Contentline.from_parts(key, params, value)) cl.append('') assert Contentlines.from_ical(cl.to_ical()) == cl
def test_main(self, lines): cl = Contentlines() for key, params, value in lines: try: params = Parameters(**params) except TypeError: # Happens when there is a random parameter 'self'... continue cl.append(Contentline.from_parts(key, params, value)) cl.append('') assert Contentlines.from_ical(cl.to_ical()) == cl
def from_ical(st, multiple=False): """ Populates the component recursively from a string RecurrenceIDs may contain a TZID parameter, if so, they should create a tz localized datetime, otherwise, create a naive datetime >>> componentStr = 'BEGIN:VEVENT\\nRECURRENCE-ID;TZID=America/Denver:20120404T073000\\nEND:VEVENT' >>> component = Component.from_ical(componentStr) >>> component['RECURRENCE-ID'].dt.tzinfo <DstTzInfo 'America/Denver' MDT-1 day, 18:00:00 DST> >>> componentStr = 'BEGIN:VEVENT\\nRECURRENCE-ID:20120404T073000\\nEND:VEVENT' >>> component = Component.from_ical(componentStr) >>> component['RECURRENCE-ID'].dt.tzinfo == None True """ stack = [] # a stack of components comps = [] for line in Contentlines.from_ical(st): # raw parsing if not line: continue name, params, vals = line.parts() uname = name.upper() # check for start of component if uname == 'BEGIN': # try and create one of the components defined in the spec, # otherwise get a general Components for robustness. component_name = vals.upper() component_class = component_factory.get(component_name, Component) component = component_class() if not getattr(component, 'name', ''): # for undefined components component.name = component_name stack.append(component) # check for end of event elif uname == 'END': # we are done adding properties to this component # so pop it from the stack and add it to the new top. component = stack.pop() if not stack: # we are at the end comps.append(component) else: if not component.is_broken: stack[-1].add_component(component) # we are adding properties to the current top of the stack else: factory = types_factory.for_property(name) component = stack[-1] try: if name in ('DTSTART', 'DTEND','RECURRENCE-ID') and 'TZID' in params: # TODO: add DUE, FREEBUSY vals = factory(factory.from_ical(vals, params['TZID'])) else: vals = factory(factory.from_ical(vals)) except ValueError: if not component.ignore_exceptions: raise component.is_broken = True else: vals.params = params component.add(name, vals, encode=0) if multiple: return comps if len(comps) > 1: raise ValueError('Found multiple components where ' 'only one is allowed: {st!r}'.format(**locals())) if len(comps) < 1: raise ValueError('Found no components where ' 'exactly one is required: {st!r}'.format(**locals())) return comps[0]
def from_ical(cls, st, multiple=False): """Populates the component recursively from a string. """ stack = [] # a stack of components comps = [] for line in Contentlines.from_ical(st): # raw parsing if not line: continue try: name, params, vals = line.parts() except ValueError as e: # if unable to parse a line within a component # that ignores exceptions, mark the component # as broken and skip the line. otherwise raise. component = stack[-1] if stack else None if not component or not component.ignore_exceptions: raise component.errors.append((None, unicode_type(e))) continue uname = name.upper() # check for start of component if uname == 'BEGIN': # try and create one of the components defined in the spec, # otherwise get a general Components for robustness. c_name = vals.upper() c_class = component_factory.get(c_name, Component) # If component factory cannot resolve ``c_name``, the generic # ``Component`` class is used which does not have the name set. # That's opposed to the usage of ``cls``, which represents a # more concrete subclass with a name set (e.g. VCALENDAR). component = c_class() if not getattr(component, 'name', ''): # undefined components component.name = c_name stack.append(component) # check for end of event elif uname == 'END': # we are done adding properties to this component # so pop it from the stack and add it to the new top. component = stack.pop() if not stack: # we are at the end comps.append(component) else: stack[-1].add_component(component) if vals == 'VTIMEZONE' and \ 'TZID' in component and \ component['TZID'] not in pytz.all_timezones and \ component['TZID'] not in _timezone_cache: _timezone_cache[component['TZID']] = component.to_tz() # we are adding properties to the current top of the stack else: factory = types_factory.for_property(name) component = stack[-1] if stack else None if not component: raise ValueError('Property "{prop}" does not have ' 'a parent component.'.format(prop=name)) datetime_names = ('DTSTART', 'DTEND', 'RECURRENCE-ID', 'DUE', 'FREEBUSY', 'RDATE', 'EXDATE') try: if name in datetime_names and 'TZID' in params: vals = factory(factory.from_ical(vals, params['TZID'])) else: vals = factory(factory.from_ical(vals)) except ValueError as e: if not component.ignore_exceptions: raise component.errors.append((uname, unicode_type(e))) component.add(name, None, encode=0) else: vals.params = params component.add(name, vals, encode=0) if multiple: return comps if len(comps) > 1: raise ValueError('Found multiple components where ' 'only one is allowed: {st!r}'.format(**locals())) if len(comps) < 1: raise ValueError('Found no components where ' 'exactly one is required: ' '{st!r}'.format(**locals())) return comps[0]
def from_ical(st, multiple=False): """ Populates the component recursively from a string RecurrenceIDs may contain a TZID parameter, if so, they should create a tz localized datetime, otherwise, create a naive datetime >>> componentStr = 'BEGIN:VEVENT\\nRECURRENCE-ID;TZID=America/Denver:20120404T073000\\nEND:VEVENT' >>> component = Component.from_ical(componentStr) >>> component['RECURRENCE-ID'].dt.tzinfo <DstTzInfo 'America/Denver' MDT-1 day, 18:00:00 DST> >>> componentStr = 'BEGIN:VEVENT\\nRECURRENCE-ID:20120404T073000\\nEND:VEVENT' >>> component = Component.from_ical(componentStr) >>> component['RECURRENCE-ID'].dt.tzinfo == None True """ stack = [] # a stack of components comps = [] for line in Contentlines.from_ical(st): # raw parsing if not line: continue name, params, vals = line.parts() uname = name.upper() # check for start of component if uname == 'BEGIN': # try and create one of the components defined in the spec, # otherwise get a general Components for robustness. component_name = vals.upper() component_class = component_factory.get( component_name, Component) component = component_class() if not getattr(component, 'name', ''): # for undefined components component.name = component_name stack.append(component) # check for end of event elif uname == 'END': # we are done adding properties to this component # so pop it from the stack and add it to the new top. component = stack.pop() if not stack: # we are at the end comps.append(component) else: if not component.is_broken: stack[-1].add_component(component) # we are adding properties to the current top of the stack else: factory = types_factory.for_property(name) component = stack[-1] try: if name in ( 'DTSTART', 'DTEND', 'RECURRENCE-ID' ) and 'TZID' in params: # TODO: add DUE, FREEBUSY vals = factory(factory.from_ical(vals, params['TZID'])) else: vals = factory(factory.from_ical(vals)) except ValueError: if not component.ignore_exceptions: raise component.is_broken = True else: vals.params = params component.add(name, vals, encode=0) if multiple: return comps if len(comps) > 1: raise ValueError('Found multiple components where ' 'only one is allowed: {st!r}'.format(**locals())) if len(comps) < 1: raise ValueError( 'Found no components where ' 'exactly one is required: {st!r}'.format(**locals())) return comps[0]
def from_ical(cls, st, multiple=False): """Populates the component recursively from a string. """ stack = [] # a stack of components comps = [] previous_line = None for line in Contentlines.from_ical(st): # raw parsing if not line: continue try: name, params, vals = line.parts() previous_line = line except ValueError as err: # if unable to parse a line within a component # that ignores exceptions, mark the component # as broken and skip the line. otherwise raise. try: if previous_line and name in NEWLINE_FIX_NAMES: try: #Try to generate line from last name key (fix malformed line breaks) new_line = Contentline.from_ical( previous_line + escape_char('\n') + line) name, params, vals = new_line.parts() component = stack[-1] component.pop(name) previous_line = new_line except: raise else: raise except ValueError as err: component = stack[-1] if stack else None if not component or not component.ignore_exceptions: raise component.is_broken = True print "Broken: " + str(component) continue uname = name.upper() # check for start of component if uname == 'BEGIN': # try and create one of the components defined in the spec, # otherwise get a general Components for robustness. c_name = vals.upper() c_class = component_factory.get(c_name, cls) component = c_class() if not getattr(component, 'name', ''): # undefined components component.name = c_name stack.append(component) # check for end of event elif uname == 'END': # we are done adding properties to this component # so pop it from the stack and add it to the new top. component = stack.pop() if not stack: # we are at the end comps.append(component) else: if not component.is_broken: stack[-1].add_component(component) # we are adding properties to the current top of the stack else: factory = types_factory.for_property(name) component = stack[-1] datetime_names = ('DTSTART', 'DTEND', 'RECURRENCE-ID', 'DUE', 'FREEBUSY', 'RDATE', 'EXDATE') try: if name in datetime_names and 'TZID' in params: vals = factory(factory.from_ical(vals, params['TZID'])) else: vals = factory(factory.from_ical(vals)) except ValueError: if not component.ignore_exceptions: raise component.is_broken = True else: vals.params = params component.add(name, vals, encode=0) if multiple: return comps if len(comps) > 1: raise ValueError('Found multiple components where ' 'only one is allowed: {st!r}'.format(**locals())) if len(comps) < 1: #Fix missing END:VCALENDAR flag problem if len(stack) == 1 and stack[-1].name == u'VCALENDAR': component = stack.pop() comps.append(component) else: raise ValueError('Found no components where ' 'exactly one is required: ' '{st!r}'.format(**locals())) return comps[0]