Exemplo n.º 1
0
def save_osm_data(instance_id):
    """
    Includes the OSM data in the specified submission json data.
    """
    instance = Instance.objects.filter(pk=instance_id).first()
    osm_attachments = instance.attachments.filter(extension=Attachment.OSM) \
        if instance else None

    if instance and osm_attachments:
        fields = [
            f.get_abbreviated_xpath()
            for f in instance.xform.get_survey_elements_of_type('osm')
        ]
        osm_filenames = {
            field: instance.json[field]
            for field in fields if field in instance.json
        }

        for osm in osm_attachments:
            osm_xml = osm.media_file.read()
            filename = None
            field_name = None
            for k, v in osm_filenames.items():
                if osm.filename.startswith(v.replace('.osm', '')):
                    filename = v
                    field_name = k
                    break

            if field_name is None:
                continue
            filename = osm.filename if filename is None else filename
            osm_list = parse_osm(osm_xml, include_osm_id=True)
            for osmd in osm_list:
                try:
                    osm_data = OsmData(
                        instance=instance,
                        xml=osm_xml,
                        osm_id=osmd['osm_id'],
                        osm_type=osmd['osm_type'],
                        tags=osmd['tags'],
                        geom=GeometryCollection(osmd['geom']),
                        filename=filename,
                        field_name=field_name)
                    osm_data.save()
                except IntegrityError:
                    osm_data = OsmData.objects.get(
                        instance=instance, field_name=field_name)
                    osm_data.xml = osm_xml
                    osm_data.osm_id = osmd['osm_id']
                    osm_data.osm_type = osmd['osm_type']
                    osm_data.tags = osmd['tags']
                    osm_data.geom = GeometryCollection(osmd['geom'])
                    osm_data.filename = filename
                    osm_data.save()
        instance.save()
        trigger_webhook.send(sender=instance.__class__, instance=instance)
Exemplo n.º 2
0
def _post_process_submissions(instance):
    trigger_webhook.send(sender=instance.__class__, instance=instance)
    if instance.xform.instances_with_osm:
        post_save_osm_data(instance.pk)
Exemplo n.º 3
0
def _post_process_submissions(instance):
    trigger_webhook.send(sender=instance.__class__, instance=instance)
    if instance.xform.instances_with_osm:
        post_save_osm_data(instance.pk)
Exemplo n.º 4
0
Arquivo: osm.py Projeto: onaio/onadata
def save_osm_data(instance_id):
    """
    Includes the OSM data in the specified submission json data.
    """
    instance = Instance.objects.filter(pk=instance_id).first()
    osm_attachments = instance.attachments.filter(extension=Attachment.OSM) \
        if instance else None

    if instance and osm_attachments:
        fields = [
            f.get_abbreviated_xpath()
            for f in instance.xform.get_survey_elements_of_type('osm')
        ]
        osm_filenames = {
            field: instance.json[field]
            for field in fields if field in instance.json
        }

        for osm in osm_attachments:
            try:
                osm_xml = osm.media_file.read()
                if isinstance(osm_xml, bytes):
                    osm_xml = osm_xml.decode('utf-8')
            except IOError as e:
                logging.exception("IOError saving osm data: %s" % str(e))
                continue
            else:
                filename = None
                field_name = None
                for k, v in osm_filenames.items():
                    if osm.filename.startswith(v.replace('.osm', '')):
                        filename = v
                        field_name = k
                        break

                if field_name is None:
                    continue
                filename = osm.filename if filename is None else filename
                osm_list = parse_osm(osm_xml, include_osm_id=True)
                for osmd in osm_list:
                    try:
                        with transaction.atomic():
                            osm_data = OsmData(
                                instance=instance,
                                xml=osm_xml,
                                osm_id=osmd['osm_id'],
                                osm_type=osmd['osm_type'],
                                tags=osmd['tags'],
                                geom=GeometryCollection(osmd['geom']),
                                filename=filename,
                                field_name=field_name)
                            osm_data.save()
                    except IntegrityError:
                        with transaction.atomic():
                            osm_data = OsmData.objects.exclude(
                                xml=osm_xml).filter(
                                instance=instance,
                                field_name=field_name).first()
                            if osm_data:
                                osm_data.xml = osm_xml
                                osm_data.osm_id = osmd['osm_id']
                                osm_data.osm_type = osmd['osm_type']
                                osm_data.tags = osmd['tags']
                                osm_data.geom = GeometryCollection(
                                                    osmd['geom'])
                                osm_data.filename = filename
                                osm_data.save()
        instance.save()
        trigger_webhook.send(sender=instance.__class__, instance=instance)