summaryrefslogtreecommitdiff
path: root/alot/buffers
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2021-01-20 22:04:43 +0100
committerAnton Khirnov <anton@khirnov.net>2021-01-20 22:04:43 +0100
commit21843511ef9e0482da917c9e01f1add1949fabde (patch)
treed6d5264d1641671c1171195c44ef2b7f490b6fd7 /alot/buffers
parent6b2a8ee809353f8a18f0bc6ac4b9af30e66d8762 (diff)
buffers: make get_info() asynchronous
Allows computing message/thread counts asynchronously in a separate thread.
Diffstat (limited to 'alot/buffers')
-rw-r--r--alot/buffers/buffer.py2
-rw-r--r--alot/buffers/envelope.py2
-rw-r--r--alot/buffers/namedqueries.py2
-rw-r--r--alot/buffers/search.py66
-rw-r--r--alot/buffers/thread.py2
5 files changed, 48 insertions, 26 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()