コード例 #1
0
ファイル: database.py プロジェクト: chaoflow/notmuch
    def get_directory(self, path):
        """Returns a :class:`Directory` of path,
        (creating it if it does not exist(?))

        .. warning:: This call needs a writeable database in
           :attr:`Database.MODE`.READ_WRITE mode. The underlying library will exit the
           program if this method is used on a read-only database!

        :param path: An unicode string containing the path relative to the path
              of database (see :meth:`get_path`), or else should be an absolute path
              with initial components that match the path of 'database'.
        :returns: :class:`Directory` or raises an exception.
        :exception:
            :exc:`NotmuchError` with :attr:`STATUS`.FILE_ERROR
                    If path is not relative database or absolute with initial
                    components same as database.
        """
        self._assert_db_is_initialized()
        # sanity checking if path is valid, and make path absolute
        if path[0] == os.sep:
            # we got an absolute path
            if not path.startswith(self.get_path()):
                # but its initial components are not equal to the db path
                raise NotmuchError(STATUS.FILE_ERROR,
                                   message="Database().get_directory() called "
                                           "with a wrong absolute path.")
            abs_dirpath = path
        else:
            #we got a relative path, make it absolute
            abs_dirpath = os.path.abspath(os.path.join(self.get_path(), path))

        dir_p = Database._get_directory(self._db, _str(path))

        # return the Directory, init it with the absolute path
        return Directory(_str(abs_dirpath), dir_p, self)
コード例 #2
0
ファイル: database.py プロジェクト: praet/notmuch
    def create(self, path):
        """Creates a new notmuch database

        This function is used by __init__() and usually does not need
        to be called directly. It wraps the underlying
        *notmuch_database_create* function and creates a new notmuch
        database at *path*. It will always return a database in :attr:`MODE`
        .READ_WRITE mode as creating an empty database for
        reading only does not make a great deal of sense.

        :param path: A directory in which we should create the database.
        :type path: str
        :returns: Nothing
        :exception: :exc:`NotmuchError` in case of any failure
                    (possibly after printing an error message on stderr).
        """
        if self._db is not None:
            raise NotmuchError(message="Cannot create db, this Database() "
                               "already has an open one.")

        res = Database._create(_str(path), Database.MODE.READ_WRITE)

        if not res:
            raise NotmuchError(
                message="Could not create the specified database")
        self._db = res
コード例 #3
0
ファイル: message.py プロジェクト: praet/notmuch
    def get_header(self, header):
        """Get the value of the specified header.

        The value will be read from the actual message file, not from
        the notmuch database. The header name is case insensitive.

        Returns an empty string ("") if the message does not contain a
        header line matching 'header'.

        :param header: The name of the header to be retrieved.
                       It is not case-sensitive.
        :type header: str
        :returns: The header value as string
        :exception: :exc:`NotmuchError`

                    * STATUS.NOT_INITIALIZED if the message
                      is not initialized.
                    * STATUS.NULL_POINTER if any error occured.
        """
        if self._msg is None:
            raise NotmuchError(STATUS.NOT_INITIALIZED)

        #Returns NULL if any error occurs.
        header = Message._get_header(self._msg, _str(header))
        if header == None:
            raise NotmuchError(STATUS.NULL_POINTER)
        return header.decode('UTF-8', 'ignore')
コード例 #4
0
ファイル: database.py プロジェクト: chaoflow/notmuch
    def create(self, db, querystr):
        """Creates a new query derived from a Database

        This function is utilized by __init__() and usually does not need to
        be called directly.

        :param db: Database to create the query from.
        :type db: :class:`Database`
        :param querystr: The query string
        :type querystr: utf-8 encoded str or unicode
        :returns: Nothing
        :exception:
            :exc:`NullPointerError` if the query creation failed
                (e.g. too little memory).
            :exc:`NotInitializedError` if the underlying db was not
                intitialized.
        """
        db._assert_db_is_initialized()
        # create reference to parent db to keep it alive
        self._db = db
        # create query, return None if too little mem available
        query_p = Query._create(db.db_p, _str(querystr))
        if query_p is None:
            raise NullPointerError
        self._query = query_p
