コード例 #1
0
ファイル: models.py プロジェクト: open511/open511-server
    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)
コード例 #2
0
def get_roadevent_from_summary(summary):

    elem = E.event(E.id("%s/%s" % (JURISDICTION_ID, summary['id'])))

    elem.append(
        E.geography(
            geom_to_xml_element(
                Point(float(summary['lng']), float(summary['lat']), srid=4326)
            )
        )
    )

    url = BASE_DETAIL_URL + summary['id']
    resp = urlopen(url)
    time.sleep(0.5)

    def set_val(tag, val):
        if val not in (None, ''):
            e = etree.Element(tag)
            e.text = str(val)
            elem.append(e)

    set_val('status', 'ACTIVE')
    set_val('event_type', 'CONSTRUCTION')
    set_val('severity', 'MAJOR' if summary['id'].startswith('maj') else 'MODERATE')

    root = lxml.html.fragment_fromstring(resp.read().decode('utf8'))
    set_val('headline', _get_text_from_elems(root.cssselect('#tdIdentification')))

    description = _get_text_from_elems(root.cssselect('#tdDescriptionEntrave,#tdDetail'))
    affected_roads = _get_text_from_elems(root.cssselect('#tdLocalisation'))
    traffic_restrictions = _get_text_from_elems(root.cssselect('#tdRestrictionCamionnage'))

    if affected_roads:
        description += u'\n\nLocalisation: ' + affected_roads
    if traffic_restrictions:
        description += u'\n\nRestrictions: ' + traffic_restrictions
    set_val('description', description)

    start_date = _get_text_from_elems(root.cssselect('#tdDebut'))
    end_date = _get_text_from_elems(root.cssselect('#tdFin'))
    if start_date:
        sked = E.recurring_schedule()
        sked.append(E.start_date(str(_str_to_date(start_date))))
        if end_date:
            sked.append(E.end_date(str(_str_to_date(end_date))))
        elem.append(E.schedule(E.recurring_schedules(sked)))

    return elem
コード例 #3
0
def main():

    logging.basicConfig()

    base = get_base_open511_element(lang='fr')
    cameras = E.cameras()
    base.append(cameras)

    english_names = get_english_names()

    for camera_info in get_list_of_cameras():
        camera = E.camera(
            E.id(JURISDICTION_ID + '/' + unicode(camera_info['id'])),
            E.name(camera_info['info'])
        )
        if english_names[camera_info['id']]:
            ename = E.name(english_names[camera_info['id']])
            ename.set(XML_LANG, 'en')
            camera.append(ename)

        camera.append(
            E.geography(
                geom_to_xml_element(
                    Point(float(camera_info['lng']), float(camera_info['lat']), srid=4326)
                )
            )
        )

        try:
            camera.append(
                E.media_files(
                    E.link(rel="related", href=get_image_url(camera_info['id']), type="image/jpeg")
                )
            )
        except Exception as e:
            logger.exception("Couldn't fetch image for camera #%s" % camera_info['id'])
            continue
        cameras.append(camera)

    print etree.tostring(base, pretty_print=True)
コード例 #4
0
ファイル: models.py プロジェクト: open511/open511-server
 def to_full_xml_element(self):
     return E.geography(geom_to_xml_element(self.geom))
コード例 #5
0
def feature_to_open511_element(feature):
    """Transform an OGR Feature from the KML input into an XML Element for a RoadEvent."""

    # Using a hash of the geometry for an ID. For proper production use,
    # there'll probably have to be some code in the importer
    # that compares to existing entries in the DB to determine whether
    # this is new or modified...
    id = hashlib.md5(feature.geom.wkt.encode('ascii')).hexdigest()
    while id in ids_seen:
        id += 'x'
    ids_seen.add(id)

    elem = E.event()

    def set_val(tag, val):
        if val not in (None, ''):
            e = etree.Element(tag)
            e.text = str(val)
            elem.append(e)

    def maybe_decode(s):
        if isinstance(s, str):
            return s
        return s.decode('utf8')

    set_val('id', "%s/%s" % (JURISDICTION_ID, id))
    set_val('status', 'ACTIVE')
    set_val('event_type', 'CONSTRUCTION')
    set_val('severity', 'UNKNOWN')

    set_val('headline', maybe_decode(feature.get('Name')))

    blob = lxml.html.fragment_fromstring(maybe_decode(feature.get('Description')),
        create_parent='content')

    description_label = blob.xpath('//strong[text()="Description"]')
    localisation = blob.cssselect('div#localisation p')
    if description_label or localisation:
        description_bits = []
        if description_label:
            el = description_label[0].getnext()
            while el.tag == 'p':
                description_bits.append(_get_el_text(el))
                el = el.getnext()

        if localisation:
            description_bits.append('Localisation: ' + '; '.join(
                _get_el_text(el) for el in localisation))

        set_val('description', '\n\n'.join(description_bits))

    try:
        link = blob.cssselect('#avis_residants a, #en_savoir_plus a')[0]
        e = etree.Element('link')
        e.set('rel', 'related')
        e.set('href', link.get('href'))
        if link.get('title'):
            e.set('title', link.get('title'))
        elem.append(E.attachments(e))
    except IndexError:
        pass

    facultatif = blob.cssselect('div#itineraire_facult p')
    if facultatif:
        set_val('detour', '\n\n'.join(_get_el_text(el) for el in facultatif))

    if blob.cssselect('div#dates strong'):
        try:
            start_date = blob.xpath(u'div[@id="dates"]/strong[text()="Date de d\xe9but"]')[0].tail
            end_date = blob.xpath(u'div[@id="dates"]/strong[text()="Date de fin"]')[0].tail
            start_date = _fr_string_to_date(start_date)
            end_date = _fr_string_to_date(end_date)
            if start_date:
                sked = E.recurring_schedule(E.start_date(str(start_date)))
                if end_date:
                    sked.append(E.end_date(str(end_date)))
                elem.append(E.schedule(E.recurring_schedules(sked)))
        except IndexError:
            pass

    elem.append(E.geography(
        geom_to_xml_element(feature.geom)
    ))

    return elem