mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix #3102 (ebook-device command not working in 0.6.5 for prs500) and add copy to clipboard button to all error/warning/etc dialogs
This commit is contained in:
commit
371cb45028
@ -226,7 +226,6 @@ def main():
|
|||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dev.open()
|
|
||||||
if command == "df":
|
if command == "df":
|
||||||
total = dev.total_space(end_session=False)
|
total = dev.total_space(end_session=False)
|
||||||
free = dev.free_space()
|
free = dev.free_space()
|
||||||
|
@ -9,8 +9,15 @@ Transform OEB content into FB2 markup
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import cStringIO
|
||||||
from base64 import b64encode
|
from base64 import b64encode
|
||||||
|
|
||||||
|
try:
|
||||||
|
from PIL import Image
|
||||||
|
Image
|
||||||
|
except ImportError:
|
||||||
|
import Image
|
||||||
|
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
from calibre import prepare_string_for_xml
|
from calibre import prepare_string_for_xml
|
||||||
@ -37,8 +44,10 @@ STYLES = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
class FB2MLizer(object):
|
class FB2MLizer(object):
|
||||||
|
|
||||||
def __init__(self, log):
|
def __init__(self, log):
|
||||||
self.log = log
|
self.log = log
|
||||||
|
self.image_hrefs = {}
|
||||||
|
|
||||||
def extract_content(self, oeb_book, opts):
|
def extract_content(self, oeb_book, opts):
|
||||||
self.log.info('Converting XHTML to FB2 markup...')
|
self.log.info('Converting XHTML to FB2 markup...')
|
||||||
@ -47,6 +56,7 @@ class FB2MLizer(object):
|
|||||||
return self.fb2mlize_spine()
|
return self.fb2mlize_spine()
|
||||||
|
|
||||||
def fb2mlize_spine(self):
|
def fb2mlize_spine(self):
|
||||||
|
self.image_hrefs = {}
|
||||||
output = self.fb2_header()
|
output = self.fb2_header()
|
||||||
if 'titlepage' in self.oeb_book.guide:
|
if 'titlepage' in self.oeb_book.guide:
|
||||||
self.log.debug('Generating cover page...')
|
self.log.debug('Generating cover page...')
|
||||||
@ -54,11 +64,11 @@ class FB2MLizer(object):
|
|||||||
item = self.oeb_book.manifest.hrefs[href]
|
item = self.oeb_book.manifest.hrefs[href]
|
||||||
if item.spine_position is None:
|
if item.spine_position is None:
|
||||||
stylizer = Stylizer(item.data, item.href, self.oeb_book, self.opts.output_profile)
|
stylizer = Stylizer(item.data, item.href, self.oeb_book, self.opts.output_profile)
|
||||||
output += self.dump_text(item.data.find(XHTML('body')), stylizer)
|
output += self.dump_text(item.data.find(XHTML('body')), stylizer, item)
|
||||||
for item in self.oeb_book.spine:
|
for item in self.oeb_book.spine:
|
||||||
self.log.debug('Converting %s to FictionBook2 XML' % item.href)
|
self.log.debug('Converting %s to FictionBook2 XML' % item.href)
|
||||||
stylizer = Stylizer(item.data, item.href, self.oeb_book, self.opts.output_profile)
|
stylizer = Stylizer(item.data, item.href, self.oeb_book, self.opts.output_profile)
|
||||||
output += self.dump_text(item.data.find(XHTML('body')), stylizer)
|
output += self.dump_text(item.data.find(XHTML('body')), stylizer, item)
|
||||||
output += self.fb2_body_footer()
|
output += self.fb2_body_footer()
|
||||||
output += self.fb2mlize_images()
|
output += self.fb2mlize_images()
|
||||||
output += self.fb2_footer()
|
output += self.fb2_footer()
|
||||||
@ -102,20 +112,29 @@ class FB2MLizer(object):
|
|||||||
images = u''
|
images = u''
|
||||||
for item in self.oeb_book.manifest:
|
for item in self.oeb_book.manifest:
|
||||||
if item.media_type in OEB_RASTER_IMAGES:
|
if item.media_type in OEB_RASTER_IMAGES:
|
||||||
raw_data = b64encode(item.data)
|
try:
|
||||||
# Don't put the encoded image on a single line.
|
im = Image.open(cStringIO.StringIO(item.data))
|
||||||
data = ''
|
data = cStringIO.StringIO()
|
||||||
col = 1
|
im.save(data, 'JPEG')
|
||||||
for char in raw_data:
|
data = data.getvalue()
|
||||||
if col == 72:
|
|
||||||
data += '\n'
|
raw_data = b64encode(data)
|
||||||
col = 1
|
# Don't put the encoded image on a single line.
|
||||||
col += 1
|
data = ''
|
||||||
data += char
|
col = 1
|
||||||
images += '<binary id="%s" content-type="%s">%s\n</binary>' % (os.path.basename(item.href), item.media_type, data)
|
for char in raw_data:
|
||||||
|
if col == 72:
|
||||||
|
data += '\n'
|
||||||
|
col = 1
|
||||||
|
col += 1
|
||||||
|
data += char
|
||||||
|
images += '<binary id="%s" content-type="%s">%s\n</binary>' % (self.image_hrefs.get(item.href, '0000.JPEG'), item.media_type, data)
|
||||||
|
except Exception as e:
|
||||||
|
self.log.error('Error: Could not include file %s becuase ' \
|
||||||
|
'%s.' % (item.href, e))
|
||||||
return images
|
return images
|
||||||
|
|
||||||
def dump_text(self, elem, stylizer, tag_stack=[]):
|
def dump_text(self, elem, stylizer, page, tag_stack=[]):
|
||||||
if not isinstance(elem.tag, basestring) \
|
if not isinstance(elem.tag, basestring) \
|
||||||
or namespace(elem.tag) != XHTML_NS:
|
or namespace(elem.tag) != XHTML_NS:
|
||||||
return u''
|
return u''
|
||||||
@ -131,7 +150,9 @@ class FB2MLizer(object):
|
|||||||
tag_count = 0
|
tag_count = 0
|
||||||
|
|
||||||
if tag == 'img':
|
if tag == 'img':
|
||||||
fb2_text += '<image xlink:href="#%s" />' % os.path.basename(elem.attrib['src'])
|
if page.abshref(elem.attrib['src']) not in self.image_hrefs.keys():
|
||||||
|
self.image_hrefs[page.abshref(elem.attrib['src'])] = '%s.jpg' % len(self.image_hrefs.keys())
|
||||||
|
fb2_text += '<image xlink:href="#%s" />' % self.image_hrefs[page.abshref(elem.attrib['src'])]
|
||||||
|
|
||||||
fb2_tag = TAG_MAP.get(tag, None)
|
fb2_tag = TAG_MAP.get(tag, None)
|
||||||
if fb2_tag and fb2_tag not in tag_stack:
|
if fb2_tag and fb2_tag not in tag_stack:
|
||||||
@ -155,7 +176,7 @@ class FB2MLizer(object):
|
|||||||
fb2_text += prepare_string_for_xml(elem.text)
|
fb2_text += prepare_string_for_xml(elem.text)
|
||||||
|
|
||||||
for item in elem:
|
for item in elem:
|
||||||
fb2_text += self.dump_text(item, stylizer, tag_stack)
|
fb2_text += self.dump_text(item, stylizer, page, tag_stack)
|
||||||
|
|
||||||
close_tag_list = []
|
close_tag_list = []
|
||||||
for i in range(0, tag_count):
|
for i in range(0, tag_count):
|
||||||
|
@ -5,7 +5,7 @@ import os
|
|||||||
from PyQt4.QtCore import QVariant, QFileInfo, QObject, SIGNAL, QBuffer, Qt, QSize, \
|
from PyQt4.QtCore import QVariant, QFileInfo, QObject, SIGNAL, QBuffer, Qt, QSize, \
|
||||||
QByteArray, QUrl, QTranslator, QCoreApplication, QThread
|
QByteArray, QUrl, QTranslator, QCoreApplication, QThread
|
||||||
from PyQt4.QtGui import QFileDialog, QMessageBox, QPixmap, QFileIconProvider, \
|
from PyQt4.QtGui import QFileDialog, QMessageBox, QPixmap, QFileIconProvider, \
|
||||||
QIcon, QTableView, QApplication, QDialog
|
QIcon, QTableView, QApplication, QDialog, QPushButton
|
||||||
|
|
||||||
ORG_NAME = 'KovidsBrain'
|
ORG_NAME = 'KovidsBrain'
|
||||||
APP_UID = 'libprs500'
|
APP_UID = 'libprs500'
|
||||||
@ -103,36 +103,49 @@ def available_width():
|
|||||||
def extension(path):
|
def extension(path):
|
||||||
return os.path.splitext(path)[1][1:].lower()
|
return os.path.splitext(path)[1][1:].lower()
|
||||||
|
|
||||||
def warning_dialog(parent, title, msg, det_msg='', show=False):
|
class MessageBox(QMessageBox):
|
||||||
d = QMessageBox(QMessageBox.Warning, 'WARNING: '+title, msg, QMessageBox.Ok,
|
|
||||||
parent)
|
|
||||||
d.setDetailedText(det_msg)
|
|
||||||
d.setIconPixmap(QPixmap(':/images/dialog_warning.svg'))
|
|
||||||
|
|
||||||
|
def __init__(self, type_, title, msg, buttons, parent, det_msg=''):
|
||||||
|
QMessageBox.__init__(self, type_, title, msg, buttons, parent)
|
||||||
|
self.title = title
|
||||||
|
self.msg = msg
|
||||||
|
self.det_msg = det_msg
|
||||||
|
self.setDetailedText(det_msg)
|
||||||
|
self.cb = QPushButton(_('Copy to Clipboard'))
|
||||||
|
self.layout().addWidget(self.cb)
|
||||||
|
self.connect(self.cb, SIGNAL('clicked()'), self.copy_to_clipboard)
|
||||||
|
|
||||||
|
def copy_to_clipboard(self):
|
||||||
|
QApplication.clipboard().setText('%s: %s\n\n%s' %
|
||||||
|
(self.title, self.msg, self.det_msg))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def warning_dialog(parent, title, msg, det_msg='', show=False):
|
||||||
|
d = MessageBox(QMessageBox.Warning, 'WARNING: '+title, msg, QMessageBox.Ok,
|
||||||
|
parent, det_msg)
|
||||||
|
d.setIconPixmap(QPixmap(':/images/dialog_warning.svg'))
|
||||||
if show:
|
if show:
|
||||||
return d.exec_()
|
return d.exec_()
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def error_dialog(parent, title, msg, det_msg='', show=False):
|
def error_dialog(parent, title, msg, det_msg='', show=False):
|
||||||
d = QMessageBox(QMessageBox.Critical, 'ERROR: '+title, msg, QMessageBox.Ok,
|
d = MessageBox(QMessageBox.Critical, 'ERROR: '+title, msg, QMessageBox.Ok,
|
||||||
parent)
|
parent, det_msg)
|
||||||
d.setDetailedText(det_msg)
|
|
||||||
d.setIconPixmap(QPixmap(':/images/dialog_error.svg'))
|
d.setIconPixmap(QPixmap(':/images/dialog_error.svg'))
|
||||||
if show:
|
if show:
|
||||||
return d.exec_()
|
return d.exec_()
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def question_dialog(parent, title, msg, det_msg=''):
|
def question_dialog(parent, title, msg, det_msg=''):
|
||||||
d = QMessageBox(QMessageBox.Question, title, msg, QMessageBox.Yes|QMessageBox.No,
|
d = MessageBox(QMessageBox.Question, title, msg, QMessageBox.Yes|QMessageBox.No,
|
||||||
parent)
|
parent, det_msg)
|
||||||
d.setDetailedText(det_msg)
|
|
||||||
d.setIconPixmap(QPixmap(':/images/dialog_information.svg'))
|
d.setIconPixmap(QPixmap(':/images/dialog_information.svg'))
|
||||||
return d.exec_() == QMessageBox.Yes
|
return d.exec_() == QMessageBox.Yes
|
||||||
|
|
||||||
def info_dialog(parent, title, msg, det_msg='', show=False):
|
def info_dialog(parent, title, msg, det_msg='', show=False):
|
||||||
d = QMessageBox(QMessageBox.Information, title, msg, QMessageBox.NoButton,
|
d = MessageBox(QMessageBox.Information, title, msg, QMessageBox.NoButton,
|
||||||
parent)
|
parent, det_msg)
|
||||||
d.setDetailedText(det_msg)
|
|
||||||
d.setIconPixmap(QPixmap(':/images/dialog_information.svg'))
|
d.setIconPixmap(QPixmap(':/images/dialog_information.svg'))
|
||||||
if show:
|
if show:
|
||||||
return d.exec_()
|
return d.exec_()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user