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.

This commit is contained in:
Kovid Goyal 2008-01-15 20:35:06 +00:00
parent 98462ab969
commit ef48bcc3c1
9 changed files with 95 additions and 54 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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()

View File

@ -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''

View File

@ -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'):

View File

@ -145,7 +145,9 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog):
elif isinstance(obj, QTextEdit):
obj.setPlainText(cmdline[i+1])
profile = cmdline[cmdline.index('--profile')+1]
self.gui_profile.setCurrentIndex(self.gui_profile.findText(profile))
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:

View File

@ -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)

View File

@ -5,8 +5,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>615</width>
<height>702</height>
<width>601</width>
<height>701</height>
</rect>
</property>
<property name="sizePolicy" >
@ -38,9 +38,9 @@
<item>
<widget class="QStackedWidget" name="stack" >
<property name="currentIndex" >
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="page" >
<widget class="QWidget" name="viewer_page" >
<layout class="QGridLayout" >
<property name="leftMargin" >
<number>0</number>
@ -162,7 +162,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2" >
<widget class="QWidget" name="bar_page" >
<layout class="QVBoxLayout" >
<item>
<spacer>

View File

@ -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: