Exemple #1
0
 def DELETE(self, map_name, l_name, s_name, format):
     mf = get_mapfile(map_name)
     with webapp.mightNotFound("layer", mapfile=map_name):
         layer = mf.get_layer(l_name)
     with webapp.mightNotFound("style", layer=l_name):
         layer.remove_style(s_name)
     mf.save()
Exemple #2
0
    def DELETE(self, l_name, s_name, format):
        """Remove style <s> from layer <l>."""

        mf = mra.get_available()
        with webapp.mightNotFound():
            layer = mf.get_layer(l_name)
        with webapp.mightNotFound("style", layer=l_name):
            layer.remove_style(s_name)
        mf.save()
Exemple #3
0
    def GET(self, map_name, ws_name, ds_name, ft_name, format):
        mf, ws = get_mapfile_workspace(map_name, ws_name)

        ds = ws.get_datastore(ds_name)
        with webapp.mightNotFound("dataStore", datastore=ds_name):
            dsft = ds[ft_name]

        with webapp.mightNotFound("featureType", datastore=ds_name):
            ft = ws.get_featuretypemodel(ft_name, ds_name)

        extent = ft.get_extent()
        latlon_extent = ft.get_latlon_extent()

        return {"featureType": ({
                    "name": ft.name,
                    "nativeName": ft.name,
                    "namespace": None, # TODO
                    "title": ft.get_mra_metadata("title", ft.name),
                    "abstract": ft.get_mra_metadata("abstract", None),
                    "keywords": ft.get_mra_metadata("keywords", []),
                    "srs": "%s:%s" % (ft.get_authority()[0], ft.get_authority()[1]),
                    "nativeCRS": ft.get_wkt(),
                    "attributes": [{
                            "name": f.get_name(),
                            "minOccurs": 0 if f.is_nullable() else 1,
                            "maxOccurs": 1,
                            "nillable": f.is_nullable(),
                            "binding": f.get_type_name(),
                            "length": f.get_width(),
                            } for f in dsft.iterfields()],
                    "nativeBoundingBox": {
                        "minx": extent.minX(),
                        "miny": extent.minY(),
                        "maxx": extent.maxX(),
                        "maxy": extent.maxY(),
                        "crs": "%s:%s" % (ft.get_authority_name(), ft.get_authority_code()),
                        },
                    "latLonBoundingBox": {
                        "minx": latlon_extent.minX(),
                        "miny": latlon_extent.minY(),
                        "maxx": latlon_extent.maxX(),
                        "maxy": latlon_extent.maxY(),
                        "crs": "EPSG:4326",
                        },
                    "projectionPolicy": None, # TODO
                    "enabled": True, # TODO
                    "store": { # TODO: add key: class="dataStore"
                        "name": ds_name,
                        "href": "%s/maps/%s/workspaces/%s/datastores/%s.%s" % (
                            web.ctx.home, map_name, ws_name, ds_name, format)
                        },
                    "maxFeatures": 0, # TODO
                    "numDecimals": 0, # TODO
                    })
                }
Exemple #4
0
    def PUT(self, l_name, format):
        """Modify layer <l>."""

        mf = mra.get_available()

        data = get_data(name="layer", mandatory=[],
                        authorized=["name", "title", "abstract", "resource", "enabled", "defaultStyle"])
        if l_name != data.get("name", l_name):
            raise webapp.Forbidden("Can't change the name of a layer.")

        l_enabled = data.pop("enabled", True)

        mf = mra.get_available()
        with webapp.mightNotFound():
            layer = mf.get_layer(l_name)

        # update resource if changed
        href = data.get("resource", {}).get("href")
        if href:
            try:
                ws_name, st_type, st_name, r_type, r_name = mra.href_parse(href, 5)
            except ValueError:
                raise webapp.NotFound(message="resource \"%s\" was not found." % href)

            st_type, r_type = st_type[:-1], r_type[:-1] # Remove trailing s.

            ws = get_workspace(ws_name)
            with webapp.mightNotFound(r_type, workspace=ws_name):
                try:
                    model = ws.get_layermodel(r_type, st_name, r_name)
                except ValueError:
                    raise KeyError(r_type)

            if layer.get_mra_metadata("type") != r_type:
                raise webapp.BadRequest("Can't change a \"%s\" layer into a \"%s\"."
                                    % (layer.get_mra_metadata("type"), r_type))

            model.configure_layer(layer, l_enabled)

        # If we have a defaultStyle apply it.
        s_name = data.get("defaultStyle", {}).get("name")
        if s_name:
            with webapp.mightNotFound():
                style = mra.get_style(s_name)
            layer.add_style_sld(mf, s_name, style)
            
            # Remove the automatic default style.
            for s_name in layer.iter_styles():
                if s_name == tools.get_dflt_sld_name(layer.ms.type):
                    layer.remove_style(s_name)

        mf.save()
