diff options
author | Gonzalo Odiard <godiard@gmail.com> | 2012-09-10 14:03:43 (GMT) |
---|---|---|
committer | Gonzalo Odiard <godiard@gmail.com> | 2012-09-10 14:19:33 (GMT) |
commit | eafed20bd06a82e1737786da10fa829b1e220b70 (patch) | |
tree | b2df004d09c79eeda3dda0a5d2c753be726e9c93 /epubview | |
parent | ef1810e61bf4658a48191fcff238857e1458b21b (diff) |
Fix index management in epub files - SL #3853
Epub index can point to internal links in the content files.
This patch manage this cases. A particular case was found in a
file generated in UY (see attachment in the ticket) where the links
don't point to the start of a file, but to the end of the previous file.
Then, if the index is at the end of a file, we open the next file.
Signed-off-by: Gonzalo Odiard <gonzalo@laptop.org>
Diffstat (limited to 'epubview')
-rw-r--r-- | epubview/epubview.py | 69 | ||||
-rw-r--r-- | epubview/jobs.py | 21 | ||||
-rw-r--r-- | epubview/widgets.py | 30 |
3 files changed, 105 insertions, 15 deletions
diff --git a/epubview/epubview.py b/epubview/epubview.py index 8865aeb..b200d36 100644 --- a/epubview/epubview.py +++ b/epubview/epubview.py @@ -20,6 +20,7 @@ from gi.repository import GObject from gi.repository import Gdk import widgets +import logging import os.path import math import shutil @@ -71,6 +72,8 @@ class _View(Gtk.HBox): self._findjob = None self.__in_search = False self.__search_fwd = True + self._filelist = None + self._internal_link = None self._sw = Gtk.ScrolledWindow() self._view = widgets._WebView() @@ -439,13 +442,40 @@ class _View(Gtk.HBox): else: self._scroll_page() - # prepare text to speech - html_file = open(self._loaded_filename) - soup = BeautifulSoup.BeautifulSoup(html_file) - body = soup.find('body') - tags = body.findAll(text=True) - self._all_text = ''.join([tag for tag in tags]) - self._prepare_text_to_speech(self._all_text) + process_file = True + if self._internal_link is not None: + self._view.go_to_link(self._internal_link) + vertical_pos = \ + self._view.get_vertical_position_element(self._internal_link) + # set the page number based in the vertical position + initial_page = self._paginator.get_base_pageno_for_file(filename) + self._loaded_page = initial_page + int(vertical_pos / + self._paginator.get_single_page_height()) + + # There are epub files, created with Calibre, + # where the link in the index points to the end of the previos + # file to the needed chapter. + # if the link is at the bottom of the page, we open the next file + one_page_height = self._paginator.get_single_page_height() + self._internal_link = None + if vertical_pos > self._view.get_page_height() - one_page_height: + logging.error('bottom page link, go to next file') + next_file = self._paginator.get_next_filename(filename) + if next_file is not None: + logging.error('load next file %s', next_file) + self.__in_search = False + self.__going_back = False + process_file = False + GObject.idle_add(self._load_file, next_file) + + if process_file: + # prepare text to speech + html_file = open(self._loaded_filename) + soup = BeautifulSoup.BeautifulSoup(html_file) + body = soup.find('body') + tags = body.findAll(text=True) + self._all_text = ''.join([tag for tag in tags]) + self._prepare_text_to_speech(self._all_text) def _prepare_text_to_speech(self, page_text): i = 0 @@ -489,10 +519,17 @@ class _View(Gtk.HBox): filelist = [] for i in self._epub._navmap.get_flattoc(): filelist.append(os.path.join(self._epub._tempdir, i)) - + # init files info + self._filelist = filelist self._paginator = _Paginator(filelist) self._paginator.connect('paginated', self._paginated_cb) + def get_filelist(self): + return self._filelist + + def get_tempdir(self): + return self._epub._tempdir + def _load_next_page(self): self._load_page(self._loaded_page + 1) @@ -599,11 +636,19 @@ class _View(Gtk.HBox): shutil.copy(file_name + '.tmp', file_name) def _load_file(self, path): - #TODO: This is a bit suboptimal - fix it - for pageno in range(1, self.get_pagecount()): - filepath = self._paginator.get_file_for_pageno(pageno) + self._internal_link = None + if path.find('#') > -1: + self._internal_link = path[path.find('#'):] + path = path[:path.find('#')] + + for filepath in self._filelist: if filepath.endswith(path): - self._load_page(pageno) + self._view.load_uri('file://' + filepath) + oldpage = self._loaded_page + self._loaded_page = \ + self._paginator.get_base_pageno_for_file(filepath) + self._scroll_page() + self._on_page_changed(oldpage, self._loaded_page) break def _scrollbar_change_value_cb(self, range, scrolltype, value): diff --git a/epubview/jobs.py b/epubview/jobs.py index 368e210..96a7e22 100644 --- a/epubview/jobs.py +++ b/epubview/jobs.py @@ -134,8 +134,9 @@ class _JobPaginator(GObject.GObject): sw = Gtk.ScrolledWindow() sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER) self._dpi = 96 + self._single_page_height = _mm_to_pixel(PAGE_HEIGHT, self._dpi) sw.set_size_request(_mm_to_pixel(PAGE_WIDTH, self._dpi), - _mm_to_pixel(PAGE_HEIGHT, self._dpi)) + self._single_page_height) sw.add(self._temp_view) self._temp_win.add(sw) self._temp_view.connect('load-finished', self._page_load_finished_cb) @@ -145,14 +146,28 @@ class _JobPaginator(GObject.GObject): self._temp_view.open(self._filelist[self._count]) + def get_single_page_height(self): + """ + Returns the height in pixels of a single page + """ + return self._single_page_height + + def get_next_filename(self, actual_filename): + for n in range(len(self._filelist)): + filename = self._filelist[n] + if filename == actual_filename: + if n < len(self._filelist): + return self._filelist[n + 1] + return None + def _page_load_finished_cb(self, v, frame): f = v.get_main_frame() pageheight = v.get_page_height() - if pageheight <= _mm_to_pixel(PAGE_HEIGHT, self._dpi): + if pageheight <= self._single_page_height: pages = 1 else: - pages = pageheight / float(_mm_to_pixel(PAGE_HEIGHT, self._dpi)) + pages = pageheight / float(self._single_page_height) for i in range(1, int(math.ceil(pages) + 1)): if pages - i < 0: pagelen = (pages - math.floor(pages)) / pages diff --git a/epubview/widgets.py b/epubview/widgets.py index 340ff48..4dc5846 100644 --- a/epubview/widgets.py +++ b/epubview/widgets.py @@ -49,3 +49,33 @@ class _WebView(WebKit.WebView): Highlight next word (for text to speech) ''' self.execute_script('highLightNextWord();') + + def go_to_link(self, id_link): + self.execute_script('window.location.href = "%s";' % id_link) + + def get_vertical_position_element(self, id_link): + ''' + Get the vertical position of a element, in pixels + ''' + # remove the first '#' char + id_link = id_link[1:] + js = "oldtitle = document.title;" \ + "obj = document.getElementById('%s');" \ + "var top = 0;" \ + "if(obj.offsetParent) {" \ + " while(1) {" \ + " top += obj.offsetTop;" \ + " if(!obj.offsetParent) {break;};" \ + " obj = obj.offsetParent;" \ + " };" \ + "}" \ + "else if(obj.y) { top += obj.y; };" \ + "document.title=top;" % id_link + self.execute_script(js) + ret = self.get_main_frame().get_title() + js = 'document.title=oldtitle;' + self.execute_script(js) + try: + return int(ret) + except ValueError: + return 0 |