From d4e236c218f6c0705d9eb78cb4a4034d8b781e9d Mon Sep 17 00:00:00 2001 From: GRiker Date: Tue, 7 Aug 2012 04:59:31 -0600 Subject: [PATCH 1/2] Added initial support for AZW3, validates in Kindle Previewer --- src/calibre/gui2/actions/catalog.py | 2 +- src/calibre/gui2/catalog/catalog_epub_mobi.py | 2 +- src/calibre/library/catalogs/epub_mobi.py | 37 ++++++++++--------- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/calibre/gui2/actions/catalog.py b/src/calibre/gui2/actions/catalog.py index ba3756003c..2dbc9bbf11 100644 --- a/src/calibre/gui2/actions/catalog.py +++ b/src/calibre/gui2/actions/catalog.py @@ -85,7 +85,7 @@ class GenerateCatalogAction(InterfaceAction): dynamic.set('catalogs_to_be_synced', sync) self.gui.status_bar.show_message(_('Catalog generated.'), 3000) self.gui.sync_catalogs() - if job.fmt not in ['EPUB','MOBI']: + if job.fmt not in ['AZW3','EPUB','MOBI']: export_dir = choose_dir(self.gui, _('Export Catalog Directory'), _('Select destination for %(title)s.%(fmt)s') % dict( title=job.catalog_title, fmt=job.fmt.lower())) diff --git a/src/calibre/gui2/catalog/catalog_epub_mobi.py b/src/calibre/gui2/catalog/catalog_epub_mobi.py index 7468ed6f27..72363046d7 100644 --- a/src/calibre/gui2/catalog/catalog_epub_mobi.py +++ b/src/calibre/gui2/catalog/catalog_epub_mobi.py @@ -25,7 +25,7 @@ from PyQt4.Qt import (Qt, QAbstractItemView, QCheckBox, QComboBox, QDialog, class PluginWidget(QWidget,Ui_Form): TITLE = _('E-book options') - HELP = _('Options specific to')+' EPUB/MOBI '+_('output') + HELP = _('Options specific to')+' AZW3/EPUB/MOBI '+_('output') # Output synced to the connected device? sync_enabled = True diff --git a/src/calibre/library/catalogs/epub_mobi.py b/src/calibre/library/catalogs/epub_mobi.py index 1007c6d762..6f4d7d4821 100644 --- a/src/calibre/library/catalogs/epub_mobi.py +++ b/src/calibre/library/catalogs/epub_mobi.py @@ -20,7 +20,7 @@ class EPUB_MOBI(CatalogPlugin): 'ePub catalog generator' name = 'Catalog_EPUB_MOBI' - description = 'EPUB/MOBI catalog generator' + description = 'AZW3/EPUB/MOBI catalog generator' supported_platforms = ['windows', 'osx', 'linux'] minimum_calibre_version = (0, 7, 40) author = 'Greg Riker' @@ -36,7 +36,7 @@ class EPUB_MOBI(CatalogPlugin): action = None, help = _('Title of generated catalog used as title in metadata.\n' "Default: '%default'\n" - "Applies to: ePub, MOBI output formats")), + "Applies to: AZW3, ePub, MOBI output formats")), Option('--debug-pipeline', default=None, dest='debug_pipeline', @@ -46,17 +46,17 @@ class EPUB_MOBI(CatalogPlugin): "directory. Useful if you are unsure at which stage " "of the conversion process a bug is occurring.\n" "Default: '%default'\n" - "Applies to: ePub, MOBI output formats")), + "Applies to: AZW3, ePub, MOBI output formats")), Option('--exclude-genre', default='\[.+\]|\+', dest='exclude_genre', action = None, help=_("Regex describing tags to exclude as genres.\n" "Default: '%default' excludes bracketed tags, e.g. '[Project Gutenberg]', and '+', the default tag for read books.\n" - "Applies to: ePub, MOBI output formats")), + "Applies to: AZW3, ePub, MOBI output formats")), Option('--exclusion-rules', - default="(('Excluded tags','Tags','~,Catalog'),)", + default="(('Excluded tags','Tags','Catalog'),)", dest='exclusion_rules', action=None, help=_("Specifies the rules used to exclude books from the generated catalog.\n" @@ -67,7 +67,7 @@ class EPUB_MOBI(CatalogPlugin): "will exclude a book with a value of 'Archived' in the custom column 'status'.\n" "When multiple rules are defined, all rules will be applied.\n" "Default: \n" + '"' + '%default' + '"' + "\n" - "Applies to ePub, MOBI output formats")), + "Applies to AZW3, ePub, MOBI output formats")), Option('--generate-authors', default=False, @@ -75,49 +75,49 @@ class EPUB_MOBI(CatalogPlugin): action = 'store_true', help=_("Include 'Authors' section in catalog.\n" "Default: '%default'\n" - "Applies to: ePub, MOBI output formats")), + "Applies to: AZW3, ePub, MOBI output formats")), Option('--generate-descriptions', default=False, dest='generate_descriptions', action = 'store_true', help=_("Include 'Descriptions' section in catalog.\n" "Default: '%default'\n" - "Applies to: ePub, MOBI output formats")), + "Applies to: AZW3, ePub, MOBI output formats")), Option('--generate-genres', default=False, dest='generate_genres', action = 'store_true', help=_("Include 'Genres' section in catalog.\n" "Default: '%default'\n" - "Applies to: ePub, MOBI output formats")), + "Applies to: AZW3, ePub, MOBI output formats")), Option('--generate-titles', default=False, dest='generate_titles', action = 'store_true', help=_("Include 'Titles' section in catalog.\n" "Default: '%default'\n" - "Applies to: ePub, MOBI output formats")), + "Applies to: AZW3, ePub, MOBI output formats")), Option('--generate-series', default=False, dest='generate_series', action = 'store_true', help=_("Include 'Series' section in catalog.\n" "Default: '%default'\n" - "Applies to: ePub, MOBI output formats")), + "Applies to: AZW3, ePub, MOBI output formats")), Option('--generate-recently-added', default=False, dest='generate_recently_added', action = 'store_true', help=_("Include 'Recently Added' section in catalog.\n" "Default: '%default'\n" - "Applies to: ePub, MOBI output formats")), + "Applies to: AZW3, ePub, MOBI output formats")), Option('--header-note-source-field', default='', dest='header_note_source_field', action = None, help=_("Custom field containing note text to insert in Description header.\n" "Default: '%default'\n" - "Applies to: ePub, MOBI output formats")), + "Applies to: AZW3, ePub, MOBI output formats")), Option('--merge-comments', default='::', dest='merge_comments', @@ -127,14 +127,14 @@ class EPUB_MOBI(CatalogPlugin): " [before|after] Placement of notes with respect to Comments\n" " [True|False] - A horizontal rule is inserted between notes and Comments\n" "Default: '%default'\n" - "Applies to ePub, MOBI output formats")), + "Applies to AZW3, ePub, MOBI output formats")), Option('--output-profile', default=None, dest='output_profile', action = None, help=_("Specifies the output profile. In some cases, an output profile is required to optimize the catalog for the device. For example, 'kindle' or 'kindle_dx' creates a structured Table of Contents with Sections and Articles.\n" "Default: '%default'\n" - "Applies to: ePub, MOBI output formats")), + "Applies to: AZW3, ePub, MOBI output formats")), Option('--prefix-rules', default="(('Read books','tags','+','\u2713'),('Wishlist items','tags','Wishlist','\u00d7'))", dest='prefix_rules', @@ -143,7 +143,7 @@ class EPUB_MOBI(CatalogPlugin): "The model for a prefix rule is ('','','','').\n" "When multiple rules are defined, the first matching rule will be used.\n" "Default:\n" + '"' + '%default' + '"' + "\n" - "Applies to ePub, MOBI output formats")), + "Applies to AZW3, ePub, MOBI output formats")), Option('--thumb-width', default='1.0', dest='thumb_width', @@ -151,7 +151,7 @@ class EPUB_MOBI(CatalogPlugin): help=_("Size hint (in inches) for book covers in catalog.\n" "Range: 1.0 - 2.0\n" "Default: '%default'\n" - "Applies to ePub, MOBI output formats")), + "Applies to AZW3, ePub, MOBI output formats")), ] # }}} @@ -172,7 +172,8 @@ class EPUB_MOBI(CatalogPlugin): if op is None: op = 'default' - if opts.connected_device['name'] and 'kindle' in opts.connected_device['name'].lower(): + if opts.connected_device['name'] and \ + opts.connected_device['short_name'] in ['kindle','kindle dx']: opts.connected_kindle = True if opts.connected_device['serial'] and \ opts.connected_device['serial'][:4] in ['B004','B005']: From 746c148997ea53cc3b5434df0eed9ac328f26f7a Mon Sep 17 00:00:00 2001 From: GRiker Date: Tue, 7 Aug 2012 07:01:38 -0600 Subject: [PATCH 2/2] Generate default cover if no existing cover found, other bug fixes --- src/calibre/gui2/catalog/catalog_epub_mobi.py | 6 ++--- src/calibre/library/catalogs/epub_mobi.py | 23 ++++++++++++++++++- .../library/catalogs/epub_mobi_builder.py | 2 +- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/calibre/gui2/catalog/catalog_epub_mobi.py b/src/calibre/gui2/catalog/catalog_epub_mobi.py index 72363046d7..da9139a25e 100644 --- a/src/calibre/gui2/catalog/catalog_epub_mobi.py +++ b/src/calibre/gui2/catalog/catalog_epub_mobi.py @@ -402,7 +402,6 @@ class PluginWidget(QWidget,Ui_Form): self.exclude_genre.setText(default[1]) break - class CheckableTableWidgetItem(QTableWidgetItem): ''' Borrowed from kiwidude @@ -637,8 +636,9 @@ class GenericRulesTable(QTableWidget): pass def resize_name(self, scale): - current_width = self.columnWidth(1) - self.setColumnWidth(1, min(225,int(current_width * scale))) + #current_width = self.columnWidth(1) + #self.setColumnWidth(1, min(225,int(current_width * scale))) + self.setColumnWidth(1, 225) def rule_name_edited(self): current_row = self.currentRow() diff --git a/src/calibre/library/catalogs/epub_mobi.py b/src/calibre/library/catalogs/epub_mobi.py index 6f4d7d4821..0787d149ca 100644 --- a/src/calibre/library/catalogs/epub_mobi.py +++ b/src/calibre/library/catalogs/epub_mobi.py @@ -13,6 +13,9 @@ from collections import namedtuple from calibre import strftime from calibre.customize import CatalogPlugin from calibre.customize.conversion import OptionRecommendation, DummyReporter +from calibre.ebooks import calibre_cover +from calibre.ptempfile import PersistentTemporaryFile +from calibre.utils.magick.draw import save_cover_data_to Option = namedtuple('Option', 'option, default, dest, action, help') @@ -338,7 +341,7 @@ class EPUB_MOBI(CatalogPlugin): OptionRecommendation.HIGH)) recommendations.append(('comments', '', OptionRecommendation.HIGH)) - # Use to debug generated catalog code before conversion + # >>> Use to debug generated catalog code before conversion <<< #setattr(opts,'debug_pipeline',os.path.expanduser("~/Desktop/Catalog debug")) dp = getattr(opts, 'debug_pipeline', None) @@ -356,6 +359,7 @@ class EPUB_MOBI(CatalogPlugin): # If cover exists, use it cpath = None + generate_new_cover = False try: search_text = 'title:"%s" author:%s' % ( opts.catalog_title.replace('"', '\\"'), 'calibre') @@ -365,9 +369,26 @@ class EPUB_MOBI(CatalogPlugin): if cpath and os.path.exists(cpath): recommendations.append(('cover', cpath, OptionRecommendation.HIGH)) + log.info("using existing cover") + else: + log.info("no existing cover, generating new cover") + generate_new_cover = True + else: + log.info("no existing cover, generating new cover") + generate_new_cover = True except: pass + if generate_new_cover: + new_cover_path = PersistentTemporaryFile(suffix='.jpg') + new_cover_path.close() + new_cover = calibre_cover(opts.catalog_title.replace('"', '\\"'), 'calibre') + save_cover_data_to(new_cover,new_cover_path.name) + recommendations.append(('cover', new_cover_path.name, OptionRecommendation.HIGH)) + + if opts.verbose: + log.info("Invoking Plumber with recommendations:\n %s" % recommendations) + # Run ebook-convert from calibre.ebooks.conversion.plumber import Plumber plumber = Plumber(os.path.join(catalog.catalogPath, diff --git a/src/calibre/library/catalogs/epub_mobi_builder.py b/src/calibre/library/catalogs/epub_mobi_builder.py index 91856600d8..1c79901037 100644 --- a/src/calibre/library/catalogs/epub_mobi_builder.py +++ b/src/calibre/library/catalogs/epub_mobi_builder.py @@ -1126,7 +1126,7 @@ Author '{0}': aTag = Tag(soup, "a") current_letter = self.letter_or_symbol(book['author_sort'][0].upper()) if current_letter == self.SYMBOLS: - aTag['id'] = self.SYMBOLS + aTag['id'] = self.SYMBOLS + '_authors' else: aTag['id'] = "%s_authors" % self.generateUnicodeName(current_letter) pIndexTag.insert(0,aTag)