Example #1
0
def test_tms():
    # Find out what a TMS has to offer. Service metadata:
    from owslib.tms import TileMapService
    tms = TileMapService(SERVICE_URL)

    # Fetch a tile (using some defaults):
    tile = tms.gettile(7, 7, 4, title='brtachtergrondkaart', srs='EPSG:28992', mimetype='image/png')
    out = open(scratch_file('brtachtergrondkaart.png'), 'wb')
    out.write(tile.read())
    out.close()
Example #2
0
 def get_metadata(self, resource, version='1.0.0'):
     """
     Get metadata, specific per Resource type.
     :param resource:
     :param version:
     :return: Metadata object
     """
     return TileMapService(resource.url, version=version)
Example #3
0
    def before_request(self):
        """ Before request to service, overridden from base class"""

        # Get capabilities doc to get all layers
        try:
            self.tms = TileMapService(self._resource.url, version='1.0.0')
            self.layers = self.tms.contents
        except Exception as err:
            self.result.set(False, str(err))
Example #4
0
def _verify_service_type(base_url, service_type=None):
    """
    Try to determine service type by process of elimination
    """
    exceptions = []

    if service_type in ['WMS', 'OWS', None]:
        try:
            service = WebMapService(base_url)
        except:
            pass
        else:
            return ['WMS', service]

    if service_type in ['WFS', 'OWS', None]:
        try:
            servicewfs = WebFeatureService(base_url)
        except:
            pass
        else:
            return ['WFS', servicewfs]

    if service_type in ['TMS', None]:
        try:
            service = TileMapService(base_url)
        except:
            pass
        else:
            return ['TMS', service]


    if service_type in ['REST', None]:
        try:
            service = ArcFolder(base_url)
        except:
            pass
        else:
            service.services
            return ['REST', service]


    if service_type in ['CSW', None]:
        try:
            service = CatalogueServiceWeb(base_url)
        except:
            raise
        else:
            return ['CSW', service]

    if service_type in ['OGP', None]:
        #Just use a specific OGP URL for now
        if base_url == settings.OGP_URL:
            return ["OGP", None]

    return [None, None]
Example #5
0
    def expand_params(self, resource):

        # Use WMS Capabilities doc to get metadata for
        # PARAM_DEFS ranges/defaults
        try:
            tms = TileMapService(resource.url, version='1.0.0')
            layers = tms.contents
            self.layer_count = len(layers)

            # Determine Layers and Extensions
            layer_list = [layer_name.split('1.0.0/')[-1]
                          for layer_name in layers]
            self.PARAM_DEFS['layer']['range'] = layer_list

            # Make a set of all extensions
            extensions = set([layer.extension
                              for layer_name, layer in layers.items()])
            self.PARAM_DEFS['extension']['range'] = list(extensions)
        except Exception as err:
            raise err
