Example #1
0
    def put(self, key):
        """
        A REST endpoint for adding or editing a single layer.
        All registration requests must contain entries for all languages and will be validated against a JSON schema.

        :param smallkey: A unique identifier for the dataset (can be any unique string, but preferably should be short)
        :type smallkey: str
        :returns: JSON Response -- 201 on success; 400 with JSON payload of an errors array on failure
        """
        try:
            req = json.loads(request.data)
        except Exception as e:
            current_app.logger.error(e.message)
            return '{"errors":["Unparsable json"]}', 400
        errors = get_registration_errors(req)
        if errors:
            resp = {'errors': errors}
            current_app.logger.info(resp)
            return Response(json.dumps(resp), mimetype='application/json', status=400)

        try:
            v2_node, v1_node = regparse.make_node(key, req, current_app.config)
        except regparse.metadata.MetadataException as mde:
            current_app.logger.warning('Metadata could not be retrieved for layer', exc_info=mde)
            abort(400, msg=mde.message)
        except regparse.ServiceEndpointException as se:
            current_app.logger.warning('Problem reading service endpoints', exc_info=se)
            abort(400, msg=se.message)

        current_app.logger.debug(v2_node)
        current_app.logger.debug(v1_node)
        db.put_doc(key, v2_node.values()[0]['layerType'], req, layer_config=v2_node, v1_config=v1_node)
        current_app.logger.info('added a key %s' % key)
        return Response(json.dumps(dict(key=key)), mimetype='application/json', status=201)
Example #2
0
    def post(self, key):
        """
        A REST endpoint for upgrading a previous registration from v1 to v2.

        :param key: A unique identifier for the dataset
        :type key: str
        :returns: JSON Response -- 200 on success; 4xx if problems are encountered
        """
        dbdata = db.get_raw(key)

        if dbdata is None:
            return '{"msg":"Record not found in database"}', 404
        elif dbdata.get('version') == '2.0':
            return '{"msg":"Already upgraded"}', 200
        elif dbdata['data'].get('request') is None:
            return '{"msg":"Previous request was not cached (request caching added in 1.8.0)"}', 409

        try:
            v1_request = dbdata['data']['request']
            upgrade_method = wms_upgrade if v1_request['payload_type'] == 'wms' else feat_upgrade
            v2_request = {lang: upgrade_method(v1_request[lang]) for lang in current_app.config['LANGS']}
            print v2_request
            v2_node, v1_node = regparse.make_node(key, v2_request, current_app.config)
            db.put_doc(key, v2_node.values()[0]['layerType'], v2_request, layer_config=v2_node, v1_config=v1_node)
        except Exception as e:
            msg = {'msg': 'Error: {0}'.format(e.message)}
            current_app.logger.error('Failed to upgrade {0}'.format(key), exc_info=e)
            return Response(json.dumps(msg), mimetype='application/json', status=400)

        success = {"msg": "Upgraded", "version": "2.0", "key": key}
        return Response(json.dumps(success), mimetype='application/json', status=200)
Example #3
0
    def put(self, key):
        """
        A REST endpoint for updating one or more nodes of an existing request.

        :param key: A unique identifier for the dataset
        :type key: str
        :returns: JSON Response -- 200 on success; 4xx if problems are encountered
        """

        langs = ["en", "fr"]
        try:
            dbdata = db.get_raw(key)
            if dbdata is None:
                return '{"msg":"Record not found in database"}', 404
        except Exception as e:
            msg = {'msg': 'Error: {0}'.format(e.message)}
            return Response(json.dumps(msg),
                            mimetype='application/json',
                            status=500)

        def replace_if_set(params):
            for p in params:
                if p in payload_seg:
                    request_seg[p] = payload_seg[p]

        try:
            payload = json.loads(request.data)
            for lang in langs:
                request_seg = dbdata['request'][lang]
                payload_seg = payload[lang]
                replace_if_set(['service_url', 'service_name', 'metadata'])
                if payload_seg['service_type'] in [
                        'esriFeature', 'esriImage', 'esriTile'
                ]:
                    replace_if_set(['display_field'])
                elif payload_seg['service_type'] == 'esriMapServer':
                    replace_if_set(['scrape_only', 'recursive'])
                elif payload_seg['service_type'] == 'ogcWms':
                    replace_if_set([
                        'scrape_only', 'recursive', 'legend_format',
                        'feature_info_format'
                    ])
                v2_node, v1_node = regparse.make_node(key, dbdata["request"],
                                                      current_app.config)
                db.put_doc(key,
                           payload[lang]["service_type"],
                           dbdata["request"],
                           layer_config=v2_node,
                           v1_config=v1_node)
        except Exception as e:
            msg = {'msg': 'Error: {0}'.format(e.message)}
            return Response(json.dumps(msg),
                            mimetype='application/json',
                            status=500)
        success = {"msg": "Updated", "key": key}
        return Response(json.dumps(success),
                        mimetype='application/json',
                        status=200)
