def parse(self, ins): result = super(Calendar, self).parse(ins) # We need to store all timezones in the static object so they can be accessed by any date object from pycalendar.timezonedb import TimezoneDatabase TimezoneDatabase.mergeTimezones(self, self.getComponents(definitions.cICalComponent_VTIMEZONE)) return result
def parseComponent(self, ins): result = None LOOK_FOR_VCALENDAR = 0 GET_PROPERTY_OR_COMPONENT = 1 GOT_VCALENDAR = 4 state = LOOK_FOR_VCALENDAR # Get lines looking for start of calendar lines = [None, None] comp = self compend = None componentstack = [] got_timezone = False while readFoldedLine(ins, lines): line = lines[0] if state == LOOK_FOR_VCALENDAR: # Look for start if line == self.getBeginDelimiter(): # Next state state = GET_PROPERTY_OR_COMPONENT # Handle blank line elif len(line) == 0: # Raise if requested, otherwise just ignore if ParserContext.BLANK_LINES_IN_DATA == ParserContext.PARSER_RAISE: raise InvalidData("iCalendar data has blank lines") # Unrecognized data else: raise InvalidData("iCalendar data not recognized", line) elif state == GET_PROPERTY_OR_COMPONENT: # Parse property or look for start of component if line.startswith("BEGIN:"): # Push previous details to stack componentstack.append((comp, compend,)) # Start a new component comp = self.sComponentType.makeComponent(line[6:], comp) compend = comp.getEndDelimiter() # Cache as result - but only the first one, we ignore the rest if result is None: result = comp # Look for timezone component to trigger timezone merge only if one is present if comp.getType() == definitions.cICalComponent_VTIMEZONE: got_timezone = True elif line == self.getEndDelimiter(): # Change state state = GOT_VCALENDAR # Look for end of current component elif line == compend: # Finalise the component (this caches data from the properties) comp.finalise() # Embed component in parent and reset to use parent componentstack[-1][0].addComponent(comp) comp, compend = componentstack.pop() # Blank line elif len(line) == 0: # Raise if requested, otherwise just ignore if ParserContext.BLANK_LINES_IN_DATA == ParserContext.PARSER_RAISE: raise InvalidData("iCalendar data has blank lines") # Ignore top-level items elif comp is self: pass # Must be a property else: # Parse parameter/value for top-level calendar item prop = self.sPropertyType.parseText(line) # Check for valid property if comp is not self: comp.addProperty(prop) # Exit if we have one - ignore all the rest if state == GOT_VCALENDAR: break # We need to store all timezones in the static object so they can be accessed by any date object # Only do this if we read in a timezone if got_timezone: from pycalendar.timezonedb import TimezoneDatabase TimezoneDatabase.mergeTimezones(self, self.getComponents(definitions.cICalComponent_VTIMEZONE)) return result