KG updates

This commit is contained in:
GRiker 2011-03-28 15:50:56 -07:00
commit 171897529e
14 changed files with 128 additions and 86 deletions

View File

@ -17,9 +17,9 @@ from calibre.ebooks.metadata import authors_to_string, MetaInformation, \
title_sort title_sort
from calibre.ebooks.metadata.book.base import Metadata from calibre.ebooks.metadata.book.base import Metadata
from calibre.ebooks.metadata.epub import set_metadata from calibre.ebooks.metadata.epub import set_metadata
from calibre.gui2.dialogs.confirm_delete import _config_name from calibre.gui2.dialogs.confirm_delete import config_name
from calibre.library.server.utils import strftime from calibre.library.server.utils import strftime
from calibre.utils.config import config_dir, dynamic, DynamicConfig, prefs from calibre.utils.config import config_dir, dynamic, prefs
from calibre.utils.date import now, parse_date from calibre.utils.date import now, parse_date
from calibre.utils.logging import Log from calibre.utils.logging import Log
from calibre.utils.zipfile import ZipFile from calibre.utils.zipfile import ZipFile
@ -33,8 +33,8 @@ class AppleOpenFeedback(OpenFeedback):
self.plugin = plugin self.plugin = plugin
def custom_dialog(self, parent): def custom_dialog(self, parent):
from PyQt4.Qt import (QCheckBox, QDialog, QDialogButtonBox, QIcon, from PyQt4.Qt import (QDialog, QDialogButtonBox, QIcon,
QLabel, QPixmap, QPushButton, QSize, QVBoxLayout) QLabel, QPushButton, QVBoxLayout)
class Dialog(QDialog): class Dialog(QDialog):
@ -45,19 +45,20 @@ class AppleOpenFeedback(OpenFeedback):
self.l = l = QVBoxLayout() self.l = l = QVBoxLayout()
self.setLayout(l) self.setLayout(l)
msg = QLabel() msg = QLabel()
msg.setText( msg.setText(_(
'<p>If you do not want calibre to recognize your Apple iDevice ' '<p>If you do not want calibre to recognize your Apple iDevice '
'when it is connected to your computer, ' 'when it is connected to your computer, '
'click <b>Disable Apple Driver</b>.</p>' 'click <b>Disable Apple Driver</b>.</p>'
'<p>To transfer books to your iDevice, ' '<p>To transfer books to your iDevice, '
'click <b>Disable Apple Driver</b>, ' 'click <b>Disable Apple Driver</b>, '
"then use the 'Connect to iTunes' method recommended in the " "then use the 'Connect to iTunes' method recommended in the "
'<a href=\"http://www.mobileread.com/forums/showthread.php?t=118559\">Calibre + iDevices FAQ</a>, ' '<a href="http://www.mobileread.com/forums/showthread.php?t=118559">Calibre + iDevices FAQ</a>, '
'using the <em>Connect/Share</em>|<em>Connect to iTunes</em> menu item.</p>' 'using the <em>Connect/Share</em>|<em>Connect to iTunes</em> menu item.</p>'
'<p>Enabling the Apple driver for direct connection to iDevices ' '<p>Enabling the Apple driver for direct connection to iDevices '
'is an unsupported advanced user mode.</p>' 'is an unsupported advanced user mode.</p>'
'<p></p>' '<p></p>'
) ))
msg.setOpenExternalLinks(True)
msg.setWordWrap(True) msg.setWordWrap(True)
l.addWidget(msg) l.addWidget(msg)
@ -75,17 +76,19 @@ class AppleOpenFeedback(OpenFeedback):
self.setWindowIcon(QIcon(I(pixmap))) self.setWindowIcon(QIcon(I(pixmap)))
self.resize(self.sizeHint()) self.resize(self.sizeHint())
if Dialog(parent).exec_(): self.finished.connect(self.do_it)
# Enable Apple driver, inhibit future display of dialog
# Reset dialog with Preferences|Behavior|Reset all disabled confirmation dialogs def do_it(self, return_code):
if return_code == self.Accepted:
self.log.info(" Apple driver ENABLED") self.log.info(" Apple driver ENABLED")
dynamic[_config_name(self.plugin.DISPLAY_DISABLE_DIALOG)] = False dynamic[config_name(self.plugin.DISPLAY_DISABLE_DIALOG)] = False
else: else:
# Disable Apple driver
from calibre.customize.ui import disable_plugin from calibre.customize.ui import disable_plugin
self.log.info(" Apple driver DISABLED") self.log.info(" Apple driver DISABLED")
disable_plugin(self.plugin) disable_plugin(self.plugin)
return Dialog(parent)
from PIL import Image as PILImage from PIL import Image as PILImage
from lxml import etree from lxml import etree
@ -179,7 +182,7 @@ class ITUNES(DriverBase):
#: The version of this plugin as a 3-tuple (major, minor, revision) #: The version of this plugin as a 3-tuple (major, minor, revision)
version = (1,0,0) version = (1,0,0)
DISPLAY_DISABLE_DIALOG = "display_disable_dialog" DISPLAY_DISABLE_DIALOG = "display_disable_apple_driver_dialog"
# EXTRA_CUSTOMIZATION_MESSAGE indexes # EXTRA_CUSTOMIZATION_MESSAGE indexes
USE_SERIES_AS_CATEGORY = 0 USE_SERIES_AS_CATEGORY = 0
@ -805,7 +808,7 @@ class ITUNES(DriverBase):
# Display a dialog recommending using 'Connect to iTunes' if user hasn't # Display a dialog recommending using 'Connect to iTunes' if user hasn't
# previously disabled the dialog # previously disabled the dialog
if dynamic.get(_config_name(self.DISPLAY_DISABLE_DIALOG),True): if dynamic.get(config_name(self.DISPLAY_DISABLE_DIALOG),True):
raise AppleOpenFeedback(self) raise AppleOpenFeedback(self)
else: else:
if DEBUG: if DEBUG:

