From 30add33dfe31fdab3b08d5208b2f6952fab72a85 Mon Sep 17 00:00:00 2001 From: GRiker Date: Sat, 30 Jan 2010 12:00:42 -0700 Subject: [PATCH 1/4] User-specified font for Kindle mastheads --- src/calibre/web/feeds/news.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index 125d766190..709af4bea2 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -992,7 +992,7 @@ class BasicNewsRecipe(Recipe): from calibre.ebooks.conversion.config import load_defaults recs = load_defaults('mobi_output') font_path = recs.get('masthead_font') - default-font = P('fonts/liberation/LiberationSerif-Bold.ttf') + default_font = P('fonts/liberation/LiberationSerif-Bold.ttf') if not font_path or not os.access(font_path, os.R_OK): font_path = default_font From 3f3bd00c3a5dd480e105c91a4482bd3891c5c690 Mon Sep 17 00:00:00 2001 From: GRiker Date: Sat, 30 Jan 2010 12:23:45 -0700 Subject: [PATCH 2/4] Only build custom masthead for Kindle output --- src/calibre/library/catalog.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/calibre/library/catalog.py b/src/calibre/library/catalog.py index 91c5a1bdb8..be63ffedef 100644 --- a/src/calibre/library/catalog.py +++ b/src/calibre/library/catalog.py @@ -797,11 +797,13 @@ class EPUB_MOBI(CatalogPlugin): os.path.join(self.catalogPath, file[0])) # Create the custom masthead image overwriting default - - if True: #try: - self.generate_masthead_image(os.path.join(self.catalogPath, 'images/mastheadImage.gif')) -# except: -# pass + # If failure, default mastheadImage.gif should still be in place + if self.generateForKindle: + try: + self.generate_masthead_image(os.path.join(self.catalogPath, + 'images/mastheadImage.gif')) + except: + pass def fetchBooksByTitle(self): self.updateProgressFullStep("Fetching database") @@ -2521,7 +2523,8 @@ class EPUB_MOBI(CatalogPlugin): font_path = default_font else: if self.opts.verbose: - self.opts.log(" Rendering catalog masthead with user-specifed font '%s'" % font_path) + self.opts.log(" Rendering catalog masthead with user-specifed font:") + self.opts.log(" '%s'" % font_path) MI_WIDTH = 600 MI_HEIGHT = 60 @@ -2686,7 +2689,7 @@ class EPUB_MOBI(CatalogPlugin): opts.descriptionClip = 380 if op.endswith('dx') or 'kindle' not in op else 90 opts.basename = "Catalog" opts.plugin_path = self.plugin_path - opts.cli_environment = getattr(opts,'sync',True) + opts.cli_environment = not hasattr(opts,'sync') if opts.verbose: opts_dict = vars(opts) From e067ad567aaad3c1ee62338310fadaee7dd82612 Mon Sep 17 00:00:00 2001 From: GRiker Date: Sun, 31 Jan 2010 10:35:58 -0700 Subject: [PATCH 3/4] GwR fixes for lxml bug, category synonyms --- src/calibre/library/catalog.py | 167 ++++++++++++++++++++++----------- 1 file changed, 111 insertions(+), 56 deletions(-) diff --git a/src/calibre/library/catalog.py b/src/calibre/library/catalog.py index be63ffedef..0defc419c8 100644 --- a/src/calibre/library/catalog.py +++ b/src/calibre/library/catalog.py @@ -4,7 +4,7 @@ from collections import namedtuple from datetime import date from xml.sax.saxutils import escape -from calibre import filesystem_encoding, prints, strftime +from calibre import filesystem_encoding, prints, prepare_string_for_xml, strftime from calibre.customize import CatalogPlugin from calibre.customize.conversion import OptionRecommendation, DummyReporter from calibre.ebooks.BeautifulSoup import BeautifulSoup, BeautifulStoneSoup, Tag, NavigableString @@ -524,6 +524,7 @@ class EPUB_MOBI(CatalogPlugin): self.opts.output_profile and \ self.opts.output_profile.startswith("kindle")) else False self.__genres = None + self.__genre_tags_dict = None self.__htmlFileList = [] self.__markerTags = self.getMarkerTags() self.__ncxSoup = None @@ -630,6 +631,13 @@ class EPUB_MOBI(CatalogPlugin): self.__genres = val return property(fget=fget, fset=fset) @dynamic_property + def genre_tags_dict(self): + def fget(self): + return self.__genre_tags_dict + def fset(self, val): + self.__genre_tags_dict = val + return property(fget=fget, fset=fset) + @dynamic_property def htmlFileList(self): def fget(self): return self.__htmlFileList @@ -856,7 +864,11 @@ class EPUB_MOBI(CatalogPlugin): this_title['date'] = strftime(u'%B %Y', record['pubdate'].timetuple()) this_title['timestamp'] = record['timestamp'] if record['comments']: - this_title['description'] = re.sub('&', '&', record['comments']) + #this_title['description'] = re.sub('&', '&', record['comments']) + if re.search('<(?P.+)>.+||<.+/>',record['comments']): + self.opts.log(chr(7) + " %d: %s (%s) contains suspect metadata" % \ + (this_title['id'], this_title['title'],this_title['author'])) + this_title['description'] = prepare_string_for_xml(record['comments']) this_title['short_description'] = self.generateShortDescription(this_title['description']) else: this_title['description'] = None @@ -1006,7 +1018,8 @@ class EPUB_MOBI(CatalogPlugin): for tag in title['tags']: aTag = Tag(soup,'a') - aTag['href'] = "Genre%s.html" % re.sub("\W","",self.convertHTMLEntities(tag)) + #print "aTag: %s" % "Genre_%s.html" % re.sub("\W","",tag.lower()) + aTag['href'] = "Genre_%s.html" % re.sub("\W","",tag.lower()) aTag.insert(0,escape(NavigableString(tag))) emTag = Tag(soup, "em") emTag.insert(0, aTag) @@ -1438,17 +1451,22 @@ class EPUB_MOBI(CatalogPlugin): self.updateProgressFullStep("'Genres'") - # Filter out REMOVE_TAGS, sort - filtered_tags = self.filterDbTags(self.db.all_tags()) + # filtered_tags = {friendly:normalized, } + self.genre_tags_dict = self.filterDbTags(self.db.all_tags()) # Extract books matching filtered_tags genre_list = [] - for tag in filtered_tags: + for friendly_tag in self.genre_tags_dict: + #print "\ngenerateHTMLByTags(): looking for books with friendly_tag '%s'" % friendly_tag + # tag_list => {'tag': '', 'books':[{}, {}, {}]} tag_list = {} - tag_list['tag'] = tag + tag_list['tag'] = self.genre_tags_dict[friendly_tag] tag_list['books'] = [] for book in self.booksByAuthor: - if 'tags' in book and tag in book['tags']: + # Scan each book for tag matching friendly_tag + #if 'tags' in book: print " evaluating %s with tags: %s" % (book['title'], book['tags']) + if 'tags' in book and friendly_tag in book['tags']: + #print " adding '%s'" % (book['title']) this_book = {} this_book['author'] = book['author'] this_book['title'] = book['title'] @@ -1458,8 +1476,36 @@ class EPUB_MOBI(CatalogPlugin): tag_list['books'].append(this_book) if len(tag_list['books']): - # Possible to have an empty tag list if the books were excluded - genre_list.append(tag_list) + genre_exists = False + book_not_in_genre = True + if not genre_list: + #print " genre_list empty, adding '%s'" % tag_list['tag'] + genre_list.append(tag_list) + else: + # Check for existing_genre + for genre in genre_list: + if genre['tag'] == tag_list['tag']: + genre_exists = True + # Check to see if the book is already in this list + for existing_book in genre['books']: + if this_book['title'] == existing_book['title']: + #print "%s already in %s" % (this_book['title'], genre) + book_not_in_genre = False + break + break + + if genre_exists: + if book_not_in_genre: + #print " adding %s to existing genre '%s'" % (this_book['title'],genre['tag']) + genre['books'].append(this_book) + else: + #print " appending genre '%s'" % tag_list['tag'] + genre_list.append(tag_list) + + if self.opts.verbose: + self.opts.log.info(" Genre summary: %d active genres" % len(genre_list)) + for genre in genre_list: + self.opts.log.info(" %s: %d titles" % (genre['tag'], len(genre['books']))) # Write the results # genre_list = [ [tag_list], [tag_list] ...] @@ -1492,12 +1538,11 @@ class EPUB_MOBI(CatalogPlugin): if not author in unique_authors: unique_authors.append(author) ''' - # Write the genre book list as an article titles_spanned = self.generateHTMLByGenre(genre['tag'], True if index==0 else False, genre['books'], - "%s/Genre%s.html" % (self.contentDir, re.sub("\W","", self.convertHTMLEntities(genre['tag'])))) + "%s/Genre_%s.html" % (self.contentDir, genre['tag'])) - tag_file = "content/Genre%s.html" % (re.sub("\W","", self.convertHTMLEntities(genre['tag']))) + tag_file = "content/Genre_%s.html" % genre['tag'] master_genre_list.append({'tag':genre['tag'], 'file':tag_file, 'authors':unique_authors, @@ -2110,9 +2155,6 @@ class EPUB_MOBI(CatalogPlugin): self.updateProgressFullStep("NCX 'Genres'") - - - if not len(self.genres): self.opts.log.warn(" No genres found in tags.\n" " No Genre section added to Catalog") @@ -2139,13 +2181,12 @@ class EPUB_MOBI(CatalogPlugin): navPointTag.insert(nptc, navLabelTag) nptc += 1 contentTag = Tag(ncx_soup,"content") - contentTag['src'] = "content/Genre%s.html#section_start" % (re.sub("\W","", self.convertHTMLEntities(self.genres[0]['tag']))) + contentTag['src'] = "content/Genre_%s.html#section_start" % self.genres[0]['tag'] navPointTag.insert(nptc, contentTag) nptc += 1 for genre in self.genres: # Add an article for each genre - navPointVolumeTag = Tag(ncx_soup, 'navPoint') navPointVolumeTag['class'] = "article" navPointVolumeTag['id'] = "genre-%s-ID" % genre['tag'] @@ -2153,13 +2194,18 @@ class EPUB_MOBI(CatalogPlugin): self.playOrder += 1 navLabelTag = Tag(ncx_soup, "navLabel") textTag = Tag(ncx_soup, "text") - textTag.insert(0, self.formatNCXText(NavigableString(genre['tag']))) + + # GwR *** Can this be optimized? + normalized_tag = None + for genre_tag in self.genre_tags_dict: + if self.genre_tags_dict[genre_tag] == genre['tag']: + normalized_tag = self.genre_tags_dict[genre_tag] + break + textTag.insert(0, self.formatNCXText(NavigableString(genre_tag))) navLabelTag.insert(0,textTag) navPointVolumeTag.insert(0,navLabelTag) - contentTag = Tag(ncx_soup, "content") - genre_name = re.sub("\W","", self.convertHTMLEntities(genre['tag'])) - contentTag['src'] = "content/Genre%s.html#Genre%s" % (genre_name, genre_name) + contentTag['src'] = "content/Genre_%s.html#Genre_%s" % (normalized_tag, normalized_tag) navPointVolumeTag.insert(1, contentTag) if self.generateForKindle: @@ -2271,16 +2317,10 @@ class EPUB_MOBI(CatalogPlugin): def filterDbTags(self, tags): # Remove the special marker tags from the database's tag list, - # return sorted list of tags representing valid genres + # return sorted list of normalized genre tags - def next_tag(tags): - for (i, tag) in enumerate(tags): - if i < len(tags) - 1: - yield tag + ", " - else: - yield tag - - filtered_tags = [] + normalized_tags = [] + friendly_tags = [] for tag in tags: if tag[0] in self.markerTags: continue @@ -2289,32 +2329,39 @@ class EPUB_MOBI(CatalogPlugin): if tag == ' ': continue - filtered_tags.append(tag) + normalized_tags.append(re.sub('\W','',tag).lower()) + friendly_tags.append(tag) - filtered_tags.sort() - # Enable this code to force certain tags to the front of the genre list - if False: - for (i, tag) in enumerate(filtered_tags): - if tag == 'Fiction': - filtered_tags.insert(0, (filtered_tags.pop(i))) - elif tag == 'Nonfiction': - filtered_tags.insert(1, (filtered_tags.pop(i))) - else: - continue + genre_tags_dict = dict(zip(friendly_tags,normalized_tags)) + + # Test for multiple genres resolving to same normalized form + normalized_set = set(normalized_tags) + for normalized in normalized_set: + if normalized_tags.count(normalized) > 1: + self.opts.log.warn(" Warning: multiple tags resolving to genre '%s':" % normalized) + for key in genre_tags_dict: + if genre_tags_dict[key] == normalized: + self.opts.log.warn(" %s" % key) if self.verbose: - self.opts.log.info(u' %d Genre tags in database (exclude_genre: %s):' % \ - (len(filtered_tags), self.opts.exclude_genre)) - out_buf = '' + def next_tag(tags): + for (i, tag) in enumerate(tags): + if i < len(tags) - 1: + yield tag + ", " + else: + yield tag - for tag in next_tag(filtered_tags): - out_buf += tag - if len(out_buf) > 72: - self.opts.log(u' %s' % out_buf.rstrip()) - out_buf = '' - self.opts.log(u' %s' % out_buf) + self.opts.log.info(u' %d total genre tags in database (exclude_genre: %s):' % \ + (len(genre_tags_dict), self.opts.exclude_genre)) - return filtered_tags + # Display friendly/normalized genres + # friendly => normalized + sorted_tags = ['%s => %s' % (key, genre_tags_dict[key]) for key in sorted(genre_tags_dict.keys())] + + for tag in next_tag(sorted_tags): + self.opts.log(u' %s' % tag) + + return genre_tags_dict def formatNCXText(self, description): # Kindle TOC descriptions won't render certain characters @@ -2346,15 +2393,23 @@ class EPUB_MOBI(CatalogPlugin): body.insert(btc, aTag) btc += 1 - # Insert the anchor with spaces stripped + # Create an anchor from the tag aTag = Tag(soup, 'a') - aTag['name'] = "Genre%s" % re.sub("\W","", genre) + #aTag['name'] = "Genre%s" % re.sub("\W","", genre) + aTag['name'] = "Genre_%s" % genre body.insert(btc,aTag) btc += 1 - # Insert the genre title + # Insert the genre title using the friendly name + # GwR *** optimize + for genre_tag in self.genre_tags_dict: + if self.genre_tags_dict[genre_tag] == genre: + friendly_tag = genre_tag + break + + titleTag = body.find(attrs={'class':'title'}) - titleTag.insert(0,NavigableString('%s' % escape(genre))) + titleTag.insert(0,NavigableString('%s' % escape(friendly_tag))) # Insert the books by author list divTag = body.find(attrs={'class':'authors'}) From 0027f82e1d918eeaa7f5332fd7b7d9b45322c06d Mon Sep 17 00:00:00 2001 From: GRiker Date: Sun, 31 Jan 2010 15:54:24 -0700 Subject: [PATCH 4/4] Reworked tag/genre parsing code --- src/calibre/library/catalog.py | 210 +++++++++++++++++---------------- 1 file changed, 109 insertions(+), 101 deletions(-) diff --git a/src/calibre/library/catalog.py b/src/calibre/library/catalog.py index 0defc419c8..44ab82ac19 100644 --- a/src/calibre/library/catalog.py +++ b/src/calibre/library/catalog.py @@ -765,6 +765,8 @@ class EPUB_MOBI(CatalogPlugin): # Methods def buildSources(self): self.fetchBooksByTitle() + if not self.booksByTitle: + return False self.fetchBooksByAuthor() self.generateHTMLDescriptions() self.generateHTMLByAuthor() @@ -784,6 +786,7 @@ class EPUB_MOBI(CatalogPlugin): self.generateNCXByDateAdded("Recently Added") self.generateNCXByGenre("Genres") self.writeNCX() + return True def cleanUp(self): pass @@ -1448,107 +1451,109 @@ class EPUB_MOBI(CatalogPlugin): def generateHTMLByTags(self): # Generate individual HTML files for each tag, e.g. Fiction, Nonfiction ... # Note that special tags - ~+*[] - have already been filtered from books[] + # There may be synonomous tags self.updateProgressFullStep("'Genres'") - # filtered_tags = {friendly:normalized, } self.genre_tags_dict = self.filterDbTags(self.db.all_tags()) # Extract books matching filtered_tags genre_list = [] - for friendly_tag in self.genre_tags_dict: + for friendly_tag in sorted(self.genre_tags_dict): #print "\ngenerateHTMLByTags(): looking for books with friendly_tag '%s'" % friendly_tag # tag_list => {'tag': '', 'books':[{}, {}, {}]} + # tag_list => { normalized_genre_tag : [{book},{},{}], + # normalized_genre_tag : [{book},{},{}] } + tag_list = {} - tag_list['tag'] = self.genre_tags_dict[friendly_tag] - tag_list['books'] = [] for book in self.booksByAuthor: # Scan each book for tag matching friendly_tag - #if 'tags' in book: print " evaluating %s with tags: %s" % (book['title'], book['tags']) if 'tags' in book and friendly_tag in book['tags']: - #print " adding '%s'" % (book['title']) this_book = {} this_book['author'] = book['author'] this_book['title'] = book['title'] this_book['author_sort'] = book['author_sort'] this_book['read'] = book['read'] this_book['id'] = book['id'] - tag_list['books'].append(this_book) - - if len(tag_list['books']): - genre_exists = False - book_not_in_genre = True - if not genre_list: - #print " genre_list empty, adding '%s'" % tag_list['tag'] - genre_list.append(tag_list) - else: - # Check for existing_genre - for genre in genre_list: - if genre['tag'] == tag_list['tag']: - genre_exists = True - # Check to see if the book is already in this list - for existing_book in genre['books']: - if this_book['title'] == existing_book['title']: - #print "%s already in %s" % (this_book['title'], genre) - book_not_in_genre = False - break - break - - if genre_exists: - if book_not_in_genre: - #print " adding %s to existing genre '%s'" % (this_book['title'],genre['tag']) - genre['books'].append(this_book) + normalized_tag = self.genre_tags_dict[friendly_tag] + genre_tag_list = [key for genre in genre_list for key in genre] + if normalized_tag in genre_tag_list: + for existing_genre in genre_list: + for key in existing_genre: + new_book = None + if key == normalized_tag: + for book in existing_genre[key]: + if book['title'] == this_book['title']: + new_book = False + break + else: + new_book = True + if new_book: + existing_genre[key].append(this_book) else: - #print " appending genre '%s'" % tag_list['tag'] + tag_list[normalized_tag] = [this_book] genre_list.append(tag_list) if self.opts.verbose: - self.opts.log.info(" Genre summary: %d active genres" % len(genre_list)) + self.opts.log.info(" Genre summary: %d active genre tags used in generating catalog with %d titles" % + (len(genre_list), len(self.booksByTitle))) + for genre in genre_list: - self.opts.log.info(" %s: %d titles" % (genre['tag'], len(genre['books']))) + for key in genre: + self.opts.log.info(" %s: %d titles" % (key, len(genre[key]))) # Write the results - # genre_list = [ [tag_list], [tag_list] ...] + # genre_list = [ {friendly_tag:[{book},{book}]}, {friendly_tag:[{book},{book}]}, ...] master_genre_list = [] - for (index, genre) in enumerate(genre_list): - # Create sorted_authors[0] = friendly, [1] = author_sort for NCX creation - authors = [] - for book in genre['books']: - authors.append((book['author'],book['author_sort'])) + for genre_tag_set in genre_list: + for (index, genre) in enumerate(genre_tag_set): + #print "genre: %s \t genre_tag_set[genre]: %s" % (genre, genre_tag_set[genre]) - # authors[] contains a list of all book authors, with multiple entries for multiple books by author - # Create unique_authors with a count of books per author as the third tuple element - books_by_current_author = 1 - current_author = authors[0] - unique_authors = [] - for (i,author) in enumerate(authors): - if author != current_author and i: - unique_authors.append((current_author[0], current_author[1], books_by_current_author)) - current_author = author - books_by_current_author = 1 - elif i==0 and len(authors) == 1: - # Allow for single-book lists - unique_authors.append((current_author[0], current_author[1], books_by_current_author)) - else: - books_by_current_author += 1 - ''' - # Extract the unique entries - unique_authors = [] - for author in authors: - if not author in unique_authors: - unique_authors.append(author) - ''' - # Write the genre book list as an article - titles_spanned = self.generateHTMLByGenre(genre['tag'], True if index==0 else False, genre['books'], - "%s/Genre_%s.html" % (self.contentDir, genre['tag'])) + # Create sorted_authors[0] = friendly, [1] = author_sort for NCX creation + authors = [] + for book in genre_tag_set[genre]: + authors.append((book['author'],book['author_sort'])) - tag_file = "content/Genre_%s.html" % genre['tag'] - master_genre_list.append({'tag':genre['tag'], - 'file':tag_file, - 'authors':unique_authors, - 'books':genre['books'], - 'titles_spanned':titles_spanned}) + # authors[] contains a list of all book authors, with multiple entries for multiple books by author + # Create unique_authors with a count of books per author as the third tuple element + books_by_current_author = 1 + current_author = authors[0] + unique_authors = [] + for (i,author) in enumerate(authors): + if author != current_author and i: + unique_authors.append((current_author[0], current_author[1], books_by_current_author)) + current_author = author + books_by_current_author = 1 + elif i==0 and len(authors) == 1: + # Allow for single-book lists + unique_authors.append((current_author[0], current_author[1], books_by_current_author)) + else: + books_by_current_author += 1 + ''' + # Extract the unique entries + unique_authors = [] + for author in authors: + if not author in unique_authors: + unique_authors.append(author) + ''' + # Write the genre book list as an article + titles_spanned = self.generateHTMLByGenre(genre, True if index==0 else False, + genre_tag_set[genre], + "%s/Genre_%s.html" % (self.contentDir, + genre)) + tag_file = "content/Genre_%s.html" % genre + master_genre_list.append({'tag':genre, + 'file':tag_file, + 'authors':unique_authors, + 'books':genre_tag_set[genre], + 'titles_spanned':titles_spanned}) + + if False and self.opts.verbose: + for genre in master_genre_list: + print "genre['tag']: %s" % genre['tag'] + for book in genre['books']: + print book['title'] self.genres = master_genre_list def generateThumbnails(self): @@ -2351,7 +2356,7 @@ class EPUB_MOBI(CatalogPlugin): else: yield tag - self.opts.log.info(u' %d total genre tags in database (exclude_genre: %s):' % \ + self.opts.log.info(u' %d available genre tags in database (exclude_genre: %s):' % \ (len(genre_tags_dict), self.opts.exclude_genre)) # Display friendly/normalized genres @@ -2395,19 +2400,15 @@ class EPUB_MOBI(CatalogPlugin): # Create an anchor from the tag aTag = Tag(soup, 'a') - #aTag['name'] = "Genre%s" % re.sub("\W","", genre) aTag['name'] = "Genre_%s" % genre body.insert(btc,aTag) btc += 1 - # Insert the genre title using the friendly name + # Find the first instance of friendly_tag matching genre # GwR *** optimize - for genre_tag in self.genre_tags_dict: - if self.genre_tags_dict[genre_tag] == genre: - friendly_tag = genre_tag + for friendly_tag in self.genre_tags_dict: + if self.genre_tags_dict[friendly_tag] == genre: break - - titleTag = body.find(attrs={'class':'title'}) titleTag.insert(0,NavigableString('%s' % escape(friendly_tag))) @@ -2748,8 +2749,8 @@ class EPUB_MOBI(CatalogPlugin): if opts.verbose: opts_dict = vars(opts) - log("%s(): Generating %s for %s in %s environment" % - (self.name,self.fmt,opts.output_profile, + log("%s(): Generating %s %sin %s environment" % + (self.name,self.fmt,'for %s ' % opts.output_profile if opts.output_profile else '', 'CLI' if opts.cli_environment else 'GUI')) if opts_dict['ids']: log(" Book count: %d" % len(opts_dict['ids'])) @@ -2765,32 +2766,39 @@ class EPUB_MOBI(CatalogPlugin): # Launch the Catalog builder if opts.verbose: - log.info("Begin generating catalog source") + log.info("Begin catalog source generation") catalog = self.CatalogBuilder(db, opts, self, report_progress=notification) catalog.createDirectoryStructure() catalog.copyResources() - catalog.buildSources() + catalog_source_built = catalog.buildSources() if opts.verbose: - log.info("Finished generating catalog source\n") + if catalog_source_built: + log.info("Finished catalog source generation\n") + else: + log.warn("No database hits with supplied criteria") - recommendations = [] + if catalog_source_built: + recommendations = [] - dp = getattr(opts, 'debug_pipeline', None) - if dp is not None: - recommendations.append(('debug_pipeline', dp, - OptionRecommendation.HIGH)) + dp = getattr(opts, 'debug_pipeline', None) + if dp is not None: + recommendations.append(('debug_pipeline', dp, + OptionRecommendation.HIGH)) - if opts.fmt == 'mobi' and opts.output_profile and opts.output_profile.startswith("kindle"): - recommendations.append(('output_profile', opts.output_profile, - OptionRecommendation.HIGH)) - recommendations.append(('no_inline_toc', True, - OptionRecommendation.HIGH)) + if opts.fmt == 'mobi' and opts.output_profile and opts.output_profile.startswith("kindle"): + recommendations.append(('output_profile', opts.output_profile, + OptionRecommendation.HIGH)) + recommendations.append(('no_inline_toc', True, + OptionRecommendation.HIGH)) - # Run ebook-convert - from calibre.ebooks.conversion.plumber import Plumber - plumber = Plumber(os.path.join(catalog.catalogPath, - opts.basename + '.opf'), path_to_output, log, report_progress=notification, - abort_after_input_dump=False) - plumber.merge_ui_recommendations(recommendations) + # Run ebook-convert + from calibre.ebooks.conversion.plumber import Plumber + plumber = Plumber(os.path.join(catalog.catalogPath, + opts.basename + '.opf'), path_to_output, log, report_progress=notification, + abort_after_input_dump=False) + plumber.merge_ui_recommendations(recommendations) - plumber.run() + plumber.run() + return 0 + else: + return 1