mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
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:
parent
98462ab969
commit
ef48bcc3c1
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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''
|
||||
|
@ -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'):
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user