for n,v in pl: if n == name: return v return None def lines2cli(s): ''' Convert a string into a list of lines. Replace continuation characters. Strip white space, left and right. Drop empty lines. ''' cl = [] l = s.split('\n') cum = [] for p in l: p = p.strip() if p.endswith('\\'): p = p.rstrip('\\') cum.append(p) else: cum.append(p) cl.append(''.join(cum).strip()) cum = [] if cum: # in case s ends with backslash cl.append(''.join(cum)) return [x for x in cl if x] user_prefs = UserPrefs.getInstance() options = Options.getInstance() vars = Vars.getInstance() # vim:ts=4:sw=4:et:
def DELETE(self, name=None): try: logging.info("[LayMan][DELETE] %s"% name) params = repr(web.input()) logging.info("[LayMan][DELETE] Parameters: %s ... %s"%\ (str(params)[:500], str(params)[-500:])) if not self.auth.authorised: logging.error("[LayMan][DELETE] Unauthorised") raise AuthError(401, "Authorisation failed. Are you logged-in?") code = 404 # 200, 404... message = "Call not supported: DELETE "+name+" Please check the API doc or report a bug if appropriate." path = [d for d in name.split(os.path.sep) if d] if len(name) > 0: if path[0] != "fileman" and not self.auth.canDelete(): logging.error("[LayMan][DELETE] Only admin can DELETE") raise AuthError(401, "Authorisation failed. Only Administrator can delete") # /fileman/file.shp" if path[0] == "fileman": from fileman import FileMan fm = FileMan() fileName = name[8:] (code, message) = fm.deleteFile(self._getTargetFile(path[-1])) # /user/<username> elif path[0] == "user" and len(path) == 2: userName = path[1] from userprefs import UserPrefs up = UserPrefs(config) (code, message) = up.deleteUser(userName) # /layed/<layer> elif path[0] == "layed" and len(path) == 2: from layed import LayEd le = LayEd() layerName = path[1] inpt = web.input(usergroup=None) deleteTable = True if "deleteTable" in inpt: if inpt["deleteTable"].lower() == "false": deleteTable = False gsWorkspace = self.auth.getGSWorkspace(inpt.usergroup) dbSchema = self.auth.getDBSchema(inpt.usergroup) logging.info("[LayMan][DELETE] Delete layer '%s'"% layerName ) logging.info("[LayMan][DELETE] Delete from workspace '%s'"% gsWorkspace) (code, message) = le.deleteLayer(gsWorkspace, layerName, dbSchema, deleteTable) # /publish/<layer> elif path[0] == "publish" and len(path) == 2: from layed import LayEd le = LayEd() layerName = path[1] inpt = web.input() if not "schema" in inpt: raise LaymanError( 400, "'schema' parameter missing") gsWorkspace = self.auth.getGSWorkspace(inpt.schema) dbSchema = self.auth.getDBSchema(inpt.schema) logging.info("[LayMan][DELETE] Delete layer '%s'"% layerName ) logging.info("[LayMan][DELETE] Delete from workspace '%s'"% gsWorkspace) (code, message) = le.deleteLayer(gsWorkspace, layerName, dbSchema, deleteTable=False) success = self._setReturnCode(code) retval = self._jsonReply(code, message, success) return retval except LaymanError as le: return self._handleLaymanError(le) except Exception as e: return self._handleException(e)
def otherword(self, n, s): if "color" in user_prefs.output: return self.colorstring(n, s) else: return s def id(self, s): return self.otherword(1, s) def attr_name(self, s): return self.otherword(2, s) def attr_value(self, s): return self.otherword(3, s) def rscref(self, s): return self.otherword(4, s) def idref(self, s): return self.otherword(4, s) def score(self, s): return self.otherword(5, s) user_prefs = UserPrefs.getInstance() vars = Vars.getInstance() termctrl = TerminalController.getInstance() # vim:ts=4:sw=4:et:
def PUT(self, name=None): try: logging.info("[LayMan][PUT] %s"% name) params = repr(web.input()) logging.info("[LayMan][PUT] Parameters: %s ... %s"%\ (str(params)[:500], str(params)[-500:])) global config if not self.auth.authorised: logging.error("[LayMan][PUT] Unauthorised") raise AuthError(401, "Authorisation failed. Are you logged-in?") code = 404 # 200, 404... message = "Call not supported: PUT "+name+" Please check the API doc or report a bug if appropriate." path = [d for d in name.split(os.path.sep) if d] # PUT "http://localhost:8080/layman/fileman/file.shp" if path[0] == "fileman": from fileman import FileMan fm = FileMan() fileName = path[-1] data = web.data() (code, message) = fm.putFile(self._getTargetFile( fileName), data) # PUT /layman/user/ # data: {screenName: "user", roles: [{roleTitle, roleName}, {roleTitle, roleName}]} elif path[0] == "user": from userprefs import UserPrefs up = UserPrefs(config) data = web.data() logging.debug(data) (code, message) = up.updateUser(userJsonStr=data) elif path[0] == "geoserver": from layed.gsconfig import GsConfig # /geoserver/style/style_name if path[1] == "style": #ws = None #if len(path) > 3: # ws = path[-2] gsc = GsConfig() # If PUT Style fails, gsconfig throws an exception try: gsc.putStyle(path[-1], web.data()) (code, message) = (200, "PUT Style OK") except Exception as e: code = 500 message = "PUT Style failed: " + str(e) # /layed/config/<layer>?usergroup=FireBrigade elif path[0] == "layed" and len(path) == 2: from layed import LayEd le = LayEd() layerName = path[1] inpt = web.input(usergroup=None) gsWorkspace = self.auth.getGSWorkspace(inpt.usergroup) data = web.data() data = json.loads(data) # string -> json usergroup = inpt.usergroup if (not usergroup) and ("usergroup" in data.keys()): logging.debug("[LayMan][PUT] Usergroup not provided in params, but given in data: %s"% data["usergroup"]) usergroup = data["usergroup"] fsUserDir = self.auth.getFSUserDir() fsGroupDir = self.auth.getFSGroupDir(usergroup) dbSchema = self.auth.getDBSchema(usergroup) gsWorkspace = self.auth.getGSWorkspace(usergroup) (code, message) = le.putLayerConfig(gsWorkspace, layerName, data, fsUserDir, fsGroupDir, dbSchema) success = self._setReturnCode(code) retval = self._jsonReply(code, message, success) return retval except LaymanError as le: return self._handleLaymanError(le) except Exception as e: return self._handleException(e)
def POST(self, name=None): try: logging.info("[LayMan][POST] %s"% name) params = repr(web.input()) logging.info("[LayMan][POST] Parameters: %s ... %s"%\ (str(params)[:500], str(params)[-500:])) global config if not self.auth.authorised: logging.error("[LayMan][POST] Unauthorised") raise AuthError(401, "Authorisation failed. Are you logged-in?") code = None message = None origName = name name = [d for d in os.path.split(origName) if d] if len(name) > 0: # POST "http://localhost:8080/layman/fileman/file.shp" if name[0] == "fileman": from fileman import FileMan fm = FileMan() # Jachyme, what we expect here to receive from the client? # Where is it documented? inpt = web.input(filename={}, newfilename="") newFilename = inpt["newfilename"] if not newFilename: newFilename = inpt["filename"].filename newFilename = self._getTargetFile(newFilename,False) (code, message) = fm.postFile(newFilename, inpt["filename"].file.read()) # FIXME Security: we # shoudl read file size up to X megabytes web.header("Content-type", "text/html") # POST /layman/user # data: {screenName: "user", roles: [{roleTitle, roleName}, {roleTitle, roleName}]} elif name[0] == "user": from userprefs import UserPrefs up = UserPrefs(config) data = web.data() logging.debug(data) (code, message) = up.createUser(userJsonStr=data) # POST "http://localhost:8080/layman/layed?fileName=Rivers.shp&usergroup=RescueRangers" elif name[0] == "layed": from layed import LayEd le = LayEd(config) inpt = web.input(usergroup=None) if not inpt.fileName: raise LaymanError( 400, "'fileName' parameter missing") fileName = inpt.fileName fsUserDir = self.auth.getFSUserDir() fsGroupDir = self.auth.getFSGroupDir(inpt.usergroup) dbSchema = self.auth.getDBSchema(inpt.usergroup) gsWorkspace = self.auth.getGSWorkspace(inpt.usergroup) crs = inpt.crs # native crs tsrs = inpt.tsrs # target srs cpg = inpt.cpg # code page secureLayer = True if "secureLayer" in inpt: if inpt.secureLayer.lower() == "false": secureLayer = False (code, layerName, message) = le.importAndPublish(fsUserDir, fsGroupDir, dbSchema, gsWorkspace, fileName, crs, tsrs, cpg, inpt, secureLayer) # Set Location header if code == 201 and layerName is not None: location = layerName # TODO: provide full URI here web.header("Location", location) elif name[0] == "publish" or name[0] == "data": from layed import LayEd le = LayEd(config) inpt = web.input() # Obligatory parameters if not "schema" in inpt: raise LaymanError( 400, "'schema' parameter missing") if not "view" in inpt: raise LaymanError( 400, "'view' parameter missing") if not "crs" in inpt: raise LaymanError( 400, "'crs' parameter missing") viewName = inpt.view dbSchema = self.auth.getDBSchema(inpt.schema) gsWorkspace = self.auth.getGSWorkspace(inpt.schema) crs = inpt.crs secureLayer = True if "secureLayer" in inpt: if inpt.secureLayer.lower() == "false": secureLayer = False # Optional parameters styleName = None styleWs = None if "style" in inpt: styleName = inpt.style if "style_ws" in inpt: styleWs = inpt.style_ws (code, layerName, message) = le.publishFromDbToGs(dbSchema, viewName, gsWorkspace, crs, inpt, styleName, styleWs, secureLayer) # Set Location header if code == 201 and layerName is not None: location = layerName # TODO: provide full URI here web.header("Location", location) else: (code, message) = self._callNotSupported(restMethod="POST", call=origName) else: (code, message) = self._callNotSupported(restMethod="POST", call=origName) success = self._setReturnCode(code) retval = self._jsonReply(code, message, success) return retval except LaymanError as le: return self._handleLaymanError(le) except Exception as e: return self._handleException(e)
def DELETE(self, name=None): try: logging.info("[LayMan][DELETE] %s"% name) params = repr(web.input()) logging.info("[LayMan][DELETE] Parameters: %s ... %s"%\ (str(params)[:500], str(params)[-500:])) if not self.auth.authorised: logging.error("[LayMan][DELETE] Unauthorised") raise AuthError(401, "Authorisation failed. Are you logged-in?") code = 404 # 200, 404... message = "Call not supported: DELETE "+name+" Please check the API doc or report a bug if appropriate." path = [d for d in name.split(os.path.sep) if d] if len(name) > 0: # /files/<user>/file.shp" if path[0] == "files" and len(path) == 3: from fileman import FileMan fm = FileMan() # Everyone can DELETE only his/her own files userName = self.auth.getUserName() if userName != path[1]: logging.error("[LayMan][DELETE] %s is not authorized to delete files of %s"% (userName, path[1])) raise AuthError(401, "Sorry, you are not authorized to delete files of %s"% path[1]) (code, message) = fm.deleteFile(self._getTargetFile(path[-1])) # /user/<username> elif path[0] == "user" and len(path) == 2: userName = path[1] from userprefs import UserPrefs up = UserPrefs(config) (code, message) = up.deleteUser(userName) # /layers/<group>/<layer> # was /layed/<layer> elif path[0] == "layers" and len(path) == 3: from layed import LayEd le = LayEd() # Check authorization for the given group checkRole = self.auth.getRole(path[1]) if checkRole["roleName"] != path[1]: logging.error("[LayMan][DELETE] Not authorized to DELETE layer from %s group"% path[1]) raise AuthError(401, "Sorry, you are not authorized to delete layer from %s group"% path[1]) gsWorkspace = self.auth.getGSWorkspace(path[1]) dbSchema = self.auth.getDBSchema(path[1]) logging.info("[LayMan][DELETE] Delete layer '%s'"% path[2] ) logging.info("[LayMan][DELETE] Delete from workspace '%s'"% gsWorkspace) # Delete layer only (code, message) = le.deleteLayer(gsWorkspace, path[2], dbSchema, deleteTable=False) # /datalayers/<group>/<layer> elif path[0] == "datalayers" and len(path) == 3: from layed import LayEd le = LayEd() # Check authorization for the given group checkRole = self.auth.getRole(path[1]) if checkRole["roleName"] != path[1]: logging.error("[LayMan][DELETE] Not authorized to DELETE layer from %s group"% path[1]) raise AuthError(401, "Sorry, you are not authorized to delete layer from %s group"% path[1]) gsWorkspace = self.auth.getGSWorkspace(path[1]) dbSchema = self.auth.getDBSchema(path[1]) logging.info("[LayMan][DELETE] Delete layer and data '%s'"% path[2] ) logging.info("[LayMan][DELETE] Delete from workspace '%s'"% gsWorkspace) # Delete layer and data (code, message) = le.deleteLayer(gsWorkspace, path[2], dbSchema, deleteTable=True) success = self._setReturnCode(code) retval = self._jsonReply(code, message, success) return retval except LaymanError as le: return self._handleLaymanError(le) except Exception as e: return self._handleException(e)
def PUT(self, name=None): try: logging.info("[LayMan][PUT] %s"% name) params = repr(web.input()) logging.info("[LayMan][PUT] Parameters: %s ... %s"%\ (str(params)[:500], str(params)[-500:])) global config if not self.auth.authorised: logging.error("[LayMan][PUT] Unauthorised") raise AuthError(401, "Authorisation failed. Are you logged-in?") code = 404 # 200, 404... message = "Call not supported: PUT "+name+" Please check the API doc or report a bug if appropriate." path = [d for d in name.split(os.path.sep) if d] # PUT /files/<user>/file.shp" if path[0] == "files" and len(path) == 3: from fileman import FileMan fm = FileMan() # Everyone can PUT only his/her own files userName = self.auth.getUserName() if userName != path[1]: logging.error("[LayMan][PUT] %s is not authorized to put files of %s"% (userName, path[1])) raise AuthError(401, "Sorry, you are not authorized to update files of %s"% path[1]) fileName = path[-1] data = web.data() (code, message) = fm.putFile(self._getTargetFile( fileName), data) # PUT /data/<group>/{table|view|file}/<data>?fileName=Rivers.shp elif path[0] == "data" and len(path) == 4: from layed import LayEd le = LayEd() # Check authorization for the given group checkRole = self.auth.getRole(path[1]) if checkRole["roleName"] != path[1]: logging.error("[LayMan][PUT] Not authorized to PUT data for %s group"% path[1]) raise AuthError(401, "Sorry, you are not authorized to put data in %s group"% path[1]) # fileName must be given inpt = web.input() if not inpt.fileName: raise LaymanError(400, "'fileName' parameter must be given") # Note: currently all vectors are stored in database and all rasters are stored in filesystem. # If some vector is to be stored in the fs or some raster in the db, # LayEd.updateData() must be adjusted and receive path[2] as a parameter fsUserDir = self.auth.getFSUserDir() fsGroupDir = self.auth.getFSGroupDir(path[1]) dbSchema = self.auth.getDBSchema(path[1]) gsWorkspace = self.auth.getGSWorkspace(path[1]) (code, message) = le.updateData(path[3], gsWorkspace, fsUserDir, fsGroupDir, dbSchema, inpt.fileName) # PUT /layman/user/ # data: {screenName: "user", roles: [{roleTitle, roleName}, {roleTitle, roleName}]} elif path[0] == "user": from userprefs import UserPrefs up = UserPrefs(config) data = web.data() logging.debug(data) (code, message) = up.updateUser(userJsonStr=data) elif path[0] == "geoserver": from layed.gsconfig import GsConfig # /geoserver/style/style_name if path[1] == "style": #ws = None #if len(path) > 3: # ws = path[-2] gsc = GsConfig() # If PUT Style fails, gsconfig throws an exception try: gsc.putStyle(path[-1], web.data()) (code, message) = (200, "PUT Style OK") except Exception as e: code = 500 message = "PUT Style failed: " + str(e) # PUT /layers/<group>/<layer> # was /layed/config/<layer>?usergroup=FireBrigade elif path[0] == "layers" and len(path) == 3: from layed import LayEd le = LayEd() # Check authorization for the given group checkRole = self.auth.getRole(path[1]) if checkRole["roleName"] != path[1]: logging.error("[LayMan][PUT] Not authorized to PUT layer for %s group"% path[1]) raise AuthError(401, "Sorry, you are not authorized to put layer in %s group"% path[1]) data = web.data() data = json.loads(data) # string -> json fsUserDir = self.auth.getFSUserDir() fsGroupDir = self.auth.getFSGroupDir(path[1]) dbSchema = self.auth.getDBSchema(path[1]) gsWorkspace = self.auth.getGSWorkspace(path[1]) (code, message) = le.putLayerConfig(gsWorkspace, path[2], data, fsUserDir, fsGroupDir, dbSchema) success = self._setReturnCode(code) retval = self._jsonReply(code, message, success) return retval except LaymanError as le: return self._handleLaymanError(le) except Exception as e: return self._handleException(e)
def POST(self, name=None): try: logging.info("[LayMan][POST] %s"% name) params = repr(web.input()) logging.info("[LayMan][POST] Parameters: %s ... %s"%\ (str(params)[:500], str(params)[-500:])) global config if not self.auth.authorised: logging.error("[LayMan][POST] Unauthorised") raise AuthError(401, "Authorisation failed. Are you logged-in?") code = None message = None origName = name path = [d for d in os.path.split(origName) if d] if len(path) > 0: # POST "http://localhost:8080/layman/files/<user>" if path[0] == "files" and len(path) == 2: from fileman import FileMan fm = FileMan() # Everyone can post only in his/her own directory userName = self.auth.getUserName() if userName != path[1]: logging.error("[LayMan][POST] %s is not authorized to post files into %s's directory"% (userName, path[1])) raise AuthError(401, "Sorry, you are not authorized to post files into %s's directory"% path[1]) # Request params inpt = web.input(filename={}, newfilename="") # User dir fsUserDir = self.auth.getFSUserDir() # Chek 'source' parameter ['url'|'payload'] if "source" in inpt and inpt["source"].lower() == "url": # Check URL param if not inpt["url"] or inpt["url"] == "": # Get from url requested, but url not given code = 400 message = "URL source requested, but URL not given" else: # Get file from URL (code, message) = fm.postFileFromUrl(fsUserDir, inpt["url"]) else: # Get file data from request payload newFilename = inpt["newfilename"] if not newFilename: newFilename = inpt["filename"].filename (code, message) = fm.postFileFromPayload(fsUserDir, newFilename, inpt["filename"].file.read()) web.header("Content-type", "text/html") # POST /layman/user # data: {screenName: "user", roles: [{roleTitle, roleName}, {roleTitle, roleName}]} elif path[0] == "user": from userprefs import UserPrefs up = UserPrefs(config) data = web.data() logging.debug(data) (code, message) = up.createUser(userJsonStr=data) # /datalayers/<group>?fileName=Rivers.shp # was /layed?fileName=Rivers.shp&usergroup=RescueRangers" elif path[0] == "datalayers" and len(path) == 2: from layed import LayEd le = LayEd(config) inpt = web.input() if not inpt.fileName: raise LaymanError( 400, "'fileName' parameter missing") checkRole = self.auth.getRole(path[1]) logging.debug("[LayMan][POST] checkRole: '%s', path[1]: '%s'"% (checkRole, path[1])) if checkRole["roleName"] != path[1]: logging.error("[LayMan][POST] Not authorized to post files into %s group"% path[1]) raise AuthError(401, "Sorry, you are not authorized to post files into %s group"% path[1]) fileName = inpt.fileName userName = self.auth.getUserName() fsUserDir = self.auth.getFSUserDir() fsGroupDir = self.auth.getFSGroupDir(path[1]) dbSchema = self.auth.getDBSchema(path[1]) gsWorkspace = self.auth.getGSWorkspace(path[1]) crs = inpt.crs # native crs tsrs = inpt.tsrs # target srs cpg = inpt.cpg # code page secureLayer = False if "secureLayer" in inpt: if inpt.secureLayer.lower() == "true": secureLayer = True (code, layerName, message) = le.importAndPublish(fsUserDir, fsGroupDir, dbSchema, gsWorkspace, fileName, userName, crs, tsrs, cpg, inpt, secureLayer) # Set Location header if code == 201 and layerName is not None: location = layerName # TODO: provide full URI here web.header("Location", location) # /layers/<group> # was: /publish or /data elif path[0] == "layers" and len(path) == 2: from layed import LayEd le = LayEd(config) inpt = web.input() # Check authorization checkRole = self.auth.getRole(path[1]) if checkRole["roleName"] != path[1]: logging.error("[LayMan][POST] Not authorized to post files into %s group"% path[1]) raise AuthError(401, "Sorry, you are not authorized to post files into %s group"% path[1]) # Obligatory parameters if not "dataname" in inpt: raise LaymanError( 400, "'dataname' parameter missing") if not "datatype" in inpt: raise LaymanError( 400, "'datatype' parameter missing") if not "crs" in inpt: raise LaymanError( 400, "'crs' parameter missing") dataName = inpt.dataname dataType = inpt.datatype userName = self.auth.getUserName() dbSchema = self.auth.getDBSchema(path[1]) gsWorkspace = self.auth.getGSWorkspace(path[1]) crs = inpt.crs secureLayer = False if "secureLayer" in inpt: if inpt.secureLayer.lower() == "true": secureLayer = True # Optional parameters styleName = None styleWs = None if "style" in inpt: styleName = inpt.style if "style_ws" in inpt: styleWs = inpt.style_ws (code, layerName, message) = le.publishFromDbToGs(dbSchema, dataName, dataType, gsWorkspace, userName, crs, inpt, styleName, styleWs, secureLayer) # Set Location header if code == 201 and layerName is not None: location = layerName # TODO: provide full URI here web.header("Location", location) else: (code, message) = self._callNotSupported(restMethod="POST", call=origName) else: (code, message) = self._callNotSupported(restMethod="POST", call=origName) success = self._setReturnCode(code) retval = self._jsonReply(code, message, success) return retval except LaymanError as le: return self._handleLaymanError(le) except Exception as e: return self._handleException(e)