Beispiel #1
0
    def filter_queryset(self, queryset):
        """ Filters the queryset

        Args:
            queryset (Queryset): Unfiltered queryset
        Returns:
             queryset (Queryset): Filtered queryset
        """
        # filter by dimensions
        time_min = self.request.query_params.get("time-min", None) or None
        time_max = self.request.query_params.get("time-max", None) or None
        elevation_unit = self.request.query_params.get("elevation-unit",
                                                       None) or None
        elevation_min = self.request.query_params.get("elevation-min",
                                                      None) or None
        elevation_max = self.request.query_params.get("elevation-max",
                                                      None) or None
        queryset = view_helper.filter_queryset_metadata_dimension_time(
            queryset, time_min, time_max)
        queryset = view_helper.filter_queryset_metadata_dimension_elevation(
            queryset, elevation_min, elevation_max, elevation_unit)

        # filter by bbox extent. fully-inside and partially-inside are mutually exclusive
        bbox = self.request.query_params.get("bbox", None) or None
        bbox_srs = self.request.query_params.get("bbox-srs",
                                                 DEFAULT_SRS_STRING)
        bbox_strict = utils.resolve_boolean_attribute_val(
            self.request.query_params.get("bbox-strict", False) or False)
        queryset = view_helper.filter_queryset_metadata_bbox(
            queryset, bbox, bbox_srs, bbox_strict)

        # filter by service type
        type = self.request.query_params.get("type", None)
        queryset = view_helper.filter_queryset_metadata_type(queryset, type)

        # filter by category
        category = self.request.query_params.get("cat", None)
        category_strict = utils.resolve_boolean_attribute_val(
            self.request.query_params.get("cat-strict", False) or False)
        queryset = view_helper.filter_queryset_metadata_category(
            queryset, category, category_strict)

        # filter by query
        query = self.request.query_params.get("q", None)
        q_test = self.request.query_params.get("q-test", False)
        queryset = view_helper.filter_queryset_metadata_query(
            queryset, query, q_test)

        # order by
        order_by = self.request.query_params.get("order",
                                                 CATALOGUE_DEFAULT_ORDER)
        if order_by not in self.orderable_fields:
            order_by = CATALOGUE_DEFAULT_ORDER
        queryset = view_helper.order_queryset(queryset, order_by)

        return queryset
Beispiel #2
0
    def active_state(self, request, pk=None):
        """ Activates a service via remote access

        Args:
            request: The incoming request
            pk: The service id
        Returns:
             Response
        """
        user = user_helper.get_user(request)
        parameter_name = "active"
        new_status = request.POST.dict().get(parameter_name, None)
        new_status = utils.resolve_boolean_attribute_val(new_status)

        response = APIResponse()
        if new_status is None or not isinstance(new_status, bool):
            response.data["msg"] = PARAMETER_ERROR.format(parameter_name)
            return Response(data=response.data, status=500)

        try:
            md = Metadata.objects.get(service__id=pk)

            response.data["oldStatus"] = md.is_active

            md.is_active = new_status
            md.save()
            response.data["newStatus"] = md.is_active
            response.data["success"] = True
            return Response(data=response.data, status=200)
        except ObjectDoesNotExist:
            response.data["msg"] = SERVICE_NOT_FOUND
            return Response(data=response.data, status=404)
Beispiel #3
0
 def parse_cascaded(self, layer, layer_obj):
     try:
         is_opaque = layer.get("cascaded")
         if is_opaque is None:
             is_opaque = False
         else:
             is_opaque = utils.resolve_boolean_attribute_val(is_opaque)
         layer_obj.is_cascaded = is_opaque
     except AttributeError:
         pass
Beispiel #4
0
 def parse_queryable(self, layer, layer_obj):
         try:
             is_queryable = layer.get("queryable")
             if is_queryable is None:
                 is_queryable = False
             else:
                 is_queryable = utils.resolve_boolean_attribute_val(is_queryable)
             layer_obj.is_queryable = is_queryable
         except AttributeError:
             pass
