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