示例#1
0
    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
示例#2
0
    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"
示例#3
0
    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)
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
    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"
示例#7
0
    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))