Beispiel #5
0
    def get_queryset(self):
        """ Specifies if the queryset shall be filtered or not

        Returns:
             The queryset
        """
        self.queryset = Organization.objects.all()

        # filter by real or auto generated organizations
        auto_generated = self.request.query_params.get("ag", None)
        auto_generated = utils.resolve_boolean_attribute_val(auto_generated)
        self.queryset = view_helper.filter_queryset_real_organization(
            self.queryset, auto_generated)

        # order by
        order_by = self.request.query_params.get("order",
                                                 ORGANIZATION_DEFAULT_ORDER)
        if order_by not in self.orderable_fields:
            order_by = ORGANIZATION_DEFAULT_ORDER
        self.queryset = view_helper.order_queryset(self.queryset, order_by)

        return self.queryset
    def parse_xml(self):
        """ Reads the needed data from the xml and writes to an ISOMetadata instance (self)

        Returns:
             nothing
        """
        xml = self.raw_metadata
        xml_obj = xml_helper.parse_xml(xml)
        self.file_identifier = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            "//gmd:MD_Metadata/gmd:fileIdentifier/gco:CharacterString")
        self.character_set_code = xml_helper.try_get_attribute_from_xml_element(
            xml_elem=xml_obj,
            attribute="codeListValue",
            elem="//gmd:MD_Metadata/gmd:characterSet/gmd:MD_CharacterSetCode")
        if self.file_identifier is None:
            self.file_identifier = uuid.uuid4()
        self.date_stamp = xml_helper.try_get_text_from_xml_element(
            xml_obj, "//gmd:MD_Metadata/gmd:dateStamp/gco:Date")
        self.last_change_date = xml_helper.try_get_text_from_xml_element(
            xml_obj, "//gmd:MD_Metadata/gmd:dateStamp/gco:Date")

        self.md_standard_name = xml_helper.try_get_text_from_xml_element(
            xml_obj, "//gmd:metadataStandardName/gco:CharacterString")
        self.md_standard_version = xml_helper.try_get_text_from_xml_element(
            xml_obj, "//gmd:metadataStandardVersion/gco:CharacterString")

        self._parse_xml_legal_dates(xml_obj)
        self._parse_xml_legal_reports(xml_obj)

        # try to transform the last_change_date into a datetime object
        try:
            self.last_change_date = parse(self.last_change_date,
                                          tzinfo=timezone.utc)
        except (ValueError, OverflowError, TypeError):
            # if this is not possible due to wrong input, just use the current time...
            self.last_change_date = timezone.now()

        self.hierarchy_level = xml_helper.try_get_attribute_from_xml_element(
            xml_obj, "codeListValue",
            "//gmd:MD_Metadata/gmd:hierarchyLevel/gmd:MD_ScopeCode")
        if self.hierarchy_level == "service":
            xpath_type = "srv:SV_ServiceIdentification"
        else:
            xpath_type = "gmd:MD_DataIdentification"
        self.title = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            "//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:citation/gmd:CI_Citation/gmd:title/gco:CharacterString"
            .format(xpath_type))
        self._parse_xml_dataset_id(xml_obj, xpath_type)
        self.abstract = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            "//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:abstract/gco:CharacterString"
            .format(xpath_type))
        keywords = xml_helper.try_get_element_from_xml(
            xml_elem=xml_obj,
            elem=
            "//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:descriptiveKeywords/gmd:MD_Keywords/gmd:keyword/gco:CharacterString"
            .format(xpath_type))
        for keyword in keywords:
            if keyword.text is not None and keyword not in self.keywords:
                self.keywords.append(
                    xml_helper.try_get_text_from_xml_element(keyword))

        language = xml_helper.try_get_single_element_from_xml(
            xml_elem=xml_obj,
            elem=
            "//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:language/gmd:LanguageCode"
            .format(xpath_type))
        if language and language.text is not None:
            self.language = xml_helper.try_get_text_from_xml_element(language)

        iso_categories = xml_helper.try_get_element_from_xml(
            xml_elem=xml_obj,
            elem=
            "//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:topicCategory/gmd:MD_TopicCategoryCode"
            .format(xpath_type))
        if iso_categories:
            for iso_category in iso_categories:
                self.iso_categories.append(
                    xml_helper.try_get_text_from_xml_element(iso_category))

        # Get all values from <gmd:distributionInfo> which declares the distributionFormat
        formats = xml_helper.try_get_element_from_xml(
            xml_elem=xml_obj,
            elem="//" +
            GENERIC_NAMESPACE_TEMPLATE.format("distributionFormat"))
        if formats:
            for format_elem in formats:
                # get the character value per format
                name_elem = xml_helper.try_get_single_element_from_xml(
                    xml_elem=format_elem,
                    elem=".//" + GENERIC_NAMESPACE_TEMPLATE.format("name"))
                if name_elem is None:
                    continue
                val = xml_helper.try_get_text_from_xml_element(
                    xml_elem=name_elem,
                    elem=".//" +
                    GENERIC_NAMESPACE_TEMPLATE.format("CharacterString"))
                self.formats.append(val)

        self.download_link = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            '//gmd:MD_Metadata/gmd:distributionInfo/gmd:MD_Distribution/gmd:transferOptions/gmd:MD_DigitalTransferOptions/gmd:onLine/gmd:CI_OnlineResource[gmd:function/gmd:CI_OnLineFunctionCode/@codeListValue="download"]/gmd:linkage/gmd:URL'
        )
        self.transfer_size = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            '//gmd:MD_Metadata/gmd:distributionInfo/gmd:MD_Distribution/gmd:transferOptions/gmd:MD_DigitalTransferOptions/gmd:transferSize/gco:Real'
        )
        self.preview_image = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            "//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:graphicOverview/gmd:MD_BrowseGraphic/gmd:fileName/gco:CharacterString"
            .format(xpath_type))
        try:
            self.bounding_box["min_x"] = float(
                xml_helper.try_get_text_from_xml_element(
                    xml_obj,
                    "//gmd:westBoundLongitude/gco:Decimal".format(xpath_type)))
            self.bounding_box["min_y"] = float(
                xml_helper.try_get_text_from_xml_element(
                    xml_obj,
                    "//gmd:southBoundLatitude/gco:Decimal".format(xpath_type)))
            self.bounding_box["max_x"] = float(
                xml_helper.try_get_text_from_xml_element(
                    xml_obj,
                    "//gmd:eastBoundLongitude/gco:Decimal".format(xpath_type)))
            self.bounding_box["max_y"] = float(
                xml_helper.try_get_text_from_xml_element(
                    xml_obj,
                    "//gmd:northBoundLatitude/gco:Decimal".format(xpath_type)))
        except TypeError:
            self.bounding_box = None

        self._parse_xml_polygons(xml_obj, xpath_type)

        self.tmp_extent_begin = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            "//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:extent/gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml:TimePeriod/gml:beginPosition"
            .format(xpath_type))
        if self.tmp_extent_begin is None:
            self.tmp_extent_begin = "1900-01-01"

        self.tmp_extent_end = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            "//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:extent/gmd:EX_Extent/gmd:temporalElement/gmd:EX_TemporalExtent/gmd:extent/gml:TimePeriod/gml:endPosition"
            .format(xpath_type))
        if self.tmp_extent_end is None:
            self.tmp_extent_end = "1900-01-01"

        equivalent_scale = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            "//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:spatialResolution/gmd:MD_Resolution/gmd:equivalentScale/gmd:MD_RepresentativeFraction/gmd:denominator/gco:Integer"
            .format(xpath_type))
        ground_res = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            "//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:spatialResolution/gmd:MD_Resolution/gmd:distance/gco:Distance"
            .format(xpath_type))
        if equivalent_scale is not None and int(equivalent_scale) > 0:
            self.spatial_res_val = equivalent_scale
            self.spatial_res_type = "scaleDenominator"
        elif ground_res is not None and len(ground_res) > 0:
            self.spatial_res_val = ground_res
            self.spatial_res_type = "groundDistance"

        self.ref_system = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            "//gmd:MD_Metadata/gmd:referenceSystemInfo/gmd:MD_ReferenceSystem/gmd:referenceSystemIdentifier/gmd:RS_Identifier/gmd:code/gco:CharacterString"
        )
        self.ref_system_version = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            "//gmd:MD_Metadata/gmd:referenceSystemInfo/gmd:MD_ReferenceSystem/gmd:referenceSystemIdentifier/gmd:RS_Identifier/gmd:version/gco:CharacterString"
        )
        self.ref_system_authority = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            "//gmd:MD_Metadata/gmd:referenceSystemInfo/gmd:MD_ReferenceSystem/gmd:referenceSystemIdentifier/gmd:RS_Identifier/gmd:authority/gmd:CI_Citation/gmd:title/gco:CharacterString"
        )
        epsg_api = EpsgApi()
        if self.ref_system is not None:
            self.ref_system = "EPSG:{}".format(
                epsg_api.get_subelements(self.ref_system).get("code"))

        # gmd:CI_OnLineFunctionCode
        dist_func_elem = xml_helper.try_get_single_element_from_xml(
            "//" + GENERIC_NAMESPACE_TEMPLATE.format("CI_OnLineFunctionCode"),
            xml_obj)
        self.distribution_function = xml_helper.try_get_attribute_from_xml_element(
            dist_func_elem,
            "codeListValue",
        )
        del dist_func_elem

        # gmd:MD_RepresentativeFraction
        fraction_elem = xml_helper.try_get_single_element_from_xml(
            "//" +
            GENERIC_NAMESPACE_TEMPLATE.format("MD_RepresentativeFraction"),
            xml_obj)
        self.fraction_denominator = xml_helper.try_get_text_from_xml_element(
            fraction_elem,
            ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Integer"))
        del fraction_elem

        # gmd:useLimitation
        limit_elem = xml_helper.try_get_single_element_from_xml(
            "//" + GENERIC_NAMESPACE_TEMPLATE.format("useLimitation"), xml_obj)
        self.use_limitation = xml_helper.try_get_text_from_xml_element(
            limit_elem,
            ".//" + GENERIC_NAMESPACE_TEMPLATE.format("CharacterString"))
        del limit_elem

        self.lineage = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            "//gmd:MD_Metadata/gmd:dataQualityInfo/gmd:DQ_DataQuality/gmd:lineage/gmd:LI_Lineage/gmd:statement/gco:CharacterString"
        )

        restriction_code_attr_val = xml_helper.try_get_element_from_xml(
            xml_elem=xml_obj,
            elem=
            '//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:resourceConstraints/gmd:MD_LegalConstraints/gmd:useConstraints/gmd:MD_RestrictionCode/@codeListValue'
            .format(xpath_type))
        if len(restriction_code_attr_val) >= 2:
            legal_constraints = ""
            if restriction_code_attr_val[
                    0] == 'license' and restriction_code_attr_val[
                        1] == 'otherRestrictions':
                other_constraints = xml_helper.try_get_element_from_xml(
                    xml_elem=xml_obj,
                    elem=
                    '//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:resourceConstraints/gmd:MD_LegalConstraints[gmd:useConstraints/gmd:MD_RestrictionCode/@codeListValue="otherRestrictions"]/gmd:otherConstraints/gco:CharacterString'
                    .format(xpath_type))
                for constraint in other_constraints:
                    try:
                        tmp_constraint = xml_helper.try_get_text_from_xml_element(
                            xml_elem=constraint)
                        constraint_json = json.loads(tmp_constraint)
                        self.license_source_note = constraint_json.get(
                            "quelle", None)
                        self.license_json = constraint_json
                    except ValueError:
                        # no, this is not a json!
                        # handle it is a normal text
                        legal_constraints += tmp_constraint + ";"
            self.fees = legal_constraints

        self.access_constraints = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            '//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:resourceConstraints/gmd:MD_LegalConstraints[gmd:accessConstraints/gmd:MD_RestrictionCode/@codeListValue="otherRestrictions"]/gmd:otherConstraints/gco:CharacterString'
            .format(xpath_type))
        self.responsible_party = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            '//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:organisationName/gco:CharacterString'
            .format(xpath_type))
        self.contact_person = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            '//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:individualName/gco:CharacterString'
            .format(xpath_type))
        self.contact_phone = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            '//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:contactInfo/gmd:CI_Contact/gmd:phone/gmd:CI_Telephone/gmd:voice/gco:CharacterString'
            .format(xpath_type))
        self.contact_email = xml_helper.try_get_text_from_xml_element(
            xml_obj,
            '//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:pointOfContact/gmd:CI_ResponsibleParty/gmd:contactInfo/gmd:CI_Contact/gmd:address/gmd:CI_Address/gmd:electronicMailAddress/gco:CharacterString'
            .format(xpath_type))
        update_frequency = xml_helper.try_get_attribute_from_xml_element(
            xml_elem=xml_obj,
            attribute="codeListValue",
            elem=
            '//gmd:MD_Metadata/gmd:identificationInfo/{}/gmd:resourceMaintenance/gmd:MD_MaintenanceInformation/gmd:maintenanceAndUpdateFrequency/gmd:MD_MaintenanceFrequencyCode'
            .format(xpath_type))
        if update_frequency in self.valid_update_frequencies:
            self.update_frequency = update_frequency

        # inspire regulations
        regislations = {"inspire_rules": []}
        with open(INSPIRE_LEGISLATION_FILE, "r", encoding="utf-8") as _file:
            regislations = json.load(_file)
        for regislation in regislations["inspire_rules"]:
            reg = {
                "name": regislation.get("name", None),
                "date": regislation.get("date", "1900-01-01"),
                "pass": None,
            }
            statement = xml_helper.try_get_text_from_xml_element(
                xml_obj,
                '//gmd:MD_Metadata/gmd:dataQualityInfo/gmd:DQ_DataQuality/gmd:report/gmd:DQ_DomainConsistency/gmd:result/gmd:DQ_ConformanceResult[gmd:specification/gmd:CI_Citation/gmd:title/gco:CharacterString="{}" and gmd:specification/gmd:CI_Citation/gmd:date/gmd:CI_Date/gmd:date/gco:Date="{}"]/gmd:pass/gco:Boolean'
                .format(reg["name"], reg["date"]))
            statement_val = utils.resolve_boolean_attribute_val(statement)
            if statement_val is None:
                reg["pass"] = "******"
                self.inspire_interoperability = False
            else:
                reg["pass"] = statement_val
                # if only one regislation is not fullfilled, we do not have interoperability
                if not statement_val:
                    self.inspire_interoperability = False
            self.interoperability_list.append(reg)