コード例 #5
0
ファイル: database.py プロジェクト: chaoflow/notmuch
    def find_message_by_filename(self, filename):
        """Find a message with the given filename

        .. warning:: This call needs a writeable database in
           :attr:`Database.MODE`.READ_WRITE mode. The underlying library will
           exit the program if this method is used on a read-only
           database!

        :returns: If the database contains a message with the given
            filename, then a class:`Message:` is returned.  This
            function returns None if no message is found with the given
            filename.

        :exception:
            :exc:`OutOfMemoryError`
                  If an Out-of-memory occured while constructing the message.
            :exc:`XapianError`
                  In case of a Xapian Exception. These exceptions
                  include "Database modified" situations, e.g. when the
                  notmuch database has been modified by another program
                  in the meantime. In this case, you should close and
                  reopen the database and retry.
            :exc:`NotInitializedError` if
                    the database was not intitialized.

        *Added in notmuch 0.9*"""
        self._assert_db_is_initialized()
        msg_p = c_void_p()
        status = Database._find_message_by_filename(self._db, _str(filename),
                                                    byref(msg_p))
        if status != STATUS.SUCCESS:
            raise NotmuchError(status)
        return msg_p and Message(msg_p, self) or None
コード例 #6
0
ファイル: database.py プロジェクト: chaoflow/notmuch
    def find_message(self, msgid):
        """Returns a :class:`Message` as identified by its message ID

        Wraps the underlying *notmuch_database_find_message* function.

        :param msgid: The message ID
        :type msgid: unicode or str
        :returns: :class:`Message` or `None` if no message is found.
        :exception:
            :exc:`OutOfMemoryError`
                  If an Out-of-memory occured while constructing the message.
            :exc:`XapianError`
                  In case of a Xapian Exception. These exceptions
                  include "Database modified" situations, e.g. when the
                  notmuch database has been modified by another program
                  in the meantime. In this case, you should close and
                  reopen the database and retry.
            :exc:`NotInitializedError` if
                    the database was not intitialized.
        """
        self._assert_db_is_initialized()
        msg_p = c_void_p()
        status = Database._find_message(self._db, _str(msgid), byref(msg_p))
        if status != STATUS.SUCCESS:
            raise NotmuchError(status)
        return msg_p and Message(msg_p, self) or None
コード例 #7
0
ファイル: database.py プロジェクト: praet/notmuch
    def find_message_by_filename(self, filename):
        """Find a message with the given filename

        .. warning::

            This call needs a writeable database in
            :attr:`Database.MODE`.READ_WRITE mode. The underlying library will
            exit the program if this method is used on a read-only database!

        :returns: If the database contains a message with the given
            filename, then a class:`Message:` is returned.  This
            function returns None if no message is found with the given
            filename.

        :exception:
            :exc:`OutOfMemoryError`
                  If an Out-of-memory occured while constructing the message.
            :exc:`XapianError`
                  In case of a Xapian Exception. These exceptions
                  include "Database modified" situations, e.g. when the
                  notmuch database has been modified by another program
                  in the meantime. In this case, you should close and
                  reopen the database and retry.
            :exc:`NotInitializedError` if
                    the database was not intitialized.

        *Added in notmuch 0.9*"""
        self._assert_db_is_initialized()
        msg_p = NotmuchMessageP()
        status = Database._find_message_by_filename(self._db, _str(filename),
                                                    byref(msg_p))
        if status != STATUS.SUCCESS:
            raise NotmuchError(status)
        return msg_p and Message(msg_p, self) or None
コード例 #8
0
ファイル: database.py プロジェクト: praet/notmuch
    def remove_message(self, filename):
        """Removes a message (filename) from the given notmuch database

        Note that only this particular filename association is removed from
        the database. If the same message (as determined by the message ID)
        is still available via other filenames, then the message will
        persist in the database for those filenames. When the last filename
        is removed for a particular message, the database content for that
        message will be entirely removed.

        :returns: A :attr:`STATUS` value with the following meaning:

             :attr:`STATUS`.SUCCESS
               The last filename was removed and the message was removed
               from the database.
             :attr:`STATUS`.DUPLICATE_MESSAGE_ID
               This filename was removed but the message persists in the
               database with at least one other filename.

        :exception: Raises a :exc:`NotmuchError` with the following meaning.
             If such an exception occurs, nothing was removed from the
             database.

             :attr:`STATUS`.READ_ONLY_DATABASE
               Database was opened in read-only mode so no message can be
               removed.
        """
        self._assert_db_is_initialized()
        return self._remove_message(self._db, _str(filename))
