From 2b5b422301e593c214c7c763ea3ac8905d719ea8 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 12 Dec 2022 21:37:40 +0530 Subject: [PATCH] Allow enabling indexing from the server --- src/calibre/srv/errors.py | 2 +- src/calibre/srv/fts.py | 14 ++++++++++++++ src/polyglot/http_client.py | 3 ++- src/pyj/book_list/fts.pyj | 26 ++++++++++++++++++++++++-- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/calibre/srv/errors.py b/src/calibre/srv/errors.py index 8f367335df..7c449cd7bf 100644 --- a/src/calibre/srv/errors.py +++ b/src/calibre/srv/errors.py @@ -4,7 +4,7 @@ __license__ = 'GPL v3' __copyright__ = '2015, Kovid Goyal ' -from polyglot import http_client +import http.client as http_client class JobQueueFull(Exception): diff --git a/src/calibre/srv/fts.py b/src/calibre/srv/fts.py index 4aa60db00a..5186f0f276 100644 --- a/src/calibre/srv/fts.py +++ b/src/calibre/srv/fts.py @@ -72,6 +72,20 @@ def fts_reindex(ctx, rd): return '' +@endpoint('/fts/indexing', needs_db_write=True, methods=('POST',)) +def fts_indexing(ctx, rd): + data = rd.request_body_file.read() + try: + enable = json.loads(data) + except Exception: + raise HTTPBadRequest('Invalid boolean') + if not isinstance(enable, bool): + raise HTTPBadRequest('Invalid boolean') + db = get_library_data(ctx, rd)[0] + db.enable_fts(enable) + return '' + + @endpoint('/fts/snippets/{book_ids}', postprocess=json) def fts_snippets(ctx, rd, book_ids): ''' diff --git a/src/polyglot/http_client.py b/src/polyglot/http_client.py index dbd2ccf3dd..ebd2e6b868 100644 --- a/src/polyglot/http_client.py +++ b/src/polyglot/http_client.py @@ -8,9 +8,10 @@ from http.client import (responses, HTTPConnection, HTTPSConnection, NOT_FOUND, NOT_IMPLEMENTED, NOT_MODIFIED, OK, PARTIAL_CONTENT, PRECONDITION_FAILED, REQUEST_ENTITY_TOO_LARGE, REQUEST_URI_TOO_LONG, REQUESTED_RANGE_NOT_SATISFIABLE, REQUEST_TIMEOUT, SEE_OTHER, - SERVICE_UNAVAILABLE, UNAUTHORIZED, _CS_IDLE, _CS_REQ_SENT) + SERVICE_UNAVAILABLE, UNAUTHORIZED, _CS_IDLE, _CS_REQ_SENT, PRECONDITION_REQUIRED, UNPROCESSABLE_ENTITY) if False: responses, HTTPConnection, HTTPSConnection, BAD_REQUEST, FOUND, FORBIDDEN, HTTP_VERSION_NOT_SUPPORTED, INTERNAL_SERVER_ERROR, METHOD_NOT_ALLOWED MOVED_PERMANENTLY, NOT_FOUND, NOT_IMPLEMENTED, NOT_MODIFIED, OK, PARTIAL_CONTENT, PRECONDITION_FAILED, REQUEST_ENTITY_TOO_LARGE, REQUEST_URI_TOO_LONG REQUESTED_RANGE_NOT_SATISFIABLE, REQUEST_TIMEOUT, SEE_OTHER, SERVICE_UNAVAILABLE, UNAUTHORIZED, _CS_IDLE, _CS_REQ_SENT + PRECONDITION_REQUIRED, UNPROCESSABLE_ENTITY diff --git a/src/pyj/book_list/fts.pyj b/src/pyj/book_list/fts.pyj index bdd77de7ee..ff3db5b232 100644 --- a/src/pyj/book_list/fts.pyj +++ b/src/pyj/book_list/fts.pyj @@ -53,13 +53,35 @@ def make_new_fts_query(q): xhr.send() +def enable_indexing(): + def on_response(end_type, xhr, ev): + if end_type is 'abort' or not showing_search_panel(): + return + if end_type is not 'load': + if xhr.status is 403: + return error_dialog(_('Permission denied'), _( + 'You do not have permission to enable indexing. Only logged in users with write permission are allowed.'), xhr.error_html) + return error_dialog(_('Failed to enable indexing'), _('Enabling indexing failed. Click "Show details" for more information.'), xhr.error_html) + info_dialog(_('Indexing enabled'), _('Indexing of this library has been enabled. Depending on library size it can take a long time to index all books.')) + ajax_send(f'fts/indexing', True, on_response) + + +def report_fts_not_enabled(): + clear_to_waiting_for_results(_('No matches found')) + question_dialog(_('Full text searching disabled'), _( + 'Full text search indexing has not been enabled for this library. Once enabled, indexing' + ' will take some time to complete after which searching will work. Enable indexing?'), + def (yes): + if yes: + enable_indexing() + ) + def on_initial_fts_fetched(end_type, xhr, ev): if end_type is 'abort' or not showing_search_panel(): return if end_type is not 'load': if xhr.status is 428: - # TODO: Implement FTS not enabled - pass + return report_fts_not_enabled() return error_dialog(_('Failed to search'), _('The search failed. Click "Show details" for more information.'), xhr.error_html) try: results = JSON.parse(xhr.responseText)