Beispiel #7
0
def get_resource_capabilities(request: HttpRequest, md: Metadata):
    """ Logic for retrieving a capabilities document.

    If no capabilities document can be provided by the given parameter, a fallback document will be returned.

    Args:
        request:
        md:
    Returns:

    """
    from service.tasks import async_increase_hits
    stored_version = md.get_service_version().value
    # move increasing hits to background process to speed up response time!
    # todo: after refactoring of md.increase_hits() maybe we don't need to start async tasks... test it!!!
    async_increase_hits.delay(md.id)

    if not md.is_active:
        return HttpResponse(content=SERVICE_DISABLED, status=423)

    # check that we have the requested version in our database
    version_param = None
    version_tag = None

    request_param = None
    request_tag = None

    use_fallback = None

    for k, v in request.GET.dict().items():
        if k.upper() == "VERSION":
            version_param = v
            version_tag = k
        elif k.upper() == "REQUEST":
            request_param = v
            request_tag = k
        elif k.upper() == "FALLBACK":
            use_fallback = resolve_boolean_attribute_val(v)

    # No version parameter has been provided by the request - we simply use the one we have.
    if version_param is None or len(version_param) == 0:
        version_param = stored_version

    if version_param not in [data.value for data in OGCServiceVersionEnum]:
        # version number not valid
        return HttpResponse(content=PARAMETER_ERROR.format(version_tag), status=404)

    elif request_param is not None and request_param != OGCOperationEnum.GET_CAPABILITIES.value:
        # request not valid
        return HttpResponse(content=PARAMETER_ERROR.format(request_tag), status=404)

    else:
        pass

    if md.is_catalogue_metadata:
        doc = md.get_remote_original_capabilities_document(version_param)

    elif stored_version == version_param or use_fallback is True or not md.is_root():
        # This is the case if
        # 1) a version is requested, which we have in our database
        # 2) the fallback parameter is set explicitly
        # 3) a subelement is requested, which normally do not have capability documents

        # We can check the cache for this document or we need to generate it!
        doc = md.get_current_capability_xml(version_param)
    else:
        # we have to fetch the remote document
        # fetch the requested capabilities document from remote - we do not provide this as our default (registered) one
        xml = md.get_remote_original_capabilities_document(version_param)
        tmp = xml_helper.parse_xml(xml)

        if tmp is None:
            raise ValueError("No xml document was retrieved. Content was :'{}'".format(xml))
        # we fake the persisted service version, so the document setters will change the correct elements in the xml
        # md.service.service_type.version = version_param
        doc = Document(
            content=xml,
            metadata=md,
            document_type=DocumentEnum.CAPABILITY.value,
            is_original=True
        )
        doc.set_capabilities_secured(auto_save=False)

        if md.use_proxy_uri:
            doc.set_proxy(True, auto_save=False, force_version=version_param)
        doc = doc.content

    return doc