Example #4
0
def refresh_records(day_limit, limit, config):
    import datetime, string
    valid = []
    invalid = {}
    query = ""
    if day_limit is None:
        query = "function(doc) { emit(doc._id, { updated: doc.updated_at, version: doc.version, request: doc.data ? doc.data.request : doc.request }); }"  # NOQA
    else:
        min_age = datetime.date.today() - datetime.timedelta(days=day_limit)
        query = "function(doc) { if (doc.updated_at <= '$date') emit(doc._id, { updated: doc.updated_at, version: doc.version, request: doc.data ? doc.data.request : doc.request }); }"  # NOQA
        query = string.Template(query).substitute(date=min_age)
    current_app.logger.debug('CouchDB Query {0}'.format(query))
    results = db.query(query)
    count = 0
    limit_reached = False
    for r in results:
        if limit is not None:
            # annoying count is necessary since we don't want to convert a generator into a list
            count += 1
            if count > limit:
                limit_reached = True
                break

        key = r['id']
        current_app.logger.info('refresh {0}'.format(key))
        if 'request' not in r['value']:
            invalid[
                key] = 'previous request was not cached (request caching added in 1.8.0)'
            continue
        if r['value'].get('version', None) != '2.0':
            invalid[
                key] = 'v1 record found; upgrading record types has not yet been implemented'
            continue
        req = r['value']['request']
        try:
            v2_node, v1_node = regparse.make_node(key, req, config)
            db.put_doc(key,
                       v2_node.values()[0]['layerType'],
                       req,
                       layer_config=v2_node,
                       v1_config=v1_node)
            valid.append(key)
        except Exception as e:
            current_app.logger.warning('Error in refresh', exc_info=e)
            invalid[key] = str(e)

    return {
        "updated": valid,
        "errors": invalid,
        'limit_reached': limit_reached
    }
Example #5
0
    def post(self, key):
        """
        A REST endpoint for upgrading a previous registration from v1 to v2.

        :param key: A unique identifier for the dataset
        :type key: str
        :returns: JSON Response -- 200 on success; 4xx if problems are encountered
        """
        dbdata = db.get_raw(key)

        if dbdata is None:
            return '{"msg":"Record not found in database"}', 404
        elif dbdata.get('version') == '2.0':
            return '{"msg":"Already upgraded"}', 200
        elif dbdata['data'].get('request') is None:
            return '{"msg":"Previous request was not cached (request caching added in 1.8.0)"}', 409

        try:
            v1_request = dbdata['data']['request']
            upgrade_method = wms_upgrade if v1_request[
                'payload_type'] == 'wms' else feat_upgrade
            v2_request = {
                lang: upgrade_method(v1_request[lang])
                for lang in current_app.config['LANGS']
            }
            print v2_request
            v2_node, v1_node = regparse.make_node(key, v2_request,
                                                  current_app.config)
            db.put_doc(key,
                       v2_node.values()[0]['layerType'],
                       v2_request,
                       layer_config=v2_node,
                       v1_config=v1_node)
        except Exception as e:
            msg = {'msg': 'Error: {0}'.format(e.message)}
            current_app.logger.error('Failed to upgrade {0}'.format(key),
                                     exc_info=e)
            return Response(json.dumps(msg),
                            mimetype='application/json',
                            status=400)

        success = {"msg": "Upgraded", "version": "2.0", "key": key}
        return Response(json.dumps(success),
                        mimetype='application/json',
                        status=200)
