def create_style(self, name, sld, overwrite=False): style = self.get_style(name) if not overwrite: if style is not None: raise ConflictingDataError( "There is already a style named %s" % name) headers = { "Content-type": "application/vnd.ogc.sld+xml", "Accept": "application/xml" } if overwrite and style is not None: style_url = url(self.service_url, ["styles", name + ".sld"]) headers, response = self.http.request(style_url, "PUT", sld, headers) if headers.status < 200 or headers.status > 299: raise UploadError(response) else: style_url = url(self.service_url, ["styles"], dict(name=name)) headers, response = self.http.request(style_url, "POST", sld, headers) self._cache.clear() if headers.status < 200 or headers.status > 299: raise UploadError(response)
def create_style(self, name, sld, overwrite = False): style = self.get_style(name) if not overwrite: if style is not None: raise ConflictingDataError("There is already a style named %s" % name) if not overwrite or style is None: headers = { "Content-type": "application/xml", "Accept": "application/xml" } xml = "<style><name>{0}</name><filename>{0}.sld</filename></style>".format(name) style_url = url(self.service_url, ["styles"], dict(name=name)) headers, response = self.http.request(style_url, "POST", xml, headers) if headers.status < 200 or headers.status > 299: raise UploadError(response) headers = { "Content-type": "application/vnd.ogc.sld+xml", "Accept": "application/xml" } style_url = url(self.service_url, ["styles", name + ".sld"]) headers, response = self.http.request(style_url, "PUT", sld, headers) self._cache.clear() if headers.status < 200 or headers.status > 299: raise UploadError(response)
def href(self): if self.workspace is not None: return url(self.catalog.service_url, [ "workspaces", self.workspace.name, "styles", self.name + ".xml" ]) else: return url(self.catalog.service_url, ["styles", self.name + ".xml"])
def get_layergroup(self, name=None): try: group_url = url(self.service_url, ["layergroups", name + ".xml"]) group = self.get_xml(group_url) return LayerGroup(self, group.find("name").text) except FailedRequestError: return None
def create_pg_featuretype(self, name, store, workspace=None, srs="EPSG:4326"): if workspace is None: workspace = self.get_default_workspace() params = dict() workspace = util.name(workspace) store = util.name(store) ds_url = url( self.service_url, ["workspaces", workspace, "datastores", store, "featuretypes.xml"], params) #create the datastore headers = {"Content-type": "text/xml"} xml = ("<featureType>\n" "<enabled>true</enabled>\n" "<metadata />\n" "<keywords><string>KEYWORD</string></keywords>\n" "<projectionPolicy>REPROJECT_TO_DECLARED</projectionPolicy>\n" "<title>" + name + "</title>\n" "<name>" + name + "</name>\n" "<srs>" + srs + "</srs>" "</featureType>") headers, response = self.http.request(ds_url, "POST", xml, headers) if headers.status != 201 and headers.status != 200: raise UploadError(response)
def create_pg_featuretype(self, name, store, workspace=None, srs = "EPSG:4326"): if workspace is None: workspace = self.get_default_workspace() params = dict() workspace = util.name(workspace) store = util.name(store) ds_url = url(self.service_url, ["workspaces", workspace, "datastores", store, "featuretypes.xml"], params) #create the datastore headers = { "Content-type": "text/xml" } xml = ("<featureType>\n" "<enabled>true</enabled>\n" "<metadata />\n" "<keywords><string>KEYWORD</string></keywords>\n" "<projectionPolicy>REPROJECT_TO_DECLARED</projectionPolicy>\n" "<title>" + name + "</title>\n" "<name>" + name +"</name>\n" "<srs>" + srs +"</srs>" "</featureType>") headers, response = self.http.request(ds_url, "POST", xml, headers) if headers.status != 201 and headers.status != 200: raise UploadError(response)
def add_data_to_store(self, store, name, data, workspace=None, overwrite = False, charset = None): if isinstance(store, basestring): store = self.get_store(store, workspace=workspace) if workspace is not None: workspace = util.name(workspace) assert store.workspace.name == workspace, "Specified store (%s) is not in specified workspace (%s)!" % (store, workspace) else: workspace = store.workspace.name store = store.name if isinstance(data, dict): bundle = prepare_upload_bundle(name, data) else: bundle = data params = dict() if overwrite: params["update"] = "overwrite" if charset is not None: params["charset"] = charset message = open(bundle) headers = { 'Content-Type': 'application/zip', 'Accept': 'application/xml' } upload_url = url(self.service_url, ["workspaces", workspace, "datastores", store, "file.shp"], params) try: headers, response = self.http.request(upload_url, "PUT", message, headers) self._cache.clear() if headers.status != 201: raise UploadError(response) finally: unlink(bundle)
def update(self, settings): root = ET.Element('global') for section in settings: params = settings[section] element = ET.SubElement(root, section) for name, value in params: if '/' in name: name, subname = name.split('/') subelement = element.find(name) if subelement is None: subelement = ET.SubElement(element, name) subsubelement = ET.SubElement(subelement, subname) subsubelement.text = unicode(value) else: subelement = ET.SubElement(element, name) subelement.text = unicode(value) xml = ET.tostring(root) settings_url = url(self.catalog.service_url, ['settings.xml']) headers = {'Content-type': 'text/xml'} headers, response = self.http.request(settings_url, 'PUT', xml, headers=headers) if headers.status != 200: raise Exception('Settings update failed - %s, %s' % (headers, response))
def get_styles(self): styles_url = url(self.service_url, ["styles.xml"]) description = self.get_xml(styles_url) return [ Style(self, s.find('name').text) for s in description.findall("style") ]
def get_resources(self): 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) return [cov_from_node(node) for node in xml.findall("coverage")]
def get_resources(self): res_url = url(self.catalog.service_url, ["workspaces", self.workspace.name, "datastores", self.name, "featuretypes.xml"]) xml = self.catalog.get_xml(res_url) def ft_from_node(node): return featuretype_from_index(self.catalog, self.workspace, self, node) return [ft_from_node(node) for node in xml.findall("featureType")]
def get_layers(self, resource=None): if isinstance(resource, basestring): resource = self.get_resource(resource) layers_url = url(self.service_url, ["layers.xml"]) description = self.get_xml(layers_url) #dump(description) lyrs = [Layer(self, l.find("name").text) for l in description.findall("layer")] if resource is not None: lyrs = [l for l in lyrs if l.resource.href == resource.href] # TODO: Filter by style return lyrs
def get_style(self, name, workspace = None): if workspace is not None: style_url = url(self.service_url, ["workspaces", workspace.name, "styles", name + ".xml"]) try: dom = self.get_xml(style_url) return Style(self, name, workspace) except: return None else: style_url = url(self.service_url, ["styles", name + ".xml"]) try: dom = self.get_xml(style_url) return Style(self, name)#dom.find("name").text) except: pass for ws in self.get_workspaces(): style = self.get_style(name, workspace=ws) if style is not None: return style return None
def create_shp_featurestore(self, name, data, workspace=None, overwrite=False, charset=None): '''creates a shapefile-based datastore''' if workspace is None: workspace = self.get_default_workspace() if not overwrite: try: store = self.get_store(name, workspace) msg = "There is already a store named " + name if workspace: msg += " in " + str(workspace) raise ConflictingDataError(msg) except FailedRequestError: # we don't really expect that every layer name will be taken pass workspace = util.name(workspace) params = dict() if charset is not None: params['charset'] = charset ds_url = url(self.service_url, ["workspaces", workspace, "datastores", name, "file.shp"], params) # PUT /workspaces/<ws>/datastores/<ds>/file.shp headers = { "Content-type": "application/zip", "Accept": "application/xml" } if isinstance(data, dict): logger.debug('Data is NOT a zipfile') archive = prepare_upload_bundle(name, data) else: logger.debug('Data is a zipfile') archive = data message = open(archive) try: headers, response = self.http.request(ds_url, "PUT", message, headers) self._cache.clear() if headers.status != 201: raise UploadError(response) finally: try: unlink(archive) except WindowsError: #FIXME: handle this better pass
def get_resources(self): res_url = url(self.catalog.service_url, [ "workspaces", self.workspace.name, "datastores", self.name, "featuretypes.xml" ]) xml = self.catalog.get_xml(res_url) def ft_from_node(node): return featuretype_from_index(self.catalog, self.workspace, self, node) return [ft_from_node(node) for node in xml.findall("featureType")]
def get_resources(self): 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) return [cov_from_node(node) for node in xml.findall("coverage")]
def get_style(self, name, workspace=None): if workspace is not None: style_url = url( self.service_url, ["workspaces", workspace.name, "styles", name + ".xml"]) try: dom = self.get_xml(style_url) return Style(self, name, workspace) except: return None else: style_url = url(self.service_url, ["styles", name + ".xml"]) try: dom = self.get_xml(style_url) return Style(self, name) #dom.find("name").text) except: pass for ws in self.get_workspaces(): style = self.get_style(name, workspace=ws) if style is not None: return style return None
def get_layers(self, resource=None): if isinstance(resource, basestring): resource = self.get_resource(resource) layers_url = url(self.service_url, ["layers.xml"]) description = self.get_xml(layers_url) #dump(description) lyrs = [ Layer(self, l.find("name").text) for l in description.findall("layer") ] if resource is not None: lyrs = [l for l in lyrs if l.resource.href == resource.href] # TODO: Filter by style return lyrs
def create_coveragestore(self, name, data, workspace=None, overwrite=False): if workspace is None: workspace = self.get_default_workspace() if not overwrite: try: store = self.get_store(name, workspace) msg = "There is already a store named " + name if workspace: msg += " in " + str(workspace) raise ConflictingDataError(msg) except FailedRequestError: # we don't really expect that every layer name will be taken pass headers = {"Content-type": "image/tiff", "Accept": "application/xml"} archive = None ext = "geotiff" if isinstance(data, dict): archive = prepare_upload_bundle(name, data) message = open(archive) if "tfw" in data: headers['Content-type'] = 'application/archive' ext = "worldimage" elif isinstance(data, basestring): message = open(data) else: message = data cs_url = url(self.service_url, [ "workspaces", workspace.name, "coveragestores", name, "file." + ext ]) try: headers, response = self.http.request(cs_url, "PUT", message, headers) self._cache.clear() if headers.status != 201: raise UploadError(response) finally: if archive is not None: unlink(archive)
def create_coveragestore(self, name, data, workspace=None, overwrite=False): if workspace is None: workspace = self.get_default_workspace() if not overwrite: try: store = self.get_store(name, workspace) msg = "There is already a store named " + name if workspace: msg += " in " + str(workspace) raise ConflictingDataError(msg) except FailedRequestError: # we don't really expect that every layer name will be taken pass headers = { "Content-type": "image/tiff", "Accept": "application/xml" } archive = None ext = "geotiff" if isinstance(data, dict): archive = prepare_upload_bundle(name, data) message = open(archive) if "tfw" in data: headers['Content-type'] = 'application/archive' ext = "worldimage" elif isinstance(data, basestring): message = open(data) else: message = data cs_url = url(self.service_url, ["workspaces", workspace.name, "coveragestores", name, "file." + ext]) try: headers, response = self.http.request(cs_url, "PUT", message, headers) self._cache.clear() if headers.status != 201: raise UploadError(response) finally: if archive is not None: unlink(archive)
def add_data_to_store(self, store, name, data, workspace=None, overwrite=False, charset=None): if isinstance(store, basestring): store = self.get_store(store, workspace=workspace) if workspace is not None: workspace = util.name(workspace) assert store.workspace.name == workspace, "Specified store (%s) is not in specified workspace (%s)!" % ( store, workspace) else: workspace = store.workspace.name store = store.name if isinstance(data, dict): bundle = prepare_upload_bundle(name, data) else: bundle = data params = dict() if overwrite: params["update"] = "overwrite" if charset is not None: params["charset"] = charset message = open(bundle) headers = { 'Content-Type': 'application/zip', 'Accept': 'application/xml' } upload_url = url( self.service_url, ["workspaces", workspace, "datastores", store, "file.shp"], params) try: headers, response = self.http.request(upload_url, "PUT", message, headers) self._cache.clear() if headers.status != 201: raise UploadError(response) finally: unlink(bundle)
def create_shp_featurestore(self, name, data, workspace=None, overwrite=False, charset=None): '''creates a shapefile-based datastore''' if workspace is None: workspace = self.get_default_workspace() if not overwrite: try: store = self.get_store(name, workspace) msg = "There is already a store named " + name if workspace: msg += " in " + str(workspace) raise ConflictingDataError(msg) except FailedRequestError: # we don't really expect that every layer name will be taken pass workspace = util.name(workspace) params = dict() if charset is not None: params['charset'] = charset ds_url = url(self.service_url, ["workspaces", workspace, "datastores", name, "file.shp"], params) # PUT /workspaces/<ws>/datastores/<ds>/file.shp headers = { "Content-type": "application/zip", "Accept": "application/xml" } if isinstance(data,dict): logger.debug('Data is NOT a zipfile') archive = prepare_upload_bundle(name, data) else: logger.debug('Data is a zipfile') archive = data message = open(archive) try: headers, response = self.http.request(ds_url, "PUT", message, headers) self._cache.clear() if headers.status != 201: raise UploadError(response) finally: try: unlink(archive) except WindowsError: #FIXME: handle this better pass
def settings(self): settings = {} settings_url = url(self.catalog.service_url, ['settings.xml']) headers, response = self.http.request(settings_url, 'GET') if headers.status != 200: raise Exception('Settings listing failed - %s, %s' % (headers,response)) dom = XML(response) sections = ['settings', 'jai','coverageAccess'] for section in sections: params = [] node = dom.find(section) if node is not None: #it will be none if the catalog does not support this operation for entry in node: if len(entry) == 0: params.append((entry.tag, entry.text)) else: for subentry in entry: params.append((entry.tag + '/' + subentry.tag, subentry.text)) settings[section] = params return settings
def settings(self): settings = {} settings_url = url(self.catalog.service_url, ['settings.xml']) headers, response = self.http.request(settings_url, 'GET') if headers.status != 200: raise Exception('Settings listing failed - %s, %s' % (headers, response)) dom = XML(response) sections = ['settings', 'jai', 'coverageAccess'] for section in sections: params = [] node = dom.find(section) if node is not None: #it will be none if the catalog does not support this operation for entry in node: if len(entry) == 0: params.append((entry.tag, entry.text)) else: for subentry in entry: params.append((entry.tag + '/' + subentry.tag, subentry.text)) settings[section] = params return settings
def update(self, settings): root = ET.Element('global') for section in settings: params = settings[section] element = ET.SubElement(root, section) for name, value in params: if '/' in name: name, subname = name.split('/') subelement = element.find(name) if subelement is None: subelement = ET.SubElement(element, name) subsubelement = ET.SubElement(subelement, subname) subsubelement.text = unicode(value) else: subelement = ET.SubElement(element, name) subelement.text = unicode(value) xml = ET.tostring(root) settings_url = url(self.catalog.service_url, ['settings.xml']) headers = {'Content-type': 'text/xml'} headers, response = self.http.request(settings_url, 'PUT', xml, headers = headers) if headers.status != 200: raise Exception('Settings update failed - %s, %s' % (headers,response))
def href(self): return url(self.catalog.service_url, [ "workspaces", self.workspace.name, "datastores", self.store.name, "featuretypes", self.name + ".xml" ])
def href(self): return url(self.catalog.service_url, [ "workspaces", self.workspace.name, "coveragestores", self.store.name, "coverages", self.name + ".xml" ])
def href(self): if self.workspace is not None: return url(self.catalog.service_url, ["workspaces", self.workspace.name, "styles", self.name + ".xml"]) else: return url(self.catalog.service_url, ["styles", self.name + ".xml"])
def href(self): return url( self.catalog.service_url, ["workspaces", self.workspace.name, "datastores", self.store.name, "featuretypes", self.name + ".xml"], )
def href(self): return url(self.catalog.service_url, ["workspaces", self.workspace.name, "coveragestores", self.name + ".xml"])
def href(self): return url(self.catalog.service_url, ["layers", self.name + ".xml"])
def datastore_url(self): return url(self.catalog.service_url, ["workspaces", self.name, "datastores.xml"])
def reload(self): reload_url = url(self.service_url, ['reload']) response = self.http.request(reload_url, "POST") self._cache.clear() return response
def coveragestore_url(self): return url(self.catalog.service_url, ["workspaces", self.name, "coveragestores.xml"])
def href(self): return url(self.catalog.service_url, ["workspaces", self.name + ".xml"])
def href(self): return url(self.catalog.service_url, ["workspaces", self.workspace.name, "coveragestores"], dict(name=self.name))
def get_styles(self): styles_url = url(self.service_url, ["styles.xml"]) description = self.get_xml(styles_url) return [Style(self, s.find('name').text) for s in description.findall("style")]
def create_pg_featurestore(self, name, workspace=None, overwrite=False, host="localhost", port = 5432 , database="db", schema="public", user="******", passwd=""): '''creates a postgis-based datastore''' if user == "" and passwd == "": raise Exception("Both username and password are empty strings. Use a different user/passwd combination") if workspace is None: workspace = self.get_default_workspace() try: store = self.get_store(name, workspace) except FailedRequestError: store = None if store is not None: if overwrite: #if the existing store is the same we are trying to add, we do nothing params = store.connection_parameters if (str(params['port']) == str(port) and params['database'] == database and params['host'] == host and params['user'] == user): print "db connection already exists" return else: msg = "There is already a store named " + name if workspace: msg += " in " + str(workspace) raise ConflictingDataError(msg) workspace = util.name(workspace) params = dict() #create the datastore headers = { "Content-type": "text/xml" } if user is None: raise Exception("Undefined user") xml = ("<dataStore>\n" "<name>" + name + "</name>\n" "<connectionParameters>" "<host>" + host + "</host>\n" "<port>" + str(port) + "</port>\n" "<database>" + database + "</database>\n" "<schema>" + schema + "</schema>\n" "<user>" + user + "</user>\n" "<passwd>" + passwd + "</passwd>\n" "<dbtype>postgis</dbtype>\n" "</connectionParameters>\n" "</dataStore>") if store is not None: ds_url = url(self.service_url, ["workspaces", workspace, "datastores", name], params) headers, response = self.http.request(ds_url, "PUT", xml, headers) else: ds_url = url(self.service_url, ["workspaces", workspace, "datastores.xml"], params) headers, response = self.http.request(ds_url, "POST", xml, headers) self._cache.clear() if headers.status != 201 and headers.status != 200: raise UploadError(response)
def create_pg_featurestore(self, name, workspace=None, overwrite=False, host="localhost", port=5432, database="db", schema="public", user="******", passwd=""): '''creates a postgis-based datastore''' if user == "" and passwd == "": raise Exception( "Both username and password are empty strings. Use a different user/passwd combination" ) if workspace is None: workspace = self.get_default_workspace() try: store = self.get_store(name, workspace) except FailedRequestError: store = None if store is not None: if overwrite: #if the existing store is the same we are trying to add, we do nothing params = store.connection_parameters if (str(params['port']) == str(port) and params['database'] == database and params['host'] == host and params['user'] == user): print "db connection already exists" return else: msg = "There is already a store named " + name if workspace: msg += " in " + str(workspace) raise ConflictingDataError(msg) workspace = util.name(workspace) params = dict() #create the datastore headers = {"Content-type": "text/xml"} if user is None: raise Exception("Undefined user") xml = ("<dataStore>\n" "<name>" + name + "</name>\n" "<connectionParameters>" "<host>" + host + "</host>\n" "<port>" + str(port) + "</port>\n" "<database>" + database + "</database>\n" "<schema>" + schema + "</schema>\n" "<user>" + user + "</user>\n" "<passwd>" + passwd + "</passwd>\n" "<dbtype>postgis</dbtype>\n" "</connectionParameters>\n" "</dataStore>") if store is not None: ds_url = url(self.service_url, ["workspaces", workspace, "datastores", name], params) headers, response = self.http.request(ds_url, "PUT", xml, headers) else: ds_url = url(self.service_url, ["workspaces", workspace, "datastores.xml"], params) headers, response = self.http.request(ds_url, "POST", xml, headers) self._cache.clear() if headers.status != 201 and headers.status != 200: raise UploadError(response)
def href(self): path = [ "workspaces", self.workspace.name, "datastores"] query = dict(name=self.name) return url(self.catalog.service_url, path, query)
def href(self): path = ["workspaces", self.workspace.name, "datastores"] query = dict(name=self.name) return url(self.catalog.service_url, path, query)