diff --git a/resources/content-server/autoreload.js b/resources/content-server/autoreload.js deleted file mode 100644 index 573cee5355..0000000000 --- a/resources/content-server/autoreload.js +++ /dev/null @@ -1,55 +0,0 @@ -/* vim:fileencoding=utf-8 - * - * Copyright (C) 2015 Kovid Goyal - * - * Distributed under terms of the GPLv3 license - */ - -(function(autoreload_port) { - "use strict"; - var host = document.location.host.split(':')[0]; - var url = 'ws://' + host + ':' + autoreload_port; - var MAX_RETRIES = 10; - - function ReconnectingWebSocket() { - self = this; - self.retries = 0; - self.interval = 100; - self.disable = false; - self.opened_at_least_once = false; - - self.reconnect = function() { - self.ws = new WebSocket(url); - - self.ws.onopen = function(event) { - self.retries = 0; - self.opened_at_least_once = true; - self.interval = 100; - console.log('Connected to reloading WebSocket server at: ' + url); - window.addEventListener('beforeunload', function (event) { - console.log('Shutting down connection to reload server, before page unload'); - self.disable = true; - self.ws.close(); - }); - }; - - self.ws.onmessage = function(event) { - if (event.data !== 'ping') console.log('Received mesasge from reload server: ' + event.data); - if (event.data === 'reload') window.location.reload(true); - }; - - self.ws.onclose = function(event) { - if (self.disable || !self.opened_at_least_once) return; - console.log('Connection to reload server closed with code: ' + event.code + ' and reason: ' + event.reason); - self.retries += 1; - if (self.retries < MAX_RETRIES) { - setTimeout(self.reconnect, self.interval); - } else window.location.reload(true); - }; - }; - self.reconnect(); - } - - var sock = new ReconnectingWebSocket(); -})(AUTORELOAD_PORT); - diff --git a/src/calibre/srv/code.py b/src/calibre/srv/code.py index 0701d26b4f..ea105c82be 100644 --- a/src/calibre/srv/code.py +++ b/src/calibre/srv/code.py @@ -28,12 +28,16 @@ def index(ctx, rd): return lopen(P('content-server/index-generated.html'), 'rb') -@endpoint('/auto-reload', auth_required=False) +@endpoint('/calibre.appcache', auth_required=False, cache_control='no-cache') +def appcache(ctx, rd): + return lopen(P('content-server/calibre.appcache'), 'rb') + + +@endpoint('/auto-reload-port', auth_required=False, cache_control='no-cache') def auto_reload(ctx, rd): auto_reload_port = getattr(rd.opts, 'auto_reload_port', 0) - if auto_reload_port > 0: - rd.outheaders.set('Calibre-Auto-Reload-Port', type('')(auto_reload_port), replace_all=True) - return lopen(P('content-server/autoreload.js'), 'rb') + rd.outheaders.set('Content-Type', 'text/plain') + return str(max(0, auto_reload_port)) @endpoint('/console-print', methods=('POST',)) diff --git a/src/pyj/autoreload.pyj b/src/pyj/autoreload.pyj new file mode 100644 index 0000000000..98c9f3f543 --- /dev/null +++ b/src/pyj/autoreload.pyj @@ -0,0 +1,55 @@ +# vim:fileencoding=utf-8 +# License: GPL v3 Copyright: 2017, Kovid Goyal +from __python__ import bound_methods, hash_literals + +MAX_RETRIES = 10 + +class Watcher: + + def __init__(self, autoreload_port): + host = document.location.host.split(':')[0] + self.url = 'ws://' + host + ':' + autoreload_port + self.retries = 0 + self.interval = 100 + self.disable = False + self.opened_at_least_once = False + self.reconnect() + + def reconnect(self): + self.ws = WebSocket(self.url) + + self.ws.onopen = def(event): + self.retries = 0 + self.opened_at_least_once = True + self.interval = 100 + print('Connected to reloading WebSocket server at: ' + self.url) + window.addEventListener('beforeunload', def (event): + print('Shutting down connection to reload server, before page unload') + self.disable = True + self.ws.close() + ) + + self.ws.onmessage = def(event): + if event.data is not 'ping': + print('Received mesasge from reload server: ' + event.data) + if event.data is 'reload': + self.reload_app() + + self.ws.onclose = def (event): + if self.disable or not self.opened_at_least_once: + return + print('Connection to reload server closed with code: ' + event.code + ' and reason: ' + event.reason) + self.retries += 1 + if (self.retries < MAX_RETRIES): + setTimeout(self.reconnect, self.interval) + else: + self.reload_app() + + def reload_app(self): + window.location.reload(True) + + +def create_auto_reload_watcher(autoreload_port): + if not create_auto_reload_watcher.watcher: + create_auto_reload_watcher.watcher = Watcher(autoreload_port) + return create_auto_reload_watcher.watcher diff --git a/src/pyj/srv.pyj b/src/pyj/srv.pyj index 8ef60d169d..c31d4bf03c 100644 --- a/src/pyj/srv.pyj +++ b/src/pyj/srv.pyj @@ -4,7 +4,7 @@ from __python__ import hash_literals import initialize # noqa: unused-import from ajax import ajax - +from autoreload import create_auto_reload_watcher from book_list.globals import main_js from book_list.main import main from read_book.iframe import init @@ -23,10 +23,9 @@ else: # we know are going to be needed immediately. window.addEventListener('load', main) - ajax('auto-reload', def(end_type, xhr, event): + ajax('auto-reload-port', def(end_type, xhr, event): if end_type is 'load': - port = xhr.getResponseHeader('Calibre-Auto-Reload-Port') - if port: - src = xhr.responseText.replace('AUTORELOAD_PORT', port) - eval(src) + port = parseInt(xhr.responseText) + if not isNaN(port) and port > 0: + create_auto_reload_watcher(port) ).send() # We must bypass cache as otherwise we could get stale port info