diff --git a/src/calibre/library/catalogs/epub_mobi.py b/src/calibre/library/catalogs/epub_mobi.py index a50c7ba861..9a7e728220 100644 --- a/src/calibre/library/catalogs/epub_mobi.py +++ b/src/calibre/library/catalogs/epub_mobi.py @@ -3,7 +3,7 @@ from __future__ import (unicode_literals, division, absolute_import, print_function) -__license__ = 'GPL v3' +__license__ = 'GPL v3' __copyright__ = '2012, Kovid Goyal ' __docformat__ = 'restructuredtext en' @@ -21,6 +21,7 @@ from calibre.utils.localization import get_lang Option = namedtuple('Option', 'option, default, dest, action, help') + class EPUB_MOBI(CatalogPlugin): 'ePub catalog generator' @@ -30,29 +31,29 @@ class EPUB_MOBI(CatalogPlugin): minimum_calibre_version = (0, 7, 40) author = 'Greg Riker' version = (1, 0, 0) - file_types = set(['azw3','epub','mobi']) + file_types = set(['azw3', 'epub', 'mobi']) THUMB_SMALLEST = "1.0" THUMB_LARGEST = "2.0" - cli_options = [Option('--catalog-title', # {{{ - default = 'My Books', - dest = 'catalog_title', - action = None, - help = _('Title of generated catalog used as title in metadata.\n' + cli_options = [Option('--catalog-title', # {{{ + default='My Books', + dest='catalog_title', + action=None, + help=_('Title of generated catalog used as title in metadata.\n' "Default: '%default'\n" "Applies to: AZW3, ePub, MOBI output formats")), Option('--cross-reference-authors', default=False, dest='cross_reference_authors', - action = 'store_true', + action='store_true', help=_("Create cross-references in Authors section for books with multiple authors.\n" "Default: '%default'\n" "Applies to: AZW3, ePub, MOBI output formats")), Option('--debug-pipeline', default=None, dest='debug_pipeline', - action = None, + action=None, help=_("Save the output from different stages of the conversion " "pipeline to the specified " "directory. Useful if you are unsure at which stage " @@ -62,7 +63,7 @@ class EPUB_MOBI(CatalogPlugin): Option('--exclude-genre', default='\[.+\]|^\+$', dest='exclude_genre', - action = None, + 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: AZW3, ePub, MOBI output formats")), @@ -82,63 +83,63 @@ class EPUB_MOBI(CatalogPlugin): Option('--generate-authors', default=False, dest='generate_authors', - action = 'store_true', + action='store_true', help=_("Include 'Authors' section in catalog.\n" "Default: '%default'\n" "Applies to: AZW3, ePub, MOBI output formats")), Option('--generate-descriptions', default=False, dest='generate_descriptions', - action = 'store_true', + action='store_true', help=_("Include 'Descriptions' section in catalog.\n" "Default: '%default'\n" "Applies to: AZW3, ePub, MOBI output formats")), Option('--generate-genres', default=False, dest='generate_genres', - action = 'store_true', + action='store_true', help=_("Include 'Genres' section in catalog.\n" "Default: '%default'\n" "Applies to: AZW3, ePub, MOBI output formats")), Option('--generate-titles', default=False, dest='generate_titles', - action = 'store_true', + action='store_true', help=_("Include 'Titles' section in catalog.\n" "Default: '%default'\n" "Applies to: AZW3, ePub, MOBI output formats")), Option('--generate-series', default=False, dest='generate_series', - action = 'store_true', + action='store_true', help=_("Include 'Series' section in catalog.\n" "Default: '%default'\n" "Applies to: AZW3, ePub, MOBI output formats")), Option('--generate-recently-added', default=False, dest='generate_recently_added', - action = 'store_true', + action='store_true', help=_("Include 'Recently Added' section in catalog.\n" "Default: '%default'\n" "Applies to: AZW3, ePub, MOBI output formats")), Option('--genre-source-field', default='Tags', dest='genre_source_field', - action = None, + action=None, help=_("Source field for Genres section.\n" "Default: '%default'\n" "Applies to: AZW3, ePub, MOBI output formats")), Option('--header-note-source-field', default='', dest='header_note_source_field', - action = None, + action=None, help=_("Custom field containing note text to insert in Description header.\n" "Default: '%default'\n" "Applies to: AZW3, ePub, MOBI output formats")), Option('--merge-comments-rule', default='::', dest='merge_comments_rule', - action = None, + action=None, help=_("#:[before|after]:[True|False] specifying:\n" " Custom field containing notes to merge with Comments\n" " [before|after] Placement of notes with respect to Comments\n" @@ -148,7 +149,7 @@ class EPUB_MOBI(CatalogPlugin): Option('--output-profile', default=None, dest='output_profile', - action = None, + 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: AZW3, ePub, MOBI output formats")), @@ -164,14 +165,14 @@ class EPUB_MOBI(CatalogPlugin): Option('--use-existing-cover', default=False, dest='use_existing_cover', - action = 'store_true', + action='store_true', help=_("Replace existing cover when generating the catalog.\n" "Default: '%default'\n" "Applies to: AZW3, ePub, MOBI output formats")), Option('--thumb-width', default='1.0', dest='thumb_width', - action = None, + action=None, help=_("Size hint (in inches) for book covers in catalog.\n" "Range: 1.0 - 2.0\n" "Default: '%default'\n" @@ -199,7 +200,7 @@ class EPUB_MOBI(CatalogPlugin): if opts.connected_device['name'] and 'kindle' in opts.connected_device['name'].lower(): opts.connected_kindle = True if opts.connected_device['serial'] and \ - opts.connected_device['serial'][:4] in ['B004','B005']: + opts.connected_device['serial'][:4] in ['B004', 'B005']: op = "kindle_dx" else: op = "kindle" @@ -209,7 +210,7 @@ class EPUB_MOBI(CatalogPlugin): opts.output_profile = op opts.basename = "Catalog" - opts.cli_environment = not hasattr(opts,'sync') + opts.cli_environment = not hasattr(opts, 'sync') # Hard-wired to always sort descriptions by author, with series after non-series opts.sort_descriptions_by_author = True @@ -278,14 +279,14 @@ class EPUB_MOBI(CatalogPlugin): opts.generate_genres = True opts.generate_recently_added = True opts.generate_descriptions = True - sections_list = ['Authors','Titles','Series','Genres','Recently Added','Descriptions'] + sections_list = ['Authors', 'Titles', 'Series', 'Genres', 'Recently Added', 'Descriptions'] else: opts.log.warn('\n*** No enabled Sections, terminating catalog generation ***') - return ["No Included Sections","No enabled Sections.\nCheck E-book options tab\n'Included sections'\n"] + return ["No Included Sections", "No enabled Sections.\nCheck E-book options tab\n'Included sections'\n"] if opts.fmt == 'mobi' and sections_list == ['Descriptions']: warning = _("\n*** Adding 'By Authors' Section required for MOBI output ***") opts.log.warn(warning) - sections_list.insert(0,'Authors') + sections_list.insert(0, 'Authors') opts.generate_authors = True opts.log(u" Sections: %s" % ', '.join(sections_list)) @@ -294,14 +295,14 @@ class EPUB_MOBI(CatalogPlugin): # Limit thumb_width to 1.0" - 2.0" try: if float(opts.thumb_width) < float(self.THUMB_SMALLEST): - log.warning("coercing thumb_width from '%s' to '%s'" % (opts.thumb_width,self.THUMB_SMALLEST)) + log.warning("coercing thumb_width from '%s' to '%s'" % (opts.thumb_width, self.THUMB_SMALLEST)) opts.thumb_width = self.THUMB_SMALLEST if float(opts.thumb_width) > float(self.THUMB_LARGEST): - log.warning("coercing thumb_width from '%s' to '%s'" % (opts.thumb_width,self.THUMB_LARGEST)) + log.warning("coercing thumb_width from '%s' to '%s'" % (opts.thumb_width, self.THUMB_LARGEST)) opts.thumb_width = self.THUMB_LARGEST opts.thumb_width = "%.2f" % float(opts.thumb_width) except: - log.error("coercing thumb_width from '%s' to '%s'" % (opts.thumb_width,self.THUMB_SMALLEST)) + log.error("coercing thumb_width from '%s' to '%s'" % (opts.thumb_width, self.THUMB_SMALLEST)) opts.thumb_width = "1.0" # eval prefix_rules if passed from command line @@ -331,13 +332,13 @@ class EPUB_MOBI(CatalogPlugin): keys.sort() build_log.append(" opts:") for key in keys: - if key in ['catalog_title','author_clip','connected_kindle','creator', - 'cross_reference_authors','description_clip','exclude_book_marker', - 'exclude_genre','exclude_tags','exclusion_rules', 'fmt', - 'genre_source_field', 'header_note_source_field','merge_comments_rule', - 'output_profile','prefix_rules','read_book_marker', - 'search_text','sort_by','sort_descriptions_by_author','sync', - 'thumb_width','use_existing_cover','wishlist_tag']: + if key in ['catalog_title', 'author_clip', 'connected_kindle', 'creator', + 'cross_reference_authors', 'description_clip', 'exclude_book_marker', + 'exclude_genre', 'exclude_tags', 'exclusion_rules', 'fmt', + 'genre_source_field', 'header_note_source_field', 'merge_comments_rule', + 'output_profile', 'prefix_rules', 'read_book_marker', + 'search_text', 'sort_by', 'sort_descriptions_by_author', 'sync', + 'thumb_width', 'use_existing_cover', 'wishlist_tag']: build_log.append(" %s: %s" % (key, repr(opts_dict[key]))) if opts.verbose: log('\n'.join(line for line in build_log)) @@ -370,8 +371,8 @@ class EPUB_MOBI(CatalogPlugin): """ GENERATE_DEBUG_EPUB = False if GENERATE_DEBUG_EPUB: - catalog_debug_path = os.path.join(os.path.expanduser('~'),'Desktop','Catalog debug') - setattr(opts,'debug_pipeline',os.path.expanduser(catalog_debug_path)) + catalog_debug_path = os.path.join(os.path.expanduser('~'), 'Desktop', 'Catalog debug') + setattr(opts, 'debug_pipeline', os.path.expanduser(catalog_debug_path)) dp = getattr(opts, 'debug_pipeline', None) if dp is not None: @@ -381,11 +382,13 @@ class EPUB_MOBI(CatalogPlugin): if opts.output_profile and opts.output_profile.startswith("kindle"): recommendations.append(('output_profile', opts.output_profile, OptionRecommendation.HIGH)) - recommendations.append(('book_producer',opts.output_profile, + recommendations.append(('book_producer', opts.output_profile, OptionRecommendation.HIGH)) if opts.fmt == 'mobi': recommendations.append(('no_inline_toc', True, OptionRecommendation.HIGH)) + recommendations.append(('verbose', 2, + OptionRecommendation.HIGH)) # Use existing cover or generate new cover cpath = None @@ -432,14 +435,13 @@ class EPUB_MOBI(CatalogPlugin): from calibre.ebooks.epub import initialize_container from calibre.ebooks.tweak import zip_rebuilder from calibre.utils.zipfile import ZipFile - input_path = os.path.join(catalog_debug_path,'input') - epub_shell = os.path.join(catalog_debug_path,'epub_shell.zip') + input_path = os.path.join(catalog_debug_path, 'input') + epub_shell = os.path.join(catalog_debug_path, 'epub_shell.zip') initialize_container(epub_shell, opf_name='content.opf') with ZipFile(epub_shell, 'r') as zf: zf.extractall(path=input_path) os.remove(epub_shell) - zip_rebuilder(input_path, os.path.join(catalog_debug_path,'input.epub')) + zip_rebuilder(input_path, os.path.join(catalog_debug_path, 'input.epub')) # returns to gui2.actions.catalog:catalog_generated() return catalog.error - diff --git a/src/calibre/library/catalogs/epub_mobi_builder.py b/src/calibre/library/catalogs/epub_mobi_builder.py index 24049e83f0..65ed89da5c 100644 --- a/src/calibre/library/catalogs/epub_mobi_builder.py +++ b/src/calibre/library/catalogs/epub_mobi_builder.py @@ -126,7 +126,7 @@ class CatalogBuilder(object): self.bookmarked_books_by_date_read = None self.books_by_author = None self.books_by_date_range = None - self.books_by_description = None + self.books_by_description = [] self.books_by_month = None self.books_by_series = None self.books_by_title = None @@ -748,8 +748,9 @@ class CatalogBuilder(object): # Assumes books_by_title already populated # init books_by_description before relisting multiple authors - books_by_description = list(books_by_author) if self.opts.sort_descriptions_by_author \ - else list(self.books_by_title) + if self.opts.generate_descriptions: + books_by_description = list(books_by_author) if self.opts.sort_descriptions_by_author \ + else list(self.books_by_title) if self.opts.cross_reference_authors: books_by_author = self.relist_multiple_authors(books_by_author) @@ -760,8 +761,9 @@ class CatalogBuilder(object): asl = [i['author_sort'] for i in books_by_author] las = max(asl, key=len) - self.books_by_description = sorted(books_by_description, - key=lambda x: sort_key(self._kf_books_by_author_sorter_author_sort(x, len(las)))) + if self.opts.generate_descriptions: + self.books_by_description = sorted(books_by_description, + key=lambda x: sort_key(self._kf_books_by_author_sorter_author_sort(x, len(las)))) books_by_author = sorted(books_by_author, key=lambda x: sort_key(self._kf_books_by_author_sorter_author_sort(x, len(las)))) @@ -2973,7 +2975,7 @@ class CatalogBuilder(object): contentTag = Tag(soup, 'content') contentTag['src'] = "content/ByDateAdded.html" navPointTag.insert(1, contentTag) - else: + elif self.opts.generate_descriptions: # Descriptions only contentTag = Tag(soup, 'content') contentTag['src'] = "content/book_%d.html" % int(self.books_by_description[0]['id']) @@ -4103,21 +4105,20 @@ class CatalogBuilder(object): spine.insert(stc, itemrefTag) stc += 1 - if self.opts.generate_descriptions: - for book in self.books_by_description: - # manifest - itemTag = Tag(soup, "item") - itemTag['href'] = "content/book_%d.html" % int(book['id']) - itemTag['id'] = "book%d" % int(book['id']) - itemTag['media-type'] = "application/xhtml+xml" - manifest.insert(mtc, itemTag) - mtc += 1 + for book in self.books_by_description: + # manifest + itemTag = Tag(soup, "item") + itemTag['href'] = "content/book_%d.html" % int(book['id']) + itemTag['id'] = "book%d" % int(book['id']) + itemTag['media-type'] = "application/xhtml+xml" + manifest.insert(mtc, itemTag) + mtc += 1 - # spine - itemrefTag = Tag(soup, "itemref") - itemrefTag['idref'] = "book%d" % int(book['id']) - spine.insert(stc, itemrefTag) - stc += 1 + # spine + itemrefTag = Tag(soup, "itemref") + itemrefTag['idref'] = "book%d" % int(book['id']) + spine.insert(stc, itemrefTag) + stc += 1 # Guide if self.generate_for_kindle_mobi: