diff options
author | Sayamindu Dasgupta <sayamindu@gmail.com> | 2009-12-29 17:26:05 (GMT) |
---|---|---|
committer | Sayamindu Dasgupta <sayamindu@gmail.com> | 2009-12-29 17:26:05 (GMT) |
commit | fe211f9a0adcec2c1e32505fdc13913cc1159cf9 (patch) | |
tree | f9de3a8f0de026b9af9b091a6d41107ce3c0f3f3 | |
parent | 32dc3b942d8b0e169ca01434fdb131939b326b67 (diff) |
Get rid of the epubview folder (to be replaced by submodule)
-rw-r--r-- | epubview/__init__.py | 24 | ||||
-rw-r--r-- | epubview/epub.py | 152 | ||||
-rw-r--r-- | epubview/epubinfo.py | 90 | ||||
-rw-r--r-- | epubview/epubview.py | 558 | ||||
-rw-r--r-- | epubview/jobs.py | 296 | ||||
-rw-r--r-- | epubview/navmap.py | 93 | ||||
-rw-r--r-- | epubview/widgets.py | 31 |
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) - |