Example #6
0
def create_services_from_endpoint(url, catalog, greedy_opt=True):
    """
    Generate service/services from an endpoint.
    WMS, WMTS, TMS endpoints correspond to a single service.
    ESRI, CSW endpoints corrispond to many services.
    :return: imported, message
    """

    # this variable will collect any exception message during the routine.
    # will be used in the last step to send a message if "detected" var is False.
    messages = []

    num_created = 0
    endpoint = get_sanitized_endpoint(url)
    try:
        urllib.request.urlopen(endpoint, timeout=10)
    except Exception as e:
        message = traceback.format_exception(*sys.exc_info())
        LOGGER.error('Cannot open this endpoint: %s' % endpoint)
        LOGGER.error('ERROR MESSAGE: %s' % message)
        LOGGER.error(e, exc_info=True)

        return False, message

    detected = False

    # handle specific service types for some domains (WorldMap, Wrapper...)
    parsed_uri = urlparse(endpoint)
    domain = '{uri.scheme}://{uri.netloc}/'.format(uri=parsed_uri)
    if domain == 'http://worldmap.harvard.edu/':
        service_type = 'Hypermap:WorldMap'
        title = 'Harvard WorldMap'
        abstract = 'Harvard WorldMap'
        endpoint = domain
        detected = True
    if domain in [
            'http://maps.nypl.org/',
            'http://mapwarper.net/',
            'http://warp.worldmap.harvard.edu/',
    ]:
        service_type = 'Hypermap:WARPER'
        title = 'Warper at %s' % domain
        abstract = 'Warper at %s' % domain
        detected = True

    # test if it is CSW, WMS, TMS, WMTS or Esri
    # CSW
    try:
        csw = CatalogueServiceWeb(endpoint)
        service_type = 'OGC:CSW'
        service_links = {}
        detected = True

        typenames = 'csw:Record'
        outputschema = 'http://www.opengis.net/cat/csw/2.0.2'

        if 'csw_harvest_pagesize' in settings.REGISTRY_PYCSW['manager']:
            pagesize = int(
                settings.REGISTRY_PYCSW['manager']['csw_harvest_pagesize'])
        else:
            pagesize = 10

        LOGGER.debug('Harvesting CSW %s' % endpoint)
        # now get all records
        # get total number of records to loop against
        try:
            csw.getrecords2(typenames=typenames,
                            resulttype='hits',
                            outputschema=outputschema)
            matches = csw.results['matches']
        except:  # this is a CSW, but server rejects query
            raise RuntimeError(csw.response)

        if pagesize > matches:
            pagesize = matches

        LOGGER.info('Harvesting %d CSW records' % matches)

        # loop over all catalogue records incrementally
        for r in range(1, matches + 1, pagesize):
            LOGGER.info('Parsing %s from %s' % (r, matches))
            try:
                csw.getrecords2(typenames=typenames,
                                startposition=r,
                                maxrecords=pagesize,
                                outputschema=outputschema,
                                esn='full')
            except Exception as err:  # this is a CSW, but server rejects query
                raise RuntimeError(csw.response)
            for k, v in list(csw.records.items()):
                # try to parse metadata
                try:
                    LOGGER.info('Looking for service links')

                    LOGGER.debug(
                        'Looking for service links via dct:references')
                    if v.references:
                        for ref in v.references:
                            scheme = None

                            if ref['scheme'] in [
                                    st[0] for st in SERVICE_TYPES
                            ]:
                                if ref['url'] not in service_links:
                                    scheme = ref['scheme']
                                    service_links[ref['url']] = scheme
                            else:  # loose detection
                                scheme = detect_metadata_url_scheme(ref['url'])
                                if scheme is not None:
                                    if ref['url'] not in service_links:
                                        service_links[ref['url']] = scheme

                            if scheme is None:
                                continue
                            try:
                                service = create_service_from_endpoint(
                                    ref['url'], scheme, catalog=catalog)

                                if service is not None:
                                    num_created = num_created + 1
                                    LOGGER.info(
                                        'Found %s services on endpoint' %
                                        num_created)
                            except Exception as e:
                                LOGGER.error(
                                    'Could not create service for %s : %s' %
                                    (scheme, ref['url']))
                                LOGGER.error(e, exc_info=True)
                    LOGGER.debug(
                        'Looking for service links via the GeoNetwork-ish dc:URI'
                    )
                    if v.uris:
                        for u in v.uris:  # loose detection
                            scheme = detect_metadata_url_scheme(u['url'])
                            if scheme is not None:
                                if u['url'] not in service_links:
                                    service_links[u['url']] = scheme
                            else:
                                continue

                            try:
                                service = create_service_from_endpoint(
                                    u['url'], scheme, catalog=catalog)

                                if service is not None:
                                    num_created = num_created + 1
                                    LOGGER.info(
                                        'Found %s services on endpoint' %
                                        num_created)
                            except Exception as e:
                                LOGGER.error(
                                    'Could not create service for %s : %s' %
                                    (scheme, u['url']))
                                LOGGER.error(e, exc_info=True)

                except Exception as err:  # parsing failed for some reason
                    LOGGER.warning('Metadata parsing failed %s', err)
                    LOGGER.error(err, exc_info=True)

    except XMLSyntaxError as e:
        # This is not XML, so likely not a CSW. Moving on.
        pass
    except Exception as e:
        LOGGER.error(e, exc_info=True)
        messages.append(str(e))

    # WMS
    if not detected:
        try:
            service = get_wms_version_negotiate(endpoint, timeout=10)
            service_type = 'OGC:WMS'
            title = service.identification.title,
            abstract = service.identification.abstract
            detected = True
        except XMLSyntaxError as e:
            # This is not XML, so likely not a WMS. Moving on.
            pass
        except Exception as e:
            LOGGER.error(e, exc_info=True)
            messages.append(str(e))

    # TMS
    if not detected:
        try:
            service = TileMapService(endpoint, timeout=10)
            service_type = 'OSGeo:TMS'
            title = service.identification.title,
            abstract = service.identification.abstract
            detected = True
        except XMLSyntaxError as e:
            # This is not XML, so likely not a TsMS. Moving on.
            pass
        except Exception as e:
            LOGGER.error(e, exc_info=True)
            messages.append(str(e))

    # WMTS
    if not detected:
        try:
            # @tomkralidis timeout is not implemented for WebMapTileService?
            service = WebMapTileService(endpoint)
            service_type = 'OGC:WMTS'
            title = service.identification.title,
            abstract = service.identification.abstract
            detected = True
        except XMLSyntaxError as e:
            # This is not XML, so likely not a WMTS. Moving on.
            pass
        except Exception as e:
            LOGGER.error(e, exc_info=True)
            messages.append(str(e))

    # if detected, let's create the service
    if detected and service_type != 'OGC:CSW':
        try:
            service = create_service_from_endpoint(endpoint,
                                                   service_type,
                                                   title,
                                                   abstract=abstract,
                                                   catalog=catalog)
            if service is not None:
                num_created = num_created + 1
        except XMLSyntaxError as e:
            # This is not XML, so likely not a OGC:CSW. Moving on.
            pass
        except Exception as e:
            LOGGER.error(e, exc_info=True)
            messages.append(str(e))

    # Esri
    # a good sample is here: https://gis.ngdc.noaa.gov/arcgis/rest/services

    # we can safely assume the following condition (at least it is true for 1170 services)
    # we need to test this as arcrest.Folder can freeze with not esri url such as this one:
    # http://hh.worldmap.harvard.edu/admin/aggregator/service/?q=%2Frest%2Fservices

    if '/rest/services' in endpoint:
        if not detected:
            try:
                esri = arcrest.Folder(endpoint)
                service_type = 'ESRI'
                detected = True

                service_to_process, folder_to_process = esri.services, esri.folders
                if not greedy_opt:
                    folder_to_process = []
                    sections = service_url_parse(url)
                    service_to_process = get_single_service(esri, sections)

                processed_services = process_esri_services(
                    service_to_process, catalog)
                num_created = num_created + len(processed_services)

                for folder in folder_to_process:
                    folder_services = process_esri_services(
                        folder.services, catalog)
                    num_created = num_created + len(folder_services)

            except Exception as e:
                LOGGER.error(e, exc_info=True)
                messages.append(str(e))

    if detected:
        return True, '%s service/s created' % num_created
    else:
        m = '|'.join(messages)
        return False, 'ERROR! Could not detect service type for ' \
                      'endpoint %s or already existing. messages=(%s)' % (endpoint, m)
