def readKeywordsFromLayer(theLayer, keyword): """Get metadata from the keywords file associated with a layer. .. note:: Requires a inasafe layer instance as parameter. .. seealso:: getKeywordFromPath Args: * theLayer - a InaSAFE layer (vector or raster) * keyword - the metadata keyword to retrieve e.g. 'title' Returns: A string containing the retrieved value for the keyword. Raises: KeywordNotFoundError if the keyword is not recognised. """ value = None if theLayer is None: raise InvalidParameterError() try: value = theLayer.get_keywords(keyword) except Exception, e: message = \ tr('Keyword retrieval failed for %s (%s) \n %s' % ( theLayer.get_filename(), keyword, str(e))) raise KeywordNotFoundError(message)
def read_keyword_from_uri(self, uri, keyword=None): """Get metadata from the keywords file associated with a URI. This is used for layers that are non local layer (e.g. postgresql connection) and so we need to retrieve the keywords from the sqlite keywords db. A hash will be constructed from the supplied uri and a lookup made in a local SQLITE database for the keywords. If there is an existing record it will be returned, if not and error will be thrown. .. seealso:: write_keywords_for_uri, delete_keywords_for_uri :param uri: A layer uri. e.g. ```dbname=\'osm\' host=localhost port=5432 user=\'foo\' password=\'bar\' sslmode=disable key=\'id\' srid=4326``` :type uri: str :param keyword: The metadata keyword to retrieve. If none, all keywords are returned. :type keyword: str :returns: A string containing the retrieved value for the keyword if the keyword argument is specified, otherwise the complete keywords dictionary is returned. :raises: KeywordNotFoundError if the keyword is not found. """ myHash = self.hash_for_datasource(uri) try: self.open_connection() except OperationalError: raise try: myCursor = self.get_cursor() # now see if we have any data for our hash mySQL = 'select dict from keyword where hash = \'' + myHash + '\';' myCursor.execute(mySQL) myData = myCursor.fetchone() # unpickle it to get our dict back if myData is None: raise HashNotFoundError('No hash found for %s' % myHash) myData = myData[0] # first field myDict = pickle.loads(str(myData)) if keyword is None: return myDict if keyword in myDict: return myDict[keyword] else: raise KeywordNotFoundError('Keyword "%s" not found in %s' % (keyword, myDict)) except sqlite.Error, e: LOGGER.debug("Error %s:" % e.args[0])
def read_file_keywords(layer_path, keyword=None): """Get metadata from the keywords file associated with a local file in the file system. .. note:: Requires a str representing a file path instance as parameter As opposed to readKeywordsFromLayer which takes a inasafe file object as parameter. .. seealso:: readKeywordsFromLayer :param: layer_path: a string representing a path to a layer (e.g. '/tmp/foo.shp', '/tmp/foo.tif') :type layer_path: str :param keyword: optional - the metadata keyword to retrieve e.g. 'title' :type keyword: str :return: A string containing the retrieved value for the keyword if the keyword argument is specified, otherwise the complete keywords dictionary is returned. :raises: KeywordNotFoundError, NoKeywordsFoundError, InvalidParameterError Note: * KeywordNotFoundError - occurs when the keyword is not recognised. * NoKeywordsFoundError - occurs when no keyword file exists. * InvalidParameterError - occurs when the layer does not exist. """ # check the source layer path is valid if not os.path.isfile(layer_path): message = tr('Cannot get keywords from a non-existent file.' '%s does not exist.' % layer_path) raise InvalidParameterError(message) # check there really is a keywords file for this layer keyword_file_path = os.path.splitext(layer_path)[0] keyword_file_path += '.keywords' if not os.path.isfile(keyword_file_path): message = tr('No keywords file found for %s' % keyword_file_path) raise NoKeywordsFoundError(message) # now get the requested keyword using the inasafe library dictionary = None try: dictionary = read_keywords(keyword_file_path) except Exception, e: message = \ tr('Keyword retrieval failed for %s (%s) \n %s' % ( keyword_file_path, keyword, str(e))) raise KeywordNotFoundError(message)
def readKeywordFromUri(self, theUri, theKeyword=None): """Get metadata from the keywords file associated with a non local layer (e.g. postgresql connection). A hash will be constructed from the supplied uri and a lookup made in a local SQLITE database for the keywords. If there is an existing record it will be returned, if not and error will be thrown. .. seealso:: writeKeywordsForUri,deleteKeywordsForUri Args: * theUri - a str representing a layer uri as parameter. .e.g. 'dbname=\'osm\' host=localhost port=5432 user=\'foo\' password=\'bar\' sslmode=disable key=\'id\' srid=4326 * keyword - optional - the metadata keyword to retrieve e.g. 'title' Returns: A string containing the retrieved value for the keyword if the keyword argument is specified, otherwise the complete keywords dictionary is returned. Raises: KeywordNotFoundError if the keyword is not found. """ myHash = self.getHashForDatasource(theUri) try: self.openConnection() except OperationalError: raise try: myCursor = self.getCursor() #now see if we have any data for our hash mySQL = 'select dict from keyword where hash = \'' + myHash + '\';' myCursor.execute(mySQL) myData = myCursor.fetchone() #unpickle it to get our dict back if myData is None: raise HashNotFoundError('No hash found for %s' % myHash) myData = myData[0] # first field myDict = pickle.loads(str(myData)) if theKeyword is None: return myDict if theKeyword in myDict: return myDict[theKeyword] else: raise KeywordNotFoundError('No hash found for %s' % myHash) except sqlite.Error, e: LOGGER.debug("Error %s:" % e.args[0])
def get_keywords(self, key=None): """Return a copy of the keywords dictionary Args: * key (optional): If specified value will be returned for key only """ if key is None: return self.keywords.copy() else: if key in self.keywords: return self.keywords[key] else: msg = ('Keyword %s does not exist in %s: Options are ' '%s' % (key, self.get_name(), self.keywords.keys())) raise KeywordNotFoundError(msg)
def read_file_keywords(theLayerPath, theKeyword=None): """Get metadata from the keywords file associated with a local file in the file system. .. note:: Requires a str representing a file path instance as parameter As opposed to readKeywordsFromLayer which takes a inasafe file object as parameter. .. seealso:: readKeywordsFromLayer Args: * theLayerPath - a string representing a path to a layer (e.g. '/tmp/foo.shp', '/tmp/foo.tif') * theKeyword - optional - the metadata keyword to retrieve e.g. 'title' Returns: A string containing the retrieved value for the keyword if the keyword argument is specified, otherwise the complete keywords dictionary is returned. Raises: KeywordNotFoundError if the keyword is not recognised. NoKeywordsFoundError if no keyword file exists. InvalidParameterError if the layer does not exist. """ # check the source layer path is valid if not os.path.isfile(theLayerPath): myMessage = tr('Cannot get keywords from a non-existent file.' '%s does not exist.' % theLayerPath) raise InvalidParameterError(myMessage) # check there really is a keywords file for this layer myKeywordFilePath = os.path.splitext(theLayerPath)[0] myKeywordFilePath += '.keywords' if not os.path.isfile(myKeywordFilePath): myMessage = tr('No keywords file found for %s' % myKeywordFilePath) raise NoKeywordsFoundError(myMessage) # now get the requested keyword using the inasafe library myDictionary = None try: myDictionary = read_keywords(myKeywordFilePath) except Exception, e: myMessage = \ tr('Keyword retrieval failed for %s (%s) \n %s' % ( myKeywordFilePath, theKeyword, str(e))) raise KeywordNotFoundError(myMessage)
""" value = None if theLayer is None: raise InvalidParameterError() try: value = theLayer.get_keywords(keyword) except Exception, e: message = \ tr('Keyword retrieval failed for %s (%s) \n %s' % ( theLayer.get_filename(), keyword, str(e))) raise KeywordNotFoundError(message) if not value or value == '': message = \ tr('No value was found for keyword %s in layer %s' % ( theLayer.get_filename(), keyword)) raise KeywordNotFoundError(message) return value def read_file_keywords(layer_path, keyword=None): """Get metadata from the keywords file associated with a local file in the file system. .. note:: Requires a str representing a file path instance as parameter As opposed to readKeywordsFromLayer which takes a inasafe file object as parameter. .. seealso:: readKeywordsFromLayer :param: layer_path: a string representing a path to a layer (e.g. '/tmp/foo.shp', '/tmp/foo.tif')
def validate_all_layers(self): """Validate all layers based on the keywords. When we do the validation, we also fetch the information we need: 1. 'map_title' from each impact layer 2. 'exposure_title' from each impact layer 3. 'postprocessing_report' from each impact layer 4. 'aggregation_attribute' on aggregation layer, if user runs merging tools with aggregation layer chosen The things that we validate are: 1. 'map_title' keyword must exist on each impact layer 2. 'exposure_title' keyword must exist on each impact layer 3. 'postprocessing_report' keyword must exist on each impact layer 4. 'hazard_title' keyword must exist on each impact layer. Hazard title from first impact layer must be the same with second impact layer to indicate that both are generated from the same hazard layer. 5. 'aggregation attribute' must exist when user wants to run merging tools with aggregation layer chosen. """ required_attribute = [ 'map_title', 'exposure_title', 'hazard_title', 'postprocessing_report' ] # Fetch for first impact layer for attribute in required_attribute: try: # noinspection PyTypeChecker self.first_impact[attribute] = self.keyword_io.read_keywords( self.first_impact['layer'], attribute) except NoKeywordsFoundError: raise NoKeywordsFoundError( self.tr('No keywords found for first impact layer.')) except KeywordNotFoundError: raise KeywordNotFoundError( self.tr('Keyword %s not found for first layer.' % attribute)) # Fetch for second impact layer for attribute in required_attribute: try: # noinspection PyTypeChecker self.second_impact[attribute] = self.keyword_io.read_keywords( self.second_impact['layer'], attribute) except NoKeywordsFoundError: raise NoKeywordsFoundError( self.tr('No keywords found for second impact layer.')) except KeywordNotFoundError: raise KeywordNotFoundError( self.tr('Keyword %s not found for second layer.' % attribute)) # Validate that two impact layers are obtained from the same hazard. # Indicated by the same 'hazard_title' (to be fixed later by using # more reliable method) if (self.first_impact['hazard_title'] != self.second_impact['hazard_title']): raise InvalidLayerError( self.tr('First impact layer and second impact layer do not ' 'use the same hazard layer.')) # Fetch 'aggregation_attribute' # If the chosen aggregation layer not Entire Area, it should have # aggregation attribute keywords if not self.entire_area_mode: try: # noinspection PyTypeChecker self.aggregation['aggregation_attribute'] = \ self.keyword_io.read_keywords( self.aggregation['layer'], 'aggregation attribute') except NoKeywordsFoundError: raise NoKeywordsFoundError( self.tr('No keywords exist in aggregation layer.')) except KeywordNotFoundError: raise KeywordNotFoundError( self.tr('Keyword aggregation attribute not found for ' 'aggregation layer.'))
def read_keyword_from_uri(self, uri, keyword=None): """Get metadata from the keywords file associated with a URI. This is used for layers that are non local layer (e.g. postgresql connection) and so we need to retrieve the keywords from the sqlite keywords db. A hash will be constructed from the supplied uri and a lookup made in a local SQLITE database for the keywords. If there is an existing record it will be returned, if not and error will be thrown. If the record is a dictionary, it means that it was inserted into the DB in a pre 2.2 version which had no ISO metadata. In this case, we use that dictionary to update the entry to the new ISO based metadata .. seealso:: write_keywords_for_uri, delete_keywords_for_uri :param uri: A layer uri. e.g. ```dbname=\'osm\' host=localhost port=5432 user=\'foo\' password=\'bar\' sslmode=disable key=\'id\' srid=4326``` :type uri: str :param keyword: The metadata keyword to retrieve. If none, all keywords are returned. :type keyword: str :returns: A string containing the retrieved value for the keyword if the keyword argument is specified, otherwise the complete keywords dictionary is returned. :raises: KeywordNotFoundError if the keyword is not found. """ hash_value = self.hash_for_datasource(uri) try: self.open_connection() except OperationalError: raise try: cursor = self.get_cursor() # now see if we have any data for our hash sql = ('select dict from keyword where hash = \'%s\';' % hash_value) cursor.execute(sql) data = cursor.fetchone() # unpickle it to get our dict back if data is None: raise HashNotFoundError('No hash found for %s' % hash_value) data = data[0] # first field # get the ISO XML out of the DB metadata = pickle.loads(str(data)) # the uri already had a KW entry in the DB using the old KW system # we use that dictionary to update the entry to the new ISO based # metadata system if type(metadata) is dict: metadata = self.write_keywords_for_uri(uri, metadata) root = ElementTree.fromstring(metadata) keyword_element = root.find(ISO_METADATA_KEYWORD_TAG) dict_str = keyword_element.text picked_dict = json.loads(dict_str) if keyword is None: return picked_dict if keyword in picked_dict: return picked_dict[keyword] else: raise KeywordNotFoundError('Keyword "%s" not found in %s' % (keyword, picked_dict)) except sqlite.Error, e: LOGGER.debug("Error %s:" % e.args[0])