コード例 #9
0
ファイル: database.py プロジェクト: alip/notmuch
    def create(self, db, querystr):
        """Creates a new query derived from a Database

        This function is utilized by __init__() and usually does not need to
        be called directly.

        :param db: Database to create the query from.
        :type db: :class:`Database`
        :param querystr: The query string
        :type querystr: utf-8 encoded str or unicode
        :returns: Nothing
        :exception: :exc:`NotmuchError`

                      * :attr:`STATUS`.NOT_INITIALIZED if db is not inited
                      * :attr:`STATUS`.NULL_POINTER if the query creation failed
                        (too little memory)
        """
        if db.db_p is None:
            raise NotmuchError(STATUS.NOT_INITIALIZED)
        # create reference to parent db to keep it alive
        self._db = db
        # create query, return None if too little mem available
        query_p = Query._create(db.db_p, _str(querystr))
        if query_p is None:
            raise NotmuchError(STATUS.NULL_POINTER)
        self._query = query_p
コード例 #10
0
ファイル: message.py プロジェクト: dme/notmuch
    def get_header(self, header):
        """Get the value of the specified header.

        The value will be read from the actual message file, not from
        the notmuch database. The header name is case insensitive.

        Returns an empty string ("") if the message does not contain a
        header line matching 'header'.

        :param header: The name of the header to be retrieved.
                       It is not case-sensitive.
        :type header: str
        :returns: The header value as string
        :exception: :exc:`NotmuchError`

                    * STATUS.NOT_INITIALIZED if the message
                      is not initialized.
                    * STATUS.NULL_POINTER if any error occured.
        """
        if self._msg is None:
            raise NotmuchError(STATUS.NOT_INITIALIZED)

        #Returns NULL if any error occurs.
        header = Message._get_header(self._msg, _str(header))
        if header == None:
            raise NotmuchError(STATUS.NULL_POINTER)
        return header.decode('UTF-8', 'ignore')
コード例 #11
0
ファイル: database.py プロジェクト: praet/notmuch
    def create(self, db, querystr):
        """Creates a new query derived from a Database

        This function is utilized by __init__() and usually does not need to
        be called directly.

        :param db: Database to create the query from.
        :type db: :class:`Database`
        :param querystr: The query string
        :type querystr: utf-8 encoded str or unicode
        :returns: Nothing
        :exception:
            :exc:`NullPointerError` if the query creation failed
                (e.g. too little memory).
            :exc:`NotInitializedError` if the underlying db was not
                intitialized.
        """
        db._assert_db_is_initialized()
        # create reference to parent db to keep it alive
        self._db = db
        # create query, return None if too little mem available
        query_p = Query._create(db.db_p, _str(querystr))
        if not query_p:
            raise NullPointerError
        self._query = query_p
コード例 #12
0
ファイル: database.py プロジェクト: alip/notmuch
    def create(self, path):
        """Creates a new notmuch database

        This function is used by __init__() and usually does not need
        to be called directly. It wraps the underlying
        *notmuch_database_create* function and creates a new notmuch
        database at *path*. It will always return a database in :attr:`MODE`
        .READ_WRITE mode as creating an empty database for
        reading only does not make a great deal of sense.

        :param path: A directory in which we should create the database.
        :type path: str
        :returns: Nothing
        :exception: :exc:`NotmuchError` in case of any failure
                    (after printing an error message on stderr).
        """
        if self._db is not None:
            raise NotmuchError(message="Cannot create db, this Database() "
                                       "already has an open one.")

        res = Database._create(_str(path), Database.MODE.READ_WRITE)

        if res is None:
            raise NotmuchError(
                message="Could not create the specified database")
        self._db = res
