def load_state_from_ical_file(self, file): """Load state from the given ical file. """ self.reset() self.set_changed() components = {} # Read the data data = file.read() # Parse lines = [] for name, value, parameters in parse_table(data): # Timestamp (ts), Schema, or Something else datatype = self.get_record_datatype(name) value = datatype.decode(value) property = Property(value, **parameters) # Append lines.append((name, property)) # Read first line first = lines[0] if (first[0] != 'BEGIN' or first[1].value != 'VCALENDAR' or len(first[1].parameters) != 0): raise ValueError, 'icalendar must begin with BEGIN:VCALENDAR' lines = lines[1:] ################################################################### # Skip properties # TODO Currently tables are not able to handler global properties, # we must implement this feature to be able to load from ical files. n_line = 0 for name, value in lines: if name == 'BEGIN': break elif name == 'END': break n_line += 1 lines = lines[n_line:] ################################################################### # Read components c_type = None c_inner_type = None uid = None records = self.records record_properties = self.record_properties id = 0 uids = {} for prop_name, prop_value in lines[:-1]: if prop_name in ('PRODID', 'VERSION'): raise ValueError, 'PRODID and VERSION must appear before '\ 'any component' if prop_name == 'BEGIN': if c_type is None: c_type = prop_value.value c_properties = {} c_inner_components = [] else: # Inner component like DAYLIGHT or STANDARD c_inner_type = prop_value.value c_inner_properties = {} continue if prop_name == 'END': value = prop_value.value if value == c_type: if uid is None: raise ValueError, 'UID is not present' record = self.get_record(id) or Record( id, record_properties) c_properties['type'] = Property(c_type) c_properties['UID'] = Property(uid) sequence = c_properties.get('SEQUENCE', None) c_properties['SEQUENCE'] = sequence or Property(0) c_properties['ts'] = Property(datetime.now()) # Add ids of inner components if c_inner_components: c_inner_components = [ Property(x) for x in c_inner_components ] c_properties['inner'] = c_inner_components record.append(c_properties) if uid in uids: n = uids[uid] + 1 uids[uid] = n else: n = 0 uids[uid] = 0 self.added_records.append((id, n)) records.append(record) # Next c_type = None uid = None if n == 0: id = id + 1 # Inner component elif value == c_inner_type: record = self.get_record(id) or Record( id, record_properties) c_inner_properties['type'] = Property(c_inner_type) sequence = c_inner_properties.get('SEQUENCE', None) c_inner_properties['SEQUENCE'] = sequence or Property(0) c_inner_properties['ts'] = Property(datetime.now()) record.append(c_inner_properties) c_inner_components.append(id) self.added_records.append((id, 0)) records.append(record) # Next c_inner_type = None id = id + 1 else: raise ValueError, 'Component %s found, %s expected' \ % (value, c_inner_type) else: datatype = self.get_record_datatype(prop_name) if c_inner_type is None: if prop_name in ('UID', 'TZID'): uid = prop_value.value else: if getattr(datatype, 'multiple', False) is True: value = c_properties.setdefault(prop_name, []) value.append(prop_value) else: # Check the property has not yet being found if prop_name in c_properties: raise ValueError, \ "property '%s' can occur only once" % name # Set the property c_properties[prop_name] = prop_value else: # Inner component properties if getattr(datatype, 'multiple', False) is True: value = c_inner_properties.setdefault(prop_name, []) value.append(prop_value) else: # Check the property has not yet being found if prop_name in c_inner_properties: msg = ('the property %s can be assigned only one' ' value' % prop_name) raise ValueError, msg # Set the property c_inner_properties[prop_name] = prop_value # Index the records for record in records: if record is not None: self.catalog.index_document(record)
def _load_state_from_file(self, file): properties = self.properties data = file.read() parser = parse_table(data) # Read the format & version name, value, parameters = parser.next() if name != 'format': raise ValueError, 'unexpected "%s" property' % name if 'version' in parameters: version = parameters.pop('version') if len(version) > 1: raise ValueError, 'version parameter cannot be repeated' self.version = version[0] if parameters: raise ValueError, 'unexpected parameters for the format property' self.format = value # Get the schema resource_class = self.database.get_resource_class(value) # Parse for name, value, parameters in parser: if name == 'format': raise ValueError, 'unexpected "format" property' # 1. Get the field field = resource_class.get_field(name) if field is None: msg = 'unexpected field "%s"' % name if resource_class.fields_soft: log_warning(msg, domain='itools.database') field = DefaultField else: raise ValueError, msg # 2. Deserialize the parameters params_schema = field.parameters_schema params_default = field.parameters_schema_default try: deserialize_parameters(parameters, params_schema, params_default) except ValueError, e: msg = 'in class "{0}" property "{1}": {2}' raise ValueError, msg.format(resource_class, name, e) # 3. Get the datatype properties if field.multiple and field.multilingual: error = 'property "%s" is both multilingual and multiple' raise ValueError, error % name # 4. Build the property datatype = field.datatype value = datatype.decode(value) property = Property(value, **parameters) # Case 1: Multilingual if field.multilingual: language = parameters.get('lang') if language is None: err = 'multilingual property "%s" is missing the language' raise ValueError, err % name properties.setdefault(name, {})[language] = property # Case 2: multiple elif field.multiple: properties.setdefault(name, []).append(property) # Case 3: simple else: properties[name] = property
def _load_state_from_file(self, file): # Read the data and figure out the encoding data = file.read() encoding = guess_encoding(data) self.encoding = encoding # Parse lines = [] for name, value, parameters in parse_table(data): # Deserialize datatype = self.get_record_datatype(name) if isinstance(datatype, Unicode): value = datatype.decode(value, encoding=encoding) else: value = datatype.decode(value) # Build the value (a Property instance) deserialize_parameters(parameters, self.record_parameters) value = Property(value, **parameters) # Append lines.append((name, value)) # Read first line first = lines[0] if (first[0] != 'BEGIN' or first[1].value != 'VCALENDAR' or len(first[1].parameters) != 0): raise ValueError, 'icalendar must begin with BEGIN:VCALENDAR' lines = lines[1:] ################################################################### # Read properties n_line = 0 for name, value in lines: if name == 'BEGIN': break elif name == 'END': break elif name == 'VERSION': if 'VERSION' in self.properties: raise ValueError, 'VERSION can appear only one time' elif name == 'PRODID': if 'PRODID' in self.properties: raise ValueError, 'PRODID can appear only one time' # Add the property self.properties[name] = value n_line += 1 # The properties VERSION and PRODID are mandatory if ('VERSION' not in self.properties or 'PRODID' not in self.properties): raise ValueError, 'PRODID or VERSION parameter missing' lines = lines[n_line:] ################################################################### # Read components c_type = None c_inner_type = None uid = None for prop_name, prop_value in lines[:-1]: if prop_name in ('PRODID', 'VERSION'): raise ValueError, 'PRODID and VERSION must appear before '\ 'any component' if prop_name == 'BEGIN': if c_type is None: c_type = prop_value.value c_properties = {} c_inner_components = [] else: # Inner component like DAYLIGHT or STANDARD c_inner_type = prop_value.value c_inner_properties = {} continue if prop_name == 'END': value = prop_value.value if value == c_type: if uid is None: raise ValueError, 'UID is not present' if uid in self.components: component = self.components[uid] component.add_version(c_properties) else: component = Component(c_type, uid) component.add_version(c_properties) component.c_inner_components = c_inner_components self.components[uid] = component # Next c_type = None uid = None # Inner component elif value == c_inner_type: inner_component = InnerComponent(c_inner_type) inner_component.add_version(c_inner_properties) c_inner_components.append(inner_component) c_inner_type = None else: raise ValueError, 'Component %s found, %s expected' \ % (value, c_inner_type) else: datatype = self.get_record_datatype(prop_name) if c_inner_type is None: if prop_name in ('UID', 'TZID'): uid = prop_value.value else: if getattr(datatype, 'multiple', False) is True: value = c_properties.setdefault(prop_name, []) value.append(prop_value) else: # Check the property has not yet being found if prop_name in c_properties: msg = ('the property %s can be assigned only ' 'one value' % prop_name) raise ValueError, msg # Set the property c_properties[prop_name] = prop_value else: # Inner component properties if getattr(datatype, 'multiple', False) is True: value = c_inner_properties.setdefault(prop_name, []) value.append(prop_value) else: # Check the property has not yet being found if prop_name in c_inner_properties: msg = ('the property %s can be assigned only one' ' value' % prop_name) raise ValueError, msg value = prop_value # Set the property c_inner_properties[prop_name] = value ################################################################### # Index components for uid in self.components: component = self.components[uid] self.catalog.index_document(component)
def load_state_from_ical_file(self, file): """Load state from the given ical file. """ self.reset() self.set_changed() components = {} # Read the data data = file.read() # Parse lines = [] for name, value, parameters in parse_table(data): # Timestamp (ts), Schema, or Something else datatype = self.get_record_datatype(name) value = datatype.decode(value) property = Property(value, **parameters) # Append lines.append((name, property)) # Read first line first = lines[0] if (first[0] != 'BEGIN' or first[1].value != 'VCALENDAR' or len(first[1].parameters) != 0): raise ValueError, 'icalendar must begin with BEGIN:VCALENDAR' lines = lines[1:] ################################################################### # Skip properties # TODO Currently tables are not able to handler global properties, # we must implement this feature to be able to load from ical files. n_line = 0 for name, value in lines: if name == 'BEGIN': break elif name == 'END': break n_line += 1 lines = lines[n_line:] ################################################################### # Read components c_type = None c_inner_type = None uid = None records = self.records record_properties = self.record_properties id = 0 uids = {} for prop_name, prop_value in lines[:-1]: if prop_name in ('PRODID', 'VERSION'): raise ValueError, 'PRODID and VERSION must appear before '\ 'any component' if prop_name == 'BEGIN': if c_type is None: c_type = prop_value.value c_properties = {} c_inner_components = [] else: # Inner component like DAYLIGHT or STANDARD c_inner_type = prop_value.value c_inner_properties = {} continue if prop_name == 'END': value = prop_value.value if value == c_type: if uid is None: raise ValueError, 'UID is not present' record = self.get_record(id) or Record(id, record_properties) c_properties['type'] = Property(c_type) c_properties['UID'] = Property(uid) sequence = c_properties.get('SEQUENCE', None) c_properties['SEQUENCE'] = sequence or Property(0) c_properties['ts'] = Property(datetime.now()) # Add ids of inner components if c_inner_components: c_inner_components = [Property(x) for x in c_inner_components] c_properties['inner'] = c_inner_components record.append(c_properties) if uid in uids: n = uids[uid] + 1 uids[uid] = n else: n = 0 uids[uid] = 0 self.added_records.append((id, n)) records.append(record) # Next c_type = None uid = None if n == 0: id = id + 1 # Inner component elif value == c_inner_type: record = self.get_record(id) or Record(id, record_properties) c_inner_properties['type'] = Property(c_inner_type) sequence = c_inner_properties.get('SEQUENCE', None) c_inner_properties['SEQUENCE'] = sequence or Property(0) c_inner_properties['ts'] = Property(datetime.now()) record.append(c_inner_properties) c_inner_components.append(id) self.added_records.append((id, 0)) records.append(record) # Next c_inner_type = None id = id + 1 else: raise ValueError, 'Component %s found, %s expected' \ % (value, c_inner_type) else: datatype = self.get_record_datatype(prop_name) if c_inner_type is None: if prop_name in ('UID', 'TZID'): uid = prop_value.value else: if getattr(datatype, 'multiple', False) is True: value = c_properties.setdefault(prop_name, []) value.append(prop_value) else: # Check the property has not yet being found if prop_name in c_properties: raise ValueError, \ "property '%s' can occur only once" % name # Set the property c_properties[prop_name] = prop_value else: # Inner component properties if getattr(datatype, 'multiple', False) is True: value = c_inner_properties.setdefault(prop_name, []) value.append(prop_value) else: # Check the property has not yet being found if prop_name in c_inner_properties: msg = ('the property %s can be assigned only one' ' value' % prop_name) raise ValueError, msg # Set the property c_inner_properties[prop_name] = prop_value # Index the records for record in records: if record is not None: self.catalog.index_document(record)