Exemple #5
0
    def PUT(self, l_name, format):
        """Modify layer <l>."""

        mf = mra.get_available()

        data = get_data(name="layer", mandatory=[],
                        authorized=["name", "resource", "defaultStyle"])
        if l_name != data.get("name", l_name):
            raise webapp.Forbidden("Can't change the name of a layer.")

        l_enabled = True # TODO: => data.pop("enabled", True)

        mf = mra.get_available()
        with webapp.mightNotFound():
            layer = mf.get_layer(l_name)

        # update resource if changed
        href = data.get("resource", {}).get("href")
        if href:
            try:
                ws_name, st_type, st_name, r_type, r_name = mra.href_parse(href, 5)
            except ValueError:
                raise webapp.NotFound(message="resource \"%s\" was not found." % href)

            st_type, r_type = st_type[:-1], r_type[:-1] # Remove trailing s.

            ws = get_workspace(ws_name)
            with webapp.mightNotFound(r_type, workspace=ws_name):
                try:
                    model = ws.get_layermodel(r_type, st_name, r_name)
                except ValueError:
                    raise KeyError(r_type)

            if layer.get_mra_metadata("type") != r_type:
                raise webapp.BadRequest("Can't change a \"%s\" layer into a \"%s\"."
                                    % (layer.get_mra_metadata("type"), r_type))
        model.configure_layer(layer, l_enabled)

        # If we have a defaultStyle apply it.
        s_name = data.get("defaultStyle", {}).get("name")
        if s_name:
            with webapp.mightNotFound():
                style = mra.get_style(s_name)
            layer.add_style_sld(mf, s_name, style)
            
            # Remove the automatic default style.
            for s_name in layer.iter_styles():
                if s_name == tools.get_dflt_sld_name(layer.ms.type):
                    layer.remove_style(s_name)

        mf.save()
Exemple #6
0
    def DELETE(self, lg_name, format):
        """Delete layergroup <lg>."""

        mf = mra.get_available()
        with webapp.mightNotFound():
            mf.delete_layergroup(lg_name)
        mf.save()
Exemple #7
0
    def GET(self, map_name, ws_name, cs_name, format):
        mf, ws = get_mapfile_workspace(map_name, ws_name)

        with webapp.mightNotFound("coverageStore", workspace=ws_name):
            info = ws.get_coveragestore_info(cs_name)

        return {"coverageStore": {
                    "name": info["name"],
                    "type": None, # TODO
                    "enabled": True, # TODO
                    "__default": False, # TODO
                    "workspace": {
                        "name": ws.name,
                        "href": "%s/maps/%s/workspaces/%s.%s" % (
                            web.ctx.home, map_name, ws.name, format),
                        },
                    "coverages": href("%s/maps/%s/workspaces/%s/coveragestores/%s/coverages.%s" % (
                                    web.ctx.home, map_name, ws.name, cs_name, format)
                        ),
                    "connectionParameters": Entries({
                        "url": info["connectionParameters"]["url"],
                        "namespace": None, # TODO
                        }, tag_name="entry")
                    }
                }
Exemple #8
0
    def POST(self, map_name, l_name, format):
        data = get_data(name="style", mandatory=["resource"],
                        authorized=["name", "title", "abstract", "resource"])

        url = urlparse.urlparse(data["resource"]["href"])
        if url.path.startswith(web.ctx.homepath):
            path = url.path[len(web.ctx.homepath):]
        else:
            raise webapp.BadRequest(message="Resource href (%s) is not handled by MRA." % url.path)

        try:
            _, map_name, _, s_name = path.rsplit("/", 3)
        except ValueError:
            raise webapp.NotFound(message="ressource '%s' was not found." % path)

        s_name = s_name.rsplit(".", 1)[0]

        # Get the new style.
        mf = get_mapfile(map_name)

        try:
            style = open(tools.get_style_path(s_name)).read()
        except IOError, OSError:
            with webapp.mightNotFound("style", mapfile=map_name):
                style = mf.get_style_sld(s_name)
Exemple #9
0
    def POST(self, map_name, format):
        data = get_data(name="layer",
                        mandatory=["name", "resource"],
                        authorized=["name", "title", "abstract", "resource", "enabled"])

        l_name = data.pop("name")
        l_enabled = data.pop("enabled", True)

        # This means we can have one mapfile for each workspace
        # and if eveything uses urls it should work *almost* as is.
        url = urlparse.urlparse(data["resource"]["href"])
        if url.path.startswith(web.ctx.homepath):
            path = url.path[len(web.ctx.homepath):]
        else:
            raise webapp.BadRequest(message="Resource href is not handled by MRA.")

        try:
            _, map_name, _, ws_name, st_type, st_name, r_type, r_name = path.rsplit("/", 7)
        except ValueError:
            raise webapp.NotFound(message="ressource '%s' was not found." % path)

        r_name = r_name.rsplit(".", 1)[0]

        mf, ws = get_mapfile_workspace(map_name, ws_name)
        with webapp.mightNotFound(r_type, workspace=ws_name):
            try:
                model = ws.get_model(r_name, r_type[:-1], st_name)
            except ValueError:
                webapp.NotFound("Invalid layer model '%s'" % r_type[:-1])

        with webapp.mightConflict("layer", mapfile=map_name):
            mf.create_layer(ws, model, l_name, l_enabled)
        mf.save()

        webapp.Created("%s/maps/%s/layers/%s%s" % (web.ctx.home, map_name, l_name, (".%s" % format) if format else ""))
