def update_or_create_from_xml(self, el, default_language=settings.LANGUAGE_CODE, base_url='', save=True): """ Returns a tuple of (CREATED/UPDATED/UNMODIFIED, model_obj)""" el_hash = hashlib.md5(etree.tostring(el)).hexdigest() el = deepcopy(el) jurisdiction_id, obj_id = el.findtext('id').split('/') if not (jurisdiction_id and obj_id): raise ValidationError(u"%s is not a valid Open511 ID" % el.findtext('id')) el.remove(el.xpath('id')[0]) external_jurisdiction = el.xpath('link[@rel="jurisdiction"]') if external_jurisdiction: el.remove(external_jurisdiction[0]) try: jurisdiction = Jurisdiction.objects.get(id=jurisdiction_id) except Jurisdiction.DoesNotExist: if not external_jurisdiction: raise Exception("No jurisdiction URL provided for %s" % jurisdiction_id) jurisdiction = Jurisdiction.objects.get_or_create_from_url( urljoin(base_url, external_jurisdiction[0].get('href'))) try: obj = self.get(id=obj_id, jurisdiction=jurisdiction) if obj.last_import_hash == el_hash: return ('UNMODIFIED', obj) created = False except ObjectDoesNotExist: created = True obj = self.model(id=obj_id, jurisdiction=jurisdiction, last_import_hash=el_hash) self_link = el.xpath('link[@rel="self"]') if self_link: obj.external_url = urljoin(base_url, self_link[0].get('href')) el.remove(self_link[0]) # Extract the geometry geometry = el.xpath('geography')[0] gml = etree.tostring(geometry[0], encoding='unicode') ewkt = gml_to_ewkt(gml, force_2D=True) obj.geom = geos_geom_from_string(ewkt) # And regenerate the GML so it's consistent with the PostGIS representation el.remove(geometry) el.append(E.geography(geom_to_xml_element(obj.geom))) # Push down the default language if necessary if not el.get(XML_LANG): el.set(XML_LANG, default_language) obj.xml_elem = el if save: obj.save() return ('CREATED' if created else 'UPDATED', obj)
def handle(self, filename=sys.stdin, **options): root = etree.parse(filename).getroot() assert root.tag == 'Open511' created = [] for event in root.xpath('RoadEvent'): try: jurisdiction, dummy, id = event.get('id').partition(':') try: rdev = RoadEvent.objects.get(id=id, jurisdiction=jurisdiction) except RoadEvent.DoesNotExist: rdev = RoadEvent(id=id, jurisdiction=jurisdiction) logger.info("Importing event %s" % rdev.id) # Extract the geometry geometry = event.xpath('Geometry')[0] gml = etree.tostring(geometry[0]) ewkt = gml_to_ewkt(gml, force_2D=True) rdev.geom = geos_geom_from_string(ewkt) event.remove(geometry) # Remove the ID from the stored XML (we keep it in the table) del event.attrib['id'] # Push down the default language if necessary if not event.get(XML_LANG): event.set(XML_LANG, root.get(XML_LANG)) rdev.xml_elem = event rdev.save() created.append(rdev) except ValueError as e: logger.error("ValueError importing %s: %s" % (e, rdev.compound_id)) print "%s entries imported." % len(created)
def update(self, key, val): if key in ('updated', 'created'): raise NotImplementedError elif key == 'status': self.active = (val.upper() == 'ACTIVE') return elif key == '!unpublished': self.published = (not val) or unicode(val).lower() == 'false' return elif key.startswith('_'): # ignore internal fields return update_el = self._get_or_create_el(key) if val is None: update_el.getparent().remove(update_el) elif isinstance(val, (str, unicode)): update_el.text = val elif key == 'geography': if 'opengis' in getattr(val, 'tag', ''): gml = val else: gml = geojson_to_gml(val) wkt = gml_to_ewkt(etree.tostring(gml, encoding='unicode')) self.geom = geos_geom_from_string(wkt) update_el.clear() update_el.append(gml) elif isinstance(val, (dict, list)): if not val: update_el.getparent().remove(update_el) update_el.clear() json_struct_to_xml(val, update_el) else: raise NotImplementedError
def fromstring(cls, input): if is_hex(input): # Looks like an ID return cls.get(input) geom = geos_geom_from_string(input) return cls(geom, id=None)