Implement manual position sync

This commit is contained in:
Kovid Goyal 2017-04-04 20:03:40 +05:30
parent 66e4cd3779
commit 84f7464be5
3 changed files with 91 additions and 24 deletions

View File

@ -5,9 +5,9 @@ from __python__ import bound_methods, hash_literals
from elementmaker import E
from gettext import gettext as _
from ajax import ajax
from book_list.cover_grid import BORDER_RADIUS
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.top_bar import create_top_bar
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)
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):
libraries = {}
for key, last_read in to_sync:
@ -97,7 +84,7 @@ def start_sync(to_sync):
libraries[library_id] = v'[]'
libraries[library_id].push(v'[key, last_read]')
for lid in libraries:
sync_library_books(lid, libraries[lid])
sync_library_books(lid, libraries[lid], sync_data_received)
def show_recent_stage2(books):

View File

@ -155,3 +155,16 @@ class ThumbnailCache:
callback(img, load_type)
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()

View File

@ -1,18 +1,23 @@
# vim:fileencoding=utf-8
# 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 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 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.prefs.main import create_prefs_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: # {{{
@ -96,6 +101,63 @@ class DeleteBook: # {{{
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 {{{
MAIN_OVERLAY_TS_CLASS = 'read-book-main-overlay-top-section'
@ -161,7 +223,7 @@ class MainOverlay:
),
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(_('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.show_current_panel()
def sync_book(self):
self.hide_current_panel()
self.panels = [SyncBook(self)]
self.show_current_panel()
def show_toc(self):
self.panels.push(TOCOverlay(self))
self.show_current_panel()