View File

@ -43,8 +43,8 @@ class OpenFeedback(DeviceError):
def custom_dialog(self, parent): def custom_dialog(self, parent):
''' '''
If you need to show the user a custom dialog, create and If you need to show the user a custom dialog, instead if just
run it from a custom_dialog() method in your subclass. displaying the feedback_msg, create and return it here.
''' '''
raise NotImplementedError raise NotImplementedError

View File

@ -1003,8 +1003,10 @@ OptionRecommendation(name='sr3_replace',
self.opts.insert_blank_line = oibl self.opts.insert_blank_line = oibl
self.opts.remove_paragraph_spacing = orps self.opts.remove_paragraph_spacing = orps
from calibre.ebooks.oeb.transforms.page_margin import RemoveFakeMargins from calibre.ebooks.oeb.transforms.page_margin import \
RemoveFakeMargins, RemoveAdobeMargins
RemoveFakeMargins()(self.oeb, self.log, self.opts) RemoveFakeMargins()(self.oeb, self.log, self.opts)
RemoveAdobeMargins()(self.oeb, self.log, self.opts)
pr(0.9) pr(0.9)
self.flush() self.flush()

View File

@ -182,6 +182,19 @@ def metadata_from_filename(name, pat=None):
mi.isbn = si mi.isbn = si
except (IndexError, ValueError): except (IndexError, ValueError):
pass pass
try:
publisher = match.group('publisher')
mi.publisher = publisher
except (IndexError, ValueError):
pass
try:
pubdate = match.group('published')
if pubdate:
from calibre.utils.date import parse_date
mi.pubdate = parse_date(pubdate)
except:
pass
if mi.is_null('title'): if mi.is_null('title'):
mi.title = name mi.title = name
return mi return mi

View File

@ -102,6 +102,7 @@ class MobiMLizer(object):
def __call__(self, oeb, context): def __call__(self, oeb, context):
oeb.logger.info('Converting XHTML to Mobipocket markup...') oeb.logger.info('Converting XHTML to Mobipocket markup...')
self.oeb = oeb self.oeb = oeb
self.log = self.oeb.logger
self.opts = context self.opts = context
self.profile = profile = context.dest self.profile = profile = context.dest
self.fnums = fnums = dict((v, k) for k, v in profile.fnums.items()) self.fnums = fnums = dict((v, k) for k, v in profile.fnums.items())
@ -118,6 +119,10 @@ class MobiMLizer(object):
del oeb.guide['cover'] del oeb.guide['cover']
item = oeb.manifest.hrefs[href] item = oeb.manifest.hrefs[href]
if item.spine_position is not None: if item.spine_position is not None:
self.log.warn('Found an HTML cover,', item.href, 'removing it.',
'If you find some content missing from the output MOBI, it '
'is because you misidentified the HTML cover in the input '
'document')
oeb.spine.remove(item) oeb.spine.remove(item)
if item.media_type in OEB_DOCS: if item.media_type in OEB_DOCS:
self.oeb.manifest.remove(item) self.oeb.manifest.remove(item)
@ -206,6 +211,10 @@ class MobiMLizer(object):
vspace = bstate.vpadding + bstate.vmargin vspace = bstate.vpadding + bstate.vmargin
bstate.vpadding = bstate.vmargin = 0 bstate.vpadding = bstate.vmargin = 0
if tag not in TABLE_TAGS: if tag not in TABLE_TAGS:
if tag in ('ul', 'ol') and vspace > 0:
wrapper.addprevious(etree.Element(XHTML('div'),
height=self.mobimlize_measure(vspace)))
else:
wrapper.attrib['height'] = self.mobimlize_measure(vspace) wrapper.attrib['height'] = self.mobimlize_measure(vspace)
para.attrib['width'] = self.mobimlize_measure(indent) para.attrib['width'] = self.mobimlize_measure(indent)
elif tag == 'table' and vspace > 0: elif tag == 'table' and vspace > 0:

View File

@ -1,56 +0,0 @@
#!/usr/bin/env python
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
__license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
class RemoveFakeMargins(object):
'''
Try to detect and remove fake margins inserted by asinine ebook creation
software on each paragraph/wrapper div. Can be used only after CSS
flattening.
'''
def __call__(self, oeb, opts, log):
self.oeb, self.opts, self.log = oeb, opts, log
from calibre.ebooks.oeb.base import XPath, OEB_STYLES
stylesheet = None
for item in self.oeb.manifest:
if item.media_type.lower() in OEB_STYLES:
stylesheet = item.data
break
if stylesheet is None:
return
top_level_elements = {}
second_level_elements = {}
for x in self.oeb.spine:
root = x.data
body = XPath('//h:body')(root)
if body:
body = body[0]
if not hasattr(body, 'xpath'):
continue
# Check for margins on top level elements
for lb in XPath('./h:div|./h:p|./*/h:div|./*/h:p')(body):
cls = lb.get('class', '')
level = top_level_elements if lb.getparent() is body else \
second_level_elements
if cls not in level:
level[cls] = []
top_level_elements[cls] = []
level[cls].append(lb)
def get_margins(self, stylesheet, cls):
pass

View File

@ -11,6 +11,26 @@ from collections import Counter
from calibre.ebooks.oeb.base import OEB_STYLES, barename, XPath from calibre.ebooks.oeb.base import OEB_STYLES, barename, XPath
class RemoveAdobeMargins(object):
'''
Remove margins specified in Adobe's page templates.
'''
def __call__(self, oeb, log, opts):
self.oeb, self.opts, self.log = oeb, opts, log
for item in self.oeb.manifest:
if item.media_type == 'application/vnd.adobe-page-template+xml':
self.log('Removing page margins specified in the'
' Adobe page template')
for elem in item.data.xpath(
'//*[@margin-bottom or @margin-top '
'or @margin-left or @margin-right]'):
for margin in ('left', 'right', 'top', 'bottom'):
attr = 'margin-'+margin
elem.attrib.pop(attr, None)
class RemoveFakeMargins(object): class RemoveFakeMargins(object):
''' '''

View File

@ -7,7 +7,7 @@ from calibre.gui2 import dynamic
from calibre.gui2.dialogs.confirm_delete_ui import Ui_Dialog from calibre.gui2.dialogs.confirm_delete_ui import Ui_Dialog
from PyQt4.Qt import QDialog, Qt, QPixmap, QIcon from PyQt4.Qt import QDialog, Qt, QPixmap, QIcon
def _config_name(name): def config_name(name):
return name + '_again' return name + '_again'
class Dialog(QDialog, Ui_Dialog): class Dialog(QDialog, Ui_Dialog):
@ -22,11 +22,11 @@ class Dialog(QDialog, Ui_Dialog):
self.buttonBox.setFocus(Qt.OtherFocusReason) self.buttonBox.setFocus(Qt.OtherFocusReason)
def toggle(self, *args): def toggle(self, *args):
dynamic[_config_name(self.name)] = self.again.isChecked() dynamic[config_name(self.name)] = self.again.isChecked()
def confirm(msg, name, parent=None, pixmap='dialog_warning.png'): def confirm(msg, name, parent=None, pixmap='dialog_warning.png'):
if not dynamic.get(_config_name(name), True): if not dynamic.get(config_name(name), True):
return True return True
d = Dialog(msg, name, parent) d = Dialog(msg, name, parent)
d.label.setPixmap(QPixmap(I(pixmap))) d.label.setPixmap(QPixmap(I(pixmap)))

View File

@ -206,6 +206,46 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Publisher:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="publisher">
<property name="toolTip">
<string>Regular expression (?P&lt;publisher&gt;)</string>
</property>
<property name="text">
<string>No match</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Published:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="pubdate">
<property name="toolTip">
<string>Regular expression (?P&lt;published&gt;)</string>
</property>
<property name="text">
<string>No match</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</widget> </widget>

View File

@ -121,6 +121,12 @@ class FilenamePattern(QWidget, Ui_Form):
else: else:
self.series_index.setText(_('No match')) self.series_index.setText(_('No match'))
if mi.publisher:
self.publisher.setText(mi.publisher)
if mi.pubdate:
self.pubdate.setText(mi.pubdate.strftime('%Y-%m-%d'))
self.isbn.setText(_('No match') if mi.isbn is None else str(mi.isbn)) self.isbn.setText(_('No match') if mi.isbn is None else str(mi.isbn))

View File

@ -76,6 +76,8 @@ class CustomColumns(object):
'num':record[6], 'num':record[6],
'is_multiple':record[7], 'is_multiple':record[7],
} }
if data['display'] is None:
data['display'] = {}
table, lt = self.custom_table_names(data['num']) table, lt = self.custom_table_names(data['num'])
if table not in custom_tables or (data['normalized'] and lt not in if table not in custom_tables or (data['normalized'] and lt not in
custom_tables): custom_tables):

View File

@ -31,8 +31,11 @@ class cmd_commit(_cmd_commit):
summary = '' summary = ''
raw = urllib.urlopen('https://bugs.launchpad.net/calibre/+bug/' + raw = urllib.urlopen('https://bugs.launchpad.net/calibre/+bug/' +
bug).read() bug).read()
try:
h1 = html.fromstring(raw).xpath('//h1[@id="edit-title"]')[0] h1 = html.fromstring(raw).xpath('//h1[@id="edit-title"]')[0]
summary = html.tostring(h1, method='text', encoding=unicode).strip() summary = html.tostring(h1, method='text', encoding=unicode).strip()
except:
summary = 'Private bug'
print 'Working on bug:', summary print 'Working on bug:', summary
if summary: if summary:
msg = msg.replace('#%s'%bug, '#%s (%s)'%(bug, summary)) msg = msg.replace('#%s'%bug, '#%s (%s)'%(bug, summary))