diff options
author | Anton Khirnov <anton@khirnov.net> | 2021-01-20 22:04:43 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2021-01-20 22:04:43 +0100 |
commit | 21843511ef9e0482da917c9e01f1add1949fabde (patch) | |
tree | d6d5264d1641671c1171195c44ef2b7f490b6fd7 | |
parent | 6b2a8ee809353f8a18f0bc6ac4b9af30e66d8762 (diff) |
buffers: make get_info() asynchronous
Allows computing message/thread counts asynchronously in a separate
thread.
-rw-r--r-- | alot/buffers/buffer.py | 2 | ||||
-rw-r--r-- | alot/buffers/envelope.py | 2 | ||||
-rw-r--r-- | alot/buffers/namedqueries.py | 2 | ||||
-rw-r--r-- | alot/buffers/search.py | 66 | ||||
-rw-r--r-- | alot/buffers/thread.py | 2 | ||||
-rw-r--r-- | alot/db/manager.py | 2 | ||||
-rw-r--r-- | alot/ui.py | 2 |
7 files changed, 49 insertions, 29 deletions
diff --git a/alot/buffers/buffer.py b/alot/buffers/buffer.py index d5b662eb..f78ae0a5 100644 --- a/alot/buffers/buffer.py +++ b/alot/buffers/buffer.py @@ -28,7 +28,7 @@ class Buffer: """called before buffer is closed""" pass - def get_info(self): + async def get_info(self): """ return dict of meta infos about this buffer. This can be requested to be displayed in the statusbar. diff --git a/alot/buffers/envelope.py b/alot/buffers/envelope.py index 83a3c57b..55745ed0 100644 --- a/alot/buffers/envelope.py +++ b/alot/buffers/envelope.py @@ -65,7 +65,7 @@ class EnvelopeBuffer(Buffer): to = self.envelope.get('To', fallback='unset') return '[envelope] to: %s' % (shorten_author_string(to, 400)) - def get_info(self): + async def get_info(self): info = {} info['to'] = self.envelope.get('To', fallback='unset') return info diff --git a/alot/buffers/namedqueries.py b/alot/buffers/namedqueries.py index 2ff7ac08..80dcd13e 100644 --- a/alot/buffers/namedqueries.py +++ b/alot/buffers/namedqueries.py @@ -74,7 +74,7 @@ class NamedQueriesBuffer(Buffer): """returns selected query""" return self.querylist.get_focus()[0].original_widget.query - def get_info(self): + async def get_info(self): info = {} info['query_count'] = len(self.queries) diff --git a/alot/buffers/search.py b/alot/buffers/search.py index 8cd76a87..c1650db4 100644 --- a/alot/buffers/search.py +++ b/alot/buffers/search.py @@ -1,6 +1,9 @@ # Copyright (C) 2011-2018 Patrick Totzke <patricktotzke@gmail.com> # This file is released under the GNU GPL, version 3 or a later revision. # For further details see the COPYING file + +import asyncio + import urwid from notmuch2 import NotmuchError @@ -93,8 +96,8 @@ class SearchBuffer(Buffer): modename = 'search' - _result_count_val = None - _thread_count_val = None + _message_count = None + _thread_count = None def __init__(self, ui, initialquery='', sort_order=None): self.dbman = ui.dbman @@ -107,27 +110,46 @@ class SearchBuffer(Buffer): super().__init__() def __str__(self): - formatstring = '[search] for "%s" (%d message%s in %d thread%s)' - return formatstring % (self.querystring, - self._result_count, 's' if self._result_count > 1 else '', - self._thread_count, 's' if self._thread_count > 1 else '') + ret = '[search] for "%s"' % self.querystring - @property - def _result_count(self): - if self._result_count_val is None: - self._result_count_val = self.dbman.count_messages(self.querystring) - return self._result_count_val - @property - def _thread_count(self): - if self._thread_count_val is None: - self._thread_count_val = self.dbman.count_threads(self.querystring) - return self._thread_count_val + if self._thread_count is not None: + threadstr = ' in %d thread%s' % (self._thread_count, '' if self._thread_count == 1 else 's') + else: + threadstr = '' + + if self._message_count is not None: + ret += ' (%d message%s%s)' % (self._message_count, '' if self._message_count == 1 else 's', + threadstr) + + return ret + + async def _calc_result_count(self): + """ + Asynchronously compute message/thread counts. + Cache and return them. + """ + # instance variables can get reset if rebuild() gets called + # while we are waiting, hence this code + message_count = self._message_count + thread_count = self._thread_count + + if message_count is None or thread_count is None: + tasks = [self.ui._loop.run_in_executor(None, f, self.querystring) + for f in (self.dbman.count_messages, self.dbman.count_threads)] + message_count, thread_count = await asyncio.gather(*tasks) + + self._message_count = message_count + self._thread_count = thread_count + + return message_count, thread_count + + async def get_info(self): + message_count, thread_count = await self._calc_result_count() - def get_info(self): info = {} - info['querystring'] = self.querystring - info['result_count'] = self._result_count - info['thread_count'] = self._thread_count + info['querystring'] = self.querystring + info['result_count'] = message_count + info['thread_count'] = thread_count info['result_count_positive'] = 's' if info['result_count'] > 1 else '' return info @@ -138,8 +160,8 @@ class SearchBuffer(Buffer): else: exclude_tags = frozenset() - self._result_count_val = None - self._thread_count_val = None + self._result_count = None + self._thread_count = None try: threads = self.dbman.get_threads(self.querystring, self.sort_order, diff --git a/alot/buffers/thread.py b/alot/buffers/thread.py index 47b7f9d0..30d313af 100644 --- a/alot/buffers/thread.py +++ b/alot/buffers/thread.py @@ -97,7 +97,7 @@ class ThreadBuffer(Buffer): for tag in tags] return ' '.join(trans) - def get_info(self): + async def get_info(self): info = {} info['subject'] = self.thread.subject info['authors'] = self.thread.get_authors_string() diff --git a/alot/db/manager.py b/alot/db/manager.py index 728dcddb..6477d696 100644 --- a/alot/db/manager.py +++ b/alot/db/manager.py @@ -154,8 +154,6 @@ class DBManager: def _db_ro(self): return closing(Database(path = self.path, mode = Database.MODE.READ_ONLY)) - - def count_messages(self, querystring): """returns number of messages that match `querystring`""" with self._db_ro() as db: @@ -71,7 +71,7 @@ class _StatusBar(urwid.WidgetWrap): self._do_update(fmtstrings, initial_info) async def sb_update(): - buf_info = buf.get_info() + buf_info = await buf.get_info() buf_info.update(info) self._do_update(fmtstrings, buf_info) |