mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Load the db early during initialization
This commit is contained in:
parent
b99e261260
commit
09717b15c4
@ -21,3 +21,15 @@ def get_current_query(newval):
|
||||
if newval:
|
||||
get_current_query.ans = newval
|
||||
return get_current_query.ans
|
||||
|
||||
|
||||
def get_db(db):
|
||||
if db:
|
||||
get_db.db = db
|
||||
return get_db.db
|
||||
|
||||
|
||||
def get_translations(val):
|
||||
if val:
|
||||
get_translations.ans = val
|
||||
return get_translations.ans
|
||||
|
@ -14,8 +14,10 @@ from utils import parse_url_params
|
||||
|
||||
from book_list.constants import book_list_container_id, read_book_container_id
|
||||
from book_list.theme import get_color
|
||||
from book_list.router import update_window_title, set_default_mode_handler, apply_url
|
||||
from book_list.router import update_window_title, set_default_mode_handler, apply_url, set_mode_handler
|
||||
from book_list.globals import get_db, set_session_data
|
||||
from book_list.ui import apply_url_state as book_list_mode_handler
|
||||
from read_book.ui import ReadUI
|
||||
|
||||
# Register the various panels
|
||||
import book_list.home # noqa: unused-import
|
||||
@ -39,13 +41,17 @@ def onerror(msg, script_url, line_number, column_number, error_object):
|
||||
except:
|
||||
console.log('There was an error in the unhandled exception handler')
|
||||
|
||||
read_ui = None
|
||||
|
||||
def init_ui():
|
||||
nonlocal read_ui
|
||||
install_event_filters()
|
||||
set_default_mode_handler(book_list_mode_handler)
|
||||
window.onerror = onerror
|
||||
translations = get_translations()
|
||||
if translations:
|
||||
install(translations)
|
||||
get_translations(translations)
|
||||
remove_initial_progress_bar()
|
||||
document.head.appendChild(E.style(get_widget_css()))
|
||||
set_css(document.body, background_color=get_color('window-background'), color=get_color('window-foreground'))
|
||||
@ -54,6 +60,9 @@ def init_ui():
|
||||
document.body.lastChild.appendChild(E.div(id=read_book_container_id, style='display: none'))
|
||||
create_modal_container()
|
||||
update_window_title()
|
||||
read_ui = ReadUI()
|
||||
get_db(read_ui.db)
|
||||
set_mode_handler('read_book', read_ui.apply_url_state.bind(read_ui))
|
||||
apply_url()
|
||||
|
||||
def on_data_loaded(end_type, xhr, ev):
|
||||
@ -61,6 +70,9 @@ def on_data_loaded(end_type, xhr, ev):
|
||||
if end_type is 'load':
|
||||
data = JSON.parse(xhr.responseText)
|
||||
update_interface_data(data)
|
||||
interface_data = get_interface_data()
|
||||
sd = UserSessionData(interface_data.username, interface_data.user_session_data)
|
||||
set_session_data(sd)
|
||||
if data.translations:
|
||||
get_translations(data.translations)
|
||||
init_ui()
|
||||
@ -94,4 +106,7 @@ def main():
|
||||
if get_interface_data().is_default:
|
||||
load_interface_data()
|
||||
else:
|
||||
interface_data = get_interface_data()
|
||||
sd = UserSessionData(interface_data.username, interface_data.user_session_data)
|
||||
set_session_data(sd)
|
||||
init_ui()
|
||||
|
@ -8,6 +8,7 @@ from utils import parse_url_params
|
||||
|
||||
mode_handlers = {}
|
||||
default_mode_handler = None
|
||||
read_book_mode = 'read_book'
|
||||
|
||||
|
||||
def set_mode_handler(mode, handler):
|
||||
@ -24,8 +25,13 @@ def update_window_title(subtitle, title='calibre', sep=' :: '):
|
||||
document.title = title + extra
|
||||
|
||||
|
||||
def is_reading_book():
|
||||
cq = get_current_query
|
||||
return cq and cq.mode is read_book_mode
|
||||
|
||||
|
||||
def apply_mode(mode):
|
||||
divid = read_book_container_id if (mode or get_current_query().mode) is 'read_book' else book_list_container_id
|
||||
divid = read_book_container_id if is_reading_book() else book_list_container_id
|
||||
for div in document.getElementById(divid).parentNode.childNodes:
|
||||
div.style.display = 'block' if div.id is divid else 'none'
|
||||
|
||||
@ -37,3 +43,10 @@ def apply_url():
|
||||
apply_mode()
|
||||
handler = mode_handlers[data.mode] or default_mode_handler
|
||||
handler(data)
|
||||
|
||||
|
||||
def push_state(query, replace=False, mode='book_list'):
|
||||
query = {k:query[k] for k in query}
|
||||
if mode is not 'book_list':
|
||||
query.mode = mode
|
||||
# TODO: Implement this (see push_state in boos.pyj)
|
||||
|
@ -1,9 +1,12 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
from __python__ import hash_literals
|
||||
from __python__ import hash_literals, bound_methods
|
||||
|
||||
from gettext import gettext as _
|
||||
from encodings import base64encode, base64decode
|
||||
from modals import error_dialog
|
||||
|
||||
from book_list.router import is_reading_book
|
||||
|
||||
def upgrade_schema(idb, old_version, new_version):
|
||||
print('upgrade_schema:', old_version, new_version)
|
||||
@ -31,13 +34,59 @@ DB_VERSION = 2
|
||||
|
||||
class DB:
|
||||
|
||||
def __init__(self, idb, ui, supports_blobs):
|
||||
self.interface_data = ui.interface_data
|
||||
def __init__(self, callback, show_read_book_error):
|
||||
self.initialized = False
|
||||
self.initialize_error_msg = None
|
||||
self.callback = callback
|
||||
self.show_read_book_error = show_read_book_error
|
||||
self.initialize_stage1()
|
||||
|
||||
def show_error(self, title, msg, det_msg):
|
||||
if is_reading_book():
|
||||
self.show_read_book_error(title, msg, det_msg)
|
||||
else:
|
||||
error_dialog(title, msg, det_msg)
|
||||
|
||||
def initialize_stage1(self):
|
||||
if not window.indexedDB:
|
||||
self.initialize_error_msg = _('Your browser does not support IndexedDB. Cannot read books. Consider using a modern browser, such as Firefox, Chrome or Edge.')
|
||||
self.initialized = True
|
||||
self.callback()
|
||||
return
|
||||
|
||||
request = window.indexedDB.open(DB_NAME, DB_VERSION)
|
||||
|
||||
request.onupgradeneeded = def(event):
|
||||
upgrade_schema(event.target.result, event.oldVersion, event.newVersion)
|
||||
|
||||
request.onblocked = def(event):
|
||||
self.initialize_error_msg = _('Please close all other browser tabs with calibre open')
|
||||
self.initialized = True
|
||||
self.callback()
|
||||
|
||||
request.onerror = def(event):
|
||||
self.initialize_error_msg = _('You must allow calibre to use IndexedDB storage in your browser to read books')
|
||||
self.initialized = True
|
||||
self.callback()
|
||||
|
||||
request.onsuccess = def(event):
|
||||
blob = Blob(['test'], {'type':"text/plain"})
|
||||
idb = event.target.result
|
||||
try:
|
||||
req = idb.transaction(['files'], 'readwrite').objectStore('files').put(blob, ':-test-blob-:')
|
||||
except Exception:
|
||||
self.initialize_stage2(idb, False)
|
||||
req.onsuccess = def(event):
|
||||
self.initialize_stage2(idb, True)
|
||||
req.onerror = def(event):
|
||||
self.initialize_stage2(idb, False)
|
||||
|
||||
def initialize_stage2(self, idb, supports_blobs):
|
||||
self.idb = idb
|
||||
self.supports_blobs = supports_blobs
|
||||
self.initialized = True
|
||||
if not supports_blobs:
|
||||
print('IndexedDB does not support Blob storage, using base64 encoding instead')
|
||||
self.show_error = ui.show_error.bind(ui)
|
||||
print('WARNING: browser does not support blob storage, calibre falling back to base64 encoding')
|
||||
|
||||
idb.onerror = def(event):
|
||||
self.display_error(None, event)
|
||||
@ -48,8 +97,9 @@ class DB:
|
||||
|
||||
idb.onversionchange = def(event):
|
||||
idb.close()
|
||||
ui.show_error(_('Database upgraded!'), _(
|
||||
self.show_error(_('Database upgraded!'), _(
|
||||
'A newer version of calibre is available, please click the reload button in your browser.'))
|
||||
self.callback()
|
||||
|
||||
def display_error(self, msg, event):
|
||||
if event.already_displayed_by_calibre:
|
||||
@ -225,31 +275,8 @@ class DB:
|
||||
books.delete(book.key)
|
||||
next_step()
|
||||
|
||||
def create_db(ui, interface_data):
|
||||
if not window.indexedDB:
|
||||
return ui.db_initialized(_('Your browser does not support IndexedDB. Cannot read books. Consider using a modern browser, such as Firefox, Chrome or Edge.'))
|
||||
|
||||
request = window.indexedDB.open(DB_NAME, DB_VERSION)
|
||||
|
||||
request.onupgradeneeded = def(event):
|
||||
upgrade_schema(event.target.result, event.oldVersion, event.newVersion)
|
||||
|
||||
request.onblocked = def(event):
|
||||
alert(_('Please close all other tabs with a calibre book open'))
|
||||
|
||||
request.onerror = def(event):
|
||||
ui.db_initialized(_('You must allow calibre to use IndexedDB storage in your browser to read books'))
|
||||
|
||||
request.onsuccess = def(event):
|
||||
blob = Blob(['test'], {'type':"text/plain"})
|
||||
idb = event.target.result
|
||||
try:
|
||||
req = idb.transaction(['files'], 'readwrite').objectStore('files').put(blob, ':-test-blob-:')
|
||||
except Exception:
|
||||
print('WARNING: browser does not support blob storage, calibre falling back to base64 encoding')
|
||||
return ui.db_initialized(DB(idb, ui, False))
|
||||
req.onsuccess = def(event):
|
||||
ui.db_initialized(DB(idb, ui, True))
|
||||
req.onerror = def(event):
|
||||
print('WARNING: browser does not support blob storage, calibre falling back to base64 encoding')
|
||||
ui.db_initialized(DB(idb, ui, False))
|
||||
def get_db(callback, show_read_book_error):
|
||||
if not get_db.ans:
|
||||
get_db.ans = DB(callback)
|
||||
return get_db.ans
|
||||
|
@ -10,8 +10,9 @@ from gettext import gettext as _
|
||||
from modals import error_dialog
|
||||
from utils import human_readable, debounce
|
||||
|
||||
from book_list.constants import read_book_container_id
|
||||
from read_book.db import get_db
|
||||
from book_list.router import update_window_title
|
||||
from read_book.db import create_db
|
||||
from read_book.view import View
|
||||
|
||||
RENDER_VERSION = __RENDER_VERSION__
|
||||
@ -19,19 +20,17 @@ MATHJAX_VERSION = "__MATHJAX_VERSION__"
|
||||
|
||||
class ReadUI:
|
||||
|
||||
def __init__(self, interface_data, container):
|
||||
self.interface_data = interface_data
|
||||
self.db = None
|
||||
def __init__(self):
|
||||
self.current_metadata = {'title': _('Unknown book')}
|
||||
self.current_book_id = None
|
||||
self.manifest_xhr = None
|
||||
create_db(self, interface_data)
|
||||
self.pending_load = None
|
||||
self.downloads_in_progress = []
|
||||
self.progress_id = 'book-load-progress'
|
||||
self.display_id = 'book-iframe-container'
|
||||
self.error_id = 'book-global-error-container'
|
||||
self.stacked_widgets = [self.progress_id, self.display_id, self.error_id]
|
||||
container = document.getElementById(read_book_container_id)
|
||||
|
||||
container.appendChild(E.div(
|
||||
id=self.progress_id, style='display:none; text-align: center',
|
||||
@ -51,6 +50,7 @@ class ReadUI:
|
||||
))
|
||||
self.view = View(container.lastChild, self)
|
||||
window.addEventListener('resize', debounce(self.on_resize.bind(self), 250))
|
||||
self.db = get_db(self.db_initialized.bind(self), self.show_error.bind(self))
|
||||
|
||||
def on_resize(self):
|
||||
self.view.on_resize()
|
||||
@ -99,7 +99,7 @@ class ReadUI:
|
||||
|
||||
def load_book(self, book_id, fmt, metadata, force_reload):
|
||||
self.base_url_data = {'book_id':book_id, 'fmt':fmt}
|
||||
if self.db is None:
|
||||
if not self.db.initialized:
|
||||
self.pending_load = [book_id, fmt, metadata, force_reload]
|
||||
return
|
||||
self.start_load(book_id, fmt, metadata, force_reload)
|
||||
@ -126,10 +126,12 @@ class ReadUI:
|
||||
ans.bookpos = bookpos
|
||||
return ans
|
||||
|
||||
def db_initialized(self, db):
|
||||
self.db = db
|
||||
def db_initialized(self):
|
||||
if self.pending_load is not None:
|
||||
pl, self.pending_load = self.pending_load, None
|
||||
if self.db.initialize_error_msg:
|
||||
self.show_error(_('Failed to initialize IndexedDB'), self.db.initialize_error_msg)
|
||||
else:
|
||||
self.start_load(*pl)
|
||||
|
||||
def start_load(self, book_id, fmt, metadata, force_reload):
|
||||
@ -402,3 +404,6 @@ class ReadUI:
|
||||
def display_book_stage2(self, book):
|
||||
self.show_stack(self.display_id)
|
||||
self.view.display_book(book)
|
||||
|
||||
def apply_url_state(self, current_query):
|
||||
pass
|
||||
|
@ -8,7 +8,8 @@ from gettext import gettext as _
|
||||
from utils import html_escape
|
||||
|
||||
from modals import error_dialog, warning_dialog
|
||||
from book_list.globals import get_session_data, get_boss, main_js
|
||||
from book_list.globals import get_session_data, main_js, get_translations
|
||||
from book_list.router import push_state, read_book_mode
|
||||
from read_book.globals import messenger, iframe_id, current_book, set_current_spine_item
|
||||
from read_book.resources import load_resources
|
||||
from read_book.overlay import Overlay
|
||||
@ -228,7 +229,7 @@ class View:
|
||||
|
||||
def on_iframe_ready(self, data):
|
||||
messenger.reset()
|
||||
self.send_message('initialize', secret=messenger.secret, translations=self.ui.interface_data.translations)
|
||||
self.send_message('initialize', secret=messenger.secret, translations=get_translations())
|
||||
self.iframe_ready = True
|
||||
if self.pending_load:
|
||||
data = self.pending_load
|
||||
@ -354,7 +355,7 @@ class View:
|
||||
|
||||
def on_update_cfi(self, data):
|
||||
self.currently_showing.bookpos = data.cfi
|
||||
get_boss().push_state(replace=data.replace_history)
|
||||
push_state(self.url_data, replace=data.replace_history, mode=read_book_mode)
|
||||
unkey = username_key(self.ui.interface_data.username)
|
||||
if not self.book.last_read_position:
|
||||
self.book.last_read_position = {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user