Example #7
0
def sniff_test_resource(config, resource_type, url):
    """tests a service and provides run metrics"""

    if resource_type not in RESOURCE_TYPES.keys():
        msg = gettext('Invalid resource type')
        msg2 = '%s: %s' % (msg, resource_type)
        LOGGER.error(msg2)
        raise RuntimeError(msg2)

    title = None
    start_time = datetime.datetime.utcnow()
    message = None

    try:
        if resource_type == 'OGC:WMS':
            ows = WebMapService(url)
        elif resource_type == 'OGC:WMTS':
            ows = WebMapTileService(url)
        elif resource_type == 'OSGeo:TMS':
            ows = TileMapService(url)
        elif resource_type == 'OGC:WFS':
            ows = WebFeatureService(url)
        elif resource_type == 'OGC:WCS':
            ows = WebCoverageService(url, version='1.0.0')
        elif resource_type == 'OGC:WPS':
            ows = WebProcessingService(url)
        elif resource_type == 'OGC:CSW':
            ows = CatalogueServiceWeb(url)
        elif resource_type == 'OGC:SOS':
            ows = SensorObservationService(url)
        elif resource_type == 'OGC:STA':
            ows = urlopen(url)
        elif resource_type in ['WWW:LINK', 'urn:geoss:waf']:
            ows = urlopen(url)
            if resource_type == 'WWW:LINK':
                content_type = ows.info().getheader('Content-Type')

                # Check content if the response is not an image
                if 'image/' not in content_type:
                    content = ows.read()
                    import re
                    try:
                        title_re = re.compile("<title>(.+?)</title>")
                        title = title_re.search(content).group(1)
                    except:
                        title = url

                    # Optional check for any OGC-Exceptions in Response
                    if config and config['GHC_WWW_LINK_EXCEPTION_CHECK']:
                        exception_text = None
                        try:
                            except_re = re.compile(
                                "ServiceException>|ExceptionReport>")
                            exception_text = except_re.search(content).group(0)
                        except:
                            # No Exception in Response text
                            pass

                        if exception_text:
                            # Found OGC-Exception in Response text
                            raise Exception("Exception in response: %s" %
                                            exception_text)

                    del content

            elif resource_type == 'urn:geoss:waf':
                title = 'WAF %s %s' % (gettext('for'), urlparse(url).hostname)
        elif resource_type == 'FTP':
            ows = urlopen(url)
            title = urlparse(url).hostname
        success = True
        if resource_type.startswith(('OGC:', 'OSGeo')):
            if resource_type == 'OGC:STA':
                title = 'OGC STA'
            else:
                title = ows.identification.title
        if title is None:
            title = '%s %s %s' % (resource_type, gettext('for'), url)
    except Exception as err:
        msg = str(err)
        LOGGER.exception(msg)
        message = msg
        success = False

    end_time = datetime.datetime.utcnow()

    delta = end_time - start_time
    response_time = '%s.%s' % (delta.seconds, delta.microseconds)

    return [title, success, response_time, message, start_time]
