More catalog tweaks

This commit is contained in:
Kovid Goyal 2010-01-29 18:52:56 -07:00
commit d69fd87023
3 changed files with 109 additions and 155 deletions

View File

@ -33,7 +33,7 @@ p.description {
p.date_index { p.date_index {
font-size:x-large; font-size:x-large;
text-align:center; text-align:right;
font-weight:bold; font-weight:bold;
margin-top:1em; margin-top:1em;
margin-bottom:0px; margin-bottom:0px;

View File

@ -288,7 +288,7 @@ class CatalogPlugin(Plugin):
fields = list(all_fields) fields = list(all_fields)
fields.sort() fields.sort()
if opts.sort_by: if opts.sort_by and opts.sort_by in fields:
fields.insert(0,fields.pop(int(fields.index(opts.sort_by)))) fields.insert(0,fields.pop(int(fields.index(opts.sort_by))))
return fields return fields

View File

@ -51,18 +51,23 @@ class CSV_XML(CatalogPlugin):
self.fmt = path_to_output.rpartition('.')[2] self.fmt = path_to_output.rpartition('.')[2]
self.notification = notification self.notification = notification
if False and opts.verbose: if opts.verbose:
log("%s:run" % self.name)
log(" path_to_output: %s" % path_to_output)
log(" Output format: %s" % self.fmt)
# Display opts
opts_dict = vars(opts) opts_dict = vars(opts)
keys = opts_dict.keys() log("%s(): Generating %s" % (self.name,self.fmt))
keys.sort() if opts_dict['search_text']:
log(" opts:") log(" --search='%s'" % opts_dict['search_text'])
for key in keys:
log(" %s: %s" % (key, opts_dict[key])) if opts_dict['ids']:
log(" Book count: %d" % len(opts_dict['ids']))
if opts_dict['search_text']:
log(" (--search ignored when a subset of the database is specified)")
if opts_dict['fields']:
if opts_dict['fields'] == 'all':
log(" Fields: %s" % ', '.join(FIELDS[1:]))
else:
log(" Fields: %s" % opts_dict['fields'])
# If a list of ids are provided, don't use search_text # If a list of ids are provided, don't use search_text
if opts.ids: if opts.ids:
@ -486,7 +491,7 @@ class EPUB_MOBI(CatalogPlugin):
# Number of discrete steps to catalog creation # Number of discrete steps to catalog creation
current_step = 0.0 current_step = 0.0
total_steps = 13.0 total_steps = 14.0
THUMB_WIDTH = 75 THUMB_WIDTH = 75
THUMB_HEIGHT = 100 THUMB_HEIGHT = 100
@ -502,7 +507,7 @@ class EPUB_MOBI(CatalogPlugin):
# verbosity level of diagnostic printout # verbosity level of diagnostic printout
def __init__(self, db, opts, plugin, def __init__(self, db, opts, plugin,
notification=DummyReporter(), report_progress=DummyReporter(),
stylesheet="content/stylesheet.css"): stylesheet="content/stylesheet.css"):
self.__opts = opts self.__opts = opts
self.__authors = None self.__authors = None
@ -527,16 +532,12 @@ class EPUB_MOBI(CatalogPlugin):
self.__plugin_path = opts.plugin_path self.__plugin_path = opts.plugin_path
self.__progressInt = 0.0 self.__progressInt = 0.0
self.__progressString = '' self.__progressString = ''
self.__reporter = notification self.__reporter = report_progress
self.__stylesheet = stylesheet self.__stylesheet = stylesheet
self.__thumbs = None self.__thumbs = None
self.__title = opts.catalog_title self.__title = opts.catalog_title
self.__verbose = opts.verbose self.__verbose = opts.verbose
self.opts.log.info("CatalogBuilder(): Generating %s %s"% \
(self.opts.fmt,
"for %s" % self.opts.output_profile if self.opts.output_profile \
else ''))
# Accessors # Accessors
''' '''
@dynamic_property @dynamic_property
@ -755,59 +756,27 @@ class EPUB_MOBI(CatalogPlugin):
# Methods # Methods
def buildSources(self): def buildSources(self):
if getattr(self.reporter, 'cancel_requested', False): return 1 self.fetchBooksByTitle()
if not self.booksByTitle:
self.fetchBooksByTitle()
if getattr(self.reporter, 'cancel_requested', False): return 1
self.fetchBooksByAuthor() self.fetchBooksByAuthor()
if getattr(self.reporter, 'cancel_requested', False): return 1
self.generateHTMLDescriptions() self.generateHTMLDescriptions()
if getattr(self.reporter, 'cancel_requested', False): return 1
self.generateHTMLByAuthor() self.generateHTMLByAuthor()
if getattr(self.reporter, 'cancel_requested', False): return 1
self.generateHTMLByTitle() self.generateHTMLByTitle()
if getattr(self.reporter, 'cancel_requested', False): return 1
self.generateHTMLByDateAdded() self.generateHTMLByDateAdded()
if getattr(self.reporter, 'cancel_requested', False): return 1
self.generateHTMLByTags() self.generateHTMLByTags()
if getattr(self.reporter, 'cancel_requested', False): return 1
from calibre.utils.PythonMagickWand import ImageMagick from calibre.utils.PythonMagickWand import ImageMagick
with ImageMagick(): with ImageMagick():
self.generateThumbnails() self.generateThumbnails()
if getattr(self.reporter, 'cancel_requested', False): return 1
self.generateOPF() self.generateOPF()
if getattr(self.reporter, 'cancel_requested', False): return 1
self.generateNCXHeader() self.generateNCXHeader()
if getattr(self.reporter, 'cancel_requested', False): return 1
self.generateNCXDescriptions("Descriptions") self.generateNCXDescriptions("Descriptions")
if getattr(self.reporter, 'cancel_requested', False): return 1
self.generateNCXByAuthor("Authors") self.generateNCXByAuthor("Authors")
if getattr(self.reporter, 'cancel_requested', False): return 1
self.generateNCXByTitle("Titles") self.generateNCXByTitle("Titles")
if getattr(self.reporter, 'cancel_requested', False): return 1
self.generateNCXByDateAdded("Recently Added") self.generateNCXByDateAdded("Recently Added")
self.generateNCXByGenre("Genres")
if getattr(self.reporter, 'cancel_requested', False): return 1
self.generateNCXByTags("Genres")
if getattr(self.reporter, 'cancel_requested', False): return 1
self.writeNCX() self.writeNCX()
return 0
def cleanUp(self): def cleanUp(self):
pass pass
@ -828,7 +797,7 @@ class EPUB_MOBI(CatalogPlugin):
os.path.join(self.catalogPath, file[0])) os.path.join(self.catalogPath, file[0]))
def fetchBooksByTitle(self): def fetchBooksByTitle(self):
self.opts.log.info(self.updateProgressFullStep("fetchBooksByTitle()")) self.updateProgressFullStep("Fetching database")
# Get the database as a dictionary # Get the database as a dictionary
# Sort by title # Sort by title
@ -875,7 +844,7 @@ class EPUB_MOBI(CatalogPlugin):
this_title['publisher'] = re.sub('&', '&', record['publisher']) this_title['publisher'] = re.sub('&', '&', record['publisher'])
this_title['rating'] = record['rating'] if record['rating'] else 0 this_title['rating'] = record['rating'] if record['rating'] else 0
this_title['date'] = strftime(u'%b %Y', record['pubdate'].timetuple()) this_title['date'] = strftime(u'%B %Y', record['pubdate'].timetuple())
this_title['timestamp'] = record['timestamp'] this_title['timestamp'] = record['timestamp']
if record['comments']: if record['comments']:
this_title['description'] = re.sub('&', '&', record['comments']) this_title['description'] = re.sub('&', '&', record['comments'])
@ -912,7 +881,7 @@ class EPUB_MOBI(CatalogPlugin):
def fetchBooksByAuthor(self): def fetchBooksByAuthor(self):
# Generate a list of titles sorted by author from the database # Generate a list of titles sorted by author from the database
self.opts.log.info(self.updateProgressFullStep("fetchBooksByAuthor()")) self.updateProgressFullStep("Sorting database by author")
# Sort titles case-insensitive # Sort titles case-insensitive
self.booksByAuthor = sorted(self.booksByTitle, self.booksByAuthor = sorted(self.booksByTitle,
@ -965,14 +934,15 @@ class EPUB_MOBI(CatalogPlugin):
def generateHTMLDescriptions(self): def generateHTMLDescriptions(self):
# Write each title to a separate HTML file in contentdir # Write each title to a separate HTML file in contentdir
self.opts.log.info(self.updateProgressFullStep("generateHTMLDescriptions()")) self.updateProgressFullStep("Description")
for (title_num, title) in enumerate(self.booksByTitle): for (title_num, title) in enumerate(self.booksByTitle):
if False: if False:
self.opts.log.info("%3s: %s - %s" % (title['id'], title['title'], title['author'])) self.opts.log.info("%3s: %s - %s" % (title['id'], title['title'], title['author']))
self.updateProgressMicroStep("generating book descriptions ...", self.updateProgressMicroStep("Description %d of %d" % \
float(title_num*100/len(self.booksByTitle))/100) (title_num, len(self.booksByTitle)),
float(title_num*100/len(self.booksByTitle))/100)
# Generate the header # Generate the header
soup = self.generateHTMLDescriptionHeader("%s" % title['title']) soup = self.generateHTMLDescriptionHeader("%s" % title['title'])
@ -1093,7 +1063,7 @@ class EPUB_MOBI(CatalogPlugin):
def generateHTMLByTitle(self): def generateHTMLByTitle(self):
# Write books by title A-Z to HTML file # Write books by title A-Z to HTML file
self.opts.log.info(self.updateProgressFullStep("generateHTMLByTitle()")) self.updateProgressFullStep("Books by Title")
soup = self.generateHTMLEmptyHeader("Books By Alpha Title") soup = self.generateHTMLEmptyHeader("Books By Alpha Title")
body = soup.find('body') body = soup.find('body')
@ -1195,7 +1165,7 @@ class EPUB_MOBI(CatalogPlugin):
def generateHTMLByAuthor(self): def generateHTMLByAuthor(self):
# Write books by author A-Z # Write books by author A-Z
self.opts.log.info(self.updateProgressFullStep("generateHTMLByAuthor()")) self.updateProgressFullStep("Books by Author")
friendly_name = "By Author" friendly_name = "By Author"
@ -1324,35 +1294,31 @@ class EPUB_MOBI(CatalogPlugin):
self.htmlFileList.append("content/ByAlphaAuthor.html") self.htmlFileList.append("content/ByAlphaAuthor.html")
def generateHTMLByDateAdded(self): def generateHTMLByDateAdded(self):
# Write books by reverse chronological order
self.updateProgressFullStep("Recently Added")
def add_books_to_HTML(this_months_list, dtc): def add_books_to_HTML(this_months_list, dtc):
if len(this_months_list): if len(this_months_list):
date_string = strftime(u'%b %Y', current_date.timetuple()) date_string = strftime(u'%B %Y', current_date.timetuple())
this_months_list = sorted(this_months_list, this_months_list = sorted(this_months_list,
key=lambda x:(x['title_sort'], x['title_sort'])) key=lambda x:(x['title_sort'], x['title_sort']))
this_months_list = sorted(this_months_list, this_months_list = sorted(this_months_list,
key=lambda x:(x['author_sort'], x['author_sort'])) key=lambda x:(x['author_sort'], x['author_sort']))
prints("Books added in", date_string)
# Create a new month anchor # Create a new month anchor
pIndexTag = Tag(soup, "p") pIndexTag = Tag(soup, "p")
pIndexTag['class'] = "date_index" pIndexTag['class'] = "date_index"
aTag = Tag(soup, "a") aTag = Tag(soup, "a")
aTag['name'] = "%s-%s" % (current_date.year, current_date.month) aTag['name'] = "%s-%s" % (current_date.year, current_date.month)
pIndexTag.insert(0,aTag) pIndexTag.insert(0,aTag)
pIndexTag.insert(1,NavigableString('Books added in '+date_string)) pIndexTag.insert(1,NavigableString(date_string))
divTag.insert(dtc,pIndexTag) divTag.insert(dtc,pIndexTag)
dtc += 1 dtc += 1
current_author = None current_author = None
for purchase in this_months_list: for new_entry in this_months_list:
prints(u" %-40s \t %-20s \t %s" % (purchase['title'], if new_entry['author'] != current_author:
purchase['author'], purchase['timestamp']))
if purchase['author'] != current_author:
# Start a new author # Start a new author
current_author = purchase['author'] current_author = new_entry['author']
pAuthorTag = Tag(soup, "p") pAuthorTag = Tag(soup, "p")
pAuthorTag['class'] = "author_index" pAuthorTag['class'] = "author_index"
emTag = Tag(soup, "em") emTag = Tag(soup, "em")
@ -1369,7 +1335,7 @@ class EPUB_MOBI(CatalogPlugin):
ptc = 0 ptc = 0
# Prefix book with read/unread symbol # Prefix book with read/unread symbol
if purchase['read']: if new_entry['read']:
# check mark # check mark
pBookTag.insert(ptc,NavigableString(self.READ_SYMBOL)) pBookTag.insert(ptc,NavigableString(self.READ_SYMBOL))
pBookTag['class'] = "read_book" pBookTag['class'] = "read_book"
@ -1381,8 +1347,8 @@ class EPUB_MOBI(CatalogPlugin):
ptc += 1 ptc += 1
aTag = Tag(soup, "a") aTag = Tag(soup, "a")
aTag['href'] = "book_%d.html" % (int(float(purchase['id']))) aTag['href'] = "book_%d.html" % (int(float(new_entry['id'])))
aTag.insert(0,escape(purchase['title'])) aTag.insert(0,escape(new_entry['title']))
pBookTag.insert(ptc, aTag) pBookTag.insert(ptc, aTag)
ptc += 1 ptc += 1
@ -1390,8 +1356,6 @@ class EPUB_MOBI(CatalogPlugin):
dtc += 1 dtc += 1
return dtc return dtc
# Write books by reverse chronological order
self.opts.log.info(self.updateProgressFullStep("generateHTMLByDateAdded()"))
# Sort titles case-insensitive # Sort titles case-insensitive
self.booksByDate = sorted(self.booksByTitle, self.booksByDate = sorted(self.booksByTitle,
@ -1463,7 +1427,7 @@ class EPUB_MOBI(CatalogPlugin):
# Generate individual HTML files for each tag, e.g. Fiction, Nonfiction ... # Generate individual HTML files for each tag, e.g. Fiction, Nonfiction ...
# Note that special tags - ~+*[] - have already been filtered from books[] # Note that special tags - ~+*[] - have already been filtered from books[]
self.opts.log.info(self.updateProgressFullStep("generateHTMLByTags()")) self.updateProgressFullStep("Generating Genres")
# Filter out REMOVE_TAGS, sort # Filter out REMOVE_TAGS, sort
filtered_tags = self.filterDbTags(self.db.all_tags()) filtered_tags = self.filterDbTags(self.db.all_tags())
@ -1544,7 +1508,8 @@ class EPUB_MOBI(CatalogPlugin):
for (i,title) in enumerate(self.booksByTitle): for (i,title) in enumerate(self.booksByTitle):
# Update status # Update status
self.updateProgressMicroStep("generating thumbnails ...", self.updateProgressMicroStep("Thumbnail %d of %d" % \
(i,len(self.booksByTitle)),
i/float(len(self.booksByTitle))) i/float(len(self.booksByTitle)))
# Check to see if source file exists # Check to see if source file exists
if 'cover' in title and os.path.isfile(title['cover']): if 'cover' in title and os.path.isfile(title['cover']):
@ -1566,7 +1531,7 @@ class EPUB_MOBI(CatalogPlugin):
self.generateThumbnail(title, image_dir, thumb_file) self.generateThumbnail(title, image_dir, thumb_file)
else: else:
# Use default cover # Use default cover
if self.verbose: if False and self.verbose:
self.opts.log.warn(" using default cover for '%s'" % \ self.opts.log.warn(" using default cover for '%s'" % \
(title['title'])) (title['title']))
# Check to make sure default is current # Check to make sure default is current
@ -1599,13 +1564,13 @@ class EPUB_MOBI(CatalogPlugin):
cover_timestamp = os.path.getmtime(cover) cover_timestamp = os.path.getmtime(cover)
thumb_timestamp = os.path.getmtime(thumb_fp) thumb_timestamp = os.path.getmtime(thumb_fp)
if thumb_timestamp < cover_timestamp: if thumb_timestamp < cover_timestamp:
if self.verbose: if False and self.verbose:
self.opts.log.warn("updating thumbnail_default for %s" % title['title']) self.opts.log.warn("updating thumbnail_default for %s" % title['title'])
#title['cover'] = "%s/DefaultCover.jpg" % self.catalogPath #title['cover'] = "%s/DefaultCover.jpg" % self.catalogPath
title['cover'] = cover title['cover'] = cover
self.generateThumbnail(title, image_dir, "thumbnail_default.jpg") self.generateThumbnail(title, image_dir, "thumbnail_default.jpg")
else: else:
if self.verbose: if False and self.verbose:
self.opts.log.warn(" generating new thumbnail_default.jpg") self.opts.log.warn(" generating new thumbnail_default.jpg")
#title['cover'] = "%s/DefaultCover.jpg" % self.catalogPath #title['cover'] = "%s/DefaultCover.jpg" % self.catalogPath
title['cover'] = cover title['cover'] = cover
@ -1615,7 +1580,7 @@ class EPUB_MOBI(CatalogPlugin):
def generateOPF(self): def generateOPF(self):
self.opts.log.info(self.updateProgressFullStep("generateOPF()")) self.updateProgressFullStep("Generating OPF")
header = ''' header = '''
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
@ -1747,7 +1712,7 @@ class EPUB_MOBI(CatalogPlugin):
def generateNCXHeader(self): def generateNCXHeader(self):
self.opts.log.info(self.updateProgressFullStep("generateNCXHeader()")) self.updateProgressFullStep("NCX header")
header = ''' header = '''
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
@ -1783,7 +1748,7 @@ class EPUB_MOBI(CatalogPlugin):
def generateNCXDescriptions(self, tocTitle): def generateNCXDescriptions(self, tocTitle):
self.opts.log.info(self.updateProgressFullStep("generateNCXDescriptions()")) self.updateProgressFullStep("NCX descriptions")
# --- Construct the 'Books by Title' section --- # --- Construct the 'Books by Title' section ---
ncx_soup = self.ncxSoup ncx_soup = self.ncxSoup
@ -1850,8 +1815,12 @@ class EPUB_MOBI(CatalogPlugin):
self.ncxSoup = ncx_soup self.ncxSoup = ncx_soup
def generateNCXByTitle(self, tocTitle): def generateNCXByTitle(self, tocTitle):
self.updateProgressFullStep("NCX Titles")
self.opts.log.info(self.updateProgressFullStep("generateNCXByTitle()")) def add_to_books_by_letter(current_book_list):
current_book_list = " &bull; ".join(current_book_list)
current_book_list = self.generateShortDescription(self.formatNCXText(current_book_list))
books_by_letter.append(current_book_list)
soup = self.ncxSoup soup = self.ncxSoup
output = "ByAlphaTitle" output = "ByAlphaTitle"
@ -1886,9 +1855,7 @@ class EPUB_MOBI(CatalogPlugin):
for book in self.booksByTitle: for book in self.booksByTitle:
if self.letter_or_symbol(book['title_sort'][0]) != current_letter: if self.letter_or_symbol(book['title_sort'][0]) != current_letter:
# Save the old list # Save the old list
book_list = " &bull; ".join(current_book_list) add_to_books_by_letter(current_book_list)
short_description = self.generateShortDescription(self.formatNCXText(book_list))
books_by_letter.append(short_description)
# Start the new list # Start the new list
current_letter = self.letter_or_symbol(book['title_sort'][0]) current_letter = self.letter_or_symbol(book['title_sort'][0])
@ -1902,9 +1869,7 @@ class EPUB_MOBI(CatalogPlugin):
current_book_list.append(book['title']) current_book_list.append(book['title'])
# Add the last book list # Add the last book list
book_list = " &bull; ".join(current_book_list) add_to_books_by_letter(current_book_list)
short_description = self.generateShortDescription(self.formatNCXText(book_list))
books_by_letter.append(short_description)
# Add *article* entries for each populated title letter # Add *article* entries for each populated title letter
for (i,books) in enumerate(books_by_letter): for (i,books) in enumerate(books_by_letter):
@ -1939,8 +1904,12 @@ class EPUB_MOBI(CatalogPlugin):
self.ncxSoup = soup self.ncxSoup = soup
def generateNCXByAuthor(self, tocTitle): def generateNCXByAuthor(self, tocTitle):
self.updateProgressFullStep("NCX Authors")
self.opts.log.info(self.updateProgressFullStep("generateNCXByAuthor()")) def add_to_author_list(current_author_list, current_letter):
current_author_list = " &bull; ".join(current_author_list)
current_author_list = self.generateShortDescription(self.formatNCXText(current_author_list))
master_author_list.append((current_author_list, current_letter))
soup = self.ncxSoup soup = self.ncxSoup
HTML_file = "content/ByAlphaAuthor.html" HTML_file = "content/ByAlphaAuthor.html"
@ -1978,14 +1947,7 @@ class EPUB_MOBI(CatalogPlugin):
for author in self.authors: for author in self.authors:
if author[1][0] != current_letter: if author[1][0] != current_letter:
# Save the old list # Save the old list
author_list = " &bull; ".join(current_author_list) add_to_author_list(current_author_list, current_letter)
if len(current_author_list) == self.descriptionClip:
author_list += " &hellip;"
author_list = self.formatNCXText(author_list)
if False and self.verbose:
self.opts.log.info(" adding '%s' to master_author_list" % current_letter)
master_author_list.append((author_list, current_letter))
# Start the new list # Start the new list
current_letter = author[1][0] current_letter = author[1][0]
@ -1995,13 +1957,7 @@ class EPUB_MOBI(CatalogPlugin):
current_author_list.append(author[0]) current_author_list.append(author[0])
# Add the last author list # Add the last author list
author_list = " &bull; ".join(current_author_list) add_to_author_list(current_author_list, current_letter)
if len(current_author_list) == self.descriptionClip:
author_list += " &hellip;"
author_list = self.formatNCXText(author_list)
if False and self.verbose:
self.opts.log.info(" adding '%s' to master_author_list" % current_letter)
master_author_list.append((author_list, current_letter))
# Add *article* entries for each populated author initial letter # Add *article* entries for each populated author initial letter
# master_author_list{}: [0]:author list [1]:Initial letter # master_author_list{}: [0]:author list [1]:Initial letter
@ -2037,8 +1993,12 @@ class EPUB_MOBI(CatalogPlugin):
self.ncxSoup = soup self.ncxSoup = soup
def generateNCXByDateAdded(self, tocTitle): def generateNCXByDateAdded(self, tocTitle):
self.updateProgressFullStep("NCX Recently Added")
self.opts.log.info(self.updateProgressFullStep("generateNCXByDateAdded()")) def add_to_master_month_list(current_titles_list):
current_titles_list = " &bull; ".join(current_titles_list)
current_titles_list = self.generateShortDescription(self.formatNCXText(current_titles_list))
master_month_list.append((current_titles_list, current_date))
soup = self.ncxSoup soup = self.ncxSoup
HTML_file = "content/ByDateAdded.html" HTML_file = "content/ByDateAdded.html"
@ -2077,49 +2037,44 @@ class EPUB_MOBI(CatalogPlugin):
if book['timestamp'].month != current_date.month or \ if book['timestamp'].month != current_date.month or \
book['timestamp'].year != current_date.year: book['timestamp'].year != current_date.year:
# Save the old lists # Save the old lists
current_titles_list = " &bull; ".join(current_titles_list) add_to_master_month_list(current_titles_list)
current_titles_list = self.formatNCXText(current_titles_list)
master_month_list.append((current_titles_list, current_date))
# Start the new list # Start the new list
current_date = book['timestamp'].date() current_date = book['timestamp'].date()
current_titles_list = [book['title']] current_titles_list = [book['title']]
else: else:
if len(current_titles_list) < self.descriptionClip: current_titles_list.append(book['title'])
current_titles_list.append(book['title'])
# Add the last author list # Add the last month list
current_titles_list = " &bull; ".join(current_titles_list) add_to_master_month_list(current_titles_list)
master_month_list.append((current_titles_list, current_date))
# Add *article* entries for each populated author initial letter # Add *article* entries for each populated month
# master_months_list{}: [0]:titles list [1]:date # master_months_list{}: [0]:titles list [1]:date
for books_by_month in master_month_list: for books_by_month in master_month_list:
datestr = strftime(u'%b %Y', books_by_month[1].timetuple()) datestr = strftime(u'%B %Y', books_by_month[1].timetuple())
navPointByLetterTag = Tag(soup, 'navPoint') navPointByMonthTag = Tag(soup, 'navPoint')
navPointByLetterTag['class'] = "article" navPointByMonthTag['class'] = "article"
navPointByLetterTag['id'] = "%s-%s-ID" % (books_by_month[1].year,books_by_month[1].month ) navPointByMonthTag['id'] = "%s-%s-ID" % (books_by_month[1].year,books_by_month[1].month )
navPointTag['playOrder'] = self.playOrder navPointTag['playOrder'] = self.playOrder
self.playOrder += 1 self.playOrder += 1
navLabelTag = Tag(soup, 'navLabel') navLabelTag = Tag(soup, 'navLabel')
textTag = Tag(soup, 'text') textTag = Tag(soup, 'text')
textTag.insert(0, NavigableString("Books added in " + datestr)) textTag.insert(0, NavigableString(datestr))
navLabelTag.insert(0, textTag) navLabelTag.insert(0, textTag)
navPointByLetterTag.insert(0,navLabelTag) navPointByMonthTag.insert(0,navLabelTag)
contentTag = Tag(soup, 'content') contentTag = Tag(soup, 'content')
contentTag['src'] = "%s#%s-%s" % (HTML_file, contentTag['src'] = "%s#%s-%s" % (HTML_file,
books_by_month[1].year,books_by_month[1].month) books_by_month[1].year,books_by_month[1].month)
navPointByLetterTag.insert(1,contentTag) navPointByMonthTag.insert(1,contentTag)
if self.generateForKindle: if self.generateForKindle:
cmTag = Tag(soup, '%s' % 'calibre:meta') cmTag = Tag(soup, '%s' % 'calibre:meta')
cmTag['name'] = "description" cmTag['name'] = "description"
cmTag.insert(0, NavigableString(books_by_month[0])) cmTag.insert(0, NavigableString(books_by_month[0]))
navPointByLetterTag.insert(2, cmTag) navPointByMonthTag.insert(2, cmTag)
navPointTag.insert(nptc, navPointByLetterTag) navPointTag.insert(nptc, navPointByMonthTag)
nptc += 1 nptc += 1
# Add this section to the body # Add this section to the body
@ -2127,12 +2082,15 @@ class EPUB_MOBI(CatalogPlugin):
btc += 1 btc += 1
self.ncxSoup = soup self.ncxSoup = soup
def generateNCXByTags(self, tocTitle): def generateNCXByGenre(self, tocTitle):
# Create an NCX section for 'By Genre' # Create an NCX section for 'By Genre'
# Add each genre as an article # Add each genre as an article
# 'tag', 'file', 'authors' # 'tag', 'file', 'authors'
self.opts.log.info(self.updateProgressFullStep("generateNCXByTags()")) self.updateProgressFullStep("NCX by Genre")
if not len(self.genres): if not len(self.genres):
self.opts.log.warn(" No genres found in tags.\n" self.opts.log.warn(" No genres found in tags.\n"
@ -2214,7 +2172,7 @@ class EPUB_MOBI(CatalogPlugin):
for title in genre['books']: for title in genre['books']:
titles.append(title['title']) titles.append(title['title'])
titles = sorted(titles, key=lambda x:(self.generateSortTitle(x),self.generateSortTitle(x))) titles = sorted(titles, key=lambda x:(self.generateSortTitle(x),self.generateSortTitle(x)))
titles_list = self.generateShortDescription(" &bull; ".join(titles)) titles_list = self.generateShortDescription(u" &bull; ".join(titles))
cmTag.insert(0, NavigableString(self.formatNCXText(titles_list))) cmTag.insert(0, NavigableString(self.formatNCXText(titles_list)))
navPointVolumeTag.insert(3, cmTag) navPointVolumeTag.insert(3, cmTag)
@ -2230,8 +2188,7 @@ class EPUB_MOBI(CatalogPlugin):
self.ncxSoup = ncx_soup self.ncxSoup = ncx_soup
def writeNCX(self): def writeNCX(self):
self.updateProgressFullStep("Writing NCX")
self.opts.log.info(self.updateProgressFullStep("writeNCX()"))
outfile = open("%s/%s.ncx" % (self.catalogPath, self.basename), 'w') outfile = open("%s/%s.ncx" % (self.catalogPath, self.basename), 'w')
outfile.write(self.ncxSoup.prettify()) outfile.write(self.ncxSoup.prettify())
@ -2318,9 +2275,9 @@ class EPUB_MOBI(CatalogPlugin):
else: else:
continue continue
if self.verbose: if self.verbose:
self.opts.log.info(' %d Genre tags in database (exclude_genre: %s):' % \ self.opts.log.info(u' %d Genre tags (exclude_genre: %s):' % \
(len(filtered_tags), self.opts.exclude_genre)) (len(filtered_tags), self.opts.exclude_genre))
self.opts.log.info(' %s' % ', '.join(filtered_tags)) self.opts.log.info(u' %s' % ', '.join(filtered_tags))
return filtered_tags return filtered_tags
@ -2524,7 +2481,6 @@ class EPUB_MOBI(CatalogPlugin):
def generateShortDescription(self, description): def generateShortDescription(self, description):
# Truncate the description to description_clip, on word boundaries if necessary # Truncate the description to description_clip, on word boundaries if necessary
if not description: if not description:
return None return None
@ -2536,7 +2492,7 @@ class EPUB_MOBI(CatalogPlugin):
# Start adding words until we reach description_clip # Start adding words until we reach description_clip
short_description = "" short_description = ""
words = description.split(" ") words = description.split()
for word in words: for word in words:
short_description += word + " " short_description += word + " "
if len(short_description) > self.descriptionClip: if len(short_description) > self.descriptionClip:
@ -2634,12 +2590,10 @@ class EPUB_MOBI(CatalogPlugin):
self.opts.log.info('%s not implemented' % self.error) self.opts.log.info('%s not implemented' % self.error)
def updateProgressFullStep(self, description): def updateProgressFullStep(self, description):
self.current_step += 1 self.current_step += 1
self.progressString = description self.progressString = description
self.progressInt = float((self.current_step-1)/self.total_steps) self.progressInt = float((self.current_step-1)/self.total_steps)
self.reporter(self.progressInt/100., self.progressString) self.reporter(self.progressInt, self.progressString)
return u"%.2f%% %s" % (self.progressInt, self.progressString)
def updateProgressMicroStep(self, description, micro_step_pct): def updateProgressMicroStep(self, description, micro_step_pct):
step_range = 100/self.total_steps step_range = 100/self.total_steps
@ -2647,46 +2601,46 @@ class EPUB_MOBI(CatalogPlugin):
coarse_progress = float((self.current_step-1)/self.total_steps) coarse_progress = float((self.current_step-1)/self.total_steps)
fine_progress = float((micro_step_pct*step_range)/100) fine_progress = float((micro_step_pct*step_range)/100)
self.progressInt = coarse_progress + fine_progress self.progressInt = coarse_progress + fine_progress
self.reporter(self.progressInt/100., self.progressString) self.reporter(self.progressInt, self.progressString)
return u"%.2f%% %s" % (self.progressInt, self.progressString)
def run(self, path_to_output, opts, db, notification=DummyReporter()): def run(self, path_to_output, opts, db, notification=DummyReporter()):
opts.log = log = Log() opts.log = log = Log()
opts.fmt = self.fmt = path_to_output.rpartition('.')[2] opts.fmt = self.fmt = path_to_output.rpartition('.')[2]
self.opts = opts self.opts = opts
# Add local options # Add local options
opts.creator = "calibre" opts.creator = "calibre"
opts.descriptionClip = 250 op = self.opts.output_profile
if op is None:
op = 'default'
opts.descriptionClip = 380 if op.endswith('dx') or 'kindle' not in op else 90
opts.basename = "Catalog" opts.basename = "Catalog"
opts.plugin_path = self.plugin_path opts.plugin_path = self.plugin_path
if opts.verbose: if opts.verbose:
opts_dict = vars(opts) opts_dict = vars(opts)
log("%s:run" % self.name) log("%s(): Generating %s for %s" % (self.name,self.fmt,opts.output_profile))
log(" path_to_output: %s" % path_to_output)
log(" Output format: %s" % self.fmt)
if opts_dict['ids']: if opts_dict['ids']:
log(" Book count: %d" % len(opts_dict['ids'])) log(" Book count: %d" % len(opts_dict['ids']))
# Display opts # Display opts
keys = opts_dict.keys() keys = opts_dict.keys()
keys.sort() keys.sort()
log(" opts:") log(" opts:")
for key in keys: for key in keys:
if key == 'ids': if key in ['catalog_title','exclude_genre','exclude_tags','note_tag',
if opts_dict[key]: 'numbers_as_text','read_tag','search_text','sort_by']:
continue log(" %s: %s" % (key, opts_dict[key]))
else:
log(" %s: (all)" % key)
log(" %s: %s" % (key, opts_dict[key]))
# Launch the Catalog builder # Launch the Catalog builder
catalog = self.CatalogBuilder(db, opts, self, notification=notification) catalog = self.CatalogBuilder(db, opts, self, report_progress=notification)
catalog.createDirectoryStructure() catalog.createDirectoryStructure()
catalog.copyResources() catalog.copyResources()
catalog.buildSources() catalog.buildSources()
if opts.verbose:
log.info("Catalog source generation complete")
recommendations = [] recommendations = []
dp = getattr(opts, 'debug_pipeline', None) dp = getattr(opts, 'debug_pipeline', None)