Exemple #10
0
    def GET(self, map_name, l_name, format):
        mf = get_mapfile(map_name)
        with webapp.mightNotFound("layer", mapfile=map_name):
            layer = mf.get_layer(l_name)

        data_type, store_type = {
            "featuretype": ("featuretype", "datastore"),
            "coverage": ("coverage", "coveragestore")
            }[layer.get_mra_metadata("type")]

        return {"layer" : {
                    "name": l_name,
                    "path": "/", # TODO
                    "type": layer.get_type_name(),
                    "defaultStyle": {
                        "name": layer.ms.classgroup,
                        "href": "%s/maps/%s/styles/%s.%s" % (web.ctx.home, map_name, layer.ms.classgroup, format),
                        },
                    "styles": [{ # TODO: Add attr class="linked-hash-set"
                            "name": s_name,
                            "href": "%s/maps/%s/styles/%s.%s" % (web.ctx.home, map_name, s_name, format),
                            } for s_name in layer.iter_styles()],
                    "resource": { # TODO: Add attr class="featureType|coverage"
                        "name": layer.get_mra_metadata("name"),
                        "href": "%s/maps/%s/workspaces/%s/%ss/%s/%ss/%s.%s" % (
                            web.ctx.home, map_name, layer.get_mra_metadata("workspace"),
                            store_type, layer.get_mra_metadata("storage"), data_type, layer.get_mra_metadata("name"), format),
                        },
                    "enabled": bool(layer.ms.status),
                    "attribution": { # TODO
                        "logoWidth": 0, 
                        "logoHeight": 0,
                        },
                    }
                }
Exemple #11
0
    def GET(self, ws_name, cs_name, format):
        """Return coverage store <cs>."""

        ws = get_workspace(ws_name)
        with webapp.mightNotFound("coverageStore", workspace=ws_name):
            info = ws.get_coveragestore_info(cs_name)
        connectionParameters = info.get("connectionParameters", {})

        return {"coverageStore": {
                    "name": info["name"],
                    "enabled": True, # Always enabled
                                     # TODO: Handle enabled/disabled states
                    "workspace": {
                        "name": ws.name,
                        "href": "%s/workspaces/%s.%s" % (
                            web.ctx.home, ws.name, format),
                        },
                    "coverages": href("%s/workspaces/%s/coveragestores/%s/coverages.%s" % (
                                    web.ctx.home, ws.name, cs_name, format)
                        ),
                    "connectionParameters": connectionParameters and Entries({
                        "url": info["connectionParameters"]["url"],
                        # "namespace": None, # TODO
                        }, tag_name="entry"),
                    # TODO: type
                    }
                }
Exemple #12
0
    def GET(self, l_name, format):
        mf = mra.get_available()
        with webapp.mightNotFound():
            layer = mf.get_layer(l_name)

        if layer.get_type_name() == "RASTER":
            return {"fields": []}

        fields = [{
            "name": layer.get_metadata("gml_%s_alias" % field, None),
            "type": layer.get_metadata("gml_%s_type" % field, None),
            } for field in layer.iter_fields()]

        geom = layer.get_metadata("gml_geometries", False)
        if geom:
            type = layer.get_metadata("gml_%s_type" % geom, "undefined")
            occurs = layer.get_metadata("gml_%s_occurances" % geom, "0,1").split(",")
            min_occurs, max_occurs = int(occurs[0]), int(occurs[1])
        else:
            geom, type, min_occurs, max_occurs = "undefined", "undefined", 0, 1
        
        fields.append({
            "name": geom,
            "type": type,
            "minOccurs": min_occurs,
            "maxOccurs": max_occurs,
            })

        return {"fields": fields}
Exemple #13
0
    def GET(self, lg_name, format):
        """Return layergroup <lg>."""

        mf = mra.get_available()
        with webapp.mightNotFound():
            lg = mf.get_layergroup(lg_name)

        latlon_extent = lg.get_latlon_extent()

        bounds = {"minx": latlon_extent.minX(),
            "miny": latlon_extent.minY(),
            "maxx": latlon_extent.maxX(),
            "maxy": latlon_extent.maxY(),
            "crs": "EPSG:4326",
            }

        return {"layerGroup": ({
                    "name": lg.name,
                    "mode": "NAMED", # Only available mode in MRA.
                    "publishables": Entries([{
                            "name": layer.ms.name,
                            "href": "%s/layers/%s.%s" % (web.ctx.home, layer.ms.name, format),
                            } for layer in lg.iter_layers()], tag_name="published"),
                    "bounds": Entries(bounds),
                    # TODO: Styles
                    # "styles": [],
                    })
                }
Exemple #14
0
    def PUT(self, s_name, format):
        """Modify style <s>."""

        # TODO: Also update layers using this style.
        with webapp.mightNotFound(message="Style \"%s\" does not exist." % s_name):
            mra.delete_style(s_name)
        data = web.data()
        mra.create_style(s_name, data)
Exemple #15
0
    def POST(self, format):
        """Create a new layer."""

        data = get_data(name="layer",
                        mandatory=["name", "resource"],
                        authorized=["name", "title", "abstract", "resource", "enabled", "defaultStyle"])

        l_name = data.pop("name")
        l_enabled = data.pop("enabled", True)

        href = data["resource"]["href"]
        try:
            ws_name, st_type, st_name, r_type, r_name = mra.href_parse(href, 5)
        except ValueError:
            raise webapp.NotFound(message="resource \"%s\" was not found." % href)

        st_type, r_type = st_type[:-1], r_type[:-1] # Remove trailing s.

        ws = get_workspace(ws_name)
        with webapp.mightNotFound(r_type, workspace=ws_name):
            try:
                model = ws.get_layermodel(r_type, st_name, r_name)
            except ValueError:
                raise KeyError(r_type)

        mf = mra.get_available()
        with webapp.mightConflict():
            mf.create_layer(model, l_name, l_enabled)

        # If we have a defaultStyle apply it.
        s_name = data.get("defaultStyle", {}).get("name")
        if s_name:
            with webapp.mightNotFound():
                style = mra.get_style(s_name)
                layer = mf.get_layer(l_name)
            layer.add_style_sld(mf, s_name, style)

            # Remove the automatic default style.
            for s_name in layer.iter_styles():
                if s_name == tools.get_dflt_sld_name(layer.ms.type):
                    layer.remove_style(s_name)

        mf.save()

        webapp.Created("%s/layers/%s.%s" % (web.ctx.home, l_name, format))