Example #8
0
            service = get_wms_version_negotiate(endpoint, timeout=10)
            service_type = 'OGC:WMS'
            title = service.identification.title,
            abstract = service.identification.abstract
            detected = True
        except XMLSyntaxError as e:
            # This is not XML, so likely not a WMS. Moving on.
            pass
        except Exception as e:
            LOGGER.error(e, exc_info=True)
            messages.append(str(e))

    # TMS
    if not detected:
        try:
            service = TileMapService(endpoint, timeout=10)
            service_type = 'OSGeo:TMS'
            title = service.identification.title,
            abstract = service.identification.abstract
            detected = True
        except XMLSyntaxError as e:
            # This is not XML, so likely not a TsMS. Moving on.
            pass
        except Exception as e:
            LOGGER.error(e, exc_info=True)
            messages.append(str(e))

    # WMTS
    if not detected:
        try:
            # @tomkralidis timeout is not implemented for WebMapTileService?
Example #9
0
def create_services_from_endpoint(url):
    """
    Generate service/services from an endpoint.
    WMS, WMTS, TMS endpoints correspond to a single service.
    ESRI, CWS endpoints corrispond to many services.
    """
    num_created = 0
    endpoint = get_sanitized_endpoint(url)
    try:
        urllib2.urlopen(endpoint, timeout=10)
    except Exception as e:
        print 'ERROR! Cannot open this endpoint: %s' % endpoint
        message = traceback.format_exception(*sys.exc_info())
        return False, message

    detected = False

    # test if it is WMS, TMS, WMTS or Esri
    # WMS
    try:
        service = WebMapService(endpoint, timeout=10)
        service_type = 'OGC:WMS'
        detected = True
        service = create_service_from_endpoint(
            endpoint,
            service_type,
            title=service.identification.title,
            abstract=service.identification.abstract)
        if service is not None:
            num_created = num_created + 1
    except Exception as e:
        print str(e)

    # TMS
    if not detected:
        try:
            service = TileMapService(endpoint, timeout=10)
            service_type = 'OGC:TMS'
            detected = True
            create_service_from_endpoint(
                endpoint,
                service_type,
                title=service.identification.title,
                abstract=service.identification.abstract)
            if service is not None:
                num_created = num_created + 1
        except Exception as e:
            print str(e)

    # WMTS
    if not detected:
        try:
            service = WebMapTileService(endpoint, timeout=10)
            service_type = 'OGC:WMTS'
            detected = True
            create_service_from_endpoint(
                endpoint,
                service_type,
                title=service.identification.title,
                abstract=service.identification.abstract)
            if service is not None:
                num_created = num_created + 1
        except Exception as e:
            print str(e)

    # Esri
    # a good sample is here: https://gis.ngdc.noaa.gov/arcgis/rest/services
    if not detected:
        try:
            esri = ArcFolder(endpoint)
            services = esri.services

            service_type = 'ESRI'
            detected = True

            # root
            root_services = process_esri_services(services)
            num_created = num_created + len(root_services)

            # folders
            for folder in esri.folders:
                folder_services = process_esri_services(folder.services)
                num_created = num_created + len(folder_services)

        except Exception as e:
            print str(e)

    if detected:
        return True, '%s service/s created' % num_created
    else:
        return False, 'ERROR! Could not detect service type for endpoint %s or already existing' % endpoint
