class DataStore(ResourceInfo): resource_type = "dataStore" save_method = "PUT" def __init__(self, catalog, workspace, name): super(DataStore, self).__init__() assert isinstance(workspace, ws.Workspace) assert isinstance(name, str) self.catalog = catalog self.workspace = workspace self.name = name @property def href(self): return url(self.catalog.service_url, [ "workspaces", self.workspace.name, "datastores", self.name + ".xml" ]) enabled = xml_property("enabled", lambda x: x.text == "true") name = xml_property("name") type = xml_property("type") connection_parameters = xml_property("connectionParameters", key_value_pairs) writers = dict(enabled=write_bool("enabled"), name=write_string("name"), type=write_string("type"), connectionParameters=write_dict("connectionParameters")) @property def resource_url(self): return url(self.catalog.service_url, [ "workspaces", self.workspace.name, "datastores", self.name, "featuretypes.xml" ]) def get_resources(self, name=None, available=False): res_url = self.resource_url if available: res_url += "?list=available" xml = self.catalog.get_xml(res_url) def ft_from_node(node): return featuretype_from_index(self.catalog, self.workspace, self, node) # if name passed, return only one FeatureType, otherwise return all FeatureTypes in store: if name is not None: for node in xml.findall("featureType"): if node.findtext("name") == name: return ft_from_node(node) return None if available: return [str(node.text) for node in xml.findall("featureTypeName")] else: return [ft_from_node(node) for node in xml.findall("featureType")]
class CoverageStore(ResourceInfo): resource_type = 'coverageStore' save_method = "PUT" def __init__(self, catalog, workspace, name): super(CoverageStore, self).__init__() assert isinstance(workspace, ws.Workspace) assert isinstance(name, str) self.catalog = catalog self.workspace = workspace self.name = name @property def href(self): return url(self.catalog.service_url, [ "workspaces", self.workspace.name, "coveragestores", self.name + ".xml" ]) enabled = xml_property("enabled", lambda x: x.text == "true") name = xml_property("name") url = xml_property("url") type = xml_property("type") writers = dict(enabled=write_bool("enabled"), name=write_string("name"), url=write_string("url"), type=write_string("type"), workspace=write_string("workspace")) def get_resources(self, name=None): res_url = url(self.catalog.service_url, [ "workspaces", self.workspace.name, "coveragestores", self.name, "coverages.xml" ]) xml = self.catalog.get_xml(res_url) def cov_from_node(node): return coverage_from_index(self.catalog, self.workspace, self, node) # if name passed, return only one Coverage, otherwise return all Coverages in store: if name is not None: for node in xml.findall("coverage"): if node.findtext("name") == name: return cov_from_node(node) return None return [cov_from_node(node) for node in xml.findall("coverage")]
class Workspace(ResourceInfo): resource_type = "workspace" def __init__(self, catalog, name): super(Workspace, self).__init__() self.catalog = catalog self.name = name @property def href(self): return url(self.catalog.service_url, ["workspaces", self.name + ".xml"]) @property def coveragestore_url(self): return url(self.catalog.service_url, ["workspaces", self.name, "coveragestores.xml"]) @property def datastore_url(self): return url(self.catalog.service_url, ["workspaces", self.name, "datastores.xml"]) @property def wmsstore_url(self): return "%s/workspaces/%s/wmsstores.xml" % (self.catalog.service_url, self.name) enabled = xml_property("enabled", lambda x: x.lower() == 'true') writers = dict(enabled=write_bool("enabled")) def __repr__(self): return "%s @ %s" % (self.name, self.href)
class WmsStore(ResourceInfo): resource_type = "wmsStore" save_method = "PUT" def __init__(self, catalog, workspace, name, user, password): super(WmsStore, self).__init__() assert isinstance(workspace, ws.Workspace) assert isinstance(name, str) self.catalog = catalog self.workspace = workspace self.name = name self.metadata = {} self.metadata['user'] = user self.metadata['password'] = password @property def href(self): return "%s/workspaces/%s/wmsstores/%s.xml" % ( self.catalog.service_url, self.workspace.name, self.name) enabled = xml_property("enabled", lambda x: x.text == "true") name = xml_property("name") nativeName = xml_property("nativeName") capabilitiesURL = xml_property("capabilitiesURL") type = xml_property("type") metadata = xml_property("metadata", key_value_pairs) writers = dict(enabled=write_bool("enabled"), name=write_string("name"), capabilitiesURL=write_string("capabilitiesURL"), type=write_string("type"), metadata=write_dict("metadata")) def get_resources(self, name=None, available=False): res_url = "%s/workspaces/%s/wmsstores/%s/wmslayers.xml" % ( self.catalog.service_url, self.workspace.name, self.name) layer_name_attr = "wmsLayer" if available: res_url += "?list=available" layer_name_attr += 'Name' xml = self.catalog.get_xml(res_url) def wl_from_node(node): return wmslayer_from_index(self.catalog, self.workspace, self, node) # if name passed, return only one layer, otherwise return all layers in store: if name is not None: for node in xml.findall(layer_name_attr): if node.findtext("name") == name: return wl_from_node(node) return None if available: return [str(node.text) for node in xml.findall(layer_name_attr)] else: return [ wl_from_node(node) for node in xml.findall(layer_name_attr) ]
class LayerGroup(ResourceInfo): """ Represents a layer group in geoserver """ resource_type = "layerGroup" save_method = "PUT" def __init__(self, catalog, name, workspace=None): super(LayerGroup, self).__init__() assert isinstance(name, str) self.catalog = catalog self.name = name self.workspace = workspace # the XML format changed in 2.3.x - the element listing all the layers # and the entries themselves have changed if self.catalog.gsversion() == "2.2.x": parent, element, attributes = "layers", "layer", None else: parent, element, attributes = "publishables", "published", { 'type': 'layer' } self._layer_parent = parent self._layer_element = element self._layer_attributes = attributes self.writers = dict(name=write_string("name"), styles=_write_styles, layers=lambda b, l: _write_layers( b, l, parent, element, attributes), bounds=write_bbox("bounds"), workspace=write_string("workspace")) @property def href(self): path_parts = ["layergroups", self.name + ".xml"] if self.workspace is not None: workspace_name = getattr(self.workspace, 'name', self.workspace) path_parts = ["workspaces", workspace_name] + path_parts return url(self.catalog.service_url, path_parts) styles = xml_property("styles", _style_list) bounds = xml_property("bounds", bbox) def _layers_getter(self): if "layers" in self.dirty: return self.dirty["layers"] else: if self.dom is None: self.fetch() node = self.dom.find(self._layer_parent) return _layer_list( node, self._layer_element) if node is not None else None def _layers_setter(self, value): self.dirty["layers"] = value def _layers_delete(self): self.dirty["layers"] = None layers = property(_layers_getter, _layers_setter, _layers_delete) def __str__(self): return "<LayerGroup %s>" % self.name __repr__ = __str__
class WmsLayer(ResourceInfo): resource_type = "wmsLayer" save_method = "PUT" def __init__(self, catalog, workspace, store, name): super(WmsLayer, self).__init__() self.catalog = catalog self.workspace = workspace self.store = store self.name = name @property def href(self): return "%s/workspaces/%s/wmsstores/%s/wmslayers/%s.xml" % ( self.catalog.service_url, self.workspace.name, self.store.name, self.name ) title = xml_property("title") description = xml_property("description") abstract = xml_property("abstract") keywords = xml_property("keywords", string_list) # nativeCRS projection = xml_property("srs") native_bbox = xml_property("nativeBoundingBox", bbox) latlon_bbox = xml_property("latLonBoundingBox", bbox) projection_policy = xml_property("projectionPolicy") enabled = xml_property("enabled", lambda x: x.text == "true") advertised = xml_property("advertised", lambda x: x.text == "true", default=True) metadata_links = xml_property("metadataLinks", metadata_link_list) writers = dict( title=write_string("title"), description=write_string("description"), abstract=write_string("abstract"), keywords=write_string_list("keywords"), # nativeCRS srs=write_string("srs"), nativeBoundingBox=write_bbox("nativeBoundingBox"), latLonBoundingBox=write_bbox("latLonBoundingBox"), projectionPolicy=write_string("projectionPolicy"), enabled=write_bool("enabled"), advertised=write_bool("advertised"), metadataLinks=write_metadata_link_list("metadataLinks") )
class Coverage(_ResourceBase): resource_type = "coverage" url_part_stores = 'coveragestores' url_part_types = 'coverages' title = xml_property("title") abstract = xml_property("abstract") enabled = xml_property("enabled") advertised = xml_property("advertised", default="true") native_bbox = xml_property("nativeBoundingBox", bbox) latlon_bbox = xml_property("latLonBoundingBox", bbox) projection = xml_property("srs") projection_policy = xml_property("projectionPolicy") keywords = xml_property("keywords", string_list) request_srs_list = xml_property("requestSRS", string_list) response_srs_list = xml_property("responseSRS", string_list) supported_formats = xml_property("supportedFormats", string_list) metadata_links = xml_property("metadataLinks", metadata_link_list) metadata = xml_property("metadata", metadata) writers = dict( title=write_string("title"), abstract=write_string("abstract"), enabled=write_bool("enabled"), advertised=write_bool("advertised"), nativeBoundingBox=write_bbox("nativeBoundingBox"), latLonBoundingBox=write_bbox("latLonBoundingBox"), srs=write_string("srs"), projection_policy=write_string("projectionPolicy"), keywords=write_string_list("keywords"), metadataLinks=write_metadata_link_list("metadataLinks"), requestSRS=write_string_list("requestSRS"), responseSRS=write_string_list("responseSRS"), supportedFormats=write_string_list("supportedFormats"), metadata=write_metadata("metadata") )
class FeatureType(_ResourceBase): resource_type = "featureType" url_part_stores = 'datastores' url_part_types = 'featuretypes' title = xml_property("title") native_name = xml_property("nativeName") abstract = xml_property("abstract") enabled = xml_property("enabled") advertised = xml_property("advertised", default="true") native_bbox = xml_property("nativeBoundingBox", bbox) latlon_bbox = xml_property("latLonBoundingBox", bbox) projection = xml_property("srs") projection_policy = xml_property("projectionPolicy") keywords = xml_property("keywords", string_list) attributes = xml_property("attributes", attribute_list) metadata_links = xml_property("metadataLinks", metadata_link_list) metadata = xml_property("metadata", metadata) writers = dict( name=write_string("name"), nativeName=write_string("nativeName"), title=write_string("title"), abstract=write_string("abstract"), enabled=write_bool("enabled"), advertised=write_bool("advertised"), nativeBoundingBox=write_bbox("nativeBoundingBox"), latLonBoundingBox=write_bbox("latLonBoundingBox"), srs=write_string("srs"), nativeCRS=write_string("nativeCRS"), projectionPolicy=write_string("projectionPolicy"), keywords=write_string_list("keywords"), metadataLinks=write_metadata_link_list("metadataLinks"), metadata=write_metadata("metadata") )
class Style(ResourceInfo): supported_formats = ["sld10", "sld11", "zip"] content_types = { "sld10": "application/vnd.ogc.sld+xml", "sld11": "application/vnd.ogc.se+xml", "zip": "application/zip" } def __init__(self, catalog, name, workspace=None, style_format="sld10"): super(Style, self).__init__() assert isinstance(name, str) assert style_format in Style.supported_formats self.catalog = catalog self.workspace = workspace self.name = name self.style_format = style_format self._sld_dom = None @property def fqn(self): return self.name if not self.workspace else '%s:%s' % (self.workspace, self.name) @property def href(self): return self._build_href('.xml') @property def body_href(self): return self._build_href('.sld') @property def create_href(self): return self._build_href('.xml', True) @property def content_type(self): return Style.content_types[self.style_format] def _build_href(self, extension, create=False): path_parts = ["styles"] query = {} if not create: path_parts.append(self.name + extension) else: query['name'] = self.name if self.workspace is not None: path_parts = ["workspaces", getattr(self.workspace, 'name', self.workspace)] + path_parts return url(self.catalog.service_url, path_parts, query) filename = xml_property("filename") def _get_sld_dom(self): if self._sld_dom is None: self._sld_dom = self.catalog.get_xml(self.body_href) return self._sld_dom @property def sld_title(self): user_style = self._get_sld_dom().find( "{http://www.opengis.net/sld}NamedLayer/{http://www.opengis.net/sld}UserStyle") if not user_style: user_style = self._get_sld_dom().find( "{http://www.opengis.net/sld}UserLayer/{http://www.opengis.net/sld}UserStyle") title_node = None if user_style: try: # it is not mandatory title_node = user_style.find("{http://www.opengis.net/sld}Title") except: title_node = None return title_node.text if title_node is not None else None @property def sld_name(self): user_style = self._get_sld_dom().find( "{http://www.opengis.net/sld}NamedLayer/{http://www.opengis.net/sld}UserStyle") if not user_style: user_style = self._get_sld_dom().find( "{http://www.opengis.net/sld}UserLayer/{http://www.opengis.net/sld}UserStyle") name_node = None if user_style: try: # it is not mandatory name_node = user_style.find("{http://www.opengis.net/sld}Name") except: name_node = None return name_node.text if name_node is not None else None @property def sld_body(self): content = self.catalog.http.request(self.body_href)[1] return content def update_body(self, body): headers = {"Content-Type": self.content_type} self.catalog.http.request( self.body_href, "PUT", body, headers)
class Layer(ResourceInfo): def __init__(self, catalog, name): super(Layer, self).__init__() self.catalog = catalog self.name = name resource_type = "layer" save_method = "PUT" @property def href(self): return url(self.catalog.service_url, ["layers", self.name + ".xml"]) @property def resource(self): if self.dom is None: self.fetch() name = self.dom.find("resource/name").text return self.catalog.get_resource(name) def _get_default_style(self): if 'default_style' in self.dirty: return self.dirty['default_style'] if self.dom is None: self.fetch() element = self.dom.find("defaultStyle") # aborted data uploads can result in no default style return self._resolve_style(element) if element is not None else None def _resolve_style(self, element): name_section = element.find('name') if name_section is not None: return self.catalog.get_style(name_section.text) else: return None def _set_default_style(self, style): if isinstance(style, Style): style = style.fqn self.dirty["default_style"] = style def _get_alternate_styles(self): if "alternate_styles" in self.dirty: return self.dirty["alternate_styles"] if self.dom is None: self.fetch() styles_list = self.dom.findall("styles/style") return [ _f for _f in [self._resolve_style(s) for s in styles_list] if _f ] def _set_alternate_styles(self, styles): self.dirty["alternate_styles"] = styles default_style = property(_get_default_style, _set_default_style) styles = property(_get_alternate_styles, _set_alternate_styles) attribution_object = xml_property("attribution", _read_attribution) enabled = xml_property("enabled", lambda x: x.text == "true") advertised = xml_property("advertised", lambda x: x.text == "true", default=True) def _get_attr_attribution(self): return { 'title': self.attribution_object.title, 'width': self.attribution_object.width, 'height': self.attribution_object.height, 'href': self.attribution_object.href, 'url': self.attribution_object.url, 'type': self.attribution_object.type } def _set_attr_attribution(self, attribution): self.dirty["attribution"] = _attribution( attribution['title'], attribution['width'], attribution['height'], attribution['href'], attribution['url'], attribution['type']) assert self.attribution_object.title == attribution['title'] assert self.attribution_object.width == attribution['width'] assert self.attribution_object.height == attribution['height'] assert self.attribution_object.href == attribution['href'] assert self.attribution_object.url == attribution['url'] assert self.attribution_object.type == attribution['type'] attribution = property(_get_attr_attribution, _set_attr_attribution) writers = dict(attribution=_write_attribution, enabled=write_bool("enabled"), advertised=write_bool("advertised"), default_style=_write_default_style, alternate_styles=_write_alternate_styles)