diff --git a/src/calibre/srv/code.py b/src/calibre/srv/code.py index dc2b96c9fa..5c00b02e6b 100644 --- a/src/calibre/srv/code.py +++ b/src/calibre/srv/code.py @@ -4,7 +4,7 @@ from __future__ import (unicode_literals, division, absolute_import, print_function) -import hashlib, random, zipfile +import hashlib, random, zipfile, shutil, sys from json import load as load_json_file from calibre import as_unicode @@ -33,6 +33,14 @@ def auto_reload(ctx, rd): rd.outheaders.set('Calibre-Auto-Reload-Port', type('')(auto_reload_port), replace_all=True) return lopen(P('content-server/autoreload.js'), 'rb') + +@endpoint('/console-print', methods=('POST',)) +def console_print(ctx, rd): + if not getattr(rd.opts, 'allow_console_print', False): + raise HTTPNotFound('console printing is not allowed') + shutil.copyfileobj(rd.request_body_file, sys.stdout) + return '' + def get_basic_query_data(ctx, rd): db, library_id, library_map, default_library = get_library_data(ctx, rd) skeys = db.field_metadata.sortable_field_keys() @@ -89,6 +97,7 @@ def interface_data(ctx, rd): 'gui_last_modified_display_format':tweaks['gui_last_modified_display_format'], 'use_roman_numerals_for_series_number': get_use_roman(), 'translations': get_translations(), + 'allow_console_print':getattr(rd.opts, 'allow_console_print', False), } ans['library_map'], ans['default_library'] = ctx.library_info(rd) ud = {} diff --git a/src/calibre/srv/standalone.py b/src/calibre/srv/standalone.py index 9de34e67ed..ebce0ed671 100644 --- a/src/calibre/srv/standalone.py +++ b/src/calibre/srv/standalone.py @@ -235,6 +235,7 @@ def main(args=sys.argv): except NoAutoReload as e: raise SystemExit(e.message) opts.auto_reload_port=int(os.environ.get('CALIBRE_AUTORELOAD_PORT', 0)) + opts.allow_console_print = 'CALIBRE_ALLOW_CONSOLE_PRINT' in os.environ server=Server(libraries, opts) if opts.daemonize: if not opts.log and not iswindows: diff --git a/src/pyj/ajax.pyj b/src/pyj/ajax.pyj index ec2d8db838..331588b4a5 100644 --- a/src/pyj/ajax.pyj +++ b/src/pyj/ajax.pyj @@ -99,6 +99,20 @@ def ajax_send(path, data, on_complete, on_progress=None, query=None, timeout=30* xhr.send(JSON.stringify(data)) return xhr + +allow_console_print = False + +def set_allow_console_print(val): + nonlocal allow_console_print + allow_console_print = bool(val) + +def console_print(*args): + print(*args) + if allow_console_print: + data = ' '.join(map(str, args)) + '\n' + xhr = ajax('console-print', def():pass;, method='POST', progress_totals_needed=False) + xhr.send(data) + # TODO: Implement AJAX based switch user by: # 1) POST to a logout URL with an incorrect username and password # 2) Have the server accept that incorrect username/password diff --git a/src/pyj/srv.pyj b/src/pyj/srv.pyj index 27610183de..414317446a 100644 --- a/src/pyj/srv.pyj +++ b/src/pyj/srv.pyj @@ -3,7 +3,7 @@ from __python__ import hash_literals import initialize # noqa: unused-import -from ajax import ajax +from ajax import ajax, set_allow_console_print from elementmaker import E from gettext import gettext as _, install from session import UserSessionData @@ -20,6 +20,7 @@ def on_library_loaded(end_type, xhr, ev): if end_type is 'load': interface_data = JSON.parse(xhr.responseText) interface_data.main_js = main_js + set_allow_console_print(interface_data.allow_console_print) main_js = None script = document.getElementById('main_js') if script: