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 = _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 params["filename"] = "{0}.zip".format(name) params["target"] = "shp" # params["configure"] = "all" headers = { 'Content-Type': 'application/zip', 'Accept': 'application/xml' } upload_url = url( self.service_url, ["workspaces", workspace, "datastores", store, "file.shp"]) try: with open(bundle, "rb") as f: files = {'file': f} response = requests.put(upload_url, files=files, headers=headers, params=params, auth=(self.username, self.password)) self._cache.clear() if response.status_code != 201: raise UploadError('{0} - "{1}"'.format( response.status_code, response.text)) finally: # os.unlink(bundle) pass
def add_granule(self, data, store, workspace=None): """Harvest/add a granule into an existing imagemosaic""" ext = os.path.splitext(data)[-1] if ext == ".zip": type = "file.imagemosaic" upload_data = open(data, 'rb') headers = { "Content-type": "application/zip", "Accept": "application/xml" } else: type = "external.imagemosaic" upload_data = data if data.startswith( "file:") else "file:{data}".format(data=data) headers = { "Content-type": "text/plain", "Accept": "application/xml" } params = dict() workspace_name = workspace if isinstance(store, basestring): store_name = store else: store_name = store.name workspace_name = store.workspace.name if workspace_name is None: raise ValueError("Must specify workspace") cs_url = url( self.service_url, ["workspaces", workspace_name, "coveragestores", store_name, type]) try: response = self.request(method='post', url=cs_url, headers=headers, data=upload_data, params=params) if response.status_code != 202: raise UploadError('{0} - "{1}"'.format(response.status_code, response.text)) finally: if getattr(upload_data, "close", None) is not None: upload_data.close() self._cache.clear() return "Added granule"
def create_featurestore(self, name, data, workspace=None, overwrite=False, charset=None): if not overwrite: store = self.get_store(name, workspace) if store is not None: msg = "There is already a store named " + name if workspace: msg += " in " + str(workspace) raise ConflictingDataError(msg) if workspace is None: workspace = self.get_default_workspace() workspace = _name(workspace) params = dict() if charset is not None: params['charset'] = charset ds_url = url(self.service_url, ["workspaces", workspace, "datastores", name, "file.shp"]) # 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, 'rb') try: response = self.request(method='put', url=ds_url, headers=headers, data=message, params=params) self._cache.clear() if response.status_code != 201: raise UploadError('{0} - "{1}"'.format(response.status_code, response.text)) finally: message.close() os.unlink(archive)
def create_wmslayer(self, workspace, store, name, nativeName=None): headers = {"Content-type": "text/xml", "Accept": "application/xml"} # if not provided, fallback to name - this is what geoserver will do # anyway but nativeName needs to be provided if name is invalid xml # as this will cause verification errors since geoserver 2.6.1 if nativeName is None: nativeName = name wms_url = store.href.replace('.xml', '/wmslayers') data = "<wmsLayer><name>%s</name><nativeName>%s</nativeName></wmsLayer>" % ( name, nativeName) response = self.request(method='post', url=wms_url, headers=headers, data=data) self._cache.clear() if response.status_code < 200 or response.status_code > 299: raise UploadError('{0} - "{1}"'.format(response.status_code, response.text)) return self.get_resource(name, store=store, workspace=workspace)
def _create_coveragestore(self, name, data, workspace=None, overwrite=False, external=False): if not overwrite: store = self.get_store(name, workspace) if store is not None: msg = "There is already a store named " + name if workspace: msg += " in " + str(workspace) raise ConflictingDataError(msg) if workspace is None: workspace = self.get_default_workspace() archive = None ext = "geotiff" contet_type = "image/tiff" if not external else "text/plain" store_type = "file." if not external else "external." headers = {"Content-type": contet_type, "Accept": "application/xml"} message = data if not external: if isinstance(data, dict): archive = prepare_upload_bundle(name, data) message = open(archive, 'rb') if "tfw" in data: # If application/archive was used, server crashes with a 500 error # read in many sites that application/zip will do the trick. Successfully tested headers['Content-type'] = 'application/zip' ext = "worldimage" elif isinstance(data, basestring): message = open(data, 'rb') else: message = data cs_url = url(self.service_url, [ "workspaces", workspace.name, "coveragestores", name, store_type + ext ], { "configure": "first", "coverageName": name }) try: response = self.request(method='put', url=cs_url, headers=headers, data=message) self._cache.clear() if response.status_code != 201: raise UploadError('{0} - "{1}"'.format(response.status_code, response.text)) finally: if getattr(message, "close", None) is not None: message.close() if archive is not None: os.unlink(archive)
def create_imagemosaic(self, name, data, configure=None, workspace=None, overwrite=False, charset=None): if not overwrite: store = self.get_store(name, workspace) if store is not None: msg = "There is already a store named " + name if workspace: msg += " in " + str(workspace) raise ConflictingDataError(msg) if workspace is None: workspace = self.get_default_workspace() workspace = _name(workspace) params = dict() if charset is not None: params['charset'] = charset if configure is not None: params['configure'] = "none" if getattr(data, 'read', None) is not None or os.path.splitext(data)[-1] == ".zip": store_type = "file.imagemosaic" contet_type = "application/zip" if isinstance(data, basestring): upload_data = open(data, 'rb') elif getattr(data, 'read', None) is not None: # Adding this check only to pass tests. We should drop support for passing a file object upload_data = data else: raise ValueError( "ImageMosaic Dataset or directory: {data} is incorrect". format(data=data)) else: store_type = "external.imagemosaic" contet_type = "text/plain" if isinstance(data, basestring): upload_data = data if data.startswith( "file:") else "file:{data}".format(data=data) else: raise ValueError( "ImageMosaic Dataset or directory: {data} is incorrect". format(data=data)) cs_url = url( self.service_url, ["workspaces", workspace, "coveragestores", name, store_type], ) # PUT /workspaces/<ws>/coveragestores/<name>/file.imagemosaic?configure=none headers = {"Content-type": contet_type, "Accept": "application/xml"} try: response = self.request(method='put', url=cs_url, headers=headers, data=upload_data, params=params) self._cache.clear() if response.status_code != 201: raise UploadError('{0} - "{1}"'.format(response.status_code, response.text)) finally: if getattr(upload_data, "close", None) is not None: upload_data.close() return "Image Mosaic created"
def create_style(self, name, data, overwrite=False, workspace=None, style_format="sld10", raw=False): style = self.get_style(name, workspace) if not overwrite and style is not None: raise ConflictingDataError("There is already a style named %s" % name) # No existing style with given name, so create new one with POST (overwrite does not apply) if style is None: style = Style(self, name, workspace, style_format) # Create style using two-step approach: # 1. Create Style in Catalog headers = {"Content-type": "text/xml", "Accept": "application/xml"} xml = "<style><name>{0}</name><filename>{1}</filename></style>".format( name, name + '.sld') create_href = style.create_href response = self.request(method='post', url=create_href, headers=headers, data=xml) if response.status_code < 200 or response.status_code > 299: raise UploadError('{0} - "{1}"'.format(response.status_code, response.text)) # 2. Upload file for style headers = { "Content-type": style.content_type, "Accept": "application/xml" } body_href = style.body_href response = self.request(method='put', url=body_href, headers=headers, data=data) if response.status_code < 200 or response.status_code > 299: raise UploadError('{0} - "{1}"'.format(response.status_code, response.text)) # Style with given name already exists, so update if overwrite is True elif style is not None and overwrite: headers = { "Content-type": style.content_type, "Accept": "application/xml" } body_href = style.body_href if raw: body_href += "?raw=true" response = self.request(method='put', url=body_href, headers=headers, data=data) if response.status_code < 200 or response.status_code > 299: raise UploadError('{0} - "{1}"'.format(response.status_code, response.text)) self._cache.pop(style.href, None) self._cache.pop(style.body_href, None) # Style with given name already exists, but overwrite not allowed, so raise exception else: raise ConflictingDataError( 'Style already exists with name: "{0}"'.format(style.fqn))