diff --git a/resources/catalog/stylesheet.css b/resources/catalog/stylesheet.css index 7bfbbd22cc..b5770599e6 100644 --- a/resources/catalog/stylesheet.css +++ b/resources/catalog/stylesheet.css @@ -33,7 +33,7 @@ p.description { p.date_index { font-size:x-large; - text-align:right; + text-align:center; font-weight:bold; margin-top:1em; margin-bottom:0px; @@ -41,8 +41,9 @@ p.date_index { p.letter_index { font-size:x-large; - text-align:left; - margin-top:0px; + text-align:center; + font-weight:bold; + margin-top:1em; margin-bottom:0px; } diff --git a/src/calibre/gui2/convert/gui_conversion.py b/src/calibre/gui2/convert/gui_conversion.py index 67c50758f8..70321b049b 100644 --- a/src/calibre/gui2/convert/gui_conversion.py +++ b/src/calibre/gui2/convert/gui_conversion.py @@ -23,7 +23,7 @@ def gui_convert(input, output, recommendations, notification=DummyReporter(), plumber.run() -def gui_catalog(fmt, title, dbspec, ids, out_file_name, fmt_options, +def gui_catalog(fmt, title, dbspec, ids, out_file_name, sync, fmt_options, notification=DummyReporter(), log=None): if log is None: log = Log() @@ -46,6 +46,7 @@ def gui_catalog(fmt, title, dbspec, ids, out_file_name, fmt_options, opts.ids = ids opts.search_text = None opts.sort_by = None + opts.sync = sync # Extract the option dictionary to comma-separated lists for option in fmt_options: diff --git a/src/calibre/gui2/tools.py b/src/calibre/gui2/tools.py index 7dc83baf32..bd34f84821 100644 --- a/src/calibre/gui2/tools.py +++ b/src/calibre/gui2/tools.py @@ -254,11 +254,13 @@ def generate_catalog(parent, dbspec, ids): dbspec, ids, out.name, + d.catalog_sync, d.fmt_options ] out.close() - # This calls gui2.convert.gui_conversion:gui_catalog() + # This returns to gui2.ui:generate_catalog() + # Which then calls gui2.convert.gui_conversion:gui_catalog() return 'gui_catalog', args, _('Generate catalog'), out.name, d.catalog_sync, \ d.catalog_title diff --git a/src/calibre/library/catalog.py b/src/calibre/library/catalog.py index fb5bfb4971..67e360da68 100644 --- a/src/calibre/library/catalog.py +++ b/src/calibre/library/catalog.py @@ -796,6 +796,12 @@ class EPUB_MOBI(CatalogPlugin): shutil.copy(os.path.join(catalog_resources,file[1]), os.path.join(self.catalogPath, file[0])) + # Create the custom masthead image overwriting default + try: + self.generate_masthead_image(os.path.join(self.catalogPath, 'images/mastheadImage.gif')) + except: + pass + def fetchBooksByTitle(self): self.updateProgressFullStep("Fetching database") @@ -881,7 +887,7 @@ class EPUB_MOBI(CatalogPlugin): def fetchBooksByAuthor(self): # Generate a list of titles sorted by author from the database - self.updateProgressFullStep("Sorting database by author") + self.updateProgressFullStep("Sorting database") # Sort titles case-insensitive self.booksByAuthor = sorted(self.booksByTitle, @@ -934,7 +940,7 @@ class EPUB_MOBI(CatalogPlugin): def generateHTMLDescriptions(self): # Write each title to a separate HTML file in contentdir - self.updateProgressFullStep("Description") + self.updateProgressFullStep("'Descriptions'") for (title_num, title) in enumerate(self.booksByTitle): if False: @@ -1063,7 +1069,7 @@ class EPUB_MOBI(CatalogPlugin): def generateHTMLByTitle(self): # Write books by title A-Z to HTML file - self.updateProgressFullStep("Books by Title") + self.updateProgressFullStep("'Titles'") soup = self.generateHTMLEmptyHeader("Books By Alpha Title") body = soup.find('body') @@ -1165,7 +1171,7 @@ class EPUB_MOBI(CatalogPlugin): def generateHTMLByAuthor(self): # Write books by author A-Z - self.updateProgressFullStep("Books by Author") + self.updateProgressFullStep("'Authors'") friendly_name = "By Author" @@ -1295,7 +1301,7 @@ class EPUB_MOBI(CatalogPlugin): def generateHTMLByDateAdded(self): # Write books by reverse chronological order - self.updateProgressFullStep("Recently Added") + self.updateProgressFullStep("'Recently Added'") def add_books_to_HTML(this_months_list, dtc): if len(this_months_list): @@ -1427,7 +1433,7 @@ class EPUB_MOBI(CatalogPlugin): # Generate individual HTML files for each tag, e.g. Fiction, Nonfiction ... # Note that special tags - ~+*[] - have already been filtered from books[] - self.updateProgressFullStep("Generating Genres") + self.updateProgressFullStep("'Genres'") # Filter out REMOVE_TAGS, sort filtered_tags = self.filterDbTags(self.db.all_tags()) @@ -1580,7 +1586,7 @@ class EPUB_MOBI(CatalogPlugin): def generateOPF(self): - self.updateProgressFullStep("Generating OPF") + self.updateProgressFullStep("Saving OPF") header = ''' @@ -1748,7 +1754,7 @@ class EPUB_MOBI(CatalogPlugin): def generateNCXDescriptions(self, tocTitle): - self.updateProgressFullStep("NCX descriptions") + self.updateProgressFullStep("NCX 'Descriptions'") # --- Construct the 'Books by Title' section --- ncx_soup = self.ncxSoup @@ -1794,7 +1800,11 @@ class EPUB_MOBI(CatalogPlugin): # Add the author tag cmTag = Tag(ncx_soup, '%s' % 'calibre:meta') cmTag['name'] = "author" - cmTag.insert(0, NavigableString(self.formatNCXText(book['author']))) + navStr = '%s | %s' % (self.formatNCXText(book['author']), + book['date'].split()[1]) + if 'tags' in book: + navStr += ' | %s' % self.formatNCXText(' · '.join(sorted(book['tags']))) + cmTag.insert(0, NavigableString(navStr)) navPointVolumeTag.insert(2, cmTag) # Add the description tag @@ -1815,7 +1825,7 @@ class EPUB_MOBI(CatalogPlugin): self.ncxSoup = ncx_soup def generateNCXByTitle(self, tocTitle): - self.updateProgressFullStep("NCX Titles") + self.updateProgressFullStep("NCX 'Titles'") def add_to_books_by_letter(current_book_list): current_book_list = " • ".join(current_book_list) @@ -1904,7 +1914,7 @@ class EPUB_MOBI(CatalogPlugin): self.ncxSoup = soup def generateNCXByAuthor(self, tocTitle): - self.updateProgressFullStep("NCX Authors") + self.updateProgressFullStep("NCX 'Authors'") def add_to_author_list(current_author_list, current_letter): current_author_list = " • ".join(current_author_list) @@ -1993,12 +2003,13 @@ class EPUB_MOBI(CatalogPlugin): self.ncxSoup = soup def generateNCXByDateAdded(self, tocTitle): - self.updateProgressFullStep("NCX Recently Added") + self.updateProgressFullStep("NCX 'Recently Added'") def add_to_master_month_list(current_titles_list): + book_count = len(current_titles_list) current_titles_list = " • ".join(current_titles_list) current_titles_list = self.generateShortDescription(self.formatNCXText(current_titles_list)) - master_month_list.append((current_titles_list, current_date)) + master_month_list.append((current_titles_list, current_date, book_count)) soup = self.ncxSoup HTML_file = "content/ByDateAdded.html" @@ -2028,7 +2039,7 @@ class EPUB_MOBI(CatalogPlugin): # Create an NCX article entry for each populated month # Loop over the booksByDate list, find start of each month, # add description_preview_count titles - # self.authors[0]:friendly [1]:author_sort [2]:book_count + # master_month_list(list,date,count) current_titles_list = [] master_month_list = [] current_date = self.booksByDate[0]['timestamp'] @@ -2074,6 +2085,13 @@ class EPUB_MOBI(CatalogPlugin): cmTag.insert(0, NavigableString(books_by_month[0])) navPointByMonthTag.insert(2, cmTag) + cmTag = Tag(soup, '%s' % 'calibre:meta') + cmTag['name'] = "author" + navStr = '%d titles' % books_by_month[2] if books_by_month[2] > 1 else \ + '%d title' % books_by_month[2] + cmTag.insert(0, NavigableString(navStr)) + navPointByMonthTag.insert(3, cmTag) + navPointTag.insert(nptc, navPointByMonthTag) nptc += 1 @@ -2087,7 +2105,7 @@ class EPUB_MOBI(CatalogPlugin): # Add each genre as an article # 'tag', 'file', 'authors' - self.updateProgressFullStep("NCX by Genre") + self.updateProgressFullStep("NCX 'Genres'") @@ -2188,7 +2206,7 @@ class EPUB_MOBI(CatalogPlugin): self.ncxSoup = ncx_soup def writeNCX(self): - self.updateProgressFullStep("Writing NCX") + self.updateProgressFullStep("Saving NCX") outfile = open("%s/%s.ncx" % (self.catalogPath, self.basename), 'w') outfile.write(self.ncxSoup.prettify()) @@ -2252,6 +2270,13 @@ class EPUB_MOBI(CatalogPlugin): # Remove the special marker tags from the database's tag list, # return sorted list of tags representing valid genres + def next_tag(tags): + for (i, tag) in enumerate(tags): + if i < len(tags) - 1: + yield tag + ", " + else: + yield tag + filtered_tags = [] for tag in tags: if tag[0] in self.markerTags: @@ -2275,9 +2300,16 @@ class EPUB_MOBI(CatalogPlugin): else: continue if self.verbose: - self.opts.log.info(u' %d Genre tags (exclude_genre: %s):' % \ + self.opts.log.info(u' %d Genre tags in database (exclude_genre: %s):' % \ (len(filtered_tags), self.opts.exclude_genre)) - self.opts.log.info(u' %s' % ', '.join(filtered_tags)) + out_buf = '' + + 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) return filtered_tags @@ -2479,6 +2511,26 @@ class EPUB_MOBI(CatalogPlugin): titleTag.insert(0,escape(NavigableString(title))) return soup + def generate_masthead_image(self, out_path): + MI_WIDTH = 600 + MI_HEIGHT = 60 + + try: + from PIL import Image, ImageDraw, ImageFont + Image, ImageDraw, ImageFont + except ImportError: + import Image, ImageDraw, ImageFont + + img = Image.new('RGB', (MI_WIDTH, MI_HEIGHT), 'white') + draw = ImageDraw.Draw(img) + font = ImageFont.truetype(P('fonts/liberation/LiberationSerif-Bold.ttf'), 48) + text = self.title.encode('utf-8') + width, height = draw.textsize(text, font=font) + left = max(int((MI_WIDTH - width)/2.), 0) + top = max(int((MI_HEIGHT - height)/2.), 0) + draw.text((left, top), text, fill=(0,0,0), font=font) + img.save(open(out_path, 'wb'), 'GIF') + def generateShortDescription(self, description): # Truncate the description to description_clip, on word boundaries if necessary if not description: @@ -2512,6 +2564,7 @@ class EPUB_MOBI(CatalogPlugin): for (i,word) in enumerate(title_words): # Leading numbers optionally translated to text equivalent + # Capitalize leading sort word if i==0: if self.opts.numbers_as_text and re.search('[0-9]+',word): translated.append(EPUB_MOBI.NumberToText(word).text.capitalize()) @@ -2529,7 +2582,7 @@ class EPUB_MOBI(CatalogPlugin): word = '%10.2f' % float(re.sub('[^\d\.]','.',word)) except: word = '%10.2f' % float(EPUB_MOBI.NumberToText(word).number_as_float) - translated.append(word) + translated.append(word.capitalize()) else: if re.search('[0-9]+',word): # Coerce standard-width strings for numbers @@ -2594,6 +2647,8 @@ class EPUB_MOBI(CatalogPlugin): self.progressString = description self.progressInt = float((self.current_step-1)/self.total_steps) self.reporter(self.progressInt, self.progressString) + if self.opts.cli_environment: + self.opts.log(u"%3.0f%% %s" % (self.progressInt*100, self.progressString)) def updateProgressMicroStep(self, description, micro_step_pct): step_range = 100/self.total_steps @@ -2616,10 +2671,13 @@ 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) if opts.verbose: opts_dict = vars(opts) - log("%s(): Generating %s for %s" % (self.name,self.fmt,opts.output_profile)) + log("%s(): Generating %s for %s in %s environment" % + (self.name,self.fmt,opts.output_profile, + 'CLI' if opts.cli_environment else 'GUI')) if opts_dict['ids']: log(" Book count: %d" % len(opts_dict['ids'])) # Display opts @@ -2629,17 +2687,18 @@ class EPUB_MOBI(CatalogPlugin): for key in keys: if key in ['catalog_title','exclude_genre','exclude_tags','note_tag', - 'numbers_as_text','read_tag','search_text','sort_by']: + 'numbers_as_text','read_tag','search_text','sort_by','sync']: log(" %s: %s" % (key, opts_dict[key])) # Launch the Catalog builder + if opts.verbose: + log.info("Begin generating catalog source") catalog = self.CatalogBuilder(db, opts, self, report_progress=notification) catalog.createDirectoryStructure() catalog.copyResources() catalog.buildSources() - if opts.verbose: - log.info("Catalog source generation complete") + log.info("Finished generating catalog source\n") recommendations = []