From c9cb61a40e015059716478255ad67aa30716ea6f Mon Sep 17 00:00:00 2001 From: GRiker Date: Fri, 10 Sep 2010 13:46:01 -0700 Subject: [PATCH 01/36] GwR jacket work --- src/calibre/ebooks/oeb/transforms/jacket.py | 72 ++++++++++++++------- 1 file changed, 49 insertions(+), 23 deletions(-) diff --git a/src/calibre/ebooks/oeb/transforms/jacket.py b/src/calibre/ebooks/oeb/transforms/jacket.py index fec4d230c3..030067850c 100644 --- a/src/calibre/ebooks/oeb/transforms/jacket.py +++ b/src/calibre/ebooks/oeb/transforms/jacket.py @@ -6,14 +6,14 @@ __license__ = 'GPL v3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import textwrap +import os, textwrap from xml.sax.saxutils import escape from itertools import repeat from lxml import etree +from calibre import guess_type, strftime from calibre.ebooks.oeb.base import XPath, XPNSMAP -from calibre import guess_type from calibre.library.comments import comments_to_html class Jacket(object): ''' @@ -24,22 +24,18 @@ class Jacket(object): JACKET_TEMPLATE = textwrap.dedent(u'''\ - %(title)s + %(title_str)s + -
-
-

%(title)s

-

%(jacket)s

-
%(series)s
-
%(rating)s
-
%(tags)s
-
-
- %(comments)s -
+ +
%(comments)s
''') @@ -71,11 +67,18 @@ class Jacket(object): return ans id, href = self.oeb.manifest.generate('star', 'star.png') self.oeb.manifest.add(id, href, 'image/png', data=I('star.png', data=True)) - ans = 'Rating: ' + ''.join(repeat('star'%href, num)) + ans = 'Rating: ' + ''.join(repeat('star'%href, num)) return ans def insert_metadata(self, mi): self.log('Inserting metadata into book...') + jacket_resources = P("jacket") + + if os.path.isdir(jacket_resources): + stylesheet = os.path.join(jacket_resources, 'stylesheet.css') + with open(stylesheet) as f: + css_data = f.read() + comments = mi.comments if not comments: try: @@ -87,11 +90,13 @@ class Jacket(object): orig_comments = comments if comments: comments = comments_to_html(comments) - series = 'Series: ' + escape(mi.series if mi.series else '') + + series = 'Series: %s' % escape(mi.series if mi.series else '') if mi.series and mi.series_index is not None: - series += escape(' [%s]'%mi.format_series_index()) + series += '%s' % escape(' [%s]'%mi.format_series_index()) if not mi.series: series = '' + tags = mi.tags if not tags: try: @@ -99,23 +104,30 @@ class Jacket(object): except: tags = [] if tags: - tags = 'Tags: ' + self.opts.dest.tags_to_string(tags) + tags = 'Tags:%s' % self.opts.dest.tags_to_string(tags) else: tags = '' + try: - title = mi.title if mi.title else unicode(self.oeb.metadata.title[0]) + title_str = mi.title if mi.title else unicode(self.oeb.metadata.title[0]) except: - title = _('Unknown') + title_str = _('Unknown') + title = '%s (%s)' % (escape(title_str), strftime(u'%Y', mi.pubdate.timetuple())) + def generate_html(comments): return self.JACKET_TEMPLATE%dict(xmlns=XPNSMAP['h'], - title=escape(title), comments=comments, - jacket=escape(_('Book Jacket')), series=series, - tags=tags, rating=self.get_rating(mi.rating)) + title=title, comments=comments, + series=series, + tags=tags, rating=self.get_rating(mi.rating), + css=css_data, title_str=title_str) + id, href = self.oeb.manifest.generate('jacket', 'jacket.xhtml') from calibre.ebooks.oeb.base import RECOVER_PARSER, XPath try: root = etree.fromstring(generate_html(comments), parser=RECOVER_PARSER) +# print "root: %s" % etree.tostring(root, encoding='utf-8', +# xml_declaration=True, pretty_print=True) except: root = etree.fromstring(generate_html(escape(orig_comments)), parser=RECOVER_PARSER) @@ -137,8 +149,22 @@ class Jacket(object): def __call__(self, oeb, opts, metadata): + ''' + Add metadata in jacket.xhtml if specifed in opts + If not specified, remove previous jacket instance + ''' self.oeb, self.opts, self.log = oeb, opts, oeb.log if opts.remove_first_image: self.remove_first_image() if opts.insert_metadata: self.insert_metadata(metadata) + else: + jacket = XPath('//h:meta[@name="calibre-content" and @content="jacket"]') + for item in list(self.oeb.spine)[:4]: + if jacket(item.data): + try: + self.log.info("Removing previous jacket instance") + self.oeb.manifest.remove(item) + break + except: + continue From ba67e47c9260a1f813048ab0239ed78d5324e89a Mon Sep 17 00:00:00 2001 From: GRiker Date: Mon, 13 Sep 2010 19:12:49 -0600 Subject: [PATCH 02/36] GwR wip book jacket --- src/calibre/devices/apple/driver.py | 6 +- src/calibre/ebooks/oeb/transforms/flatcss.py | 16 +- src/calibre/ebooks/oeb/transforms/jacket.py | 147 +++++++++++++------ src/calibre/library/catalog.py | 4 + 4 files changed, 120 insertions(+), 53 deletions(-) diff --git a/src/calibre/devices/apple/driver.py b/src/calibre/devices/apple/driver.py index e318d368ff..c9bc04a242 100644 --- a/src/calibre/devices/apple/driver.py +++ b/src/calibre/devices/apple/driver.py @@ -2342,8 +2342,10 @@ class ITUNES(DriverBase): if isosx: if DEBUG: self.log.info(" deleting '%s' from iDevice" % cached_book['title']) - cached_book['dev_book'].delete() - + try: + cached_book['dev_book'].delete() + except: + self.log.error(" error deleting '%s'" % cached_book['title']) elif iswindows: hit = self._find_device_book(cached_book) if hit: diff --git a/src/calibre/ebooks/oeb/transforms/flatcss.py b/src/calibre/ebooks/oeb/transforms/flatcss.py index f48bdb9934..030c271362 100644 --- a/src/calibre/ebooks/oeb/transforms/flatcss.py +++ b/src/calibre/ebooks/oeb/transforms/flatcss.py @@ -146,7 +146,6 @@ class CSSFlattener(object): extra_css=css) self.stylizers[item] = stylizer - def baseline_node(self, node, stylizer, sizes, csize): csize = stylizer.style(node)['font-size'] if node.text: @@ -194,7 +193,7 @@ class CSSFlattener(object): value = 0.0 cssdict[property] = "%0.5fem" % (value / fsize) - def flatten_node(self, node, stylizer, names, styles, psize, left=0): + def flatten_node(self, node, stylizer, names, styles, psize, item_id, left=0): if not isinstance(node.tag, basestring) \ or namespace(node.tag) != XHTML_NS: return @@ -286,15 +285,18 @@ class CSSFlattener(object): if self.lineh and 'line-height' not in cssdict: lineh = self.lineh / psize cssdict['line-height'] = "%0.5fem" % lineh + if (self.context.remove_paragraph_spacing or self.context.insert_blank_line) and tag in ('p', 'div'): - for prop in ('margin', 'padding', 'border'): - for edge in ('top', 'bottom'): - cssdict['%s-%s'%(prop, edge)] = '0pt' + if item_id != 'jacket' or self.context.output_profile.name == 'Kindle': + for prop in ('margin', 'padding', 'border'): + for edge in ('top', 'bottom'): + cssdict['%s-%s'%(prop, edge)] = '0pt' if self.context.insert_blank_line: cssdict['margin-top'] = cssdict['margin-bottom'] = '0.5em' if self.context.remove_paragraph_spacing: cssdict['text-indent'] = "%1.1fem" % self.context.remove_paragraph_spacing_indent_size + if cssdict: items = cssdict.items() items.sort() @@ -313,7 +315,7 @@ class CSSFlattener(object): if 'style' in node.attrib: del node.attrib['style'] for child in node: - self.flatten_node(child, stylizer, names, styles, psize, left) + self.flatten_node(child, stylizer, names, styles, psize, item_id, left) def flatten_head(self, item, stylizer, href): html = item.data @@ -360,7 +362,7 @@ class CSSFlattener(object): stylizer = self.stylizers[item] body = html.find(XHTML('body')) fsize = self.context.dest.fbase - self.flatten_node(body, stylizer, names, styles, fsize) + self.flatten_node(body, stylizer, names, styles, fsize, item.id) items = [(key, val) for (val, key) in styles.items()] items.sort() css = ''.join(".%s {\n%s;\n}\n\n" % (key, val) for key, val in items) diff --git a/src/calibre/ebooks/oeb/transforms/jacket.py b/src/calibre/ebooks/oeb/transforms/jacket.py index 030067850c..309a7fd7b6 100644 --- a/src/calibre/ebooks/oeb/transforms/jacket.py +++ b/src/calibre/ebooks/oeb/transforms/jacket.py @@ -13,6 +13,9 @@ from itertools import repeat from lxml import etree from calibre import guess_type, strftime +from calibre.constants import __appname__, __version__ +from calibre.utils.date import now +from calibre.ebooks.BeautifulSoup import BeautifulSoup from calibre.ebooks.oeb.base import XPath, XPNSMAP from calibre.library.comments import comments_to_html class Jacket(object): @@ -29,13 +32,30 @@ class Jacket(object): -