diff options
Diffstat (limited to 'alot/db/thread.py')
-rw-r--r-- | alot/db/thread.py | 100 |
1 files changed, 43 insertions, 57 deletions
diff --git a/alot/db/thread.py b/alot/db/thread.py index bae48b1a..2792737c 100644 --- a/alot/db/thread.py +++ b/alot/db/thread.py @@ -36,6 +36,15 @@ class Thread: """Thread subject""" subject = None + """A list of toplevel messages""" + toplevel_messages = None + + """A list of ids of all messages in this thread in depth-first order""" + message_ids = None + + """A dict mapping Message-Id strings to Message instances""" + messages = None + def __init__(self, dbman, thread): """ :param dbman: db manager that is used for further lookups @@ -46,9 +55,12 @@ class Thread: self._dbman = dbman self._authors = None self.id = thread.get_thread_id() - self._messages = {} self._tags = set() + self.toplevel_messages = [] + self.message_ids = [] + self.messages = {} + self.refresh(thread) def refresh(self, thread=None): @@ -84,8 +96,34 @@ class Thread: self.newest_date = None self._tags = {t for t in thread.get_tags()} - self._messages = {} # this maps messages to its children - self._toplevel_messages = [] + + self.messages, self.toplevel_messages, self.message_ids = self._gather_messages() + + def _gather_messages(self): + query = self._dbman.query('thread:' + self.id) + nm_thread = next(query.search_threads()) + + msgs = {} + msg_tree = [] + ids = [] + + def thread_tree_walk(nm_msg): + msg_id = nm_msg.get_message_id() + ids.append(msg_id) + + replies = [] + for m in nm_msg.get_replies(): + replies.append(thread_tree_walk(m)) + msg = Message(self._dbman, nm_msg, self, replies) + + msgs[msg_id] = msg + + return msg + + for m in nm_thread.get_toplevel_messages(): + msg_tree.append(thread_tree_walk(m)) + + return msgs, msg_tree, ids def __str__(self): return "thread:%s: %s" % (self.id, self.subject) @@ -101,7 +139,7 @@ class Thread: """ tags = set(list(self._tags)) if intersection: - for m in self.get_messages().keys(): + for m in self.messages.values(): tags = tags.intersection(set(m.get_tags())) return tags @@ -172,7 +210,7 @@ class Thread: if self._authors is None: # Sort messages with date first (by date ascending), and those # without a date last. - msgs = sorted(self.get_messages().keys(), + msgs = sorted(self.messages.values(), key=lambda m: m.date or datetime.max) orderby = settings.get('thread_authors_order_by') @@ -222,58 +260,6 @@ class Thread: else: return self._notmuch_authors_string - def get_toplevel_messages(self): - """ - returns all toplevel messages contained in this thread. - This are all the messages without a parent message - (identified by 'in-reply-to' or 'references' header. - - :rtype: list of :class:`~alot.db.message.Message` - """ - if not self._messages: - self.get_messages() - return self._toplevel_messages - - def get_messages(self): - """ - returns all messages in this thread as dict mapping all contained - messages to their direct responses. - - :rtype: dict mapping :class:`~alot.db.message.Message` to a list of - :class:`~alot.db.message.Message`. - """ - if not self._messages: # if not already cached - query = self._dbman.query('thread:' + self.id) - thread = next(query.search_threads()) - - def accumulate(acc, msg): - M = Message(self._dbman, msg, thread=self) - acc[M] = [] - r = msg.get_replies() - if r is not None: - for m in r: - acc[M].append(accumulate(acc, m)) - return M - - self._messages = {} - for m in thread.get_toplevel_messages(): - self._toplevel_messages.append(accumulate(self._messages, m)) - return self._messages - - def get_replies_to(self, msg): - """ - returns all replies to the given message contained in this thread. - - :param msg: parent message to look up - :type msg: :class:`~alot.db.message.Message` - :returns: list of :class:`~alot.db.message.Message` or `None` - """ - msg_hash = self.get_messages() - for m in msg_hash.keys(): - if m.id == msg.id: - return msg_hash[m] - return None - def matches(self, query): """ Check if this thread matches the given notmuch query. |