From ef48bcc3c160faab958fb4225501b1c33a9c7467 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 15 Jan 2008 20:35:06 +0000 Subject: [PATCH] Fine tune the screen height for LRF conversions and drop the prs500-unsafe profile. Make GUI not die when an invalid option i passed to the ebook converter. --- src/libprs500/__init__.py | 17 +++++++++ src/libprs500/ebooks/lrf/__init__.py | 27 ++++++-------- src/libprs500/ebooks/lrf/any/convert_from.py | 7 ++-- src/libprs500/ebooks/metadata/__init__.py | 39 ++++++++++++++------ src/libprs500/ebooks/metadata/meta.py | 10 ++--- src/libprs500/gui2/dialogs/lrf_single.py | 6 ++- src/libprs500/gui2/lrf_renderer/main.py | 13 +++++-- src/libprs500/gui2/lrf_renderer/main.ui | 10 ++--- src/libprs500/gui2/main.py | 20 ++++++---- 9 files changed, 95 insertions(+), 54 deletions(-) diff --git a/src/libprs500/__init__.py b/src/libprs500/__init__.py index 1ddd68e0a6..4eb6bb68b1 100644 --- a/src/libprs500/__init__.py +++ b/src/libprs500/__init__.py @@ -21,6 +21,7 @@ __appname__ = 'libprs500' import sys, os, logging, mechanize, locale, cStringIO, re from gettext import GNUTranslations from math import floor +from optparse import OptionParser as _OptionParser from ttfquery import findsystem, describe @@ -63,6 +64,22 @@ def setup_cli_handlers(logger, level): logger.addHandler(handler) +class OptionParser(_OptionParser): + + def __init__(self, + usage='%prog [options] filename', + version=__appname__+' '+__version__, + epilog=_('Created by ')+__author__, + gui_mode=False, + **kwds): + _OptionParser.__init__(self, usage=usage, version=version, epilog=epilog, **kwds) + self.gui_mode = gui_mode + + def error(self, msg): + if self.gui_mode: + raise Exception(msg) + _OptionParser.error(self, msg) + def load_library(name, cdll): if iswindows: return cdll.LoadLibrary(name) diff --git a/src/libprs500/ebooks/lrf/__init__.py b/src/libprs500/ebooks/lrf/__init__.py index d2e7cffcdc..5d1cee0ea7 100644 --- a/src/libprs500/ebooks/lrf/__init__.py +++ b/src/libprs500/ebooks/lrf/__init__.py @@ -17,7 +17,7 @@ This package contains logic to read and write LRF files. The LRF file format is documented at U{http://www.sven.de/librie/Librie/LrfFormat}. """ import sys, os -from optparse import OptionParser, OptionValueError +from optparse import OptionValueError from htmlentitydefs import name2codepoint from uuid import uuid4 @@ -29,8 +29,7 @@ from libprs500.ebooks.lrf.pylrs.pylrs import TextBlock, Header, PutObj, \ Paragraph, TextStyle, BlockStyle from libprs500.ebooks.lrf.fonts import FONT_FILE_MAP from libprs500.ebooks import ConversionError -from libprs500 import __appname__, __version__, __author__ -from libprs500 import iswindows +from libprs500 import __appname__, __version__, __author__, iswindows, OptionParser __docformat__ = "epytext" @@ -40,10 +39,10 @@ class LRFParseError(Exception): class PRS500_PROFILE(object): screen_width = 600 - screen_height = 765 + screen_height = 775 dpi = 166 # Number of pixels to subtract from screen_height when calculating height of text area - fudge = 18 + fudge = 0 font_size = 10 #: Default (in pt) parindent = 10 #: Default (in pt) line_space = 1.2 #: Default (in pt) @@ -54,14 +53,8 @@ class PRS500_PROFILE(object): name = 'prs500' -class PRS500_PROFILE_UNSAFE(PRS500_PROFILE): - fudge = 0 - name = 'prs500-unsafe' - - profile_map = { PRS500_PROFILE.name : PRS500_PROFILE, - PRS500_PROFILE_UNSAFE.name : PRS500_PROFILE_UNSAFE, } def profile_from_string(option, opt_str, value, parser): @@ -85,9 +78,8 @@ def font_family(option, opt_str, value, parser): setattr(parser.values, option.dest, tuple()) -def option_parser(usage): - parser = OptionParser(usage=usage, version=__appname__+' '+__version__, - epilog=_('Created by ')+__author__) +def option_parser(usage, gui_mode=False): + parser = OptionParser(usage=usage, gui_mode=gui_mode) metadata = parser.add_option_group('METADATA OPTIONS') metadata.add_option("-t", "--title", action="store", type="string", default=None,\ dest="title", help=_("Set the title. Default: filename.")) @@ -272,7 +264,8 @@ def Book(options, logger, font_delta=0, header=None, ps['evensidemargin'] = options.left_margin ps['oddsidemargin'] = options.left_margin ps['textwidth'] = profile.screen_width - (options.left_margin + options.right_margin) - ps['textheight'] = profile.screen_height - (options.top_margin + options.bottom_margin) - profile.fudge + ps['textheight'] = profile.screen_height - (options.top_margin + options.bottom_margin) \ + - profile.fudge if header: hdr = Header() hb = TextBlock(textStyle=TextStyle(align='foot', @@ -283,7 +276,9 @@ def Book(options, logger, font_delta=0, header=None, ps['headheight'] = profile.header_height ps['header'] = hdr ps['topmargin'] = 0 - ps['textheight'] = profile.screen_height - (options.bottom_margin + ps['topmargin'] + ps['headheight'] + profile.fudge) + ps['textheight'] = profile.screen_height - (options.bottom_margin + ps['topmargin']) \ + - ps['headheight'] - profile.fudge + fontsize = int(10*profile.font_size+font_delta*20) baselineskip = fontsize + 20 fonts = find_custom_fonts(options, logger) diff --git a/src/libprs500/ebooks/lrf/any/convert_from.py b/src/libprs500/ebooks/lrf/any/convert_from.py index c918851fc6..81cf5d2053 100644 --- a/src/libprs500/ebooks/lrf/any/convert_from.py +++ b/src/libprs500/ebooks/lrf/any/convert_from.py @@ -12,6 +12,7 @@ ## 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. +from libprs500.ebooks import ConversionError '''Convert any ebook file into a LRF file.''' import sys, os, logging, shutil, tempfile, glob @@ -125,14 +126,14 @@ def process_file(path, options, logger=None): return 0 -def main(args=sys.argv, logger=None): - parser = option_parser('''\ +def main(args=sys.argv, logger=None, gui_mode=False): + parser = option_parser(usage='''\ any2lrf myfile Convert any ebook format into LRF. Supported formats are: LIT, RTF, TXT, HTML, EPUB and PDF. any2lrf will also process a RAR or ZIP archive. - ''') + ''', gui_mode=gui_mode) options, args = parser.parse_args(args) if len(args) != 2: parser.print_help() diff --git a/src/libprs500/ebooks/metadata/__init__.py b/src/libprs500/ebooks/metadata/__init__.py index 00534cc637..2c9570e6e2 100644 --- a/src/libprs500/ebooks/metadata/__init__.py +++ b/src/libprs500/ebooks/metadata/__init__.py @@ -40,27 +40,42 @@ def get_parser(extension): class MetaInformation(object): '''Convenient encapsulation of book metadata''' + @staticmethod + def copy(mi): + ans = MetaInformation(mi.title, mi.authors) + ans.author_sort = mi.author_sort + ans.title_sort = mi.title_sort + ans.comments = mi.comments + ans.category = mi.category + ans.publisher = mi.publisher + def __init__(self, title, authors): ''' - @param title: title or "Unknonw" + @param title: title or "Unknown" or a MetaInformation object @param authors: List of strings or [] ''' + mi = None + if isinstance(title, MetaInformation): + mi = title + title = mi.title + authors = mi.authors self.title = title self.author = authors # Needed for backward compatibility #: List of strings or [] self.authors = authors #: Sort text for author - self.author_sort = None - self.title_sort = None - self.comments = None - self.category = None - self.publisher = None - self.series = None - self.series_index = None - self.rating = None - self.isbn = None - self.tags = [] - self.cover_data = (None, None) #(extension, data) + self.author_sort = None if not mi else mi.author_sort + self.title_sort = None if not mi else mi.title_sort + self.comments = None if not mi else mi.comments + self.category = None if not mi else mi.category + self.publisher = None if not mi else mi.publisher + self.series = None if not mi else mi.series + self.series_index = None if not mi else mi.series_index + self.rating = None if not mi else mi.rating + self.isbn = None if not mi else mi.isbn + self.tags = [] if not mi else mi.tags + self.cover_data = (None, None) if not mi else mi.cover_data #(extension, data) + def __str__(self): ans = u'' diff --git a/src/libprs500/ebooks/metadata/meta.py b/src/libprs500/ebooks/metadata/meta.py index 876eb5c571..335f1b60d6 100644 --- a/src/libprs500/ebooks/metadata/meta.py +++ b/src/libprs500/ebooks/metadata/meta.py @@ -26,15 +26,15 @@ from libprs500.ebooks.metadata import MetaInformation def get_metadata(stream, stream_type='lrf'): if stream_type: stream_type = stream_type.lower() if stream_type == 'rtf': - return rtf_metadata(stream) + return MetaInformation(rtf_metadata(stream), None) if stream_type == 'lrf': - return lrf_metadata(stream) + return MetaInformation(lrf_metadata(stream), None) if stream_type == 'pdf': - return pdf_metadata(stream) + return MetaInformation(pdf_metadata(stream), None) if stream_type == 'lit': - return lit_metadata(stream) + return MetaInformation(lit_metadata(stream), None) if stream_type == 'epub': - return epub_metadata(stream) + return MetaInformation(epub_metadata(stream), None) return MetaInformation(None, None) def set_metadata(stream, mi, stream_type='lrf'): diff --git a/src/libprs500/gui2/dialogs/lrf_single.py b/src/libprs500/gui2/dialogs/lrf_single.py index 11bee76307..0f77693057 100644 --- a/src/libprs500/gui2/dialogs/lrf_single.py +++ b/src/libprs500/gui2/dialogs/lrf_single.py @@ -144,8 +144,10 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog): obj.setText(cmdline[i+1]) elif isinstance(obj, QTextEdit): obj.setPlainText(cmdline[i+1]) - profile = cmdline[cmdline.index('--profile')+1] - self.gui_profile.setCurrentIndex(self.gui_profile.findText(profile)) + profile = cmdline[cmdline.index('--profile')+1] + pindex = self.gui_profile.findText(profile) + if pindex >= 0: + self.gui_profile.setCurrentIndex(pindex) for prepro in self.PREPROCESS_OPTIONS: ops = prepro.get_opt_string() if ops in cmdline: diff --git a/src/libprs500/gui2/lrf_renderer/main.py b/src/libprs500/gui2/lrf_renderer/main.py index 533e2a449b..8c35ef9528 100644 --- a/src/libprs500/gui2/lrf_renderer/main.py +++ b/src/libprs500/gui2/lrf_renderer/main.py @@ -110,6 +110,7 @@ class Main(MainWindow, Ui_MainWindow): self.closed = False + def configure(self, triggered): opts = cPickle.loads(str(QSettings().value('ebook viewer options', QVariant(cPickle.dumps(self.opts))).toString())) d = Config(self, opts) @@ -166,11 +167,16 @@ class Main(MainWindow, Ui_MainWindow): if not self.renderer.aborted and self.renderer.lrf is not None: width, height = self.renderer.lrf.device_info.width, \ self.renderer.lrf.device_info.height - self.graphics_view.resize_for(width+5, height+5) + hdelta = self.viewer_page.size().height() - self.graphics_view.size().height() + from PyQt4.QtGui import QScrollBar + s = QScrollBar(self) + scrollbar_adjust = min(s.width(), s.height()) + self.graphics_view.resize_for(width+scrollbar_adjust, height+scrollbar_adjust) + desktop = QCoreApplication.instance().desktop() screen_height = desktop.availableGeometry().height() - 25 - height = min(screen_height, height+55) - self.resize(self.size().width(), height) + height = min(screen_height, height+hdelta+scrollbar_adjust) + self.resize(width+scrollbar_adjust, height) self.setWindowTitle(self.renderer.lrf.metadata.title + ' - ' + __appname__) self.document_title = self.renderer.lrf.metadata.title if self.opts.profile: @@ -183,6 +189,7 @@ class Main(MainWindow, Ui_MainWindow): self.document.render(self.renderer.lrf) print 'Layout time:', time.time()-start, 'seconds' self.renderer.lrf = None + self.graphics_view.setScene(self.document) self.graphics_view.show() self.spin_box.setRange(1, self.document.num_of_pages) diff --git a/src/libprs500/gui2/lrf_renderer/main.ui b/src/libprs500/gui2/lrf_renderer/main.ui index 6cbaaf1f4b..9f7a0acab2 100644 --- a/src/libprs500/gui2/lrf_renderer/main.ui +++ b/src/libprs500/gui2/lrf_renderer/main.ui @@ -5,8 +5,8 @@ 0 0 - 615 - 702 + 601 + 701 @@ -38,9 +38,9 @@ - 1 + 0 - + 0 @@ -162,7 +162,7 @@ - + diff --git a/src/libprs500/gui2/main.py b/src/libprs500/gui2/main.py index e2e9cbd134..938cd58003 100644 --- a/src/libprs500/gui2/main.py +++ b/src/libprs500/gui2/main.py @@ -12,12 +12,10 @@ ## 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.Warning -from libprs500.gui2.update import CheckForUpdates -from libprs500 import iswindows -from libprs500 import isosx -from libprs500.library.database import LibraryDatabase + import os, sys, textwrap, cStringIO, collections, traceback, shutil +from functools import partial from PyQt4.QtCore import Qt, SIGNAL, QObject, QCoreApplication, \ QSettings, QVariant, QSize, QThread @@ -29,13 +27,16 @@ from libprs500 import __version__, __appname__, islinux, sanitize_file_name from libprs500.ptempfile import PersistentTemporaryFile from libprs500.ebooks.metadata.meta import get_metadata from libprs500.ebooks.lrf.web.convert_from import main as web2lrf -from libprs500.ebooks.lrf.any.convert_from import main as any2lrf +from libprs500.ebooks.lrf.any.convert_from import main as _any2lrf from libprs500.devices.errors import FreeSpaceError from libprs500.devices.interface import Device from libprs500.gui2 import APP_UID, warning_dialog, choose_files, error_dialog, \ initialize_file_icon_provider, \ pixmap_to_data, choose_dir, ORG_NAME, \ qstring_to_unicode, set_sidebar_directories +from libprs500 import iswindows, isosx +from libprs500.library.database import LibraryDatabase +from libprs500.gui2.update import CheckForUpdates from libprs500.gui2.main_window import MainWindow from libprs500.gui2.main_ui import Ui_MainWindow from libprs500.gui2.device import DeviceDetector, DeviceManager @@ -55,6 +56,7 @@ from libprs500.ebooks.metadata.meta import set_metadata from libprs500.ebooks.metadata import MetaInformation from libprs500.ebooks import BOOK_EXTENSIONS +any2lrf = partial(_any2lrf, gui_mode=True) class Main(MainWindow, Ui_MainWindow): @@ -295,12 +297,14 @@ class Main(MainWindow, Ui_MainWindow): format = format[1:] if format else None stream = open(book, 'rb') mi = get_metadata(stream, stream_type=format) - title = mi.title if mi.title else os.path.splitext(os.path.basename(book))[0] + if not mi.title: + mi.title = os.path.splitext(os.path.basename(book))[0] formats.append(format) metadata.append(mi) names.append(os.path.basename(book)) - authors = mi.authors if mi.authors else ['Unknown'] - infos.append({'title':title, 'authors':', '.join(authors), + if not mi.authors: + mi.authors = ['Unknown'] + infos.append({'title':mi.title, 'authors':', '.join(mi.authors), 'cover':self.default_thumbnail, 'tags':[]}) if not to_device: