diff options
Diffstat (limited to 'src/leap/mail/imap/messages.py')
-rw-r--r-- | src/leap/mail/imap/messages.py | 250 |
1 files changed, 2 insertions, 248 deletions
diff --git a/src/leap/mail/imap/messages.py b/src/leap/mail/imap/messages.py index b7bb6ee..02aac2e 100644 --- a/src/leap/mail/imap/messages.py +++ b/src/leap/mail/imap/messages.py @@ -15,23 +15,20 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. """ -IMAPMessage and IMAPMessageCollection. +IMAPMessage implementation. """ import logging from twisted.mail import imap4 from twisted.internet import defer from zope.interface import implements -from leap.common.check import leap_assert, leap_assert_type from leap.mail.utils import find_charset logger = logging.getLogger(__name__) -# TODO ------------------------------------------------------------ - +# TODO # [ ] Add ref to incoming message during add_msg. -# [ ] Delete incoming mail only after successful write. class IMAPMessage(object): @@ -251,246 +248,3 @@ def _format_headers(headers, negate, *names): if cond(key): _headers[key] = value return _headers - - -class IMAPMessageCollection(object): - """ - A collection of messages, surprisingly. - - It is tied to a selected mailbox name that is passed to its constructor. - Implements a filter query over the messages contained in a soledad - database. - """ - - messageklass = IMAPMessage - - # TODO - # [ ] Add RECENT flags docs to mailbox-doc attributes (list-of-uids) - # [ ] move Query for all the headers documents to Collection - - # TODO this should be able to produce a MessageSet methinks - # TODO --- reimplement, review and prune documentation below. - - FLAGS_DOC = "FLAGS" - HEADERS_DOC = "HEADERS" - CONTENT_DOC = "CONTENT" - """ - RECENT_DOC is a document that stores a list of the UIDs - with the recent flag for this mailbox. It deserves a special treatment - because: - (1) it cannot be set by the user - (2) it's a flag that we set inmediately after a fetch, which is quite - often. - (3) we need to be able to set/unset it in batches without doing a single - write for each element in the sequence. - """ - RECENT_DOC = "RECENT" - """ - HDOCS_SET_DOC is a document that stores a set of the Document-IDs - (the u1db index) for all the headers documents for a given mailbox. - We use it to prefetch massively all the headers for a mailbox. - This is the second massive query, after fetching all the FLAGS, that - a typical IMAP MUA will do in a case where we do not have local disk cache. - """ - HDOCS_SET_DOC = "HDOCS_SET" - - def __init__(self, collection): - """ - Constructor for IMAPMessageCollection. - - :param collection: an instance of a MessageCollection - :type collection: MessageCollection - """ - leap_assert( - collection.is_mailbox_collection(), - "Need a mailbox name to initialize") - mbox_name = collection.mbox_name - leap_assert(mbox_name.strip() != "", "mbox cannot be blank space") - leap_assert(isinstance(mbox_name, (str, unicode)), - "mbox needs to be a string") - self.collection = collection - - # XXX this has to be done in IMAPAccount - # (Where the collection must be instantiated and passed to us) - # self.mbox = normalize_mailbox(mbox) - - @property - def mbox_name(self): - """ - Return the string that identifies this mailbox. - """ - return self.collection.mbox_name - - def add_msg(self, raw, flags=None, date=None): - """ - Creates a new message document. - - :param raw: the raw message - :type raw: str - - :param flags: flags - :type flags: list - - :param date: the received date for the message - :type date: str - - :return: a deferred that will be fired with the message - uid when the adding succeed. - :rtype: deferred - """ - if flags is None: - flags = tuple() - leap_assert_type(flags, tuple) - return self.collection.add_msg(raw, flags, date) - - def get_msg_by_uid(self, uid, absolute=True): - """ - Retrieves a IMAPMessage by UID. - This is used primarity in the Mailbox fetch and store methods. - - :param uid: the message uid to query by - :type uid: int - - :rtype: IMAPMessage - """ - def make_imap_msg(msg): - kls = self.messageklass - # TODO --- remove ref to collection - return kls(msg, self.collection) - - d = self.collection.get_msg_by_uid(uid, absolute=absolute) - d.addCalback(make_imap_msg) - return d - - - # TODO -- move this to collection too - # Used for the Search (Drafts) queries? - def _get_uid_from_msgid(self, msgid): - """ - Return a UID for a given message-id. - - It first gets the headers-doc for that msg-id, and - it found it queries the flags doc for the current mailbox - for the matching content-hash. - - :return: A UID, or None - """ - return self._get_uid_from_msgidCb(msgid) - - # TODO handle deferreds - def set_flags(self, messages, flags, mode): - """ - Set flags for a sequence of messages. - - :param mbox: the mbox this message belongs to - :type mbox: str or unicode - :param messages: the messages to iterate through - :type messages: sequence - :flags: the flags to be set - :type flags: tuple - :param mode: the mode for setting. 1 is append, -1 is remove, 0 set. - :type mode: int - :param observer: a deferred that will be called with the dictionary - mapping UIDs to flags after the operation has been - done. - :type observer: deferred - """ - getmsg = self.get_msg_by_uid - - def set_flags(uid, flags, mode): - msg = getmsg(uid) - if msg is not None: - # XXX IMAPMessage needs access to the collection - # to be able to set flags. Better if we make use - # of collection... here. - return uid, msg.setFlags(flags, mode) - - setted_flags = [set_flags(uid, flags, mode) for uid in messages] - result = dict(filter(None, setted_flags)) - # XXX return gatherResults or something - return result - - def count(self): - """ - Return the count of messages for this mailbox. - - :rtype: int - """ - return self.collection.count() - - # headers query - - def all_headers(self): - """ - Return a dict with all the header documents for this - mailbox. - - :rtype: dict - """ - # Use self.collection.mbox_indexer - # and derive all the doc_ids for the hdocs - raise NotImplementedError() - - # unseen messages - - def unseen_iter(self): - """ - Get an iterator for the message UIDs with no `seen` flag - for this mailbox. - - :return: iterator through unseen message doc UIDs - :rtype: iterable - """ - raise NotImplementedError() - - def count_unseen(self): - """ - Count all messages with the `Unseen` flag. - - :returns: count - :rtype: int - """ - return len(list(self.unseen_iter())) - - def get_unseen(self): - """ - Get all messages with the `Unseen` flag - - :returns: a list of LeapMessages - :rtype: list - """ - raise NotImplementedError() - #return [self.messageklass(self._soledad, doc_id, self.mbox) - #for doc_id in self.unseen_iter()] - - # recent messages - - def count_recent(self): - """ - Count all messages with the `Recent` flag. - It just retrieves the length of the recent_flags set, - which is stored in a specific type of document for - this collection. - - :returns: count - :rtype: int - """ - raise NotImplementedError() - - # magic - - def __len__(self): - """ - Returns the number of messages on this mailbox. - :rtype: int - """ - return self.count() - - def __repr__(self): - """ - Representation string for this object. - """ - return u"<IMAPMessageCollection: mbox '%s' (%s)>" % ( - self.mbox_name, self.count()) - - # TODO implement __iter__ ? |