コード例 #13
0
ファイル: database.py プロジェクト: praet/notmuch
    def find_message(self, msgid):
        """Returns a :class:`Message` as identified by its message ID

        Wraps the underlying *notmuch_database_find_message* function.

        :param msgid: The message ID
        :type msgid: unicode or str
        :returns: :class:`Message` or `None` if no message is found.
        :exception:
            :exc:`OutOfMemoryError`
                  If an Out-of-memory occured while constructing the message.
            :exc:`XapianError`
                  In case of a Xapian Exception. These exceptions
                  include "Database modified" situations, e.g. when the
                  notmuch database has been modified by another program
                  in the meantime. In this case, you should close and
                  reopen the database and retry.
            :exc:`NotInitializedError` if
                    the database was not intitialized.
        """
        self._assert_db_is_initialized()
        msg_p = NotmuchMessageP()
        status = Database._find_message(self._db, _str(msgid), byref(msg_p))
        if status != STATUS.SUCCESS:
            raise NotmuchError(status)
        return msg_p and Message(msg_p, self) or None
コード例 #14
0
ファイル: database.py プロジェクト: praet/notmuch
    def remove_message(self, filename):
        """Removes a message (filename) from the given notmuch database

        Note that only this particular filename association is removed from
        the database. If the same message (as determined by the message ID)
        is still available via other filenames, then the message will
        persist in the database for those filenames. When the last filename
        is removed for a particular message, the database content for that
        message will be entirely removed.

        :returns: A :attr:`STATUS` value with the following meaning:

             :attr:`STATUS`.SUCCESS
               The last filename was removed and the message was removed
               from the database.
             :attr:`STATUS`.DUPLICATE_MESSAGE_ID
               This filename was removed but the message persists in the
               database with at least one other filename.

        :exception: Raises a :exc:`NotmuchError` with the following meaning.
             If such an exception occurs, nothing was removed from the
             database.

             :attr:`STATUS`.READ_ONLY_DATABASE
               Database was opened in read-only mode so no message can be
               removed.
        """
        self._assert_db_is_initialized()
        return self._remove_message(self._db, _str(filename))
コード例 #15
0
ファイル: database.py プロジェクト: alip/notmuch
    def open(self, path, mode=0):
        """Opens an existing database

        This function is used by __init__() and usually does not need
        to be called directly. It wraps the underlying
        *notmuch_database_open* function.

        :param status: Open the database in read-only or read-write mode
        :type status:  :attr:`MODE`
        :returns: Nothing
        :exception: Raises :exc:`NotmuchError` in case
                    of any failure (after printing an error message on stderr).
        """
        res = Database._open(_str(path), mode)

        if res is None:
            raise NotmuchError(message="Could not open the specified database")
        self._db = res
コード例 #16
0
ファイル: database.py プロジェクト: praet/notmuch
    def open(self, path, mode=0):
        """Opens an existing database

        This function is used by __init__() and usually does not need
        to be called directly. It wraps the underlying
        *notmuch_database_open* function.

        :param status: Open the database in read-only or read-write mode
        :type status:  :attr:`MODE`
        :returns: Nothing
        :exception: Raises :exc:`NotmuchError` in case of any failure
                    (possibly after printing an error message on stderr).
        """
        res = Database._open(_str(path), mode)

        if not res:
            raise NotmuchError(message="Could not open the specified database")
        self._db = res
コード例 #17
0
ファイル: message.py プロジェクト: dme/notmuch
    def add_tag(self, tag, sync_maildir_flags=False):
        """Adds a tag to the given message

        Adds a tag to the current message. The maximal tag length is defined in
        the notmuch library and is currently 200 bytes.

        :param tag: String with a 'tag' to be added.

        :param sync_maildir_flags: If notmuch configuration is set to do
            this, add maildir flags corresponding to notmuch tags. See
            underlying method :meth:`tags_to_maildir_flags`. Use False
            if you want to add/remove many tags on a message without
            having to physically rename the file every time. Do note,
            that this will do nothing when a message is frozen, as tag
            changes will not be committed to the database yet.

        :returns: STATUS.SUCCESS if the tag was successfully added.
                  Raises an exception otherwise.
        :exception: :exc:`NotmuchError`. They have the following meaning:

                  STATUS.NULL_POINTER
                    The 'tag' argument is NULL
                  STATUS.TAG_TOO_LONG
                    The length of 'tag' is too long
                    (exceeds Message.NOTMUCH_TAG_MAX)
                  STATUS.READ_ONLY_DATABASE
                    Database was opened in read-only mode so message cannot be
                    modified.
                  STATUS.NOT_INITIALIZED
                     The message has not been initialized.
       """
        if self._msg is None:
            raise NotmuchError(STATUS.NOT_INITIALIZED)

        status = self._add_tag(self._msg, _str(tag))

        # bail out on failure
        if status != STATUS.SUCCESS:
            raise NotmuchError(status)

        if sync_maildir_flags:
            self.tags_to_maildir_flags()
        return STATUS.SUCCESS
