From 7e0aecf8554d05e30bc59522766f379265998931 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 21 Mar 2017 14:07:39 +0530 Subject: [PATCH] Send last read position to server --- src/calibre/srv/books.py | 1 + src/pyj/read_book/iframe.pyj | 21 ++++++++++++++++++--- src/pyj/read_book/paged_mode.pyj | 21 ++++++++++++++------- src/pyj/read_book/view.pyj | 10 +++++++++- 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/calibre/srv/books.py b/src/calibre/srv/books.py index e8d118e08b..b47573f2fa 100644 --- a/src/calibre/srv/books.py +++ b/src/calibre/srv/books.py @@ -216,6 +216,7 @@ def set_last_read_position(ctx, rd, library_id, book_id, fmt): raise HTTPNotFound('Invalid data') db.set_last_read_position( book_id, fmt, user=user, device=device, cfi=cfi or None, pos_frac=pos_frac) + return b'' mathjax_lock = Lock() diff --git a/src/pyj/read_book/iframe.pyj b/src/pyj/read_book/iframe.pyj index 14a8ae24ae..71342bfda1 100644 --- a/src/pyj/read_book/iframe.pyj +++ b/src/pyj/read_book/iframe.pyj @@ -21,7 +21,7 @@ from read_book.paged_mode import ( onwheel as paged_onwheel, onkeydown as paged_onkeydown, scroll_to_elem, jump_to_cfi as paged_jump_to_cfi, handle_gesture as paged_handle_gesture, scroll_by_page as paged_scroll_by_page, anchor_funcs as paged_anchor_funcs, - snap_to_selection, reset_paged_mode_globals + snap_to_selection, reset_paged_mode_globals, progress_frac ) from read_book.settings import apply_settings, opts from read_book.touch import create_handlers as create_touch_handlers @@ -212,16 +212,31 @@ class IframeBoss: self.onscroll() self.send_message('content_loaded') + def get_progress_frac(self, current_name, spine_index): + length_before = 0 + spine = self.book.manifest.spine + files = self.book.manifest.files + for i in range(spine_index): + si = spine[i] + if si: + length_before += files[si]?.length or 0 + file_length = files[current_name]?.length or 0 + frac = progress_frac() + ans = (length_before + (file_length * frac)) / self.book.manifest.spine_length + return ans + def update_cfi(self): cfi = at_current() if cfi: spine = self.book.manifest.spine - index = spine.indexOf(current_spine_item().name) + current_name = current_spine_item().name + index = spine.indexOf(current_name) if index > -1: cfi = 'epubcfi(/{}{})'.format(2*(index+1), cfi) if cfi != self.last_cfi: self.last_cfi = cfi - self.send_message('update_cfi', cfi=cfi, replace_history=self.replace_history_on_next_cfi_update) + self.send_message('update_cfi', cfi=cfi, replace_history=self.replace_history_on_next_cfi_update, + progress_frac=self.get_progress_frac(current_name, index)) self.replace_history_on_next_cfi_update = True def update_toc_position(self): diff --git a/src/pyj/read_book/paged_mode.pyj b/src/pyj/read_book/paged_mode.pyj index 42a31ecec9..cf58577e26 100644 --- a/src/pyj/read_book/paged_mode.pyj +++ b/src/pyj/read_book/paged_mode.pyj @@ -301,13 +301,6 @@ def column_boundaries(): l = column_at(window.pageXOffset + 10) return l, l + cols_per_screen -def current_pos(frac): - # The current scroll position as a fraction between 0 and 1 - limit = document.body.scrollWidth - window.innerWidth - if limit <= 0: - return 0.0 - return window.pageXOffset / limit - def current_column_location(): # The location of the left edge of the left most column currently # visible in the viewport @@ -466,6 +459,20 @@ def current_cfi(): # print('Viewport cfi:', ans) return ans + +def progress_frac(frac): + # The current scroll position as a fraction between 0 and 1 + if in_paged_mode: + limit = document.body.scrollWidth - window.innerWidth + if limit <= 0: + return 0.0 + return window.pageXOffset / limit + limit = document.body.scrollHeight - window.innerHeight + if limit <= 0: + return 0.0 + return window.pageYOffset / limit + + def onwheel(evt): if evt.deltaY: backward = evt.deltaY < 0 diff --git a/src/pyj/read_book/view.pyj b/src/pyj/read_book/view.pyj index 2c94b776f8..2c19264f63 100644 --- a/src/pyj/read_book/view.pyj +++ b/src/pyj/read_book/view.pyj @@ -2,11 +2,12 @@ # License: GPL v3 Copyright: 2016, Kovid Goyal from __python__ import bound_methods, hash_literals +from ajax import ajax_send from dom import set_css, add_extra_css, build_rule, svgicon from elementmaker import E from gettext import gettext as _ from utils import html_escape -from session import get_interface_data +from session import get_interface_data, get_device_uuid from modals import error_dialog, warning_dialog from book_list.globals import get_session_data, main_js, get_translations @@ -388,6 +389,13 @@ class View: self.book.last_read_position = {} self.book.last_read_position[unkey] = data.cfi self.ui.db.update_last_read_time(self.book) + lrd = {'device':get_device_uuid(), 'cfi':data.cfi, 'pos_frac':data.progress_frac} + key = self.book.key + ajax_send('book-set-last-read-position/{library_id}/{book_id}/{fmt}'.format( + library_id=key[0], book_id=key[1], fmt=key[2]), lrd, def(end_type, xhr, ev): + if end_type is not 'load': + print('Failed to update last read position, AJAX call did not succeed') + ) def on_update_toc_position(self, data): update_visible_toc_nodes(data.visible_anchors)