Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/epubview
diff options
context:
space:
mode:
authorGonzalo Odiard <godiard@gmail.com>2012-09-10 14:03:43 (GMT)
committer Gonzalo Odiard <godiard@gmail.com>2012-09-10 14:19:33 (GMT)
commiteafed20bd06a82e1737786da10fa829b1e220b70 (patch)
treeb2df004d09c79eeda3dda0a5d2c753be726e9c93 /epubview
parentef1810e61bf4658a48191fcff238857e1458b21b (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.py69
-rw-r--r--epubview/jobs.py21
-rw-r--r--epubview/widgets.py30
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