Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • misc/mra
1 result
Show changes
Commits on Source (2)
web.py>=0.50,<0.60
web.py>=0.60,<0.70
gdal<2.5.0
pyyaml<5.4
......@@ -24,9 +24,7 @@
import os.path
from setuptools import setup
version = '1.1.8'
from src import __version__
def parse_requirements(filename):
......@@ -42,7 +40,7 @@ reqs = [str(req) for req in parse_requirements(reqs_filename)]
setup(
name="MapServer Rest API",
version=version,
version=__version__,
description="A RESTFul interface for MapServer",
author="Neogeo Technologies",
author_email="contact@neogeo.fr",
......
......@@ -20,3 +20,6 @@
# GNU General Public License for more details. #
# #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
__version__ = '1.1.9'
......@@ -96,7 +96,7 @@ OUTPUTFORMAT = {
imagemode=mapscript.MS_IMAGEMODE_FEATURE,
transparent=mapscript.MS_OFF,
options={"FORM": "SIMPLE", "STORAGE": "stream"})
},
},
'WMS': {
'PNG8': outputformat(
"AGG/PNG8", "png8", mimetype="image/png; mode=8bit",
......@@ -109,8 +109,8 @@ OUTPUTFORMAT = {
"AGG/JPEG", "jpeg", mimetype="image/jpeg",
imagemode=mapscript.MS_IMAGEMODE_RGB,
extension="jpg", options={"GAMMA": "0.75"})
}
}
}
class MetadataMixin(object):
......@@ -134,7 +134,8 @@ class Layer(MetadataMixin):
self.ms = backend
def enable(self, enabled=True):
wms = ("GetCapabilities", "GetMap", "GetFeatureInfo", "GetLegendGraphic", "DescribeLayer", "GetStyles")
wms = ("GetCapabilities", "GetMap", "GetFeatureInfo",
"GetLegendGraphic", "DescribeLayer", "GetStyles")
wcs = ("GetCapabilities", "GetCoverage", "DescribeCoverage")
wfs = ("GetCapabilities", "GetFeature", "DescribeFeatureType")
......@@ -147,11 +148,14 @@ class Layer(MetadataMixin):
self.set_metadata("wfs_enable_request", " ".join(wfs))
else:
self.ms.status = mapscript.MS_OFF
self.set_metadata("wms_enable_request", " ".join(["!%s" % m for m in wms]))
self.set_metadata("wms_enable_request",
" ".join(["!%s" % m for m in wms]))
if self.ms.type == 3:
self.set_metadata("wcs_enable_request", " ".join(["!%s" % m for m in wcs]))
self.set_metadata("wcs_enable_request",
" ".join(["!%s" % m for m in wcs]))
else:
self.set_metadata("wfs_enable_request", " ".join(["!%s" % m for m in wfs]))
self.set_metadata("wfs_enable_request",
" ".join(["!%s" % m for m in wfs]))
def get_type_name(self):
return {
......@@ -160,7 +164,7 @@ class Layer(MetadataMixin):
2: "POLYGON",
3: "RASTER",
4: "ANNOTATION",
}[self.ms.type]
}[self.ms.type]
def get_proj4(self):
return self.ms.getProjection()
......@@ -232,7 +236,8 @@ class Layer(MetadataMixin):
xmlsld.firstChild.getElementsByTagNameNS("*", "NamedLayer")[0]\
.getElementsByTagNameNS("*", "Name")[0].firstChild.data = sld_layer_name
except Exception as e:
logging.error("mra.py::Layer::add_style_sld: Bad sld (No NamedLayer/Name): %s", e)
logging.error(
"mra.py::Layer::add_style_sld: Bad sld (No NamedLayer/Name): %s", e)
raise ValueError("Bad sld (No NamedLayer/Name)")
new_sld = xmlsld.toxml()
......@@ -245,7 +250,8 @@ class Layer(MetadataMixin):
try:
ms_template_layer.applySLD(new_sld, sld_layer_name)
except Exception as e:
logging.error("mra.py::Layer::add_style_sld: Unable to access storage : %s", e)
logging.error(
"mra.py::Layer::add_style_sld: Unable to access storage : %s", e)
raise ValueError("Unable to access storage.")
for i in range(ms_template_layer.numclasses):
......@@ -270,9 +276,11 @@ class Layer(MetadataMixin):
return None
try:
style = open(os.path.join(os.path.dirname(__file__), "%s.sld" % s_name), encoding="utf-8").read()
style = open(os.path.join(os.path.dirname(__file__),
"%s.sld" % s_name), encoding="utf-8").read()
except IOError as OSError:
logging.warning("mra.py::Layer::set_default_style IOError %s", OSError)
logging.warning(
"mra.py::Layer::set_default_style IOError %s", OSError)
return
self.add_style_sld(mf, s_name, style)
......@@ -379,7 +387,8 @@ class Mapfile(MetadataMixin):
self.set_metadata("%s_enable_request" % ows, "*")
if 'onlineresource' in config:
onlineresource = urljoin(config.get('onlineresource'), self.ms.name)
onlineresource = urljoin(config.get(
'onlineresource'), self.ms.name)
self.set_metadata('ows_onlineresource', onlineresource)
fontset and self.ms.setFontSet(fontset)
......@@ -443,7 +452,7 @@ class Mapfile(MetadataMixin):
# Add metadata.
metadata = {
"wms_srs": self.get_metadata("ows_srs"),
}
}
metadata.update(l_metadata)
layer.update_metadatas(metadata)
......@@ -534,8 +543,10 @@ class FeatureTypeModel(LayerModel):
cparam = info["connectionParameters"]
if cparam.get("dbtype", None) in ["postgis", "postgres", "postgresql"]:
self.ms.connectiontype = mapscript.MS_POSTGIS
connection = "dbname=%s port=%s host=%s " % (cparam.get("database", "postgres"), cparam.get("port", "5432"), cparam.get("host", "localhost"))
connection += " ".join("%s=%s" % (p, cparam[p]) for p in ["user", "password"] if p in cparam)
connection = "dbname=%s port=%s host=%s " % (cparam.get(
"database", "postgres"), cparam.get("port", "5432"), cparam.get("host", "localhost"))
connection += " ".join("%s=%s" % (p, cparam[p])
for p in ["user", "password"] if p in cparam)
self.ms.connection = connection
self.ms.data = '%s FROM %s.%s' % (
ds[ft_name].get_geometry_column(),
......@@ -554,7 +565,8 @@ class FeatureTypeModel(LayerModel):
# Update mra metadata, and make sure the mandatory ones are left untouched.
self.update_mra_metadatas(metadata)
self.update_mra_metadatas({"name": ft_name, "type": "featuretype", "storage": ds_name})
self.update_mra_metadatas(
{"name": ft_name, "type": "featuretype", "storage": ds_name})
def configure_layer(self, layer, enabled=True):
ws = self.ws
......@@ -578,7 +590,7 @@ class FeatureTypeModel(LayerModel):
"type": self.get_mra_metadata("type"),
"storage": self.get_mra_metadata("storage"),
"workspace": ws.name,
})
})
layer.enable(enabled)
......@@ -596,7 +608,7 @@ class FeatureTypeModel(LayerModel):
"gml_%s_type" % field_name: field.get_type_gml(),
# "gml_%s_precision" % field_name
# "gml_%s_width" % field_name
})
})
geometry_column = ft.get_geometry_column()
if geometry_column is None:
......@@ -611,7 +623,7 @@ class FeatureTypeModel(LayerModel):
self.ms.extent.miny,
self.ms.extent.maxx,
self.ms.extent.maxy,
),
),
"ows_include_items": ",".join(field_names),
"gml_include_items": ",".join(field_names),
"gml_geometries": geometry_column,
......@@ -619,13 +631,13 @@ class FeatureTypeModel(LayerModel):
# TODO: Add gml_<geometry name>_occurances,
"wfs_srs": ws.get_metadata("ows_srs"),
"wfs_getfeature_formatlist": ",".join(list(OUTPUTFORMAT["WFS"].keys()))
})
})
if ft.get_fid_column() is not None:
layer.set_metadatas({
"wfs_featureid": ft.get_fid_column(),
"gml_featureid": ft.get_fid_column(),
})
})
plugins.extend("post_configure_vector_layer", self, ws, ds, ft, layer)
......@@ -645,7 +657,8 @@ class CoverageModel(LayerModel):
try:
crs = metadata.pop("crs")
proj4 = "+init=%s:%s" % (crs["authority_name"], crs["authority_code"])
proj4 = "+init=%s:%s" % (crs["authority_name"],
crs["authority_code"])
except Exception as e:
logging.warn('mra.py::MRA::CoverageModel.update error %s', e)
proj4 = cs.get_proj4()
......@@ -672,12 +685,12 @@ class CoverageModel(LayerModel):
url = urlparse(cparam["url"])
filename = self.ws.mra.get_file_path(url.path)
if cs.tindex is None:
#if cparam["dbtype"] in ["tif", "tiff"]:
# if cparam["dbtype"] in ["tif", "tiff"]:
self.ms.data = filename
self.ms.tileindex = None
self.ms.tileitem = None
# TODO: strip extention.
#else:
# else:
# raise ValueError("Unhandled type \"%s\"." % cparam["dbtype"])
else:
self.ms.data = None
......@@ -719,7 +732,7 @@ class CoverageModel(LayerModel):
"type": self.get_mra_metadata("type"),
"storage": self.get_mra_metadata("storage"),
"workspace": ws.name,
})
})
layer.set_metadatas({
"ows_name": layer_name,
......@@ -730,11 +743,11 @@ class CoverageModel(LayerModel):
self.ms.extent.miny,
self.ms.extent.maxx,
self.ms.extent.maxy,
),
),
"wcs_name": layer.get_metadata("wcs_name", None) or layer_name,
"wcs_label": layer.get_metadata("wcs_label", None) or layer_name,
"wcs_description": layer.get_metadata("wcs_description", None) or layer_name
})
})
layer.enable(enabled)
......@@ -843,7 +856,8 @@ class Workspace(Mapfile):
except (StopIteration, SystemError):
pass # No layers use our store, all OK.
else:
raise ValueError("The datastore \"%s\" can't be delete because it is used." % name)
raise ValueError(
"The datastore \"%s\" can't be delete because it is used." % name)
return self.delete_store("datastore", name)
# Coveragestores (this is c/p from datastores):
......@@ -886,7 +900,8 @@ class Workspace(Mapfile):
except (StopIteration, SystemError):
pass # No layers use our store, all OK.
else:
raise ValueError("The coveragestore \"%s\" can't be delete because it is used." % name)
raise ValueError(
"The coveragestore \"%s\" can't be delete because it is used." % name)
return self.delete_store("coveragestore", name)
# LayerModels:
......@@ -945,7 +960,8 @@ class Workspace(Mapfile):
def delete_layermodel(self, st_type, ds_name, ft_name):
lm = self.get_layermodel(st_type, ds_name, ft_name)
if lm.get_mra_metadata("layers", []):
raise ValueError("The %s \"%s\" can't be delete because it is used." % (st_type, ft_name))
raise ValueError(
"The %s \"%s\" can't be delete because it is used." % (st_type, ft_name))
self.ms.removeLayer(lm.ms.index)
# Featuretypes
......@@ -998,7 +1014,7 @@ class MRA(object):
self.config = yaml.load(
open(config_path, "r"),
# Loader=yaml.FullLoader
)
)
except yaml.YAMLError as e:
exit("Error in configuration file: %s" % e)
......@@ -1025,7 +1041,8 @@ class MRA(object):
return os.path.relpath(path, self.get_path())
def get_resource_path(self, *args):
root = self.config["storage"].get("resources", self.get_path("resources"))
root = self.config["storage"].get(
"resources", self.get_path("resources"))
return self.get_path(root, *args)
def pub_resource_path(self, path):
......@@ -1052,7 +1069,8 @@ class MRA(object):
fontset.close
def get_font_path(self, *args):
root = self.config["storage"].get("fonts", self.get_resource_path("fonts"))
root = self.config["storage"].get(
"fonts", self.get_resource_path("fonts"))
return self.get_resource_path(root, *args)
def create_font(self, name, data=None):
......@@ -1074,7 +1092,8 @@ class MRA(object):
# Styles:
def get_style_path(self, *args):
root = self.config["storage"].get("styles", self.get_resource_path("styles"))
root = self.config["storage"].get(
"styles", self.get_resource_path("styles"))
return self.get_resource_path(root, *args)
def pub_style_path(self, path):
......@@ -1118,7 +1137,8 @@ class MRA(object):
# Files:
def get_file_path(self, *args):
root = self.config["storage"].get("data", self.get_resource_path("data"))
root = self.config["storage"].get(
"data", self.get_resource_path("data"))
return self.get_resource_path(root, *args)
def pub_file_path(self, path):
......@@ -1134,7 +1154,8 @@ class MRA(object):
# Available (get):
def get_available_path(self, *args):
root = self.config["storage"].get("available", self.get_path("available"))
root = self.config["storage"].get(
"available", self.get_path("available"))
return self.get_path(root, *args)
def pub_available_path(self, path):
......@@ -1169,12 +1190,14 @@ class MRA(object):
def delete_workspace(self, name):
# path = self.get_available_path("%s.ws.map" % name)
raise NotImplementedError("Method 'delete_workspace' is not yet available. (TODO)")
raise NotImplementedError(
"Method 'delete_workspace' is not yet available. (TODO)")
# Services:
def get_service_path(self, *args):
root = self.config["storage"].get("services", self.get_path("services"))
root = self.config["storage"].get(
"services", self.get_path("services"))
return self.get_path(root, *args)
def pub_service_path(self, path):
......@@ -1210,9 +1233,11 @@ class MRA(object):
cparam = info["connectionParameters"]
if cparam.get("dbtype", "") == "postgis":
# First mandatory
url = "PG:dbname=%s port=%s host=%s " % (cparam["database"], cparam["port"], cparam["host"])
url = "PG:dbname=%s port=%s host=%s " % (
cparam["database"], cparam["port"], cparam["host"])
# Then optionals:
url += " ".join("%s=%s" % (p, cparam[p]) for p in ["user", "password"] if p in cparam)
url += " ".join("%s=%s" % (p, cparam[p])
for p in ["user", "password"] if p in cparam)
return url
elif "url" in cparam:
url = urlparse(cparam["url"])
......@@ -1220,4 +1245,5 @@ class MRA(object):
raise ValueError("Only local files are suported.")
return self.get_file_path(url.path)
else:
raise ValueError("Unhandled type \"%s\"." % cparam.get("dbtype", "<unknown>"))
raise ValueError("Unhandled type \"%s\"." %
cparam.get("dbtype", "<unknown>"))
......@@ -44,6 +44,7 @@ import webapp
from webapp import get_data
from webapp import HTTPCompatible
from webapp import urlmap
from src import __version__
# Some helper functions first.
......@@ -64,6 +65,7 @@ class index(object):
@HTTPCompatible(authorized=["html"])
def GET(self, format):
return {
"version": href("version"),
"about/version": href("about/version"),
"workspaces": href("workspaces"),
"styles": href("styles"),
......@@ -76,6 +78,15 @@ class index(object):
}
class app_version(object):
"""To know about application version
"""
@HTTPCompatible()
def GET(self, format):
return {"mra": __version__}
class version(object):
"""To know about used versions...
......@@ -1661,6 +1672,8 @@ class OWSWorkspaceSettings(object):
# Index:
urlmap(index, "")
# App Version:
urlmap(app_version, "version")
# About version:
urlmap(version, "about", "version")
# Workspaces:
......