From c7b4d8f9793ea461ca6d76f37319de13de5fc19e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 6 Aug 2022 13:28:10 +0530 Subject: [PATCH] Report time left estimate for local calibredb indexing --- src/calibre/db/cli/cmd_fts_index.py | 36 ++++++++++++++++++++++++++--- src/calibre/db/utils.py | 9 ++++++-- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/calibre/db/cli/cmd_fts_index.py b/src/calibre/db/cli/cmd_fts_index.py index 82bfabc481..384c1c72bb 100644 --- a/src/calibre/db/cli/cmd_fts_index.py +++ b/src/calibre/db/cli/cmd_fts_index.py @@ -2,10 +2,38 @@ # License: GPLv3 Copyright: 2017, Kovid Goyal import sys +from functools import lru_cache version = 0 # change this if you change signature of implementation() +@lru_cache +def indexing_progress(): + from threading import Lock + from calibre.db.utils import IndexingProgress + ans = IndexingProgress() + ans.lock = Lock() + return ans + + +def update_indexing_progress(left, total): + ip = indexing_progress() + with ip.lock: + ip.update(left, total) + + +def reset_indexing_progress(): + ip = indexing_progress() + with ip.lock: + ip.reset() + + +def indexing_progress_time_left(): + ip = indexing_progress() + with ip.lock: + return ip.time_left + + def implementation(db, notify_changes, action, adata=None): if action == 'status': if db.is_fts_enabled(): @@ -21,6 +49,7 @@ def implementation(db, notify_changes, action, adata=None): if action == 'disable': if db.is_fts_enabled(): + reset_indexing_progress() db.enable_fts(enabled=False) return @@ -60,10 +89,11 @@ def local_wait_for_completion(db): def listen(event_type, library_id, event_data): if event_type is EventType.indexing_progress_changed: + update_indexing_progress(*event_data) q.put(event_data) def show_progress(left, total): - print('\r' + _('{} of {} book files left to index').format(left, total), flush=True, end=' ' * 10) + print('\r\x1b[K' + _('{} of {} book files indexed, {}').format(total-left, total, indexing_progress_time_left()), flush=True, end=' ...') db.add_listener(listen) l, t = db.fts_indexing_progress() @@ -88,7 +118,7 @@ def main(opts, args, dbctx): s = run_job(dbctx, 'status') if s['enabled']: print(_('FTS Indexing is enabled')) - print(_('{0} of {1} books files remain to be indexed').format(s['left'], s['total'])) + print(_('{0} of {1} books files indexed').format(s['total'] - s['left'], s['total'])) else: print(_('FTS Indexing is disabled')) raise SystemExit(2) @@ -96,7 +126,7 @@ def main(opts, args, dbctx): if action == 'enable': s = run_job(dbctx, 'enable') print(_('FTS indexing has been enabled')) - print(_('{0} of {1} books files remain to be indexed').format(s['left'], s['total'])) + print(_('{0} of {1} books files indexed').format(s['total'] - s['left'], s['total'])) if action == 'disable': print(_('Disabling indexing will mean that all books will have to be re-checked when re-enabling indexing. Are you sure?')) diff --git a/src/calibre/db/utils.py b/src/calibre/db/utils.py index f3a2076aaf..a96856530f 100644 --- a/src/calibre/db/utils.py +++ b/src/calibre/db/utils.py @@ -455,8 +455,7 @@ def human_readable_interval(secs): class IndexingProgress: def __init__(self): - self.left = self.total = -1 - self.clear_rate_information() + self.reset() def __repr__(self): return f'IndexingProgress(left={self.left}, total={self.total})' @@ -465,6 +464,10 @@ class IndexingProgress: from collections import deque self.done_events = deque() + def reset(self): + self.left = self.total = -1 + self.clear_rate_information() + def update(self, left, total): changed = (left, total) != (self.left, self.total) if changed: @@ -486,6 +489,8 @@ class IndexingProgress: @property def time_left(self): + if self.left < 0: + return _('calculating time left') if self.left < 2: return _('almost done') if len(self.done_events) < 5: