mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
More catalog tweaks
This commit is contained in:
commit
d69fd87023
@ -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;
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 = " • ".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 = " • ".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 = " • ".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 = " • ".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 = " • ".join(current_author_list)
|
add_to_author_list(current_author_list, current_letter)
|
||||||
if len(current_author_list) == self.descriptionClip:
|
|
||||||
author_list += " …"
|
|
||||||
|
|
||||||
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 = " • ".join(current_author_list)
|
add_to_author_list(current_author_list, current_letter)
|
||||||
if len(current_author_list) == self.descriptionClip:
|
|
||||||
author_list += " …"
|
|
||||||
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 = " • ".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 = " • ".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 = " • ".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(" • ".join(titles))
|
titles_list = self.generateShortDescription(u" • ".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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user