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 testHmm(self): from icalendar.parser import Contentlines, Contentline c = Contentlines([Contentline('BEGIN:VEVENT\r\n')]) c.append(Contentline(''.join(['123456789 ']*10)+'\r\n')) output = str(c) self.assertEqual(output, 'BEGIN:VEVENT\r\n\r\n123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234\r\n 56789 123456789 123456789 \r\n')
def testHmm(self): from icalendar.parser import Contentlines, Contentline c = Contentlines([Contentline('BEGIN:VEVENT\r\n')]) c.append(Contentline(''.join(['123456789 ']*10)+'\r\n')) output = c.to_ical() self.assertEqual(output, 'BEGIN:VEVENT\r\n\r\n123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234\r\n 56789 123456789 123456789 \r\n')
def XtestLongLine(self): from icalendar.parser import Contentlines, Contentline c = Contentlines([Contentline('BEGIN:VEVENT\\r\\n')]) c.append(Contentline(''.join(['123456789 ']*10)+'\\r\\n')) import pdb ; pdb.set_trace() output = str(c) self.assertEqual(output, "BEGIN:VEVENT\\r\\n\\r\\n123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234\\r\\n 56789 123456789 123456789 \\r\\n")
def content_lines(self): "Converts the Component and subcomponents into content lines" contentlines = Contentlines() for name, values in self.property_items(): params = getattr(values, 'params', Parameters()) contentlines.append(Contentline.from_parts((name, params, values))) contentlines.append('') # remember the empty string in the end return contentlines
def test_long_lines(self): from icalendar.parser import Contentlines, Contentline c = Contentlines([Contentline('BEGIN:VEVENT\r\n')]) c.append(Contentline(''.join('123456789 ' * 10) + '\r\n')) self.assertEqual( c.to_ical(), 'BEGIN:VEVENT\r\n\r\n123456789 123456789 123456789 123456789 ' '123456789 123456789 123456789 1234\r\n 56789 123456789 ' '123456789 \r\n\r\n')
def XtestLongLine(self): from icalendar.parser import Contentlines, Contentline c = Contentlines([Contentline('BEGIN:VEVENT\\r\\n')]) c.append(Contentline(''.join(['123456789 ']*10)+'\\r\\n')) output = c.to_ical() cmp = ("BEGIN:VEVENT\\r\\n\\r\\n123456789 123456789 123456789 " "123456789 123456789 123456789 123456789 1234\\r\\n 56789 " "123456789 123456789 \\r\\n") self.assertEqual(output, cmp)
def content_lines(self, sorted=True): """Converts the Component and subcomponents into content lines. """ contentlines = Contentlines() for name, value in self.property_items(sorted=sorted): cl = self.content_line(name, value, sorted=sorted) contentlines.append(cl) contentlines.append('') # remember the empty string in the end return contentlines
def XtestLongLine(self): from icalendar.parser import Contentlines, Contentline c = Contentlines([Contentline('BEGIN:VEVENT\\r\\n')]) c.append(Contentline(''.join(['123456789 '] * 10) + '\\r\\n')) output = c.to_ical() cmp = ("BEGIN:VEVENT\\r\\n\\r\\n123456789 123456789 123456789 " "123456789 123456789 123456789 123456789 1234\\r\\n 56789 " "123456789 123456789 \\r\\n") self.assertEqual(output, cmp)
def test_long_lines(self): from icalendar.parser import Contentlines, Contentline c = Contentlines([Contentline('BEGIN:VEVENT\r\n')]) c.append(Contentline(''.join('123456789 ' * 10) + '\r\n')) self.assertEqual( c.to_ical(), 'BEGIN:VEVENT\r\n\r\n123456789 123456789 123456789 123456789 ' '123456789 123456789 123456789 1234\r\n 56789 123456789 ' '123456789 \r\n\r\n' )
def testHmm(self): from icalendar.parser import Contentlines, Contentline c = Contentlines([Contentline("BEGIN:VEVENT\r\n")]) c.append(Contentline("".join(["123456789 "] * 10) + "\r\n")) output = c.to_ical() self.assertEqual( output, "BEGIN:VEVENT\r\n\r\n123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234\r\n 56789 123456789 123456789 \r\n", )
def testHmm(self): from icalendar.parser import Contentlines, Contentline c = Contentlines([Contentline('BEGIN:VEVENT\r\n')]) c.append(Contentline(''.join(['123456789 ']*10)+'\r\n')) output = c.to_ical() # XXX: sure? looks weird in conjunction with generated content above. #cmp = ('BEGIN:VEVENT\r\n\r\n123456789 123456789 123456789 123456789 ' # '123456789 123456789 123456789 1234\r\n 56789 123456789 ' # '123456789 \r\n') cmp = ('BEGIN:VEVENT\r\n\r\n123456789 123456789 123456789 123456789 ' '123456789 123456789 123456789 \r\n 123456789 123456789 ' '123456789 \r\n\r\n') self.assertEqual(output, cmp)
def testHmm(self): from icalendar.parser import Contentlines, Contentline c = Contentlines([Contentline('BEGIN:VEVENT\r\n')]) c.append(Contentline(''.join(['123456789 '] * 10) + '\r\n')) output = c.to_ical() # XXX: sure? looks weird in conjunction with generated content above. #cmp = ('BEGIN:VEVENT\r\n\r\n123456789 123456789 123456789 123456789 ' # '123456789 123456789 123456789 1234\r\n 56789 123456789 ' # '123456789 \r\n') cmp = ('BEGIN:VEVENT\r\n\r\n123456789 123456789 123456789 123456789 ' '123456789 123456789 123456789 \r\n 123456789 123456789 ' '123456789 \r\n\r\n') self.assertEqual(output, cmp)
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 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: 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_string(st, multiple=False): """ Populates the component recursively from a string """ stack = [] # a stack of components comps = [] for line in Contentlines.from_string(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: 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_string(st, multiple=False): """ Populates the component recursively from a string """ stack = [] # a stack of components comps = [] for line in Contentlines.from_string(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: stack[-1].add_component(component) # we are adding properties to the current top of the stack else: factory = types_factory.for_property(name) vals = factory(factory.from_ical(vals)) vals.params = params stack[-1].add(name, vals, encode=0) if multiple: return comps if not len(comps) == 1: raise ValueError('Found multiple components where ' 'only one is allowed') return comps[0]
def from_string(st, multiple=False): """ Populates the component recursively from a string """ stack = [] # a stack of components comps = [] for line in Contentlines.from_string(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: stack[-1].add_component(component) # we are adding properties to the current top of the stack else: factory = types_factory.for_property(name) vals = factory(factory.from_ical(vals)) vals.params = params stack[-1].add(name, vals, encode=0) if multiple: return comps if not len(comps) == 1: raise ValueError('Found multiple components where ' 'only one is allowed') 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 = [] 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]
def XtestTrailingNewline(self): from icalendar.parser import Contentlines, Contentline c = Contentlines([Contentline('BEGIN:VEVENT\\r\\n')]) output = c.to_ical() self.assertEqual(output, 'BEGIN:VEVENT\\r\\n')
def XtestTrailingNewline(self): from icalendar.parser import Contentlines, Contentline c = Contentlines([Contentline('BEGIN:VEVENT\\r\\n')]) output = str(c) self.assertEqual(output, 'BEGIN:VEVENT\\r\\n')