summaryrefslogtreecommitdiff
path: root/alot/buffers/search.py
diff options
context:
space:
mode:
Diffstat (limited to 'alot/buffers/search.py')
-rw-r--r--alot/buffers/search.py66
1 files changed, 44 insertions, 22 deletions
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,