Example #10
0
def create_services_from_endpoint(url):
    """
    Generate service/services from an endpoint.
    WMS, WMTS, TMS endpoints correspond to a single service.
    ESRI, CWS endpoints corrispond to many services.
    """
    num_created = 0
    endpoint = get_sanitized_endpoint(url)
    try:
        urllib2.urlopen(endpoint, timeout=10)
    except Exception as e:
        print 'ERROR! Cannot open this endpoint: %s' % endpoint
        message = traceback.format_exception(*sys.exc_info())
        return False, message

    detected = False

    # test if it is WMS, TMS, WMTS or Esri
    # WMS
    try:
        service = WebMapService(endpoint, timeout=10)
        service_type = 'OGC:WMS'
        detected = True
        service = create_service_from_endpoint(
            endpoint,
            service_type,
            title=service.identification.title,
            abstract=service.identification.abstract)
        if service is not None:
            num_created = num_created + 1
    except Exception as e:
        print str(e)

    # TMS
    if not detected:
        try:
            service = TileMapService(endpoint, timeout=10)
            service_type = 'OSGeo:TMS'
            detected = True
            create_service_from_endpoint(
                endpoint,
                service_type,
                title=service.identification.title,
                abstract=service.identification.abstract)
            if service is not None:
                num_created = num_created + 1
        except Exception as e:
            print str(e)

    # WMTS
    if not detected:
        try:
            service = WebMapTileService(endpoint, timeout=10)
            service_type = 'OGC:WMTS'
            detected = True
            create_service_from_endpoint(
                endpoint,
                service_type,
                title=service.identification.title,
                abstract=service.identification.abstract)
            if service is not None:
                num_created = num_created + 1
        except Exception as e:
            print str(e)

    # Esri
    # a good sample is here: https://gis.ngdc.noaa.gov/arcgis/rest/services

    # we can safely assume the following condition (at least it is true for 1170 services)
    # we need to test this as ArcFolder can freeze with not esri url such as this one:
    # http://hh.worldmap.harvard.edu/admin/aggregator/service/?q=%2Frest%2Fservices
    if '/rest/services' in endpoint:
        if not detected:
            try:
                esri = ArcFolder(endpoint)
                services = esri.services

                service_type = 'ESRI'
                detected = True

                # root
                root_services = process_esri_services(services)
                num_created = num_created + len(root_services)

                # folders
                for folder in esri.folders:
                    folder_services = process_esri_services(folder.services)
                    num_created = num_created + len(folder_services)

            except Exception as e:
                print str(e)

    if detected:
        return True, '%s service/s created' % num_created
    else:
        return False, 'ERROR! Could not detect service type for endpoint %s or already existing' % endpoint