Exemple #16
0
    def PUT(self, map_name, ws_name, st_type, st_name, f_type, format):
        import zipfile

        mf, ws = get_mapfile_workspace(map_name, ws_name)

        # TODO: According to geoserv's examples we might have to handle
        # directories as well as files, in that case we want to upload
        # all the files from the directory.

        # Lets first try to get the file.
        if f_type == "file":
            # Check if zip or not...
            data = web.data()
        elif f_type == "url":
            raise NotImplemented()
        elif f_type == "external":
            raise NotImplemented()

        # Now we make sure the store exists.
        with webapp.mightNotFound(message="Store {exception} does not exist "
                                  "and automatic creation is not yet suported."):
            ws.get_store_info(st_type, st_name)
            # TODO: Create the store if it does not exist.

        # Then we store the file.
        ext = web.ctx.env.get('CONTENT_TYPE', '').split("/")[-1]
        path = tools.mk_st_data_path(ws_name, st_type, st_name, st_name + (".%s" % ext) if ext else "")
        with open(path, "w") as f:
            f.write(data)

        # We also unzip it if its ziped.
        ctype = web.ctx.env.get('CONTENT_TYPE', None)
        if ctype == "application/zip":
            z = zipfile.ZipFile(path)
            for f in z.namelist():
                fp = tools.mk_st_data_path(ws_name, st_type, st_name, f)

                # If the file has the correct target we might want it.
                if format and fp.endswith(format) and not tools.is_hidden(fp):
                    path = fp

                z.extract(f, path=tools.get_st_data_path(ws_name, st_type, st_name))

        # Set new connection parameters:
        ws.update_store(st_type, st_name, {"connectionParameters":{"url":"file:"+tools.no_res_root(path)}})
        ws.save()

        # Finally we might have to configure it.
        params = web.input(configure="none")
        if params.configure == "first":
            raise NotImplemented()
        elif params.configure == "none":
            pass
        elif params.configure == "all":
            raise NotImplemented()
        else:
            raise webapp.BadRequest(message="configure must be one of first, none or all.")
Exemple #17
0
    def DELETE(self, map_name, ws_name, cs_name, format):
        mf, ws = get_mapfile_workspace(map_name, ws_name)

        # We need to check if this datatore is empty.
        assert_is_empty(ws.iter_coverages(cs_name=cs_name), "coveragestore", ds_name)

        with webapp.mightNotFound("coverageStore", workspace=ws_name):
            ws.delete_coveragestore(cs_name)
        ws.save()
Exemple #18
0
    def DELETE(self, map_name, ws_name, ds_name, ft_name, format):
        mf, ws = get_mapfile_workspace(map_name, ws_name)

        # We need to check if there are any layers using this.
        assert_is_empty(mf.iter_layers(mra={"name":ft_name, "workspace":ws_name, "storage":ds_name, "type":"featuretype"}),"featuretype", ft_name)

        with webapp.mightNotFound("featureType", datastore=ds_name):
            ws.delete_featuretypemodel(ft_name, ds_name)
        ws.save()
Exemple #19
0
    def DELETE(self, map_name, ws_name, ds_name, format):
        mf, ws = get_mapfile_workspace(map_name, ws_name)

        # We need to check if this datatore is empty.
        assert_is_empty(ws.iter_featuretypemodels(ds_name=ds_name), "datastore", ds_name)

        with webapp.mightNotFound("dataStore", workspace=ws_name):
            ws.delete_datastore(ds_name)
        ws.save()
Exemple #20
0
    def PUT(self, map_name, ws_name, cs_name, format):
        mf, ws = get_mapfile_workspace(map_name, ws_name)

        data = get_data(name="coverageStore", mandatory=["name"], authorized=["name", "title", "abstract", "connectionParameters"])
        if cs_name != data.pop("name"):
            raise webapp.Forbidden("Can't change the name of a coverage store.")

        with webapp.mightNotFound("coverageStore", workspace=ws_name):
            ws.update_coveragestore(cs_name, data)
        ws.save()
Exemple #21
0
    def DELETE(self, map_name, ws_name, cs_name, c_name, format):
        mf, ws = get_mapfile_workspace(map_name, ws_name)

        # We need to check if there are any layers using this.
        assert_is_empty(mf.iter_layers(mra={"name":c_name, "workspace":ws_name, "storage":cs_name, "type":"coverage"}),
                        "coverage", ft_name)

        with webapp.mightNotFound("coverage", coveragestore=cs_name):
            ws.delete_coveragemodel(c_name, cs_name)
        ws.save()
Exemple #22
0
    def GET(self, map_name, s_name, format):
        mf = get_mapfile(map_name)

        if format == "sld":
            # We look for styles on disk and in the mapfiles.
            try:
                return open(tools.get_style_path(s_name)).read()
            except IOError, OSError:
                with webapp.mightNotFound("style", mapfile=map_name):
                    return mf.get_style_sld(s_name)
