Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSayamindu Dasgupta <sayamindu@gmail.com>2009-09-02 18:36:54 (GMT)
committer Sayamindu Dasgupta <sayamindu@gmail.com>2009-09-02 18:36:54 (GMT)
commit47fe7dd173869aca32e6ea59286358da525f9336 (patch)
tree8acd930b53fe18d8ca7764da55cad83b8d2fc26a
parent0433b67dc2d74c16d6bcbe083beefbcd7134d686 (diff)
Sync with pyepubview, revision 25
-rw-r--r--epubview/epub.py70
-rw-r--r--epubview/epubinfo.py4
-rw-r--r--epubview/epubview.py60
-rw-r--r--epubview/jobs.py42
-rw-r--r--epubview/navmap.py39
-rw-r--r--epubview/widgets.py18
6 files changed, 182 insertions, 51 deletions
diff --git a/epubview/epub.py b/epubview/epub.py
index f49b0d7..71267aa 100644
--- a/epubview/epub.py
+++ b/epubview/epub.py
@@ -28,26 +28,23 @@ class _Epub(object):
def __init__(self, filepath):
self._filepath = filepath
self._zobject = None
- self._obffile = None
- self._titlepage = None
- self._obfpath = None
+ self._opfpath = None
self._ncxpath = None
- self._ncxfile = None
self._basepath = None
self._tempdir = tempfile.mkdtemp()
if not self._verify():
print 'Warning: This does not seem to be a valid epub file'
- self._get_obf()
+ self._get_opf()
self._get_ncx()
- self._get_titlepage()
- self._ncxfile = self._zobject.open(self._ncxpath)
- self._navmap = navmap.NavMap(self._ncxfile, self._basepath, self._titlepage)
+ ncxfile = self._zobject.open(self._ncxpath)
+ opffile = self._zobject.open(self._opfpath)
+ self._navmap = navmap.NavMap(opffile, ncxfile, self._basepath)
- self._obffile = self._zobject.open(self._obfpath)
- self._info = epubinfo.EpubInfo(self._obffile)
+ opffile = self._zobject.open(self._opfpath)
+ self._info = epubinfo.EpubInfo(opffile)
self._unzip()
@@ -65,7 +62,7 @@ class _Epub(object):
os.chdir(orig_cwd)
- def _get_obf(self):
+ def _get_opf(self):
containerfile = self._zobject.open('META-INF/container.xml')
tree = etree.parse(containerfile)
@@ -73,10 +70,10 @@ class _Epub(object):
for element in root.iterfind('.//{urn:oasis:names:tc:opendocument:xmlns:container}rootfile'):
if element.get('media-type') == 'application/oebps-package+xml':
- self._obfpath = element.get('full-path')
+ self._opfpath = element.get('full-path')
- if self._obfpath.rpartition('/')[0]:
- self._basepath = self._obfpath.rpartition('/')[0] + '/'
+ if self._opfpath.rpartition('/')[0]:
+ self._basepath = self._opfpath.rpartition('/')[0] + '/'
else:
self._basepath = ''
@@ -84,30 +81,20 @@ class _Epub(object):
def _get_ncx(self):
- obffile = self._zobject.open(self._obfpath)
+ opffile = self._zobject.open(self._opfpath)
- tree = etree.parse(obffile)
+ tree = etree.parse(opffile)
root = tree.getroot()
+ spine = root.find('.//{http://www.idpf.org/2007/opf}spine')
+ tocid = spine.get('toc')
+
for element in root.iterfind('.//{http://www.idpf.org/2007/opf}item'):
- if element.get('media-type') == 'application/x-dtbncx+xml' or \
- element.get('id') == 'ncx':
+ if element.get('id') == tocid:
self._ncxpath = self._basepath + element.get('href')
- obffile.close()
-
- def _get_titlepage(self):
- obffile = self._zobject.open(self._obfpath)
- tree = etree.parse(obffile)
- root = tree.getroot()
+ opffile.close()
- for element in root.iterfind('.//{http://www.idpf.org/2007/opf}item'):
- if element.get('id') == 'titlepage':
- self._titlepage = self._basepath + element.get('href')
-
- obffile.close()
-
-
def _verify(self):
'''
Method to crudely check to verify that what we
@@ -124,23 +111,42 @@ class _Epub(object):
mtypefile = self._zobject.open('mimetype')
mimetype = mtypefile.readline()
- if mimetype != 'application/epub+zip':
+ if not mimetype.startswith('application/epub+zip'): # Some files seem to have trailing characters
return False
return True
def get_toc_model(self):
+ '''
+ Returns a GtkTreeModel representation of the
+ Epub table of contents
+ '''
return self._navmap.get_gtktreestore()
def get_flattoc(self):
+ '''
+ Returns a flat (linear) list of files to be
+ rendered.
+ '''
return self._navmap.get_flattoc()
def get_basedir(self):
+ '''
+ Returns the base directory where the contents of the
+ epub has been unzipped
+ '''
return self._tempdir
def get_info(self):
+ '''
+ Returns a EpubInfo object for the open Epub file
+ '''
return self._info
def close(self):
+ '''
+ Cleans up (closes open zip files and deletes uncompressed content of Epub.
+ Please call this when a file is being closed or during application exit.
+ '''
self._zobject.close()
shutil.rmtree(self._tempdir)
diff --git a/epubview/epubinfo.py b/epubview/epubinfo.py
index ddf9ad5..d25dfc2 100644
--- a/epubview/epubinfo.py
+++ b/epubview/epubinfo.py
@@ -3,8 +3,8 @@ from lxml import etree
class EpubInfo(): #TODO: Cover the entire DC range
- def __init__(self, file):
- self._tree = etree.parse(file)
+ def __init__(self, opffile):
+ self._tree = etree.parse(opffile)
self._root = self._tree.getroot()
self._e_metadata = self._root.find('{http://www.idpf.org/2007/opf}metadata')
diff --git a/epubview/epubview.py b/epubview/epubview.py
index 5c2c7a2..7300bd0 100644
--- a/epubview/epubview.py
+++ b/epubview/epubview.py
@@ -98,6 +98,9 @@ class _View(gtk.HBox):
self._view.set_flags(gtk.CAN_DEFAULT|gtk.CAN_FOCUS)
def set_document(self, epubdocumentinstance):
+ '''
+ Sets document (should be a Epub instance)
+ '''
self._epub = epubdocumentinstance
gobject.idle_add(self._paginate)
@@ -116,15 +119,27 @@ class _View(gtk.HBox):
raise AttributeError, 'unknown property %s' % property.name
def get_has_selection(self):
+ '''
+ Returns True if any part of the content is selected
+ '''
return self.get_property('has-selection')
def get_zoom(self):
+ '''
+ Returns the current zoom level
+ '''
return self.get_property('zoom')
def set_zoom(self, value):
+ '''
+ Sets the current zoom level
+ '''
self.set_property('zoom', value)
def zoom_in(self):
+ '''
+ Zooms in (increases zoom level by 0.1)
+ '''
if self.can_zoom_in():
self.set_zoom(self.get_zoom() + 0.1)
return True
@@ -132,6 +147,9 @@ class _View(gtk.HBox):
return False
def zoom_out(self):
+ '''
+ Zooms out (decreases zoom level by 0.1)
+ '''
if self.can_zoom_out():
self.set_zoom(self.get_zoom() - 0.1)
return True
@@ -139,21 +157,33 @@ class _View(gtk.HBox):
return False
def can_zoom_in(self):
+ '''
+ Returns True if it is possible to zoom in further
+ '''
if self.zoom < 4:
return True
else:
return False
def can_zoom_out(self):
+ '''
+ Returns True if it is possible to zoom out further
+ '''
if self.zoom > 0.5:
return True
else:
return False
def get_current_page(self):
+ '''
+ Returns the currently loaded page
+ '''
return self._loaded_page
def get_current_file(self):
+ '''
+ Returns the currently loaded XML file
+ '''
#return self._loaded_filename
if self._paginator:
return self._paginator.get_file_for_pageno(self._loaded_page)
@@ -161,27 +191,46 @@ class _View(gtk.HBox):
return None
def get_pagecount(self):
+ '''
+ Returns the pagecount of the loaded file
+ '''
return self._pagecount
def set_current_page(self, n):
+ '''
+ Loads page number n
+ '''
if n < 1 or n > self._pagecount:
return False
self._load_page(n)
return True
def next_page(self):
+ '''
+ Loads next page if possible
+ Returns True if transition to next page is possible and done
+ '''
if self._loaded_page == self._pagecount:
return False
self._load_next_page()
return True
def previous_page(self):
+ '''
+ Loads previous page if possible
+ Returns True if transition to previous page is possible and done
+ '''
if self._loaded_page == 1:
return False
self._load_prev_page()
return True
def scroll(self, scrolltype, horizontal):
+ '''
+ Scrolls through the pages.
+ Scrolling is horizontal if horizontal is set to True
+ Valid scrolltypes are: gtk.SCROLL_PAGE_BACKWARD and gtk.SCROLL_PAGE_FORWARD
+ '''
if scrolltype == gtk.SCROLL_PAGE_BACKWARD:
self.__going_back = True
self.__going_fwd = False
@@ -196,9 +245,15 @@ class _View(gtk.HBox):
print ('Got unsupported scrolltype %s' % str(scrolltype))
def copy(self):
+ '''
+ Copies the current selection to clipboard.
+ '''
self._view.copy_clipboard()
def find_next(self):
+ '''
+ Highlights the next matching item for current search
+ '''
self._view.grab_focus()
self._view.grab_default()
@@ -212,6 +267,9 @@ class _View(gtk.HBox):
self._load_file(path)
def find_previous(self):
+ '''
+ Highlights the previous matching item for current search
+ '''
self._view.grab_focus()
self._view.grab_default()
@@ -335,7 +393,7 @@ class _View(gtk.HBox):
def _paginate(self):
filelist = []
for i in self._epub._navmap.get_flattoc():
- filelist.append(os.path.join(self._epub._tempdir, i[1]))
+ filelist.append(os.path.join(self._epub._tempdir, i))
self._paginator = _Paginator(filelist)
self._paginator.connect('paginated', self._paginated_cb)
diff --git a/epubview/jobs.py b/epubview/jobs.py
index de276b3..4637e2f 100644
--- a/epubview/jobs.py
+++ b/epubview/jobs.py
@@ -52,8 +52,7 @@ class SearchThread(threading.Thread):
for entry in self.obj.flattoc:
if self.stopthread.isSet():
break
- name, file = entry
- filepath = os.path.join(self.obj._document.get_basedir(), file)
+ filepath = os.path.join(self.obj._document.get_basedir(), entry)
f = open(filepath)
if self._searchfile(f):
self.obj._matchfilelist.append(file)
@@ -168,24 +167,45 @@ class _JobPaginator(gobject.GObject):
def get_file_for_pageno(self, pageno):
+ '''
+ Returns the file in which pageno occurs
+ '''
return self._pagemap[pageno][0]
def get_scrollfactor_pos_for_pageno(self, pageno):
+ '''
+ Returns the position scrollfactor (fraction) for pageno
+ '''
return self._pagemap[pageno][1]
def get_scrollfactor_len_for_pageno(self, pageno):
+ '''
+ Returns the length scrollfactor (fraction) for pageno
+ '''
return self._pagemap[pageno][2]
def get_pagecount_for_file(self, file):
+ '''
+ Returns the number of pages in file
+ '''
return self._filedict[file][0]
def get_remfactor_for_file(self, file):
+ '''
+ Returns the remainder factor (1 - fraction length of last page in file)
+ '''
return self._filedict[file][1]
def get_total_pagecount(self):
+ '''
+ Returns the total pagecount for the Epub file
+ '''
return self._pagecount
def get_total_height(self):
+ '''
+ Returns the total height of the Epub in pixels
+ '''
return self._bookheight
@@ -215,13 +235,22 @@ class _JobFind(gobject.GObject):
s_thread.start()
def cancel(self):
+ '''
+ Cancels the search job
+ '''
for s_thread in self.threads:
s_thread.stop()
def is_finished(self):
+ '''
+ Returns True if the entire search job has been finished
+ '''
return self._finished
def get_next_file(self):
+ '''
+ Returns the next file which has the search pattern
+ '''
self._current_file_index += 1
try:
path = self._matchfilelist[self._current_file_index]
@@ -232,6 +261,9 @@ class _JobFind(gobject.GObject):
return path
def get_prev_file(self):
+ '''
+ Returns the previous file which has the search pattern
+ '''
self._current_file_index -= 1
try:
path = self._matchfilelist[self._current_file_index]
@@ -242,7 +274,13 @@ class _JobFind(gobject.GObject):
return path
def get_search_text(self):
+ '''
+ Returns the search text
+ '''
return self._text
def get_case_sensitive(self):
+ '''
+ Returns True if the search is case-sensitive
+ '''
return self._case_sensitive
diff --git a/epubview/navmap.py b/epubview/navmap.py
index cdeb265..a0a1799 100644
--- a/epubview/navmap.py
+++ b/epubview/navmap.py
@@ -18,19 +18,34 @@ class NavPoint(object):
class NavMap(object):
- def __init__(self, opffile, basepath, titlepage):
+ def __init__(self, opffile, ncxfile, basepath):
self._basepath = basepath
- self._tree = etree.parse(opffile)
+ self._opffile = opffile
+ self._tree = etree.parse(ncxfile)
self._root = self._tree.getroot()
self._gtktreestore = gtk.TreeStore(str, str)
self._flattoc = []
+ self._populate_flattoc()
self._populate_toc()
+
+ def _populate_flattoc(self):
+ tree = etree.parse(self._opffile)
+ root = tree.getroot()
+
+ itemmap = {}
+ manifest = root.find('.//{http://www.idpf.org/2007/opf}manifest')
+ for element in manifest.iterfind('{http://www.idpf.org/2007/opf}item'):
+ itemmap[element.get('id')] = element
+
+ spine = root.find('.//{http://www.idpf.org/2007/opf}spine')
+ for element in spine.iterfind('{http://www.idpf.org/2007/opf}itemref'):
+ idref = element.get('idref')
+ href = itemmap[idref].get('href')
+ self._flattoc.append(self._basepath + href)
+
+ self._opffile.close()
- if titlepage and self._flattoc[0][1] != titlepage:
- self._flattoc.insert(0, ('Title Page', titlepage))
- self._gtktreestore.insert(None, 0, ['Title Page', titlepage])
-
def _populate_toc(self):
navmap = self._root.find('{http://www.daisy.org/z3986/2005/ncx/}navMap')
for navpoint in navmap.iterfind('./{http://www.daisy.org/z3986/2005/ncx/}navPoint'):
@@ -48,8 +63,10 @@ class NavMap(object):
title = self._gettitle(navpoint)
content = self._getcontent(navpoint)
+ #print title, content
+
iter = self._gtktreestore.append(parent, [title, content])
- self._flattoc.append((title, content))
+ #self._flattoc.append((title, content))
childnavpointlist = list(navpoint.iterfind('./{http://www.daisy.org/z3986/2005/ncx/}navPoint'))
@@ -60,9 +77,17 @@ class NavMap(object):
return
def get_gtktreestore(self):
+ '''
+ Returns a GtkTreeModel representation of the
+ Epub table of contents
+ '''
return self._gtktreestore
def get_flattoc(self):
+ '''
+ Returns a flat (linear) list of files to be
+ rendered.
+ '''
return self._flattoc
#t = TocParser('/home/sayamindu/Desktop/Test/OPS/fb.ncx') \ No newline at end of file
diff --git a/epubview/widgets.py b/epubview/widgets.py
index c52d590..5b6dd68 100644
--- a/epubview/widgets.py
+++ b/epubview/widgets.py
@@ -1,27 +1,31 @@
+import webkit
import gtk
-try:
- import webkit
-except ImportError:
- import os, sys
- sys.path.append(os.path.join(os.environ['SUGAR_BUNDLE_PATH'], 'epubview', 'modules'))
- import webkit
-
class _WebView(webkit.WebView):
def __init__(self):
webkit.WebView.__init__(self)
def get_page_height(self):
+ '''
+ Gets height (in pixels) of loaded (X)HTML page.
+ This is done via javascript at the moment
+ '''
#TODO: Need to check status of page load
js = 'oldtitle=document.title;document.title=document.body.clientHeight;'
self.execute_script(js)
ret = self.get_main_frame().get_title()
js = 'document.title=oldtitle;'
self.execute_script(js)
+ if ret is None:
+ return 0
return int(ret)
def add_bottom_padding(self, incr):
+ '''
+ Adds incr pixels of padding to the end of the loaded (X)HTML page.
+ This is done via javascript at the moment
+ '''
js = ('var newdiv = document.createElement("div");newdiv.style.height = "%dpx";document.body.appendChild(newdiv);' % incr)
self.execute_script(js)