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-12-29 17:26:05 (GMT)
committer Sayamindu Dasgupta <sayamindu@gmail.com>2009-12-29 17:26:05 (GMT)
commitfe211f9a0adcec2c1e32505fdc13913cc1159cf9 (patch)
treef9de3a8f0de026b9af9b091a6d41107ce3c0f3f3
parent32dc3b942d8b0e169ca01434fdb131939b326b67 (diff)
Get rid of the epubview folder (to be replaced by submodule)
-rw-r--r--epubview/__init__.py24
-rw-r--r--epubview/epub.py152
-rw-r--r--epubview/epubinfo.py90
-rw-r--r--epubview/epubview.py558
-rw-r--r--epubview/jobs.py296
-rw-r--r--epubview/navmap.py93
-rw-r--r--epubview/widgets.py31
7 files changed, 0 insertions, 1244 deletions
diff --git a/epubview/__init__.py b/epubview/__init__.py
deleted file mode 100644
index 81a3175..0000000
--- a/epubview/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2009 One Laptop Per Child
-# Author: Sayamindu Dasgupta <sayamindu@laptop.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import gobject
-
-gobject.threads_init()
-
-from epub import _Epub as Epub
-from epubview import _View as EpubView
-from jobs import _JobFind as JobFind \ No newline at end of file
diff --git a/epubview/epub.py b/epubview/epub.py
deleted file mode 100644
index 71267aa..0000000
--- a/epubview/epub.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright 2009 One Laptop Per Child
-# Author: Sayamindu Dasgupta <sayamindu@laptop.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import zipfile
-import tempfile
-import os, os.path
-from lxml import etree
-import shutil
-
-import navmap, epubinfo
-
-
-class _Epub(object):
- def __init__(self, filepath):
- self._filepath = filepath
- self._zobject = None
- self._opfpath = None
- self._ncxpath = 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_opf()
- self._get_ncx()
-
- ncxfile = self._zobject.open(self._ncxpath)
- opffile = self._zobject.open(self._opfpath)
- self._navmap = navmap.NavMap(opffile, ncxfile, self._basepath)
-
- opffile = self._zobject.open(self._opfpath)
- self._info = epubinfo.EpubInfo(opffile)
-
- self._unzip()
-
- def _unzip(self):
- #self._zobject.extractall(path = self._tempdir) # This is broken upto python 2.7
- orig_cwd = os.getcwd()
- os.chdir(self._tempdir)
- for name in self._zobject.namelist():
- if name.startswith(os.path.sep): # Some weird zip file entries start with a slash, and we don't want to write to the root directory
- name = name[1:]
- if name.endswith(os.path.sep) or name.endswith('\\'):
- os.makedirs(name)
- else:
- self._zobject.extract(name)
- os.chdir(orig_cwd)
-
-
- def _get_opf(self):
- containerfile = self._zobject.open('META-INF/container.xml')
-
- tree = etree.parse(containerfile)
- root = tree.getroot()
-
- for element in root.iterfind('.//{urn:oasis:names:tc:opendocument:xmlns:container}rootfile'):
- if element.get('media-type') == 'application/oebps-package+xml':
- self._opfpath = element.get('full-path')
-
- if self._opfpath.rpartition('/')[0]:
- self._basepath = self._opfpath.rpartition('/')[0] + '/'
- else:
- self._basepath = ''
-
- containerfile.close()
-
-
- def _get_ncx(self):
- opffile = self._zobject.open(self._opfpath)
-
- 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('id') == tocid:
- self._ncxpath = self._basepath + element.get('href')
-
- opffile.close()
-
- def _verify(self):
- '''
- Method to crudely check to verify that what we
- are dealing with is a epub file or not
- '''
- if not os.path.exists(self._filepath):
- return False
-
- self._zobject = zipfile.ZipFile(self._filepath)
-
- if not 'mimetype' in self._zobject.namelist():
- return False
-
- mtypefile = self._zobject.open('mimetype')
- mimetype = mtypefile.readline()
-
- 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
deleted file mode 100644
index d25dfc2..0000000
--- a/epubview/epubinfo.py
+++ /dev/null
@@ -1,90 +0,0 @@
-import os
-from lxml import etree
-
-
-class EpubInfo(): #TODO: Cover the entire DC range
- 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')
-
- self.title = self._get_title()
- self.creator = self._get_creator()
- self.date = self._get_date()
- self.subject = self._get_subject()
- self.source = self._get_source()
- self.rights = self._get_rights()
- self.identifier = self._get_identifier()
- self.language = self._get_language()
-
-
- def _get_data(self, tagname):
- element = self._e_metadata.find(tagname)
- return element.text
-
- def _get_title(self):
- try:
- ret = self._get_data('.//{http://purl.org/dc/elements/1.1/}title')
- except AttributeError:
- return None
-
- return ret
-
- def _get_creator(self):
- try:
- ret = self._get_data('.//{http://purl.org/dc/elements/1.1/}creator')
- except AttributeError:
- return None
- return ret
-
- def _get_date(self):
- #TODO: iter
- try:
- ret = self._get_data('.//{http://purl.org/dc/elements/1.1/}date')
- except AttributeError:
- return None
-
- return ret
-
- def _get_source(self):
- try:
- ret = self._get_data('.//{http://purl.org/dc/elements/1.1/}source')
- except AttributeError:
- return None
-
- return ret
-
- def _get_rights(self):
- try:
- ret = self._get_data('.//{http://purl.org/dc/elements/1.1/}rights')
- except AttributeError:
- return None
-
- return ret
-
- def _get_identifier(self):
- #TODO: iter
- element = self._e_metadata.find('.//{http://purl.org/dc/elements/1.1/}identifier')
-
- if element is not None:
- return {'id':element.get('id'), 'value':element.text}
- else:
- return None
-
- def _get_language(self):
- try:
- ret = self._get_data('.//{http://purl.org/dc/elements/1.1/}language')
- except AttributeError:
- return None
-
- return ret
-
- def _get_subject(self):
- try:
- subjectlist = []
- for element in self._e_metadata.iterfind('.//{http://purl.org/dc/elements/1.1/}subject'):
- subjectlist.append(element.text)
- except AttributeError:
- return None
-
- return subjectlist \ No newline at end of file
diff --git a/epubview/epubview.py b/epubview/epubview.py
deleted file mode 100644
index d28ebc3..0000000
--- a/epubview/epubview.py
+++ /dev/null
@@ -1,558 +0,0 @@
-# Copyright 2009 One Laptop Per Child
-# Author: Sayamindu Dasgupta <sayamindu@laptop.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import gtk, gtk.gdk
-import gobject
-import widgets
-
-import os.path
-import math
-import shutil
-
-from epub import _Epub
-from jobs import _JobPaginator as _Paginator
-
-
-LOADING_HTML = '''
-<div style="width:100%;height:100%;text-align:center;padding-top:50%;">
- <h1>Loading...</h1>
-</div>
-'''
-
-class _View(gtk.HBox):
- __gproperties__ = {
- 'has-selection' : (gobject.TYPE_BOOLEAN, 'whether has selection',
- 'whether the widget has selection or not',
- 0, gobject.PARAM_READABLE),
- 'zoom' : (gobject.TYPE_FLOAT, 'the zoom level',
- 'the zoom level of the widget',
- 0.5, 4.0, 1.0, gobject.PARAM_READWRITE)
- }
- __gsignals__ = {
- 'page-changed': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([]))
- }
- def __init__(self):
- gobject.threads_init()
- gtk.HBox.__init__(self)
-
- self.connect("destroy", self._destroy_cb)
-
- self._ready = False
- self._paginator = None
- self._loaded_page = -1
- #self._old_scrollval = -1
- self._loaded_filename = None
- self._pagecount = -1
- self.__going_fwd = True
- self.__going_back = False
- self.__page_changed = False
- self.has_selection = False
- self.zoom = 1.0
- self._epub = None
- self._findjob = None
- self.__in_search = False
- self.__search_fwd = True
-
- self._sw = gtk.ScrolledWindow()
- self._view = widgets._WebView()
- self._view.load_string(LOADING_HTML, 'text/html', 'utf-8', '/')
- settings = self._view.get_settings()
- settings.props.default_font_family = 'DejaVu LGC Serif'
- settings.props.enable_plugins = False
- settings.props.default_encoding = 'utf-8'
- self._view.connect('load-finished', self._view_load_finished_cb)
- self._view.connect('scroll-event', self._view_scroll_event_cb)
- self._view.connect('key-press-event', self._view_keypress_event_cb)
- self._view.connect('button-release-event', self._view_buttonrelease_event_cb)
- self._view.connect('selection-changed', self._view_selection_changed_cb)
- self._view.connect_after('populate-popup', self._view_populate_popup_cb)
-
- self._sw.add(self._view)
- self._sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_NEVER)
- self._v_vscrollbar = self._sw.get_vscrollbar()
- self._v_scrollbar_value_changed_cb_id = self._v_vscrollbar.connect('value-changed', \
- self._v_scrollbar_value_changed_cb)
- self._scrollbar = gtk.VScrollbar()
- self._scrollbar.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
- self._scrollbar_change_value_cb_id = self._scrollbar.connect('change-value', \
- self._scrollbar_change_value_cb)
- self.pack_start(self._sw, expand = True, fill = True)
- self.pack_start(self._scrollbar, expand = False, fill = False)
-
- 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)
-
- def do_get_property(self, property):
- if property.name == 'has-selection':
- return self.has_selection
- elif property.name == 'zoom':
- return self.zoom
- else:
- raise AttributeError, 'unknown property %s' % property.name
-
- def do_set_property(self, property, value):
- if property.name == 'zoom':
- self.__set_zoom(value)
- else:
- 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
- else:
- 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
- else:
- 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)
- else:
- 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
- if not self._do_page_transition():
- self._view.move_cursor(gtk.MOVEMENT_PAGES, -1)
- elif scrolltype == gtk.SCROLL_PAGE_FORWARD:
- self.__going_back = False
- self.__going_fwd = True
- if not self._do_page_transition():
- self._view.move_cursor(gtk.MOVEMENT_PAGES, 1)
- else:
- 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()
-
- if self._view.search_text(self._findjob.get_search_text(), \
- self._findjob.get_case_sensitive(), True, False):
- return
- else:
- path = os.path.join(self._epub.get_basedir(), self._findjob.get_next_file())
- self.__in_search = True
- self.__search_fwd = True
- self._load_file(path)
-
- def find_previous(self):
- '''
- Highlights the previous matching item for current search
- '''
- self._view.grab_focus()
- self._view.grab_default()
-
- if self._view.search_text(self._findjob.get_search_text(), \
- self._findjob.get_case_sensitive(), False, False):
- return
- else:
- path = os.path.join(self._epub.get_basedir(), self._findjob.get_prev_file())
- self.__in_search = True
- self.__search_fwd = False
- self._load_file(path)
-
- def _find_changed(self, job):
- self._view.grab_focus()
- self._view.grab_default()
- self._findjob = job
- #self._view.search_text(self._findjob.get_search_text(), \
- # self._findjob.get_case_sensitive(), True, False)
- self.find_next()
-
- def __set_zoom(self, value):
- self._view.set_zoom_level(value)
- self.zoom = value
-
- def __set_has_selection(self, value):
- if value != self.has_selection:
- self.has_selection = value
- self.notify('has-selection')
-
- def _view_populate_popup_cb(self, view, menu):
- menu.destroy() #HACK
- return
-
- def _view_selection_changed_cb(self, view):
- # FIXME: This does not seem to be implemented in
- # webkitgtk yet
- print view.has_selection()
-
- def _view_buttonrelease_event_cb(self, view, event):
- # Ugly hack
- self.__set_has_selection(view.can_copy_clipboard() \
- | view.can_cut_clipboard())
-
- def _view_keypress_event_cb(self, view, event):
- name = gtk.gdk.keyval_name(event.keyval)
- if name == 'Page_Down' or name == 'Down':
- self.__going_back = False
- self.__going_fwd = True
- elif name == 'Page_Up' or name == 'Up':
- self.__going_back = True
- self.__going_fwd = False
-
- self._do_page_transition()
-
- def _view_scroll_event_cb(self, view, event):
- if event.direction == gtk.gdk.SCROLL_DOWN:
- self.__going_back = False
- self.__going_fwd = True
- elif event.direction == gtk.gdk.SCROLL_UP:
- self.__going_back = True
- self.__going_fwd = False
-
- self._do_page_transition()
-
- def _do_page_transition(self):
- if self.__going_fwd:
- if self._v_vscrollbar.get_value() >= \
- self._v_vscrollbar.props.adjustment.props.upper - \
- self._v_vscrollbar.props.adjustment.props.page_size:
- self._load_next_file()
- return True
- elif self.__going_back:
- if self._v_vscrollbar.get_value() == self._v_vscrollbar.props.adjustment.props.lower:
- self._load_prev_file()
- return True
-
- return False
-
- def _view_load_finished_cb(self, v, frame):
- filename = self._view.props.uri.replace('file://', '')
- if os.path.exists(filename.replace('xhtml', 'xml')):
- filename = filename.replace('xhtml', 'xml') # Hack for making javascript work
-
- filename = filename.split('#')[0] # Get rid of anchors
-
- if self._loaded_page < 1 or filename == None:
- return False
-
- self._loaded_filename = filename
-
- remfactor = self._paginator.get_remfactor_for_file(filename)
- pages = self._paginator.get_pagecount_for_file(filename)
- extra = int(math.ceil(remfactor * self._view.get_page_height()/(pages-remfactor)))
- if extra > 0:
- self._view.add_bottom_padding(extra)
-
- if self.__in_search:
- self._view.search_text(self._findjob.get_search_text(), \
- self._findjob.get_case_sensitive(), \
- self.__search_fwd, False)
- self.__in_search = False
- else:
- if self.__going_back:
- # We need to scroll to the last page
- self._scroll_page_end()
- else:
- self._scroll_page()
-
- base_pageno = self._paginator.get_base_pageno_for_file(filename)
- scrollval = self._v_vscrollbar.get_value()
- scroll_upper = self._v_vscrollbar.props.adjustment.props.upper
-
- if scroll_upper == 0: # This is a one page file
- pageno = base_pageno
- else:
- offset = (scrollval/scroll_upper) * self._paginator.get_pagecount_for_file(filename)
- pageno = math.floor(base_pageno + offset)
-
- if pageno != self._loaded_page:
- self._on_page_changed(int(pageno))
-
-
- def _scroll_page_end(self):
- v_upper = self._v_vscrollbar.props.adjustment.props.upper
- v_page_size = self._v_vscrollbar.props.adjustment.props.page_size
- self._v_vscrollbar.set_value(v_upper)
-
- def _scroll_page(self):
- pageno = self._loaded_page
-
- v_upper = self._v_vscrollbar.props.adjustment.props.upper
- v_page_size = self._v_vscrollbar.props.adjustment.props.page_size
-
- scrollfactor = self._paginator.get_scrollfactor_pos_for_pageno(pageno)
- self._v_vscrollbar.set_value((v_upper - v_page_size) * scrollfactor)
-
- def _paginate(self):
- filelist = []
- for i in self._epub._navmap.get_flattoc():
- filelist.append(os.path.join(self._epub._tempdir, i))
-
- self._paginator = _Paginator(filelist)
- self._paginator.connect('paginated', self._paginated_cb)
-
- def _load_next_page(self):
- self._load_page(self._loaded_page + 1)
-
- def _load_prev_page(self):
- self._load_page(self._loaded_page - 1)
-
- def _v_scrollbar_value_changed_cb(self, scrollbar):
- if self._loaded_page < 1:
- return
- scrollval = scrollbar.get_value()
- scroll_upper = self._v_vscrollbar.props.adjustment.props.upper
- scroll_page_size = self._v_vscrollbar.props.adjustment.props.page_size
-
- if self.__going_fwd == True and not self._loaded_page == self._pagecount:
- if self._paginator.get_file_for_pageno(self._loaded_page) != \
- self._paginator.get_file_for_pageno(self._loaded_page + 1):
- return # We don't need this if the next page is in another file
-
- scrollfactor_next = self._paginator.get_scrollfactor_pos_for_pageno(self._loaded_page + 1)
- if scrollval > 0:
- scrollfactor = scrollval/(scroll_upper - scroll_page_size)
- else:
- scrollfactor = 0
- if scrollfactor >= scrollfactor_next:
- self._on_page_changed(self._loaded_page + 1)
- elif self.__going_back == True and self._loaded_page > 1:
- if self._paginator.get_file_for_pageno(self._loaded_page) != \
- self._paginator.get_file_for_pageno(self._loaded_page - 1):
- return
-
- scrollfactor_cur = self._paginator.get_scrollfactor_pos_for_pageno(self._loaded_page)
- if scrollval > 0:
- scrollfactor = scrollval/(scroll_upper - scroll_page_size)
- else:
- scrollfactor = 0
-
- if scrollfactor <= scrollfactor_cur:
- self._on_page_changed(self._loaded_page - 1)
-
- def _on_page_changed(self, pageno):
- self.__page_changed = True
- self._loaded_page = pageno
- self._scrollbar.handler_block(self._scrollbar_change_value_cb_id)
- self._scrollbar.set_value(pageno)
- self._scrollbar.handler_unblock(self._scrollbar_change_value_cb_id)
- self.emit('page-changed')
-
- def _load_page(self, pageno):
- if pageno > self._pagecount or pageno < 1:
- #TODO: Cause an exception
- return
-
- self._on_page_changed(pageno)
- filename = self._paginator.get_file_for_pageno(pageno)
- if filename != self._loaded_filename:
- #self._loaded_filename = filename
- if filename.endswith('xml'):
- dest = filename.replace('xml', 'xhtml')
- shutil.copy(filename.replace('file://', ''), dest.replace('file://', ''))
- self._view.open(dest)
- else:
- self._view.open(filename)
- else:
- self._scroll_page()
-
- def _load_next_file(self):
- if self._loaded_page == self._pagecount:
- return
- cur_file = self._paginator.get_file_for_pageno(self._loaded_page)
- pageno = self._loaded_page
- while pageno < self._paginator.get_total_pagecount():
- pageno += 1
- if self._paginator.get_file_for_pageno(pageno) != cur_file:
- break
-
- self._load_page(pageno)
-
- 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)
- if filepath.endswith(path):
- self._load_page(pageno)
- break
-
- def _load_prev_file(self):
- if self._loaded_page == 1:
- return
- cur_file = self._paginator.get_file_for_pageno(self._loaded_page)
- pageno = self._loaded_page
- while pageno > 1:
- pageno -= 1
- if self._paginator.get_file_for_pageno(pageno) != cur_file:
- break
-
- self._load_page(pageno)
-
- def _scrollbar_change_value_cb(self, range, scrolltype, value):
- if scrolltype == gtk.SCROLL_STEP_FORWARD:
- self.__going_fwd = True
- self.__going_back = False
- if not self._do_page_transition():
- self._view.move_cursor(gtk.MOVEMENT_DISPLAY_LINES, 1)
- elif scrolltype == gtk.SCROLL_STEP_BACKWARD:
- self.__going_fwd = False
- self.__going_back = True
- if not self._do_page_transition():
- self._view.move_cursor(gtk.MOVEMENT_DISPLAY_LINES, -1)
- elif scrolltype == gtk.SCROLL_JUMP or \
- scrolltype == gtk.SCROLL_PAGE_FORWARD or \
- scrolltype == gtk.SCROLL_PAGE_BACKWARD:
- if value > self._scrollbar.props.adjustment.props.upper:
- self._load_page(self._pagecount)
- else:
- self._load_page(round(value))
- else:
- print 'Warning: unknown scrolltype %s with value %f' % (str(scrolltype), value)
-
- self._scrollbar.set_value(self._loaded_page) #FIXME: This should not be needed here
-
- if self.__page_changed == True:
- self.__page_changed = False
- return False
- else:
- return True
-
- def _paginated_cb(self, object):
- self._ready = True
-
- self._pagecount = self._paginator.get_total_pagecount()
- self._scrollbar.set_range(1.0, self._pagecount - 1.0)
- self._scrollbar.set_increments(1.0, 1.0)
- self._view.grab_focus()
- self._view.grab_default()
- if self._loaded_page < 1:
- self._load_page(1)
-
-
-
- def _destroy_cb(self, widget):
- self._epub.close()
-
diff --git a/epubview/jobs.py b/epubview/jobs.py
deleted file mode 100644
index 3f9a1cb..0000000
--- a/epubview/jobs.py
+++ /dev/null
@@ -1,296 +0,0 @@
-# Copyright 2009 One Laptop Per Child
-# Author: Sayamindu Dasgupta <sayamindu@laptop.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-
-import gobject
-import gtk
-import widgets
-import cairo
-
-import math
-import os.path
-import BeautifulSoup
-
-import epub
-
-import threading
-
-PAGE_WIDTH = 135
-PAGE_HEIGHT = 216
-
-def _pixel_to_mm(pixel, dpi):
- inches = pixel/dpi
- return int(inches/0.03937)
-
-def _mm_to_pixel(mm, dpi):
- inches = mm * 0.03937
- return int(inches * dpi)
-
-
-
-class SearchThread(threading.Thread):
- def __init__(self, obj):
- threading.Thread.__init__ (self)
- self.obj = obj
- self.stopthread = threading.Event()
-
- def _start_search(self):
- for entry in self.obj.flattoc:
- if self.stopthread.isSet():
- break
- filepath = os.path.join(self.obj._document.get_basedir(), entry)
- f = open(filepath)
- if self._searchfile(f):
- self.obj._matchfilelist.append(entry)
- f.close()
-
- gtk.gdk.threads_enter()
- self.obj._finished = True
- self.obj.emit('updated')
- gtk.gdk.threads_leave()
-
- return False
-
- def _searchfile(self, fileobj):
- soup = BeautifulSoup.BeautifulSoup(fileobj)
- body = soup.find('body')
- tags = body.findChildren(True)
- for tag in tags:
- if not tag.string is None:
- if tag.string.find(self.obj._text) > -1:
- return True
-
- return False
-
- def run (self):
- self._start_search()
-
- def stop(self):
- self.stopthread.set()
-
-
-
-class _JobPaginator(gobject.GObject):
- __gsignals__ = {
- 'paginated': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([]))
- }
- def __init__(self, filelist):
- gobject.GObject.__init__(self)
-
- self._filelist = filelist
- self._filedict = {}
- self._pagemap = {}
-
- self._bookheight = 0
- self._count = 0
- self._pagecount = 0
-
- self._screen = gtk.gdk.screen_get_default()
- self._old_fontoptions = self._screen.get_font_options()
- options = cairo.FontOptions()
- options.set_hint_style(cairo.HINT_STYLE_MEDIUM)
- options.set_antialias(cairo.ANTIALIAS_GRAY)
- options.set_subpixel_order(cairo.SUBPIXEL_ORDER_DEFAULT)
- options.set_hint_metrics(cairo.HINT_METRICS_DEFAULT)
- self._screen.set_font_options(options)
-
- self._temp_win = gtk.Window()
- self._temp_view = widgets._WebView()
-
- settings = self._temp_view.get_settings()
- settings.props.default_font_family = 'DejaVu LGC Serif'
- settings.props.sans_serif_font_family = 'DejaVu LGC Sans'
- settings.props.serif_font_family = 'DejaVu LGC Serif'
- settings.props.monospace_font_family = 'DejaVu LGC Sans Mono'
- settings.props.enforce_96_dpi = True
- #settings.props.auto_shrink_images = False #FIXME: This does not seem to work
- settings.props.enable_plugins = False
- settings.props.default_font_size = 12
- settings.props.default_monospace_font_size = 10
- settings.props.default_encoding = 'utf-8'
-
- sw = gtk.ScrolledWindow()
- sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER)
- self._dpi = 96
- sw.set_size_request(_mm_to_pixel(PAGE_WIDTH, self._dpi), _mm_to_pixel(PAGE_HEIGHT, self._dpi))
- sw.add(self._temp_view)
- self._temp_win.add(sw)
- self._temp_view.connect('load-finished', self._page_load_finished_cb)
-
- self._temp_win.show_all()
- self._temp_win.unrealize()
-
- self._temp_view.open(self._filelist[self._count])
-
- 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):
- pages = 1
- else:
- pages = pageheight/float(_mm_to_pixel(PAGE_HEIGHT, self._dpi))
- for i in range(1, int(math.ceil(pages) + 1)):
- if pages - i < 0:
- pagelen = (pages - math.floor(pages))/pages
- else:
- pagelen = 1/pages
- self._pagemap[float(self._pagecount + i)] = (f.props.uri, (i-1)/math.ceil(pages), pagelen)
-
- self._pagecount += math.ceil(pages)
- self._filedict[f.props.uri.replace('file://', '')] = (math.ceil(pages), math.ceil(pages) - pages)
- self._bookheight += pageheight
-
- if self._count+1 >= len(self._filelist):
- self._temp_win.destroy()
- self._screen.set_font_options(self._old_fontoptions)
- self.emit('paginated')
- else:
- self._count += 1
- self._temp_view.open(self._filelist[self._count])
-
-
- 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, filename):
- '''
- Returns the number of pages in file
- '''
- return self._filedict[filename][0]
-
- def get_base_pageno_for_file(self, filename):
- '''
- Returns the pageno which begins in filename
- '''
- for key in self._pagemap.keys():
- if self._pagemap[key][0].replace('file://', '') == filename:
- return key
-
- return None
-
- def get_remfactor_for_file(self, filename):
- '''
- Returns the remainder factor (1 - fraction length of last page in file)
- '''
- return self._filedict[filename][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
-
-
-class _JobFind(gobject.GObject):
- __gsignals__ = {
- 'updated': (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ([]))
- }
- def __init__(self, document, start_page, n_pages, text, case_sensitive=False):
- gobject.GObject.__init__(self)
- gtk.gdk.threads_init()
-
- self._finished = False
- self._document = document
- self._start_page = start_page
- self._n_pages = n_pages
- self._text = text
- self._case_sensitive = case_sensitive
- self.flattoc = self._document.get_flattoc()
- self._matchfilelist = []
- self._current_file_index = 0
- self.threads = []
-
- s_thread = SearchThread(self)
- self.threads.append(s_thread)
- 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]
- except IndexError:
- self._current_file_index = 0
- path = self._matchfilelist[self._current_file_index]
-
- 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]
- except IndexError:
- self._current_file_index = -1
- path = self._matchfilelist[self._current_file_index]
-
- 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
deleted file mode 100644
index a0a1799..0000000
--- a/epubview/navmap.py
+++ /dev/null
@@ -1,93 +0,0 @@
-from lxml import etree
-import gtk
-
-class NavPoint(object):
- def __init__(self, label, contentsrc, children = []):
- self._label = label
- self._contentsrc = contentsrc
- self._children = children
-
- def get_label(self):
- return self._label
-
- def get_contentsrc(self):
- return self._contentsrc
-
- def get_children(self):
- return self._children
-
-
-class NavMap(object):
- def __init__(self, opffile, ncxfile, basepath):
- self._basepath = basepath
- 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()
-
- 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'):
- self._process_navpoint(navpoint)
-
- def _gettitle(self, navpoint):
- text = navpoint.find('./{http://www.daisy.org/z3986/2005/ncx/}navLabel/{http://www.daisy.org/z3986/2005/ncx/}text')
- return text.text
-
- def _getcontent(self, navpoint):
- text = navpoint.find('./{http://www.daisy.org/z3986/2005/ncx/}content/')
- return self._basepath + text.get('src')
-
- def _process_navpoint(self, navpoint, parent = None):
- title = self._gettitle(navpoint)
- content = self._getcontent(navpoint)
-
- #print title, content
-
- iter = self._gtktreestore.append(parent, [title, content])
- #self._flattoc.append((title, content))
-
- childnavpointlist = list(navpoint.iterfind('./{http://www.daisy.org/z3986/2005/ncx/}navPoint'))
-
- if len(childnavpointlist):
- for childnavpoint in childnavpointlist:
- self._process_navpoint(childnavpoint, parent = iter)
- else:
- 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
deleted file mode 100644
index d80c45a..0000000
--- a/epubview/widgets.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import webkit
-import gtk
-
-
-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=Math.max(document.body.scrollHeight, document.body.offsetHeight,document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);'
- 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)
-