Exemple #23
0
    def GET(self, map_name, l_name, format):
        mf = get_mapfile(map_name)
        with webapp.mightNotFound("layer", mapfile=map_name):
            layer = mf.get_layer(l_name)

            return {"fields": [{
                    "name": layer.get_metadata("gml_%s_alias" % field, None),
                    "fieldType": layer.get_metadata("gml_%s_type" % field, None),
                    } for field in layer.iter_fields()]
                }
Exemple #24
0
    def POST(self, map_name, ws_name, ds_name, format):
        mf, ws = get_mapfile_workspace(map_name, ws_name)

        data = get_data(name="featureType", mandatory=["name"], authorized=["name", "title", "abstract"])
        with webapp.mightConflict("featureType", datastore=ds_name):
            with webapp.mightNotFound("featureType", datastore=ds_name):
                ws.create_featuretypemodel(data["name"], ds_name, data)
        ws.save()

        webapp.Created("%s/maps/%s/workspaces/%s/datastores/%s/featuretypes/%s%s" % (
                web.ctx.home, map_name, ws.name, ds_name, data["name"], (".%s" % format) if format else ""))
Exemple #25
0
    def DELETE(self, ws_name, cs_name, format):
        """Delete coverage store <cs>."""

        ws = get_workspace(ws_name)
        # TODO: check, this is not consistent between ds/cs.
        # We need to check if this datastore is empty.
        assert_is_empty(ws.iter_coveragemodels(cs_name=cs_name), "coveragestore", cs_name)

        with webapp.mightNotFound("coverageStore", workspace=ws_name):
            ws.delete_coveragestore(cs_name)
        ws.save()
Exemple #26
0
    def DELETE(self, ws_name, ds_name, format):
        """Delete data store <ds>."""

        ws = get_workspace(ws_name)

        # TODO: check, this is not consistent between ds/cs.
        # We need to check if this datastore is empty.
        assert_is_empty(ws.iter_featuretypemodels(ds_name=ds_name), "datastore", ds_name)

        with webapp.mightNotFound("dataStore", workspace=ws_name):
            ws.delete_datastore(ds_name)
        ws.save()
Exemple #27
0
    def PUT(self, map_name, ws_name, ds_name, ft_name, format):
        mf, ws = get_mapfile_workspace(map_name, ws_name)

        data = get_data(name="featureType", mandatory=["name"], authorized=["name", "title", "abstract"])
        if ft_name != data["name"]:
            raise webapp.Forbidden("Can't change the name of a feature type.")

        metadata = dict((k, v) for k, v in data.iteritems() if k in ["title", "abstract"])

        with webapp.mightNotFound("featureType", datastore=ds_name):
            ws.update_featuretypemodel(ft_name, ds_name, metadata)
        ws.save()
Exemple #28
0
    def DELETE(self, ws_name, cs_name, c_name, format):
        """Delete coverage <c>."""

        ws = get_workspace(ws_name)
        # We need to check if there are any layers using this.
        mf = mra.get_available()
        assert_is_empty(mf.iter_layers(mra={"name":c_name, "workspace":ws_name, "storage":cs_name,
                                            "type":"coverage"}), "coverage", c_name)

        with webapp.mightNotFound("coverage", coveragestore=cs_name):
            ws.delete_coveragemodel(c_name, cs_name)
        ws.save()
Exemple #29
0
    def DELETE(self, ws_name, ds_name, ft_name, format):
        """Delete feature type <ft>."""

        ws = get_workspace(ws_name)

        # We need to check if there are any layers using this.
        mf = mra.get_available()
        assert_is_empty(mf.iter_layers(mra={"name":ft_name, "workspace":ws_name, "storage":ds_name,
                                            "type":"featuretype"}),"featuretype", ft_name)

        with webapp.mightNotFound("featureType", datastore=ds_name):
            ws.delete_featuretypemodel(ds_name, ft_name)
        ws.save()
Exemple #30
0
    def PUT(self, ws_name, ds_name, format):
        """Modify data store <ds>."""

        ws = get_workspace(ws_name)

        data = get_data(name="dataStore", mandatory=["name"], authorized=["name", "title", "abstract", "connectionParameters"])

        if ds_name != data.pop("name"):
            raise webapp.Forbidden("Can't change the name of a data store.")

        with webapp.mightNotFound("dataStore", workspace=ws_name):
            ws.update_datastore(ds_name, data)
        ws.save()
Exemple #31
0
    def GET(self, map_name, l_name, format):
        mf = get_mapfile(map_name)
        with webapp.mightNotFound("layer", mapfile=map_name):
            layer = mf.get_layer(l_name)

        if format == "sld":
            return layer.getSLD()

        return {"styles": [{
                    "name": s_name,
                    "href": "%s/maps/%s/styles/%s.%s" % (web.ctx.home, map_name, s_name, format),
                    } for s_name in layer.iter_styles()],
                }
Exemple #32
0
    def PUT(self, ws_name, cs_name, format):
        """Modify coverage store <ds>."""
        
        ws = get_workspace(ws_name)
        data = get_data(name="coverageStore", 
                        mandatory=["name"], 
                        authorized=["name", "title", "abstract", "connectionParameters"])
        if cs_name != data.pop("name"):
            raise webapp.Forbidden("Can't change the name of a coverage store.")

        with webapp.mightNotFound("coverageStore", workspace=ws_name):
            ws.update_coveragestore(cs_name, data)
        ws.save()
