From 5389be9376a1664a54fbea8882e7a320604f64d5 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 29 Apr 2010 15:41:18 -0600 Subject: [PATCH 1/8] Fix #5409 (Covers in ePub don't show on device) --- src/calibre/ebooks/epub/output.py | 34 +++++++++++++++++++++++-- src/calibre/gui2/convert/epub_output.py | 3 ++- src/calibre/gui2/convert/epub_output.ui | 13 +++++++--- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/calibre/ebooks/epub/output.py b/src/calibre/ebooks/epub/output.py index 61aa2c359a..dc8905619d 100644 --- a/src/calibre/ebooks/epub/output.py +++ b/src/calibre/ebooks/epub/output.py @@ -81,12 +81,40 @@ class EPUBOutput(OutputFormatPlugin): OptionRecommendation(name='no_default_epub_cover', recommended_value=False, help=_('Normally, if the input file has no cover and you don\'t' ' specify one, a default cover is generated with the title, ' - 'authors, etc. This option disables the generation of this cover.')), + 'authors, etc. This option disables the generation of this cover.') + ), + + OptionRecommendation(name='no_svg_cover', recommended_value=False, + help=_('Do not use SVG for the book cover. Use this option if ' + 'your EPUB is going to be used ona device that does not ' + 'support SVG, like the iPhone or the JetBook Lite. ' + 'Without this option, such devices will display the cover ' + 'as a blank page.') + ), ]) recommendations = set([('pretty_print', True, OptionRecommendation.HIGH)]) + NONSVG_TITLEPAGE_COVER = '''\ + + + + + Cover + + + +
+ cover +
+ + + ''' TITLEPAGE_COVER = '''\ @@ -301,7 +329,9 @@ class EPUBOutput(OutputFormatPlugin): else: href = self.default_cover() if href is not None: - tp = self.TITLEPAGE_COVER%unquote(href) + templ = self.NONSVG_TITLEPAGE_COVER if self.opts.no_svg_cover \ + else self.TITLEPAGE_COVER + tp = templ%unquote(href) id, href = m.generate('titlepage', 'titlepage.xhtml') item = m.add(id, href, guess_type('t.xhtml')[0], data=etree.fromstring(tp)) diff --git a/src/calibre/gui2/convert/epub_output.py b/src/calibre/gui2/convert/epub_output.py index 2afa662fb4..57027d9315 100644 --- a/src/calibre/gui2/convert/epub_output.py +++ b/src/calibre/gui2/convert/epub_output.py @@ -17,7 +17,8 @@ class PluginWidget(Widget, Ui_Form): def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, 'epub_output', - ['dont_split_on_page_breaks', 'flow_size', 'no_default_epub_cover'] + ['dont_split_on_page_breaks', 'flow_size', + 'no_default_epub_cover', 'no_svg_cover'] ) self.db, self.book_id = db, book_id self.initialize_options(get_option, get_help, db, book_id) diff --git a/src/calibre/gui2/convert/epub_output.ui b/src/calibre/gui2/convert/epub_output.ui index f282214996..7f92ec3087 100644 --- a/src/calibre/gui2/convert/epub_output.ui +++ b/src/calibre/gui2/convert/epub_output.ui @@ -21,7 +21,7 @@ - + Split files &larger than: @@ -31,7 +31,7 @@ - + KB @@ -47,7 +47,7 @@ - + Qt::Vertical @@ -67,6 +67,13 @@ + + + + No &SVG cover + + + From e5bb3888af9bb5b9852acc82a3b7cbdf465e2a8b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 29 Apr 2010 15:46:26 -0600 Subject: [PATCH 2/8] Fix #5408 (allow customization of the view command) --- src/calibre/gui2/ui.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index e6cdf2bda9..c1e9da8b74 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -350,7 +350,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): self.view_menu = QMenu() self.view_menu.addAction(_('View')) - self.view_menu.addAction(_('View specific format')) + ac = self.view_menu.addAction(_('View specific format')) + ac.setShortcut(Qt.AltModifier+Qt.Key_V) self.action_view.setMenu(self.view_menu) self.delete_menu = QMenu() From 6c62c10ac2d7567c6fa073acba39aa5e7fd9d24b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 29 Apr 2010 16:04:17 -0600 Subject: [PATCH 3/8] E-book viewer: Handle self-closing heading tags in XHTML documents correctly. Fixes #5413 (Rendering of ePub in view is incorrect) --- src/calibre/gui2/viewer/documentview.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index 7ca9b1bd95..3e7f7536d4 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -423,7 +423,7 @@ class DocumentView(QWebView): QWebView.__init__(self, *args) self.debug_javascript = False self.shortcuts = Shortcuts(SHORTCUTS, 'shortcuts/viewer') - self.self_closing_pat = re.compile(r'<([a-z]+)\s+([^>]+)/>', + self.self_closing_pat = re.compile(r'<([a-z1-6]+)\s+([^>]+)/>', re.IGNORECASE) self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) self._size_hint = QSize(510, 680) From 0c168b03060d0ebf03a5c652fa6407c2e7774059 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 29 Apr 2010 16:37:20 -0600 Subject: [PATCH 4/8] Fix #5402 (CBZ meta data not imported) --- src/calibre/customize/builtins.py | 8 ++++- src/calibre/ebooks/metadata/archive.py | 42 ++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index 95d5f2c31a..a3eb4272ba 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -7,7 +7,7 @@ import os import glob from calibre.customize import FileTypePlugin, MetadataReaderPlugin, MetadataWriterPlugin from calibre.constants import numeric_version -from calibre.ebooks.metadata.archive import ArchiveExtract +from calibre.ebooks.metadata.archive import ArchiveExtract, get_cbz_metadata class HTML2ZIP(FileTypePlugin): name = 'HTML to ZIP' @@ -97,6 +97,12 @@ class ComicMetadataReader(MetadataReaderPlugin): from calibre.ebooks.metadata import MetaInformation ret = extract_first(stream) mi = MetaInformation(None, None) + stream.seek(0) + if ftype == 'cbz': + try: + mi.smart_update(get_cbz_metadata(stream)) + except: + pass if ret is not None: path, data = ret ext = os.path.splitext(path)[1][1:] diff --git a/src/calibre/ebooks/metadata/archive.py b/src/calibre/ebooks/metadata/archive.py index 0af41c274f..45d549b6ea 100644 --- a/src/calibre/ebooks/metadata/archive.py +++ b/src/calibre/ebooks/metadata/archive.py @@ -64,3 +64,45 @@ class ArchiveExtract(FileTypePlugin): of.write(zf.read(fname)) return of.name +def get_comic_book_info(d, mi): + series = d.get('series', '') + if series.strip(): + mi.series = series + if d.get('volume', -1) > -1: + mi.series_index = float(d['volume']) + if d.get('rating', -1) > -1: + mi.rating = d['rating'] + for x in ('title', 'publisher'): + y = d.get(x, '').strip() + if y: + setattr(mi, x, y) + tags = d.get('tags', []) + if tags: + mi.tags = tags + authors = [] + for credit in d.get('credits', []): + if credit.get('role', '') in ('Writer', 'Artist', 'Cartoonist', + 'Creator'): + x = credit.get('person', '') + if x: + x = ' '.join((reversed(x.split(', ')))) + authors.append(x) + if authors: + mi.authors = authors + + + +def get_cbz_metadata(stream): + from calibre.utils.zipfile import ZipFile + from calibre.ebooks.metadata import MetaInformation + import json + + zf = ZipFile(stream) + mi = MetaInformation(None, None) + if zf.comment: + m = json.loads(zf.comment) + if hasattr(m, 'keys'): + for cat in m.keys(): + if cat.startswith('ComicBookInfo'): + get_comic_book_info(m[cat], mi) + return mi From 6d5d22d692b7b32414701f6579136f67ad13ceb9 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 29 Apr 2010 17:04:58 -0600 Subject: [PATCH 5/8] Fix #5410 (Error communicating with device - PRS-600 - as I edit metadata) --- src/calibre/devices/prs505/driver.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index 448965a913..7facd4d3bb 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -202,9 +202,11 @@ class PRS505(CLI, Device): def write_card_prefix(prefix, listid): if prefix is not None and hasattr(booklists[listid], 'write'): - if not os.path.exists(prefix): - os.makedirs(prefix) - with open(prefix + self.__class__.CACHE_XML, 'wb') as f: + tgt = os.path.join(prefix, *(self.CACHE_XML.split('/'))) + base = os.path.dirname(tgt) + if not os.path.exists(base): + os.makedirs(base) + with open(tgt, 'wb') as f: booklists[listid].write(f) write_card_prefix(self._card_a_prefix, 1) write_card_prefix(self._card_b_prefix, 2) From 54e524c7e113b5736134ce029f70b02489b4e1ac Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 29 Apr 2010 18:30:44 -0600 Subject: [PATCH 6/8] Fix #5403 (Articles to PC Mag not downloaded) --- resources/recipes/pc_mag.recipe | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/resources/recipes/pc_mag.recipe b/resources/recipes/pc_mag.recipe index 7d6049ec2b..227d777034 100644 --- a/resources/recipes/pc_mag.recipe +++ b/resources/recipes/pc_mag.recipe @@ -9,8 +9,9 @@ __description__ = 'PCMag (www.pcmag.com) delivers authoritative, labs-based comp ''' http://www.pcmag.com/ ''' - +import re from calibre.web.feeds.news import BasicNewsRecipe +from calibre.ebooks.BeautifulSoup import Comment class pcMag(BasicNewsRecipe): __author__ = 'Lorenzo Vigentini' @@ -33,9 +34,6 @@ class pcMag(BasicNewsRecipe): remove_javascript = True no_stylesheets = True - keep_only_tags = [ - dict(name='div', attrs={'id':'articleContent'}) - ] feeds = [ (u'Tech Commentary from the Editors of PC Magazine', u'http://rssnewsapps.ziffdavis.com/PCMAG_commentary.xml'), @@ -49,8 +47,13 @@ class pcMag(BasicNewsRecipe): (u'Technology News from Ziff Davis', u'http://rssnewsapps.ziffdavis.com/pcmagbreakingnews.xml') ] + keep_only_tags = [dict(attrs={'class':'content-page'})] remove_tags = [ - dict(name='div', attrs={'id':['microAd','intellitxt','articleDeckTalkback','inlineDigg','underArticleLinks','w_talkback']}), - dict(name='span', attrs={'id':['highlights_content','yahooBuzzBadge-48558872521263350499378']}) - ] + dict(attrs={'class':['control-side','comment','highlights_content','btn-holder','subscribe-panel', + 'grey-box comments-box']}), + dict(id=['inlineDigg']), + dict(text=lambda text:isinstance(text, Comment)), + dict(name='img', width='1'), + ] + preprocess_regexps = [(re.compile(r" Date: Thu, 29 Apr 2010 19:27:53 -0600 Subject: [PATCH 7/8] Fix #5337 (Conversion Error / NotImplementedError failure on custom news fetch) --- src/calibre/ebooks/oeb/stylizer.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/calibre/ebooks/oeb/stylizer.py b/src/calibre/ebooks/oeb/stylizer.py index c9f228a091..0557a1f74d 100644 --- a/src/calibre/ebooks/oeb/stylizer.py +++ b/src/calibre/ebooks/oeb/stylizer.py @@ -96,6 +96,8 @@ class CSSSelector(etree.XPath): path = css_to_xpath(css) except UnicodeEncodeError: # Bug in css_to_xpath path = '/' + except NotImplementedError: # Probably a subselect like :hover + path = '/' path = self.LOCAL_NAME_RE.sub(r"local-name() = '", path) etree.XPath.__init__(self, path, namespaces=namespaces) self.css = css @@ -534,6 +536,8 @@ class Style(object): result = base else: result = self._unit_convert(width, base=base) + if isinstance(result, (unicode, str, bytes)): + result = self._profile.width self._width = result return self._width @@ -555,6 +559,8 @@ class Style(object): result = base else: result = self._unit_convert(height, base=base) + if isinstance(result, (unicode, str, bytes)): + result = self._profile.height self._height = result return self._height From a47273f7b811a18b5dcb1ffdbf78f6f1243d6a1c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 29 Apr 2010 20:40:18 -0600 Subject: [PATCH 8/8] E-book viewer: Use the Qt API to set document padding during next page operation, instead of javascript. Fixes #5343 (Preview EPUB "crashes" when PgDwn is used) --- src/calibre/gui2/viewer/documentview.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index 3e7f7536d4..a1ecf14dfd 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -394,13 +394,14 @@ class Document(QWebPage): return self.mainFrame().contentsSize().width() # offsetWidth gives inaccurate results def set_bottom_padding(self, amount): - padding = '%dpx'%amount - try: - old_padding = unicode(self.javascript('$("body").css("padding-bottom")').toString()) - except: - old_padding = '' + body = self.mainFrame().documentElement().findFirst('body') + if body.isNull(): + return + old_padding = unicode(body.styleProperty('padding-bottom', + body.ComputedStyle)).strip() + padding = u'%dpx'%amount if old_padding != padding: - self.javascript('$("body").css("padding-bottom", "%s")' % padding) + body.setStyleProperty('padding-bottom', padding + ' !important') class EntityDeclarationProcessor(object):