コード例 #18
0
ファイル: message.py プロジェクト: chaoflow/notmuch
    def add_tag(self, tag, sync_maildir_flags=False):
        """Adds a tag to the given message

        Adds a tag to the current message. The maximal tag length is defined in
        the notmuch library and is currently 200 bytes.

        :param tag: String with a 'tag' to be added.

        :param sync_maildir_flags: If notmuch configuration is set to do
            this, add maildir flags corresponding to notmuch tags. See
            underlying method :meth:`tags_to_maildir_flags`. Use False
            if you want to add/remove many tags on a message without
            having to physically rename the file every time. Do note,
            that this will do nothing when a message is frozen, as tag
            changes will not be committed to the database yet.

        :returns: STATUS.SUCCESS if the tag was successfully added.
                  Raises an exception otherwise.
        :exception: :exc:`NotmuchError`. They have the following meaning:

                  STATUS.NULL_POINTER
                    The 'tag' argument is NULL
                  STATUS.TAG_TOO_LONG
                    The length of 'tag' is too long
                    (exceeds Message.NOTMUCH_TAG_MAX)
                  STATUS.READ_ONLY_DATABASE
                    Database was opened in read-only mode so message cannot be
                    modified.
                  STATUS.NOT_INITIALIZED
                     The message has not been initialized.
       """
        if self._msg is None:
            raise NotmuchError(STATUS.NOT_INITIALIZED)

        status = nmlib.notmuch_message_add_tag(self._msg, _str(tag))

        # bail out on failure
        if status != STATUS.SUCCESS:
            raise NotmuchError(status)

        if sync_maildir_flags:
            self.tags_to_maildir_flags()
        return STATUS.SUCCESS
コード例 #19
0
ファイル: database.py プロジェクト: alip/notmuch
    def find_message_by_filename(self, filename):
        """Find a message with the given filename

        .. warning:: This call needs a writeable database in
           :attr:`Database.MODE`.READ_WRITE mode. The underlying library will
           exit the program if this method is used on a read-only
           database!

        :returns: If the database contains a message with the given
            filename, then a class:`Message:` is returned.  This
            function returns None in the following situations:

                * No message is found with the given filename
                * An out-of-memory situation occurs
                * A Xapian exception occurs

        *Added in notmuch 0.9*"""
        self._assert_db_is_initialized()
        msg_p = Database._find_message_by_filename(self._db, _str(filename))
        return msg_p and Message(msg_p, self) or None
コード例 #20
0
ファイル: database.py プロジェクト: alip/notmuch
    def find_message(self, msgid):
        """Returns a :class:`Message` as identified by its message ID

        Wraps the underlying *notmuch_database_find_message* function.

        :param msgid: The message ID
        :type msgid: string
        :returns: :class:`Message` or `None` if no message is found or
                  if any xapian exception or out-of-memory situation
                  occurs. Do note that Xapian Exceptions include
                  "Database modified" situations, e.g. when the
                  notmuch database has been modified by
                  another program in the meantime. A return value of
                  `None` is therefore no guarantee that the message
                  does not exist.
        :exception: :exc:`NotmuchError` with :attr:`STATUS`.NOT_INITIALIZED if
                  the database was not intitialized.
        """
        self._assert_db_is_initialized()
        msg_p = Database._find_message(self._db, _str(msgid))
        return msg_p and Message(msg_p, self) or None