Exemple #33
0
    def PUT(self, ws_name, ds_name, ft_name, format):
        """Modify feature type <ft>."""

        ws = get_workspace(ws_name)

        data = get_data(name="featureType", mandatory=["name"], authorized=["name", "title", "abstract"])
        if ft_name != data["name"]:
            raise webapp.Forbidden("Can't change the name of a feature type.")

        metadata = dict((k, v) for k, v in data.iteritems() if k in ["title", "abstract"])

        with webapp.mightNotFound("featureType", datastore=ds_name):
            ws.update_featuretypemodel(ds_name, ft_name, metadata)
        ws.save()
Exemple #34
0
    def GET(self, l_name, format):
        """Return layer <l>."""

        mf = mra.get_available()
        with webapp.mightNotFound():
            layer = mf.get_layer(l_name)

        data_type, store_type = {
            "featuretype": ("featuretype", "datastore"),
            "coverage": ("coverage", "coveragestore")
            }[layer.get_mra_metadata("type")]

        response = {"layer": {
                    "name": l_name,
                    "title": layer.get_metadata("ows_title", None),
                    "abstract": layer.get_metadata("ows_abstract", None),
                    "type": layer.get_type_name(),
                    "resource": { 
                        # TODO: Add attr class="featureType|coverage"
                        "name": layer.get_mra_metadata("name"),
                        "href": "%s/workspaces/%s/%ss/%s/%ss/%s.%s" % (
                            web.ctx.home, layer.get_mra_metadata("workspace"),
                            store_type, layer.get_mra_metadata("storage"), 
                            data_type, layer.get_mra_metadata("name"), format),
                        },
                    "enabled": bool(layer.ms.status), # TODO because it's fictitious...
                    # "attribution" => TODO?
                    # "path" => TODO?
                    }}

        # Check CLASSGROUP
        dflt_style = layer.ms.classgroup
        if dflt_style == None:
            # If is 'None': take the first style as would MapServer.
            for s_name in layer.iter_styles():
                dflt_style = s_name
                break
        if dflt_style == None:
            return response
       
        response["layer"].update({"defaultStyle": {"name": dflt_style,
                                            "href": "%s/styles/%s.%s" % (web.ctx.home, dflt_style, format)},})
      
        styles = [{"name": s_name,
                   "href": "%s/styles/%s.%s" % (web.ctx.home, s_name, format),
                   } for s_name in layer.iter_styles() if s_name != dflt_style]
        if not styles:
            return response

        return response["layer"].update({"styles": styles})
Exemple #35
0
    def PUT(self, ws_name, cs_name, c_name, format):
        """Modify coverage <c>."""
        
        ws = get_workspace(ws_name)

        data = get_data(name="coverage", mandatory=["name"], authorized=["name", "title", "abstract"])
        if c_name != data["name"]:
            raise webapp.Forbidden("Can't change the name of a coverage.")

        metadata = dict((k, v) for k, v in data.iteritems() if k in ["title", "abstract"])

        with webapp.mightNotFound("coverage", coveragestore=cs_name):
            ws.update_coveragemodel(c_name, cs_name, metadata)
        ws.save()
Exemple #36
0
    def GET(self, l_name, format):
        """Return all style from layer <l>."""

        mf = mra.get_available()
        with webapp.mightNotFound():
            layer = mf.get_layer(l_name)

        if format == "sld":
            return layer.getSLD()

        return {"styles": [{
                    "name": s_name,
                    "href": "%s/styles/%s.%s" % (web.ctx.home, s_name, format),
                    } for s_name in layer.iter_styles()],
                }
Exemple #37
0
    def GET(self, s_name, format):
        """Return style <s>."""

        with webapp.mightNotFound(message="Style \"%s\" does not exist." % s_name):
            style = mra.get_style(s_name)

        if format == "sld":
            return style

        return {"style": {
                    "name": s_name,
                    "sldVersion": Entries(["1.0.0"], tag_name="version"),
                    "filename": s_name + ".sld",
                    }
                }
Exemple #38
0
    def POST(self, format):
        """Create a new layer group."""

        mf = mra.get_available()

        data = get_data(name="layerGroup", mandatory=["name"], authorized=["name", "title", "abstract", "layers"])
        lg_name = data.pop("name")
        with webapp.mightNotFound():
            layers = [mf.get_layer(l_name) for l_name in data.pop("layers", [])]

        with webapp.mightConflict():
            lg = mf.create_layergroup(lg_name, data)
        lg.add(*layers)

        mf.save()

        webapp.Created("%s/layergroups/%s.%s" % (web.ctx.home, lg.name, format))
Exemple #39
0
    def POST(self, ws_name, cs_name, format):
        """Create a new coverage."""

        ws = get_workspace(ws_name)
        data = get_data(name="coverage", mandatory=["name"], authorized=["name", "title", "abstract"])
        with webapp.mightConflict("coverage", coveragestore=cs_name):
            with webapp.mightNotFound("coverage", coveragestore=cs_name):
                ws.create_coveragemodel(data["name"], cs_name, data)
        ws.save()

        # Then creates the associated layer by default:
        model = ws.get_coveragemodel(cs_name, data["name"])
        mf = mra.get_available()
        with webapp.mightConflict():
            mf.create_layer(model, data["name"], True)
        mf.save()

        webapp.Created("%s/workspaces/%s/coveragestores/%s/coverages/%s.%s" % (
                web.ctx.home, ws.name, cs_name, data["name"], format))
