mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Use the HTML 5 appcache to make the browser e-book viewer fully offline-able
This commit is contained in:
parent
00147c8e6c
commit
17a5977e4f
1
.gitignore
vendored
1
.gitignore
vendored
@ -22,6 +22,7 @@ resources/template-functions.json
|
|||||||
resources/editor-functions.json
|
resources/editor-functions.json
|
||||||
resources/user-manual-translation-stats.json
|
resources/user-manual-translation-stats.json
|
||||||
resources/content-server/index-generated.html
|
resources/content-server/index-generated.html
|
||||||
|
resources/content-server/calibre.appcache
|
||||||
resources/content-server/locales.zip
|
resources/content-server/locales.zip
|
||||||
resources/content-server/mathjax.zip.xz
|
resources/content-server/mathjax.zip.xz
|
||||||
resources/content-server/mathjax.version
|
resources/content-server/mathjax.version
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html manifest="calibre.appcache">
|
||||||
<head>
|
<head>
|
||||||
<title>calibre</title>
|
<title>calibre</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
@ -1,23 +1,28 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python2
|
||||||
# vim:fileencoding=utf-8
|
# vim:fileencoding=utf-8
|
||||||
from __future__ import (unicode_literals, division, absolute_import,
|
# License: GPLv3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
print_function)
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
import atexit
|
||||||
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
|
import errno
|
||||||
|
import glob
|
||||||
import os, sys, atexit, errno, subprocess, glob, shutil, json, re
|
import json
|
||||||
from io import BytesIO
|
import os
|
||||||
from threading import local
|
import re
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from threading import Thread
|
from io import BytesIO
|
||||||
from Queue import Queue, Empty
|
from Queue import Empty, Queue
|
||||||
|
from threading import Thread, local
|
||||||
|
|
||||||
|
from calibre import force_unicode
|
||||||
|
from calibre.constants import __appname__, __version__, cache_dir
|
||||||
|
from calibre.utils.terminal import ANSIStream
|
||||||
from duktape import Context, JSError, to_python
|
from duktape import Context, JSError, to_python
|
||||||
from lzma.xz import compress, decompress
|
from lzma.xz import compress, decompress
|
||||||
from calibre import force_unicode
|
|
||||||
from calibre.constants import cache_dir, __appname__, __version__
|
|
||||||
from calibre.utils.terminal import ANSIStream
|
|
||||||
|
|
||||||
COMPILER_PATH = 'rapydscript/compiler.js.xz'
|
COMPILER_PATH = 'rapydscript/compiler.js.xz'
|
||||||
|
|
||||||
@ -47,6 +52,8 @@ def update_rapydscript():
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Compiler {{{
|
# Compiler {{{
|
||||||
|
|
||||||
|
|
||||||
tls = local()
|
tls = local()
|
||||||
|
|
||||||
|
|
||||||
@ -72,6 +79,7 @@ class CompileFailure(ValueError):
|
|||||||
def default_lib_dir():
|
def default_lib_dir():
|
||||||
return P('rapydscript/lib', allow_user_override=False)
|
return P('rapydscript/lib', allow_user_override=False)
|
||||||
|
|
||||||
|
|
||||||
_cache_dir = None
|
_cache_dir = None
|
||||||
|
|
||||||
|
|
||||||
@ -125,6 +133,7 @@ def compile_pyj(data, filename='<stdin>', beautify=True, private_scope=True, lib
|
|||||||
raise CompileFailure(result.stack)
|
raise CompileFailure(result.stack)
|
||||||
raise CompileFailure(repr(presult))
|
raise CompileFailure(repr(presult))
|
||||||
|
|
||||||
|
|
||||||
has_external_compiler = None
|
has_external_compiler = None
|
||||||
|
|
||||||
|
|
||||||
@ -170,6 +179,20 @@ def compile_fast(data, filename=None, beautify=True, private_scope=True, libdir=
|
|||||||
return js.decode('utf-8')
|
return js.decode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
def create_manifest(html):
|
||||||
|
import hashlib
|
||||||
|
from calibre.library.field_metadata import category_icon_map
|
||||||
|
h = hashlib.sha256(html)
|
||||||
|
for ci in category_icon_map.itervalues():
|
||||||
|
h.update(I(ci, data=True))
|
||||||
|
icons = {'icon/' + x for x in category_icon_map.itervalues()}
|
||||||
|
icons.add('favicon.png')
|
||||||
|
h.update(I('lt.png', data=True))
|
||||||
|
manifest = '\n'.join(sorted(icons))
|
||||||
|
return 'CACHE MANIFEST\n# {}\n{}\n\nNETWORK:\n*'.format(
|
||||||
|
h.hexdigest(), manifest).encode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
def compile_srv():
|
def compile_srv():
|
||||||
d = os.path.dirname
|
d = os.path.dirname
|
||||||
base = d(d(d(d(os.path.abspath(__file__)))))
|
base = d(d(d(d(os.path.abspath(__file__)))))
|
||||||
@ -195,8 +218,12 @@ def compile_srv():
|
|||||||
js = compile_fast(f.read(), fname).replace('__RENDER_VERSION__', rv, 1).replace('__MATHJAX_VERSION__', mathjax_version, 1).encode('utf-8')
|
js = compile_fast(f.read(), fname).replace('__RENDER_VERSION__', rv, 1).replace('__MATHJAX_VERSION__', mathjax_version, 1).encode('utf-8')
|
||||||
with lopen(os.path.join(base, 'index.html'), 'rb') as f:
|
with lopen(os.path.join(base, 'index.html'), 'rb') as f:
|
||||||
html = f.read().replace(b'RESET_STYLES', reset, 1).replace(b'ICONS', icons, 1).replace(b'MAIN_JS', js, 1)
|
html = f.read().replace(b'RESET_STYLES', reset, 1).replace(b'ICONS', icons, 1).replace(b'MAIN_JS', js, 1)
|
||||||
|
|
||||||
|
manifest = create_manifest(html)
|
||||||
with lopen(os.path.join(base, 'index-generated.html'), 'wb') as f:
|
with lopen(os.path.join(base, 'index-generated.html'), 'wb') as f:
|
||||||
f.write(html)
|
f.write(html)
|
||||||
|
with lopen(os.path.join(base, 'calibre.appcache'), 'wb') as f:
|
||||||
|
f.write(manifest)
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
@ -420,5 +447,6 @@ def main(args=sys.argv):
|
|||||||
def entry():
|
def entry():
|
||||||
main(sys.argv[1:])
|
main(sys.argv[1:])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -46,6 +46,18 @@ class Watcher:
|
|||||||
self.reload_app()
|
self.reload_app()
|
||||||
|
|
||||||
def reload_app(self):
|
def reload_app(self):
|
||||||
|
appcache = window.top.applicationCache
|
||||||
|
for which in 'cached error noupdate obsolete updateready'.split(' '):
|
||||||
|
appcache.addEventListener(which, self.cache_update_done, False)
|
||||||
|
try:
|
||||||
|
appcache.update()
|
||||||
|
except: # In chrome with devtools open, appcache is sometimes disabled/fails
|
||||||
|
window.location.reload(True)
|
||||||
|
|
||||||
|
def cache_update_done(self):
|
||||||
|
appcache = window.top.applicationCache
|
||||||
|
if appcache.status is appcache.UPDATEREADY:
|
||||||
|
appcache.swapCache()
|
||||||
window.location.reload(True)
|
window.location.reload(True)
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
from __python__ import hash_literals
|
from __python__ import hash_literals
|
||||||
|
|
||||||
|
from gettext import gettext as _
|
||||||
|
|
||||||
import initialize # noqa: unused-import
|
import initialize # noqa: unused-import
|
||||||
from ajax import ajax
|
from ajax import ajax
|
||||||
from autoreload import create_auto_reload_watcher
|
from autoreload import create_auto_reload_watcher
|
||||||
@ -14,6 +16,12 @@ is_running_in_iframe = False # Changed before script is loaded in the iframe
|
|||||||
if is_running_in_iframe:
|
if is_running_in_iframe:
|
||||||
init()
|
init()
|
||||||
else:
|
else:
|
||||||
|
window.applicationCache.addEventListener('updateready', def():
|
||||||
|
if window.applicationCache.status is window.applicationCache.UPDATEREADY:
|
||||||
|
window.applicationCache.swapCache()
|
||||||
|
if window.confirm(_('The calibre web application has been updated. Do you want reload the site?')):
|
||||||
|
window.location.reload()
|
||||||
|
, False)
|
||||||
script = document.currentScript or document.scripts[0]
|
script = document.currentScript or document.scripts[0]
|
||||||
main_js(script.textContent)
|
main_js(script.textContent)
|
||||||
script.parentNode.removeChild(script) # save some memory
|
script.parentNode.removeChild(script) # save some memory
|
||||||
|
Loading…
x
Reference in New Issue
Block a user