コード例 #21
0
ファイル: database.py プロジェクト: alip/notmuch
    def add_message(self, filename, sync_maildir_flags=False):
        """Adds a new message to the database

        :param filename: should be a path relative to the path of the
            open database (see :meth:`get_path`), or else should be an
            absolute filename with initial components that match the
            path of the database.

            The file should be a single mail message (not a
            multi-message mbox) that is expected to remain at its
            current location, since the notmuch database will reference
            the filename, and will not copy the entire contents of the
            file.

        :param sync_maildir_flags: If the message contains Maildir
            flags, we will -depending on the notmuch configuration- sync
            those tags to initial notmuch tags, if set to `True`. It is
            `False` by default to remain consistent with the libnotmuch
            API. You might want to look into the underlying method
            :meth:`Message.maildir_flags_to_tags`.

        :returns: On success, we return

           1) a :class:`Message` object that can be used for things
              such as adding tags to the just-added message.
           2) one of the following :attr:`STATUS` values:

              :attr:`STATUS`.SUCCESS
                  Message successfully added to database.
              :attr:`STATUS`.DUPLICATE_MESSAGE_ID
                  Message has the same message ID as another message already
                  in the database. The new filename was successfully added
                  to the list of the filenames for the existing message.

        :rtype:   2-tuple(:class:`Message`, :attr:`STATUS`)

        :exception: Raises a :exc:`NotmuchError` with the following meaning.
              If such an exception occurs, nothing was added to the database.

              :attr:`STATUS`.FILE_ERROR
                      An error occurred trying to open the file, (such as
                      permission denied, or file not found, etc.).
              :attr:`STATUS`.FILE_NOT_EMAIL
                      The contents of filename don't look like an email
                      message.
              :attr:`STATUS`.READ_ONLY_DATABASE
                      Database was opened in read-only mode so no message can
                      be added.
              :attr:`STATUS`.NOT_INITIALIZED
                      The database has not been initialized.
        """
        self._assert_db_is_initialized()
        msg_p = c_void_p()
        status = nmlib.notmuch_database_add_message(self._db,
                                                  _str(filename),
                                                  byref(msg_p))

        if not status in [STATUS.SUCCESS, STATUS.DUPLICATE_MESSAGE_ID]:
            raise NotmuchError(status)

        #construct Message() and return
        msg = Message(msg_p, self)
        #automatic sync initial tags from Maildir flags
        if sync_maildir_flags:
            msg.maildir_flags_to_tags()
        return (msg, status)
コード例 #22
0
ファイル: database.py プロジェクト: praet/notmuch
    def add_message(self, filename, sync_maildir_flags=False):
        """Adds a new message to the database

        :param filename: should be a path relative to the path of the
            open database (see :meth:`get_path`), or else should be an
            absolute filename with initial components that match the
            path of the database.

            The file should be a single mail message (not a
            multi-message mbox) that is expected to remain at its
            current location, since the notmuch database will reference
            the filename, and will not copy the entire contents of the
            file.

        :param sync_maildir_flags: If the message contains Maildir
            flags, we will -depending on the notmuch configuration- sync
            those tags to initial notmuch tags, if set to `True`. It is
            `False` by default to remain consistent with the libnotmuch
            API. You might want to look into the underlying method
            :meth:`Message.maildir_flags_to_tags`.

        :returns: On success, we return

           1) a :class:`Message` object that can be used for things
              such as adding tags to the just-added message.
           2) one of the following :attr:`STATUS` values:

              :attr:`STATUS`.SUCCESS
                  Message successfully added to database.
              :attr:`STATUS`.DUPLICATE_MESSAGE_ID
                  Message has the same message ID as another message already
                  in the database. The new filename was successfully added
                  to the list of the filenames for the existing message.

        :rtype:   2-tuple(:class:`Message`, :attr:`STATUS`)

        :exception: Raises a :exc:`NotmuchError` with the following meaning.
              If such an exception occurs, nothing was added to the database.

              :attr:`STATUS`.FILE_ERROR
                      An error occurred trying to open the file, (such as
                      permission denied, or file not found, etc.).
              :attr:`STATUS`.FILE_NOT_EMAIL
                      The contents of filename don't look like an email
                      message.
              :attr:`STATUS`.READ_ONLY_DATABASE
                      Database was opened in read-only mode so no message can
                      be added.
        """
        self._assert_db_is_initialized()
        msg_p = NotmuchMessageP()
        status = self._add_message(self._db, _str(filename), byref(msg_p))

        if not status in [STATUS.SUCCESS, STATUS.DUPLICATE_MESSAGE_ID]:
            raise NotmuchError(status)

        #construct Message() and return
        msg = Message(msg_p, self)
        #automatic sync initial tags from Maildir flags
        if sync_maildir_flags:
            msg.maildir_flags_to_tags()
        return (msg, status)