Exemple #40
0
    def PUT(self, lg_name, format):
        """Modify layergroup <lg>."""

        mf = mra.get_available()

        with webapp.mightNotFound():
            lg = mf.get_layergroup(lg_name)

        data = get_data(name="layerGroup", mandatory=["name"], authorized=["name", "title", "abstract", "layers"])
        if lg_name != data.pop("name"):
            raise webapp.Forbidden("Can't change the name of a layergroup.")

        layers = data.pop("layers", [])
        if not isinstance(layers, list) or any(not isinstance(x, basestring) for x in layers):
            raise webapp.BadRequest("layers must be a list of layer names.")

        lg.clear()
        lg.add(*layers)

        mf.save()
Exemple #41
0
    def GET(self, ws_name, ds_name, format):
        """Return data store <ds>."""

        ws = get_workspace(ws_name)

        with webapp.mightNotFound("dataStore", workspace=ws_name):
            info = ws.get_datastore_info(ds_name)
        connectionParameters = info.get("connectionParameters", {})

        return {"dataStore": {
                    "name": info["name"],
                    "enabled": True, # Always enabled
                                     # TODO: Handle enabled/disabled states
                    "workspace": {
                        "name": ws.name,
                        "href": "%s/workspaces/%s.%s" % (
                            web.ctx.home, ws.name, format),
                        },
                    "featureTypes": href("%s/workspaces/%s/datastores/%s/featuretypes.%s" % (
                                        web.ctx.home, ws.name, ds_name, format)
                        ),
                    "connectionParameters": Entries(connectionParameters, tag_name="entry"),
                    }
                }
Exemple #42
0
    def POST(self, ws_name, ds_name, format):
        """Create a new feature type. It create the associated layer by defaut.
        This layer is added in the mapfile: <layer.map>

        """
        ws = get_workspace(ws_name)
        data = get_data(name="featureType", mandatory=["name"],
                        authorized=["name", "title", "abstract"])

        # Creates first the feature type:
        with webapp.mightConflict("featureType", datastore=ds_name):
            with webapp.mightNotFound("featureType", datastore=ds_name):
                ws.create_featuretypemodel(ds_name, data["name"], data)
        ws.save()

        # Then creates the associated layer by default:
        model = ws.get_featuretypemodel(ds_name, data["name"])
        mf = mra.get_available()
        with webapp.mightConflict():
            mf.create_layer(model, data["name"], True)
        mf.save()

        webapp.Created("%s/workspaces/%s/datastores/%s/featuretypes/%s.%s" % (
                web.ctx.home, ws.name, ds_name, data["name"], format))
Exemple #43
0
    def GET(self, ws_name, ds_name, ft_name, format):
        """Return feature type <ft>."""

        ws = get_workspace(ws_name)

        ds = ws.get_datastore(ds_name)

        with webapp.mightNotFound("dataStore", datastore=ds_name):
            dsft = ds[ft_name]

        with webapp.mightNotFound("featureType", datastore=ds_name):
            ft = ws.get_featuretypemodel(ds_name, ft_name)

        extent = ft.get_extent()
        latlon_extent = ft.get_latlon_extent()


        # About attributs, we apply just values handled by 
        # MapServer in a GetFeature response...
        attributes = [{
            "name": f.get_name(),
            "type": f.get_type_name(),
            "length": f.get_width(),
            # "minOccurs": 0, "maxOccurs": 1, "nillable": f.is_nullable(),
            # binding?
            } for f in dsft.iterfields()]

        if dsft.get_geometry_column() is not None:
            attributes.append({
                "name": dsft.get_geometry_column(),
                "type": dsft.get_geomtype_gml(),
                "minOccurs": 0,
                "maxOccurs": 1, 
                # "nillable": True,
                # binding?
                })
        else:
            attributes.append({
                "name": "geometry",
                "type": dsft.get_geomtype_gml(),
                "minOccurs": 0,
                "maxOccurs": 1,
                # "nillable": True,
                # binding?
                })

        return {"featureType": ({
                    # Why the name would it be different from nativeName?
                    "name": ft.name,
                    "nativeName": ft.name,
                    "title": ft.get_mra_metadata("title", ft.name),
                    "abstract": ft.get_mra_metadata("abstract", None),
                    # TODO: keywords
                    "nativeCRS": ft.get_wkt(),
                    "attributes": attributes,
                    "nativeBoundingBox": {
                        "minx": extent.minX(),
                        "miny": extent.minY(),
                        "maxx": extent.maxX(),
                        "maxy": extent.maxY(),
                        "crs": "%s:%s" % (ft.get_authority_name(), ft.get_authority_code()),
                        },
                    "latLonBoundingBox": {
                        "minx": latlon_extent.minX(),
                        "miny": latlon_extent.minY(),
                        "maxx": latlon_extent.maxX(),
                        "maxy": latlon_extent.maxY(),
                        "crs": "EPSG:4326",
                        },
                    # "srs": "%s:%s" % (ft.get_authority()[0], ft.get_authority()[1]),
                    "projectionPolicy": "NONE",
                    # About srs & projectionPolicy: (TODO: Handle the other cases)
                    # In MRA, it is easier (or more logical?) to keep native CRS,
                    # Or there is a problem of understanding on our part.
                    # So, i prefer to comment 'srs' entry cause we force the
                    # value of 'projectionPolicy' to 'NONE'... but it is something 
                    # we should investigate...
                    "enabled": True, # Always enabled => TODO
                    "store": { # TODO: add key: class="dataStore"
                        "name": ds_name,
                        "href": "%s/workspaces/%s/datastores/%s.%s" % (
                            web.ctx.home, ws_name, ds_name, format)
                        },
                    # TODO: maxFeatures
                    })
                }