Example #11
0
    def check_available(self):
        """
        Check for availability of a service and provide run metrics.
        """
        success = True
        start_time = datetime.datetime.utcnow()
        message = ''

        print 'Checking service id %s' % self.id

        try:
            title = None
            abstract = None
            keywords = []
            wkt_geometry = None
            srs = '4326'
            if self.type == 'OGC:WMS':
                ows = WebMapService(self.url)
                title = ows.identification.title
                abstract = ows.identification.abstract
                keywords = ows.identification.keywords
                for c in ows.contents:
                    if ows.contents[c].parent is None:
                        wkt_geometry = bbox2wktpolygon(ows.contents[c].boundingBoxWGS84)
                    break
            if self.type == 'OGC:WMTS':
                ows = WebMapTileService(self.url)
                title = ows.identification.title
                abstract = ows.identification.abstract
                keywords = ows.identification.keywords
            if self.type == 'OSGeo:TMS':
                ows = TileMapService(self.url)
                title = ows.identification.title
                abstract = ows.identification.abstract
                keywords = ows.identification.keywords
            if self.type == 'ESRI:ArcGIS:MapServer':
                esri = ArcMapService(self.url)
                extent, srs = get_esri_extent(esri)
                title = esri.mapName
                if len(title) == 0:
                    title = get_esri_service_name(self.url)
                wkt_geometry = bbox2wktpolygon([
                    extent['xmin'],
                    extent['ymin'],
                    extent['xmax'],
                    extent['ymax']
                ])
            if self.type == 'ESRI:ArcGIS:ImageServer':
                esri = ArcImageService(self.url)
                extent, srs = get_esri_extent(esri)
                title = esri._json_struct['name']
                if len(title) == 0:
                    title = get_esri_service_name(self.url)
                wkt_geometry = bbox2wktpolygon([
                    extent['xmin'],
                    extent['ymin'],
                    extent['xmax'],
                    extent['ymax']
                ])
            if self.type == 'Hypermap:WorldMap':
                urllib2.urlopen(self.url)
                title = 'Harvard WorldMap'
            if self.type == 'Hypermap:WARPER':
                urllib2.urlopen(self.url)
            # update title without raising a signal and recursion
            if title:
                self.title = title
                Service.objects.filter(id=self.id).update(title=title)
            if abstract:
                self.abstract = abstract
                Service.objects.filter(id=self.id).update(abstract=abstract)
            if keywords:
                for kw in keywords:
                    # FIXME: persist keywords to Django model
                    self.keywords.add(kw)
            if wkt_geometry:
                self.wkt_geometry = wkt_geometry
                Service.objects.filter(id=self.id).update(wkt_geometry=wkt_geometry)
            xml = create_metadata_record(
                identifier=self.id_string,
                source=self.url,
                links=[[self.type, self.url]],
                format=self.type,
                type='service',
                title=title,
                abstract=abstract,
                keywords=keywords,
                wkt_geometry=self.wkt_geometry,
                srs=srs
            )
            anytexts = gen_anytext(title, abstract, keywords)
            Service.objects.filter(id=self.id).update(anytext=anytexts, xml=xml, csw_type='service')
        except Exception as err:
            print(err)
            message = str(err)
            success = False

        end_time = datetime.datetime.utcnow()
        delta = end_time - start_time
        response_time = '%s.%s' % (delta.seconds, delta.microseconds)

        check = Check(
            resource=self,
            success=success,
            response_time=response_time,
            message=message
        )
        check.save()
        print 'Service checked in %s seconds, status is %s' % (response_time, success)