mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement manual position sync
This commit is contained in:
parent
66e4cd3779
commit
84f7464be5
@ -5,9 +5,9 @@ from __python__ import bound_methods, hash_literals
|
|||||||
from elementmaker import E
|
from elementmaker import E
|
||||||
from gettext import gettext as _
|
from gettext import gettext as _
|
||||||
|
|
||||||
from ajax import ajax
|
|
||||||
from book_list.cover_grid import BORDER_RADIUS
|
from book_list.cover_grid import BORDER_RADIUS
|
||||||
from book_list.globals import get_db
|
from book_list.globals import get_db
|
||||||
|
from book_list.library_data import sync_library_books
|
||||||
from book_list.router import open_book, update_window_title
|
from book_list.router import open_book, update_window_title
|
||||||
from book_list.top_bar import create_top_bar
|
from book_list.top_bar import create_top_bar
|
||||||
from book_list.ui import set_default_panel_handler, show_panel
|
from book_list.ui import set_default_panel_handler, show_panel
|
||||||
@ -76,19 +76,6 @@ def sync_data_received(library_id, lrmap, load_type, xhr, ev):
|
|||||||
db.update_last_read_data_from_key(library_id, int(book_id), fmt, last_read, cfi)
|
db.update_last_read_data_from_key(library_id, int(book_id), fmt, last_read, cfi)
|
||||||
|
|
||||||
|
|
||||||
def sync_library_books(library_id, to_sync):
|
|
||||||
url = f'book-get-last-read-position/{library_id}/'
|
|
||||||
which = v'[]'
|
|
||||||
lrmap = {}
|
|
||||||
for key, last_read in to_sync:
|
|
||||||
library_id, book_id, fmt = key
|
|
||||||
fmt = fmt.upper()
|
|
||||||
which.push(f'{book_id}-{fmt}')
|
|
||||||
lrmap[f'{book_id}:{fmt}'] = last_read
|
|
||||||
url += which.join('_')
|
|
||||||
ajax(url, sync_data_received.bind(None, library_id, lrmap)).send()
|
|
||||||
|
|
||||||
|
|
||||||
def start_sync(to_sync):
|
def start_sync(to_sync):
|
||||||
libraries = {}
|
libraries = {}
|
||||||
for key, last_read in to_sync:
|
for key, last_read in to_sync:
|
||||||
@ -97,7 +84,7 @@ def start_sync(to_sync):
|
|||||||
libraries[library_id] = v'[]'
|
libraries[library_id] = v'[]'
|
||||||
libraries[library_id].push(v'[key, last_read]')
|
libraries[library_id].push(v'[key, last_read]')
|
||||||
for lid in libraries:
|
for lid in libraries:
|
||||||
sync_library_books(lid, libraries[lid])
|
sync_library_books(lid, libraries[lid], sync_data_received)
|
||||||
|
|
||||||
|
|
||||||
def show_recent_stage2(books):
|
def show_recent_stage2(books):
|
||||||
|
@ -155,3 +155,16 @@ class ThumbnailCache:
|
|||||||
callback(img, load_type)
|
callback(img, load_type)
|
||||||
|
|
||||||
thumbnail_cache = ThumbnailCache()
|
thumbnail_cache = ThumbnailCache()
|
||||||
|
|
||||||
|
|
||||||
|
def sync_library_books(library_id, to_sync, callback):
|
||||||
|
url = f'book-get-last-read-position/{library_id}/'
|
||||||
|
which = v'[]'
|
||||||
|
lrmap = {}
|
||||||
|
for key, last_read in to_sync:
|
||||||
|
library_id, book_id, fmt = key
|
||||||
|
fmt = fmt.upper()
|
||||||
|
which.push(f'{book_id}-{fmt}')
|
||||||
|
lrmap[f'{book_id}:{fmt}'] = last_read
|
||||||
|
url += which.join('_')
|
||||||
|
ajax(url, callback.bind(None, library_id, lrmap)).send()
|
||||||
|
@ -1,18 +1,23 @@
|
|||||||
# vim:fileencoding=utf-8
|
# vim:fileencoding=utf-8
|
||||||
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
from __python__ import hash_literals, bound_methods
|
from __python__ import bound_methods, hash_literals
|
||||||
|
|
||||||
from dom import clear, set_css, unique_id, svgicon, build_rule, add_extra_css
|
|
||||||
from elementmaker import E
|
from elementmaker import E
|
||||||
from book_list.theme import get_color
|
|
||||||
from book_list.globals import get_read_ui
|
|
||||||
from book_list.router import home
|
|
||||||
from widgets import create_spinner, create_button
|
|
||||||
from gettext import gettext as _
|
from gettext import gettext as _
|
||||||
from read_book.toc import create_toc_panel
|
|
||||||
|
from book_list.globals import get_read_ui
|
||||||
|
from book_list.library_data import sync_library_books
|
||||||
|
from book_list.router import home
|
||||||
|
from book_list.theme import get_color
|
||||||
|
from dom import add_extra_css, build_rule, clear, set_css, svgicon, unique_id
|
||||||
|
from modals import error_dialog
|
||||||
from read_book.goto import create_goto_panel
|
from read_book.goto import create_goto_panel
|
||||||
from read_book.prefs.main import create_prefs_panel
|
|
||||||
from read_book.prefs.font_size import create_font_size_panel
|
from read_book.prefs.font_size import create_font_size_panel
|
||||||
|
from read_book.prefs.main import create_prefs_panel
|
||||||
|
from read_book.toc import create_toc_panel
|
||||||
|
from session import get_device_uuid
|
||||||
|
from widgets import create_button, create_spinner
|
||||||
|
|
||||||
|
|
||||||
class LoadingMessage: # {{{
|
class LoadingMessage: # {{{
|
||||||
|
|
||||||
@ -96,6 +101,63 @@ class DeleteBook: # {{{
|
|||||||
self.overlay.hide_current_panel()
|
self.overlay.hide_current_panel()
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
class SyncBook: # {{{
|
||||||
|
|
||||||
|
def __init__(self, overlay):
|
||||||
|
self.overlay = overlay
|
||||||
|
self.canceled = False
|
||||||
|
|
||||||
|
def show(self, container):
|
||||||
|
self.container_id = container.getAttribute('id')
|
||||||
|
set_css(container, display='flex', justify_content='center', flex_direction='column', background_color=get_color('window-background'))
|
||||||
|
book = self.overlay.view.book
|
||||||
|
to_sync = v'[[book.key, new Date(0)]]'
|
||||||
|
sync_library_books(book.key[0], to_sync, self.sync_data_received)
|
||||||
|
container.appendChild(
|
||||||
|
E.div(style='margin:1ex 1em',
|
||||||
|
E.h2(_('Syncing to last read position')),
|
||||||
|
E.p(_('Downloading last read data from server, please wait...')),
|
||||||
|
E.div(style='display:flex; justify-content:flex-end',
|
||||||
|
create_button(_('Cancel'), action=self.cancel),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def on_container_click(self, evt):
|
||||||
|
pass # Dont allow panel to be closed by a click
|
||||||
|
|
||||||
|
def cancel(self):
|
||||||
|
self.canceled = True
|
||||||
|
self.overlay.hide_current_panel()
|
||||||
|
|
||||||
|
def sync_data_received(self, library_id, lrmap, load_type, xhr, ev):
|
||||||
|
if self.canceled:
|
||||||
|
return
|
||||||
|
self.overlay.hide()
|
||||||
|
if load_type is not 'load':
|
||||||
|
error_dialog(_('Failed to fetch sync data'), _('Failed to download last read data from server, click "Show details" for more information.'), xhr.error_html)
|
||||||
|
return
|
||||||
|
data = JSON.parse(xhr.responseText)
|
||||||
|
book = self.overlay.view.book
|
||||||
|
dev = get_device_uuid()
|
||||||
|
epoch = 0
|
||||||
|
ans = None
|
||||||
|
for key in data:
|
||||||
|
book_id, fmt = key.partition(':')[::2]
|
||||||
|
if book_id is str(book.key[1]) and fmt.upper() is book.key[2].upper():
|
||||||
|
last_read_positions = data[key]
|
||||||
|
for d in last_read_positions:
|
||||||
|
if d.device is not dev and d.epoch > epoch:
|
||||||
|
epoch = d.epoch
|
||||||
|
ans = d
|
||||||
|
if ans is not None:
|
||||||
|
cfi = ans.cfi
|
||||||
|
if cfi:
|
||||||
|
self.overlay.view.goto_bookpos(cfi)
|
||||||
|
|
||||||
|
|
||||||
|
# }}}
|
||||||
|
|
||||||
# MainOverlay {{{
|
# MainOverlay {{{
|
||||||
|
|
||||||
MAIN_OVERLAY_TS_CLASS = 'read-book-main-overlay-top-section'
|
MAIN_OVERLAY_TS_CLASS = 'read-book-main-overlay-top-section'
|
||||||
@ -161,7 +223,7 @@ class MainOverlay:
|
|||||||
),
|
),
|
||||||
|
|
||||||
E.ul(
|
E.ul(
|
||||||
ac(_('Sync'), _('Get last read position and annotations from the server'), None, 'cloud-download'),
|
ac(_('Sync'), _('Get last read position and annotations from the server'), self.overlay.sync_book, 'cloud-download'),
|
||||||
ac(_('Delete'), _('Delete this book from the device'), self.overlay.delete_book, 'trash'),
|
ac(_('Delete'), _('Delete this book from the device'), self.overlay.delete_book, 'trash'),
|
||||||
ac(_('Reload'), _('Reload this book from the server'), self.overlay.reload_book, 'refresh')
|
ac(_('Reload'), _('Reload this book from the server'), self.overlay.reload_book, 'refresh')
|
||||||
),
|
),
|
||||||
@ -337,6 +399,11 @@ class Overlay:
|
|||||||
self.panels = [DeleteBook(self, _('Are you sure you want to reload this book?'), 'refresh', _('Reload book'), True)]
|
self.panels = [DeleteBook(self, _('Are you sure you want to reload this book?'), 'refresh', _('Reload book'), True)]
|
||||||
self.show_current_panel()
|
self.show_current_panel()
|
||||||
|
|
||||||
|
def sync_book(self):
|
||||||
|
self.hide_current_panel()
|
||||||
|
self.panels = [SyncBook(self)]
|
||||||
|
self.show_current_panel()
|
||||||
|
|
||||||
def show_toc(self):
|
def show_toc(self):
|
||||||
self.panels.push(TOCOverlay(self))
|
self.panels.push(TOCOverlay(self))
|
||||||
self.show_current_panel()
|
self.show_current_panel()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user