Exemple #44
0
def get_workspace(ws_name):
    with webapp.mightNotFound():
        return mra.get_workspace(ws_name)
Exemple #45
0
    def GET(self, ws_name, cs_name, c_name, format):
        """Return coverage <c>."""

        ws = get_workspace(ws_name)
        # with webapp.mightNotFound("coveragestore", workspace=ws_name):
        #     cs = ws.get_coveragestore(cs_name)
        with webapp.mightNotFound("coverage", coveragestore=cs_name):
            c = ws.get_coveragemodel(c_name, cs_name)

        extent = c.get_extent()
        latlon_extent = c.get_latlon_extent()

        return {"coverage": ({
                    "name": c.name,
                    "nativeName": c.name,
                    "title": c.get_mra_metadata("title", c.name),
                    "abstract": c.get_mra_metadata("abstract", None),
                    # TODO: Keywords
                    "nativeCRS": c.get_wkt(), # TODO: Add key class="projected" if projected...
                    "srs": "%s:%s" % (c.get_authority_name(), c.get_authority_code()),
                    "nativeBoundingBox": {
                        "minx": extent.minX(),
                        "miny": extent.minY(),
                        "maxx": extent.maxX(),
                        "maxy": extent.maxY(),
                        "crs": "%s:%s" % (c.get_authority_name(), c.get_authority_code()), # TODO: Add key class="projected" if projected...
                        },
                    "latLonBoundingBox":{
                        "minx": latlon_extent.minX(),
                        "miny": latlon_extent.minY(),
                        "maxx": latlon_extent.maxX(),
                        "maxy": latlon_extent.maxY(),
                        "crs": "EPSG:4326"
                        },
                    "enabled": True, # Always enabled => TODO
                    "store": { # TODO: Add attr class="coverageStore"
                        "name": cs_name,
                        "href": "%s/workspaces/%s/coveragestores/%s.%s" % (
                            web.ctx.home, ws_name, cs_name, format)
                        },
                    # TODO:
                    # "nativeFormat": None,
                    # "grid": {
                    #     "range": {
                    #         "low": None,
                    #         "high": None,
                    #         },
                    #     "transform": {
                    #         "scaleX": None,
                    #         "scaleY": None,
                    #         "shearX": None,
                    #         "shearY": None,
                    #         "translateX": None,
                    #         "translateY": None,
                    #         },
                    #     "crs": None,
                    #     },
                    # "supportedFormats": [],
                    # "interpolationMethods": [],
                    # "defaultInterpolationMethod": None,
                    # "dimensions": [],
                    # "projectionPolicy": None,
                    # "requestSRS": None,
                    # "responseSRS": None,
                    # "parameters": None,
                    })
                }
Exemple #46
0
    def PUT(self, ws_name, st_type, st_name, f_type, format):
        """Uploads a file from a local source. The body of the request is the file itself."""

        import zipfile

        # TODO: According to geoserv's examples we might have to handle
        # directories as well as files, in that case we want to upload
        # all the files from the directory.

        # Lets first try to get the file.
        if f_type == "file":
            # Check if zip or not...
            data = web.data()
        elif f_type == "url":
            raise webapp.NotImplemented()
        elif f_type == "external":
            raise webapp.NotImplemented()

        ws = get_workspace(ws_name)

        # Now we make sure the store exists.
        try:
            ws.get_store_info(st_type, st_name)
        except KeyError:
            # Create the store if it seems legit and it does not exist.
            if st_type == "datastores" or st_type == "coveragestores":
                st_type = st_type[:-1] # Remove trailing 's'
                with webapp.mightConflict("Workspace", workspace=ws_name):
                    ws.create_store(st_type, st_name, {})
            # Finaly check if its OK now.
            with webapp.mightNotFound(message="Store {exception} does not exist "
                                      "and it could not be created."):
                ws.get_store_info(st_type, st_name)

        # Then we store the file.
        ext = web.ctx.env.get('CONTENT_TYPE', '').split("/")[-1]
        path = mra.create_file(st_name + (".%s" % ext) if ext else "", data=data)
        dest = os.path.join(os.path.split(path)[0], st_name)

        # We also unzip it if its ziped.
        ctype = web.ctx.env.get('CONTENT_TYPE', None)
        if ctype == "application/zip":
            z = zipfile.ZipFile(path)
            for f in z.namelist():
                fp = mra.mk_path(mra.get_file_path(st_name, f))

                # If the file has the correct target we might want it.
                if format and fp.endswith(format) and not tools.is_hidden(fp):
                    path = fp

                z.extract(f, path=dest)

        # Set new connection parameters:
        ws.update_store(st_type, st_name, {"connectionParameters":{"url":"file:"+mra.pub_file_path(path)}})
        ws.save()

        # Finally we might have to configure it.
        params = web.input(configure="none")
        if params.configure == "first":
            raise webapp.NotImplemented()
        elif params.configure == "none":
            pass
        elif params.configure == "all":
            raise webapp.NotImplemented()
        else:
            raise webapp.BadRequest(message="configure must be one of 'first', 'none' or 'all'.")