Example #6
0
    def put(self, key):
        """
        A REST endpoint for adding or editing a single layer.
        All registration requests must contain entries for all languages and will be validated against a JSON schema.

        :param smallkey: A unique identifier for the dataset (can be any unique string, but preferably should be short)
        :type smallkey: str
        :returns: JSON Response -- 201 on success; 400 with JSON payload of an errors array on failure
        """
        try:
            req = json.loads(request.data)
        except Exception as e:
            current_app.logger.error(e.message)
            return '{"errors":["Unparsable json"]}', 400
        errors = get_registration_errors(req)
        if errors:
            resp = {'errors': errors}
            current_app.logger.info(resp)
            return Response(json.dumps(resp),
                            mimetype='application/json',
                            status=400)

        try:
            v2_node, v1_node = regparse.make_node(key, req, current_app.config)
        except regparse.metadata.MetadataException as mde:
            current_app.logger.warning(
                'Metadata could not be retrieved for layer', exc_info=mde)
            abort(400, msg=mde.message)
        except regparse.ServiceEndpointException as se:
            current_app.logger.warning('Problem reading service endpoints',
                                       exc_info=se)
            abort(400, msg=se.message)

        current_app.logger.debug(v2_node)
        current_app.logger.debug(v1_node)
        db.put_doc(key,
                   v2_node.values()[0]['layerType'],
                   req,
                   layer_config=v2_node,
                   v1_config=v1_node)
        current_app.logger.info('added a key %s' % key)
        return Response(json.dumps(dict(key=key)),
                        mimetype='application/json',
                        status=201)
Example #7
0
    def put(self, key):
        """
        A REST endpoint for updating one or more nodes of an existing request.

        :param key: A unique identifier for the dataset
        :type key: str
        :returns: JSON Response -- 200 on success; 4xx if problems are encountered
        """

        langs = ["en", "fr"]
        try:
            dbdata = db.get_raw(key)
            if dbdata is None:
                return '{"msg":"Record not found in database"}', 404
        except Exception as e:
            msg = {'msg': 'Error: {0}'.format(e.message)}
            return Response(json.dumps(msg), mimetype='application/json', status=500)

        def replace_if_set(params):
            for p in params:
                if p in payload_seg:
                    request_seg[p] = payload_seg[p]

        try:
            payload = json.loads(request.data)
            for lang in langs:
                request_seg = dbdata['request'][lang]
                payload_seg = payload[lang]
                replace_if_set(['service_url', 'service_name', 'metadata'])
                if payload_seg['service_type'] in ['esriFeature', 'esriImage', 'esriTile']:
                    replace_if_set(['display_field'])
                elif payload_seg['service_type'] == 'esriMapServer':
                    replace_if_set(['scrape_only', 'recursive'])
                elif payload_seg['service_type'] == 'ogcWms':
                    replace_if_set(['scrape_only', 'recursive', 'legend_format', 'feature_info_format'])
                v2_node, v1_node = regparse.make_node(key, dbdata["request"], current_app.config)
                db.put_doc(key, payload[lang]["service_type"], dbdata["request"],
                           layer_config=v2_node, v1_config=v1_node)
        except Exception as e:
            msg = {'msg': 'Error: {0}'.format(e.message)}
            return Response(json.dumps(msg), mimetype='application/json', status=500)
        success = {"msg": "Updated", "key": key}
        return Response(json.dumps(success), mimetype='application/json', status=200)
Example #8
0
def refresh_records(day_limit, limit, config):
    import datetime, string
    valid = []
    invalid = {}
    query = ""
    if day_limit is None:
        query = "function(doc) { emit(doc._id, { updated: doc.updated_at, version: doc.version, request: doc.data ? doc.data.request : doc.request }); }"  # NOQA
    else:
        min_age = datetime.date.today() - datetime.timedelta(days=day_limit)
        query = "function(doc) { if (doc.updated_at <= '$date') emit(doc._id, { updated: doc.updated_at, version: doc.version, request: doc.data ? doc.data.request : doc.request }); }"  # NOQA
        query = string.Template(query).substitute(date=min_age)
    current_app.logger.debug('CouchDB Query {0}'.format(query))
    results = db.query(query)
    count = 0
    limit_reached = False
    for r in results:
        if limit is not None:
            # annoying count is necessary since we don't want to convert a generator into a list
            count += 1
            if count > limit:
                limit_reached = True
                break

        key = r['id']
        current_app.logger.info('refresh {0}'.format(key))
        if 'request' not in r['value']:
            invalid[key] = 'previous request was not cached (request caching added in 1.8.0)'
            continue
        if r['value'].get('version', None) != '2.0':
            invalid[key] = 'v1 record found; upgrading record types has not yet been implemented'
            continue
        req = r['value']['request']
        try:
            v2_node, v1_node = regparse.make_node(key, req, config)
            db.put_doc(key, v2_node.values()[0]['layerType'], req, layer_config=v2_node, v1_config=v1_node)
            valid.append(key)
        except Exception as e:
            current_app.logger.warning('Error in refresh', exc_info=e)
            invalid[key] = str(e)

    return {"updated": valid, "errors": invalid, 'limit_reached': limit_reached}