mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Catalog generation: Fixed improper title display in catalog when title contains ':'. Added 'ondevice' field to CSV/XML catalog output (only with connected device|folder|iTunes). Added optional 'Series' section to generated catalogs with hyperlinks between books and series. Tweaks to catalog formatting
This commit is contained in:
commit
336db024ae
@ -6,7 +6,7 @@ p.title {
|
|||||||
text-align:center;
|
text-align:center;
|
||||||
font-style:italic;
|
font-style:italic;
|
||||||
font-size:xx-large;
|
font-size:xx-large;
|
||||||
border-bottom: solid black 4px;
|
border-bottom: solid black 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.author {
|
p.author {
|
||||||
@ -17,6 +17,15 @@ p.author {
|
|||||||
font-size:large;
|
font-size:large;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.author_index {
|
||||||
|
font-size:large;
|
||||||
|
font-weight:bold;
|
||||||
|
text-align:left;
|
||||||
|
margin-top:0px;
|
||||||
|
margin-bottom:-2px;
|
||||||
|
text-indent: 0em;
|
||||||
|
}
|
||||||
|
|
||||||
p.tags {
|
p.tags {
|
||||||
margin-top:0em;
|
margin-top:0em;
|
||||||
margin-bottom:0em;
|
margin-bottom:0em;
|
||||||
@ -47,19 +56,12 @@ p.letter_index {
|
|||||||
margin-bottom:0px;
|
margin-bottom:0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.author_index {
|
|
||||||
font-size:large;
|
|
||||||
text-align:left;
|
|
||||||
margin-top:0px;
|
|
||||||
margin-bottom:0px;
|
|
||||||
text-indent: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.series {
|
p.series {
|
||||||
text-align: left;
|
font-style:italic;
|
||||||
margin-top:0px;
|
margin-top:2px;
|
||||||
margin-bottom:0px;
|
margin-bottom:0px;
|
||||||
margin-left:2em;
|
margin-left:2em;
|
||||||
|
text-align:left;
|
||||||
text-indent:-2em;
|
text-indent:-2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,11 +89,13 @@ p.date_read {
|
|||||||
text-indent:-6em;
|
text-indent:-6em;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr.series_divider {
|
hr.description_divider {
|
||||||
width:50%;
|
width:90%;
|
||||||
margin-left:1em;
|
margin-left:5%;
|
||||||
margin-top:0em;
|
border-top: solid white 0px;
|
||||||
margin-bottom:0em;
|
border-right: solid white 0px;
|
||||||
|
border-bottom: solid black 1px;
|
||||||
|
border-left: solid white 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr.annotations_divider {
|
hr.annotations_divider {
|
||||||
|
@ -294,7 +294,7 @@ class CatalogPlugin(Plugin): # {{{
|
|||||||
# Return a list of requested fields, with opts.sort_by first
|
# Return a list of requested fields, with opts.sort_by first
|
||||||
all_fields = set(
|
all_fields = set(
|
||||||
['author_sort','authors','comments','cover','formats',
|
['author_sort','authors','comments','cover','formats',
|
||||||
'id','isbn','pubdate','publisher','rating',
|
'id','isbn','ondevice','pubdate','publisher','rating',
|
||||||
'series_index','series','size','tags','timestamp',
|
'series_index','series','size','tags','timestamp',
|
||||||
'title','uuid'])
|
'title','uuid'])
|
||||||
|
|
||||||
@ -306,6 +306,9 @@ class CatalogPlugin(Plugin): # {{{
|
|||||||
else:
|
else:
|
||||||
fields = list(all_fields)
|
fields = list(all_fields)
|
||||||
|
|
||||||
|
if not opts.connected_device['is_device_connected'] and 'ondevice' in fields:
|
||||||
|
fields.pop(int(fields.index('ondevice')))
|
||||||
|
|
||||||
fields.sort()
|
fields.sort()
|
||||||
if opts.sort_by and opts.sort_by in fields:
|
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))))
|
||||||
|
@ -2303,9 +2303,9 @@ class ITUNES(DriverBase):
|
|||||||
# Delete existing from Device|Books, add to self.update_list
|
# Delete existing from Device|Books, add to self.update_list
|
||||||
# for deletion from booklist[0] during add_books_to_metadata
|
# for deletion from booklist[0] during add_books_to_metadata
|
||||||
for book in self.cached_books:
|
for book in self.cached_books:
|
||||||
if self.cached_books[book]['uuid'] == metadata.uuid and \
|
if self.cached_books[book]['uuid'] == metadata.uuid or \
|
||||||
self.cached_books[book]['title'] == metadata.title and \
|
(self.cached_books[book]['title'] == metadata.title and \
|
||||||
self.cached_books[book]['author'] == metadata.authors[0]:
|
self.cached_books[book]['author'] == metadata.authors[0]):
|
||||||
self.update_list.append(self.cached_books[book])
|
self.update_list.append(self.cached_books[book])
|
||||||
self._remove_from_device(self.cached_books[book])
|
self._remove_from_device(self.cached_books[book])
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
@ -2322,9 +2322,9 @@ class ITUNES(DriverBase):
|
|||||||
# Delete existing from Library|Books, add to self.update_list
|
# Delete existing from Library|Books, add to self.update_list
|
||||||
# for deletion from booklist[0] during add_books_to_metadata
|
# for deletion from booklist[0] during add_books_to_metadata
|
||||||
for book in self.cached_books:
|
for book in self.cached_books:
|
||||||
if self.cached_books[book]['uuid'] == metadata.uuid and \
|
if self.cached_books[book]['uuid'] == metadata.uuid or \
|
||||||
self.cached_books[book]['title'] == metadata.title and \
|
(self.cached_books[book]['title'] == metadata.title and \
|
||||||
self.cached_books[book]['author'] == metadata.authors[0]:
|
self.cached_books[book]['author'] == metadata.authors[0]):
|
||||||
self.update_list.append(self.cached_books[book])
|
self.update_list.append(self.cached_books[book])
|
||||||
self._remove_from_iTunes(self.cached_books[book])
|
self._remove_from_iTunes(self.cached_books[book])
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
@ -2488,7 +2488,7 @@ class ITUNES(DriverBase):
|
|||||||
zf_opf.close()
|
zf_opf.close()
|
||||||
|
|
||||||
# If 'News' in tags, tweak the title/author for friendlier display in iBooks
|
# If 'News' in tags, tweak the title/author for friendlier display in iBooks
|
||||||
if _('News') in metadata.tags:
|
if _('News') or _('Catalog') in metadata.tags:
|
||||||
if metadata.title.find('[') > 0:
|
if metadata.title.find('[') > 0:
|
||||||
metadata.title = metadata.title[:metadata.title.find('[')-1]
|
metadata.title = metadata.title[:metadata.title.find('[')-1]
|
||||||
date_as_author = '%s, %s %s, %s' % (strftime('%A'), strftime('%B'), strftime('%d').lstrip('0'), strftime('%Y'))
|
date_as_author = '%s, %s %s, %s' % (strftime('%A'), strftime('%B'), strftime('%d').lstrip('0'), strftime('%Y'))
|
||||||
|
@ -26,14 +26,18 @@ class GenerateCatalogAction(InterfaceAction):
|
|||||||
rows = xrange(self.gui.library_view.model().rowCount(QModelIndex()))
|
rows = xrange(self.gui.library_view.model().rowCount(QModelIndex()))
|
||||||
ids = map(self.gui.library_view.model().id, rows)
|
ids = map(self.gui.library_view.model().id, rows)
|
||||||
|
|
||||||
dbspec = None
|
|
||||||
if not ids:
|
if not ids:
|
||||||
return error_dialog(self.gui, _('No books selected'),
|
return error_dialog(self.gui, _('No books selected'),
|
||||||
_('No books selected to generate catalog for'),
|
_('No books selected to generate catalog for'),
|
||||||
show=True)
|
show=True)
|
||||||
|
|
||||||
|
db = self.gui.library_view.model().db
|
||||||
|
dbspec = {}
|
||||||
|
for id in ids:
|
||||||
|
dbspec[id] = {'ondevice': db.ondevice(id, index_is_id=True)}
|
||||||
|
|
||||||
# Calling gui2.tools:generate_catalog()
|
# Calling gui2.tools:generate_catalog()
|
||||||
ret = generate_catalog(self.gui, dbspec, ids, self.gui.device_manager.device)
|
ret = generate_catalog(self.gui, dbspec, ids, self.gui.device_manager)
|
||||||
if ret is None:
|
if ret is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ class PluginWidget(QWidget,Ui_Form):
|
|||||||
OPTION_FIELDS = [('exclude_genre','\[.+\]'),
|
OPTION_FIELDS = [('exclude_genre','\[.+\]'),
|
||||||
('exclude_tags','~,'+_('Catalog')),
|
('exclude_tags','~,'+_('Catalog')),
|
||||||
('generate_titles', True),
|
('generate_titles', True),
|
||||||
|
('generate_series', True),
|
||||||
('generate_recently_added', True),
|
('generate_recently_added', True),
|
||||||
('note_tag','*'),
|
('note_tag','*'),
|
||||||
('numbers_as_text', False),
|
('numbers_as_text', False),
|
||||||
@ -40,7 +41,7 @@ class PluginWidget(QWidget,Ui_Form):
|
|||||||
# Update dialog fields from stored options
|
# Update dialog fields from stored options
|
||||||
for opt in self.OPTION_FIELDS:
|
for opt in self.OPTION_FIELDS:
|
||||||
opt_value = gprefs.get(self.name + '_' + opt[0], opt[1])
|
opt_value = gprefs.get(self.name + '_' + opt[0], opt[1])
|
||||||
if opt[0] in ['numbers_as_text','generate_titles','generate_recently_added']:
|
if opt[0] in ['numbers_as_text','generate_titles','generate_series','generate_recently_added']:
|
||||||
getattr(self, opt[0]).setChecked(opt_value)
|
getattr(self, opt[0]).setChecked(opt_value)
|
||||||
else:
|
else:
|
||||||
getattr(self, opt[0]).setText(opt_value)
|
getattr(self, opt[0]).setText(opt_value)
|
||||||
@ -52,13 +53,13 @@ class PluginWidget(QWidget,Ui_Form):
|
|||||||
# others store as lists
|
# others store as lists
|
||||||
opts_dict = {}
|
opts_dict = {}
|
||||||
for opt in self.OPTION_FIELDS:
|
for opt in self.OPTION_FIELDS:
|
||||||
if opt[0] in ['numbers_as_text','generate_titles','generate_recently_added']:
|
if opt[0] in ['numbers_as_text','generate_titles','generate_series','generate_recently_added']:
|
||||||
opt_value = getattr(self,opt[0]).isChecked()
|
opt_value = getattr(self,opt[0]).isChecked()
|
||||||
else:
|
else:
|
||||||
opt_value = unicode(getattr(self, opt[0]).text())
|
opt_value = unicode(getattr(self, opt[0]).text())
|
||||||
gprefs.set(self.name + '_' + opt[0], opt_value)
|
gprefs.set(self.name + '_' + opt[0], opt_value)
|
||||||
|
|
||||||
if opt[0] in ['exclude_genre','numbers_as_text','generate_titles','generate_recently_added']:
|
if opt[0] in ['exclude_genre','numbers_as_text','generate_titles','generate_series','generate_recently_added']:
|
||||||
opts_dict[opt[0]] = opt_value
|
opts_dict[opt[0]] = opt_value
|
||||||
else:
|
else:
|
||||||
opts_dict[opt[0]] = opt_value.split(',')
|
opts_dict[opt[0]] = opt_value.split(',')
|
||||||
|
@ -108,20 +108,27 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="0">
|
<item row="10" column="0">
|
||||||
<widget class="QCheckBox" name="generate_recently_added">
|
<widget class="QCheckBox" name="generate_recently_added">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Include 'Recently Added' Section</string>
|
<string>Include 'Recently Added' Section</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="0">
|
<item row="11" column="0">
|
||||||
<widget class="QCheckBox" name="numbers_as_text">
|
<widget class="QCheckBox" name="numbers_as_text">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Sort numbers as text</string>
|
<string>Sort numbers as text</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="9" column="0">
|
||||||
|
<widget class="QCheckBox" name="generate_series">
|
||||||
|
<property name="text">
|
||||||
|
<string>Include 'Series' Section</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
@ -29,6 +29,7 @@ def gui_catalog(fmt, title, dbspec, ids, out_file_name, sync, fmt_options, conne
|
|||||||
log = Log()
|
log = Log()
|
||||||
from calibre.library import db
|
from calibre.library import db
|
||||||
db = db()
|
db = db()
|
||||||
|
db.catalog_plugin_on_device_temp_mapping = dbspec
|
||||||
|
|
||||||
# Create a minimal OptionParser that we can append to
|
# Create a minimal OptionParser that we can append to
|
||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
|
@ -238,7 +238,7 @@ def fetch_scheduled_recipe(arg):
|
|||||||
|
|
||||||
return 'gui_convert', args, _('Fetch news from ')+arg['title'], fmt.upper(), [pt]
|
return 'gui_convert', args, _('Fetch news from ')+arg['title'], fmt.upper(), [pt]
|
||||||
|
|
||||||
def generate_catalog(parent, dbspec, ids, device):
|
def generate_catalog(parent, dbspec, ids, device_manager):
|
||||||
from calibre.gui2.dialogs.catalog import Catalog
|
from calibre.gui2.dialogs.catalog import Catalog
|
||||||
|
|
||||||
# Build the Catalog dialog in gui2.dialogs.catalog
|
# Build the Catalog dialog in gui2.dialogs.catalog
|
||||||
@ -252,9 +252,18 @@ def generate_catalog(parent, dbspec, ids, device):
|
|||||||
|
|
||||||
# Profile the connected device
|
# Profile the connected device
|
||||||
# Parallel initialization in calibre.library.cli:command_catalog()
|
# Parallel initialization in calibre.library.cli:command_catalog()
|
||||||
connected_device = { 'storage':None,'serial':None,'save_template':None,'name':None}
|
connected_device = {
|
||||||
|
'is_device_connected': device_manager.is_device_connected,
|
||||||
|
'kind': device_manager.connected_device_kind,
|
||||||
|
'name': None,
|
||||||
|
'save_template': None,
|
||||||
|
'serial': None,
|
||||||
|
'storage': None
|
||||||
|
}
|
||||||
|
|
||||||
if device:
|
if device_manager.is_device_connected:
|
||||||
|
device = device_manager.device
|
||||||
|
connected_device['name'] = device.gui_name
|
||||||
try:
|
try:
|
||||||
storage = []
|
storage = []
|
||||||
if device._main_prefix:
|
if device._main_prefix:
|
||||||
@ -263,11 +272,10 @@ def generate_catalog(parent, dbspec, ids, device):
|
|||||||
storage.append(os.path.join(device._card_a_prefix, device.EBOOK_DIR_CARD_A))
|
storage.append(os.path.join(device._card_a_prefix, device.EBOOK_DIR_CARD_A))
|
||||||
if device._card_b_prefix:
|
if device._card_b_prefix:
|
||||||
storage.append(os.path.join(device._card_b_prefix, device.EBOOK_DIR_CARD_B))
|
storage.append(os.path.join(device._card_b_prefix, device.EBOOK_DIR_CARD_B))
|
||||||
connected_device = { 'storage': storage,
|
connected_device['storage'] = storage
|
||||||
'serial': device.detected_device.serial if \
|
connected_device['serial'] = device.detected_device.serial if \
|
||||||
hasattr(device.detected_device,'serial') else None,
|
hasattr(device.detected_device,'serial') else None
|
||||||
'save_template': device.save_template(),
|
connected_device['save_template'] = device.save_template()
|
||||||
'name': device.gui_name}
|
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ from calibre.utils.date import isoformat, now as nowf
|
|||||||
from calibre.utils.logging import default_log as log
|
from calibre.utils.logging import default_log as log
|
||||||
|
|
||||||
FIELDS = ['all', 'author_sort', 'authors', 'comments',
|
FIELDS = ['all', 'author_sort', 'authors', 'comments',
|
||||||
'cover', 'formats', 'id', 'isbn', 'pubdate', 'publisher', 'rating',
|
'cover', 'formats', 'id', 'isbn', 'ondevice', 'pubdate', 'publisher', 'rating',
|
||||||
'series_index', 'series', 'size', 'tags', 'timestamp', 'title',
|
'series_index', 'series', 'size', 'tags', 'timestamp', 'title',
|
||||||
'uuid']
|
'uuid']
|
||||||
|
|
||||||
@ -67,6 +67,8 @@ class CSV_XML(CatalogPlugin):
|
|||||||
if opts.verbose:
|
if opts.verbose:
|
||||||
opts_dict = vars(opts)
|
opts_dict = vars(opts)
|
||||||
log("%s(): Generating %s" % (self.name,self.fmt))
|
log("%s(): Generating %s" % (self.name,self.fmt))
|
||||||
|
if opts.connected_device['is_device_connected']:
|
||||||
|
log(" connected_device: %s" % opts.connected_device['name'])
|
||||||
if opts_dict['search_text']:
|
if opts_dict['search_text']:
|
||||||
log(" --search='%s'" % opts_dict['search_text'])
|
log(" --search='%s'" % opts_dict['search_text'])
|
||||||
|
|
||||||
@ -81,7 +83,6 @@ class CSV_XML(CatalogPlugin):
|
|||||||
else:
|
else:
|
||||||
log(" Fields: %s" % opts_dict['fields'])
|
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:
|
||||||
opts.search_text = None
|
opts.search_text = None
|
||||||
@ -95,6 +96,11 @@ class CSV_XML(CatalogPlugin):
|
|||||||
# Get the requested output fields as a list
|
# Get the requested output fields as a list
|
||||||
fields = self.get_output_fields(opts)
|
fields = self.get_output_fields(opts)
|
||||||
|
|
||||||
|
# If connected device, add 'On Device' values to data
|
||||||
|
if opts.connected_device['is_device_connected'] and 'ondevice' in fields:
|
||||||
|
for entry in data:
|
||||||
|
entry['ondevice'] = db.catalog_plugin_on_device_temp_mapping[entry['id']]['ondevice']
|
||||||
|
|
||||||
if self.fmt == 'csv':
|
if self.fmt == 'csv':
|
||||||
outfile = codecs.open(path_to_output, 'w', 'utf8')
|
outfile = codecs.open(path_to_output, 'w', 'utf8')
|
||||||
|
|
||||||
@ -140,10 +146,10 @@ class CSV_XML(CatalogPlugin):
|
|||||||
root.append(record)
|
root.append(record)
|
||||||
|
|
||||||
for field in ('id', 'uuid', 'title', 'publisher', 'rating', 'size',
|
for field in ('id', 'uuid', 'title', 'publisher', 'rating', 'size',
|
||||||
'isbn'):
|
'isbn','ondevice'):
|
||||||
if field in fields:
|
if field in fields:
|
||||||
val = r[field]
|
val = r[field]
|
||||||
if val is None:
|
if not val:
|
||||||
continue
|
continue
|
||||||
if not isinstance(val, (str, unicode)):
|
if not isinstance(val, (str, unicode)):
|
||||||
val = unicode(val)
|
val = unicode(val)
|
||||||
@ -561,6 +567,13 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
help=_("Include 'Titles' section in catalog.\n"
|
help=_("Include 'Titles' section in catalog.\n"
|
||||||
"Default: '%default'\n"
|
"Default: '%default'\n"
|
||||||
"Applies to: ePub, MOBI output formats")),
|
"Applies to: ePub, MOBI output formats")),
|
||||||
|
Option('--generate-series',
|
||||||
|
default=False,
|
||||||
|
dest='generate_series',
|
||||||
|
action = 'store_true',
|
||||||
|
help=_("Include 'Series' section in catalog.\n"
|
||||||
|
"Default: '%default'\n"
|
||||||
|
"Applies to: ePub, MOBI output formats")),
|
||||||
Option('--generate-recently-added',
|
Option('--generate-recently-added',
|
||||||
default=False,
|
default=False,
|
||||||
dest='generate_recently_added',
|
dest='generate_recently_added',
|
||||||
@ -886,8 +899,12 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
self.__totalSteps += 2
|
self.__totalSteps += 2
|
||||||
if self.generateRecentlyRead:
|
if self.generateRecentlyRead:
|
||||||
self.__totalSteps += 2
|
self.__totalSteps += 2
|
||||||
|
if self.opts.generate_series:
|
||||||
|
self.__totalSteps += 2
|
||||||
|
|
||||||
|
|
||||||
# Accessors
|
# Accessors
|
||||||
|
if True:
|
||||||
'''
|
'''
|
||||||
@dynamic_property
|
@dynamic_property
|
||||||
def xxxx(self):
|
def xxxx(self):
|
||||||
@ -897,7 +914,6 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
self.__ = val
|
self.__ = val
|
||||||
return property(fget=fget, fset=fset)
|
return property(fget=fget, fset=fset)
|
||||||
'''
|
'''
|
||||||
|
|
||||||
@dynamic_property
|
@dynamic_property
|
||||||
def authorClip(self):
|
def authorClip(self):
|
||||||
def fget(self):
|
def fget(self):
|
||||||
@ -1196,6 +1212,8 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
self.generateHTMLByAuthor()
|
self.generateHTMLByAuthor()
|
||||||
if self.opts.generate_titles:
|
if self.opts.generate_titles:
|
||||||
self.generateHTMLByTitle()
|
self.generateHTMLByTitle()
|
||||||
|
if self.opts.generate_series:
|
||||||
|
self.generateHTMLBySeries()
|
||||||
if self.opts.generate_recently_added:
|
if self.opts.generate_recently_added:
|
||||||
self.generateHTMLByDateAdded()
|
self.generateHTMLByDateAdded()
|
||||||
if self.generateRecentlyRead:
|
if self.generateRecentlyRead:
|
||||||
@ -1206,15 +1224,17 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
|
|
||||||
self.generateOPF()
|
self.generateOPF()
|
||||||
self.generateNCXHeader()
|
self.generateNCXHeader()
|
||||||
self.generateNCXDescriptions("Descriptions")
|
|
||||||
self.generateNCXByAuthor("Authors")
|
self.generateNCXByAuthor("Authors")
|
||||||
if self.opts.generate_titles:
|
if self.opts.generate_titles:
|
||||||
self.generateNCXByTitle("Titles")
|
self.generateNCXByTitle("Titles")
|
||||||
|
if self.opts.generate_series:
|
||||||
|
self.generateNCXBySeries("Series")
|
||||||
if self.opts.generate_recently_added:
|
if self.opts.generate_recently_added:
|
||||||
self.generateNCXByDateAdded("Recently Added")
|
self.generateNCXByDateAdded("Recently Added")
|
||||||
if self.generateRecentlyRead:
|
if self.generateRecentlyRead:
|
||||||
self.generateNCXByDateRead("Recently Read")
|
self.generateNCXByDateRead("Recently Read")
|
||||||
self.generateNCXByGenre("Genres")
|
self.generateNCXByGenre("Genres")
|
||||||
|
self.generateNCXDescriptions("Descriptions")
|
||||||
self.writeNCX()
|
self.writeNCX()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -1569,9 +1589,22 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
emTag = Tag(soup, "em")
|
emTag = Tag(soup, "em")
|
||||||
if title['series']:
|
if title['series']:
|
||||||
# title<br />series series_index
|
# title<br />series series_index
|
||||||
|
if self.opts.generate_series:
|
||||||
brTag = Tag(soup,'br')
|
brTag = Tag(soup,'br')
|
||||||
title_tokens = title['title'].split(': ')
|
title_tokens = list(title['title'].partition(':'))
|
||||||
emTag.insert(0, escape(NavigableString(title_tokens[1])))
|
emTag.insert(0, escape(NavigableString(title_tokens[2].strip())))
|
||||||
|
emTag.insert(1, brTag)
|
||||||
|
smallTag = Tag(soup,'small')
|
||||||
|
aTag = Tag(soup,'a')
|
||||||
|
aTag['href'] = "%s.html#%s_series" % ('BySeries',
|
||||||
|
re.sub('\W','',title['series']).lower())
|
||||||
|
aTag.insert(0, title_tokens[0])
|
||||||
|
smallTag.insert(0, aTag)
|
||||||
|
emTag.insert(2, smallTag)
|
||||||
|
else:
|
||||||
|
brTag = Tag(soup,'br')
|
||||||
|
title_tokens = list(title['title'].partition(':'))
|
||||||
|
emTag.insert(0, escape(NavigableString(title_tokens[2].strip())))
|
||||||
emTag.insert(1, brTag)
|
emTag.insert(1, brTag)
|
||||||
smallTag = Tag(soup,'small')
|
smallTag = Tag(soup,'small')
|
||||||
smallTag.insert(0, escape(NavigableString(title_tokens[0])))
|
smallTag.insert(0, escape(NavigableString(title_tokens[0])))
|
||||||
@ -1724,17 +1757,17 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
body.insert(btc, aTag)
|
body.insert(btc, aTag)
|
||||||
btc += 1
|
btc += 1
|
||||||
|
|
||||||
'''
|
if not self.__generateForKindle:
|
||||||
# We don't need this because the Kindle shows section titles
|
# We don't need this because the Kindle shows section titles
|
||||||
#<h2><a name="byalphatitle" id="byalphatitle"></a>By Title</h2>
|
#<h2><a name="byalphatitle" id="byalphatitle"></a>By Title</h2>
|
||||||
h2Tag = Tag(soup, "h2")
|
pTag = Tag(soup, "p")
|
||||||
|
pTag['class'] = 'title'
|
||||||
aTag = Tag(soup, "a")
|
aTag = Tag(soup, "a")
|
||||||
aTag['name'] = "bytitle"
|
aTag['name'] = "bytitle"
|
||||||
h2Tag.insert(0,aTag)
|
pTag.insert(0,aTag)
|
||||||
h2Tag.insert(1,NavigableString('By Title (%d)' % len(self.booksByTitle)))
|
pTag.insert(1,NavigableString('Titles'))
|
||||||
body.insert(btc,h2Tag)
|
body.insert(btc,pTag)
|
||||||
btc += 1
|
btc += 1
|
||||||
'''
|
|
||||||
|
|
||||||
# <p class="letter_index">
|
# <p class="letter_index">
|
||||||
# <p class="book_title">
|
# <p class="book_title">
|
||||||
@ -1742,13 +1775,13 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
dtc = 0
|
dtc = 0
|
||||||
current_letter = ""
|
current_letter = ""
|
||||||
|
|
||||||
# 2/14/10 7:11 AM Experimental: re-sort title list without leading series/series_index
|
# Re-sort title list without leading series/series_index
|
||||||
if not self.useSeriesPrefixInTitlesSection:
|
if not self.useSeriesPrefixInTitlesSection:
|
||||||
nspt = deepcopy(self.booksByTitle)
|
nspt = deepcopy(self.booksByTitle)
|
||||||
for book in nspt:
|
for book in nspt:
|
||||||
if book['series']:
|
if book['series']:
|
||||||
tokens = book['title'].split(': ')
|
tokens = book['title'].partition(':')
|
||||||
book['title'] = '%s (%s)' % (tokens[1], tokens[0])
|
book['title'] = '%s (%s)' % (tokens[2].strip(), tokens[0])
|
||||||
book['title_sort'] = self.generateSortTitle(book['title'])
|
book['title_sort'] = self.generateSortTitle(book['title'])
|
||||||
nspt = sorted(nspt,
|
nspt = sorted(nspt,
|
||||||
key=lambda x:(x['title_sort'].upper(), x['title_sort'].upper()))
|
key=lambda x:(x['title_sort'].upper(), x['title_sort'].upper()))
|
||||||
@ -1835,7 +1868,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
# Write books by author A-Z
|
# Write books by author A-Z
|
||||||
self.updateProgressFullStep("'Authors'")
|
self.updateProgressFullStep("'Authors'")
|
||||||
|
|
||||||
friendly_name = "By Author"
|
friendly_name = "Authors"
|
||||||
|
|
||||||
soup = self.generateHTMLEmptyHeader(friendly_name)
|
soup = self.generateHTMLEmptyHeader(friendly_name)
|
||||||
body = soup.find('body')
|
body = soup.find('body')
|
||||||
@ -1906,15 +1939,14 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
current_series = None
|
current_series = None
|
||||||
pAuthorTag = Tag(soup, "p")
|
pAuthorTag = Tag(soup, "p")
|
||||||
pAuthorTag['class'] = "author_index"
|
pAuthorTag['class'] = "author_index"
|
||||||
emTag = Tag(soup, "em")
|
|
||||||
aTag = Tag(soup, "a")
|
aTag = Tag(soup, "a")
|
||||||
aTag['name'] = "%s" % self.generateAuthorAnchor(current_author)
|
aTag['name'] = "%s" % self.generateAuthorAnchor(current_author)
|
||||||
aTag.insert(0,NavigableString(current_author))
|
aTag.insert(0,NavigableString(current_author))
|
||||||
emTag.insert(0,aTag)
|
pAuthorTag.insert(0,aTag)
|
||||||
pAuthorTag.insert(0,emTag)
|
|
||||||
divTag.insert(dtc,pAuthorTag)
|
divTag.insert(dtc,pAuthorTag)
|
||||||
dtc += 1
|
dtc += 1
|
||||||
|
|
||||||
|
'''
|
||||||
# Insert an <hr /> between non-series and series
|
# Insert an <hr /> between non-series and series
|
||||||
if not current_series and non_series_books and book['series']:
|
if not current_series and non_series_books and book['series']:
|
||||||
# Insert an <hr />
|
# Insert an <hr />
|
||||||
@ -1922,6 +1954,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
hrTag['class'] = "series_divider"
|
hrTag['class'] = "series_divider"
|
||||||
divTag.insert(dtc,hrTag)
|
divTag.insert(dtc,hrTag)
|
||||||
dtc += 1
|
dtc += 1
|
||||||
|
'''
|
||||||
|
|
||||||
# Check for series
|
# Check for series
|
||||||
if book['series'] and book['series'] != current_series:
|
if book['series'] and book['series'] != current_series:
|
||||||
@ -1929,7 +1962,18 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
current_series = book['series']
|
current_series = book['series']
|
||||||
pSeriesTag = Tag(soup,'p')
|
pSeriesTag = Tag(soup,'p')
|
||||||
pSeriesTag['class'] = "series"
|
pSeriesTag['class'] = "series"
|
||||||
pSeriesTag.insert(0,NavigableString(self.NOT_READ_SYMBOL + book['series']))
|
|
||||||
|
if self.opts.generate_series:
|
||||||
|
aTag = Tag(soup,'a')
|
||||||
|
aTag['href'] = "%s.html#%s_series" % ('BySeries',
|
||||||
|
re.sub('\W','',book['series']).lower())
|
||||||
|
aTag.insert(0, book['series'])
|
||||||
|
#pSeriesTag.insert(0, NavigableString(self.NOT_READ_SYMBOL))
|
||||||
|
pSeriesTag.insert(0, aTag)
|
||||||
|
else:
|
||||||
|
#pSeriesTag.insert(0,NavigableString(self.NOT_READ_SYMBOL + '%s' % book['series']))
|
||||||
|
pSeriesTag.insert(0,NavigableString('%s' % book['series']))
|
||||||
|
|
||||||
divTag.insert(dtc,pSeriesTag)
|
divTag.insert(dtc,pSeriesTag)
|
||||||
dtc += 1
|
dtc += 1
|
||||||
if current_series and not book['series']:
|
if current_series and not book['series']:
|
||||||
@ -1957,30 +2001,34 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
|
|
||||||
aTag = Tag(soup, "a")
|
aTag = Tag(soup, "a")
|
||||||
aTag['href'] = "book_%d.html" % (int(float(book['id'])))
|
aTag['href'] = "book_%d.html" % (int(float(book['id'])))
|
||||||
# Use series, series index if avail else just title
|
# Use series, series index if avail else just title, + year of publication
|
||||||
if current_series:
|
if current_series:
|
||||||
aTag.insert(0,escape(book['title'][len(book['series'])+1:]))
|
aTag.insert(0,'%s (%s)' % (escape(book['title'][len(book['series'])+1:]),
|
||||||
|
book['date'].split()[1]))
|
||||||
else:
|
else:
|
||||||
aTag.insert(0,escape(book['title']))
|
aTag.insert(0,'%s (%s)' % (escape(book['title']),
|
||||||
|
book['date'].split()[1]))
|
||||||
non_series_books += 1
|
non_series_books += 1
|
||||||
pBookTag.insert(ptc, aTag)
|
pBookTag.insert(ptc, aTag)
|
||||||
ptc += 1
|
ptc += 1
|
||||||
|
|
||||||
|
|
||||||
divTag.insert(dtc, pBookTag)
|
divTag.insert(dtc, pBookTag)
|
||||||
dtc += 1
|
dtc += 1
|
||||||
|
|
||||||
'''
|
if not self.__generateForKindle:
|
||||||
# Insert the <h2> tag with book_count at the head
|
# Insert the <h2> tag with book_count at the head
|
||||||
#<h2><a name="byalphaauthor" id="byalphaauthor"></a>By Author</h2>
|
#<h2><a name="byalphaauthor" id="byalphaauthor"></a>By Author</h2>
|
||||||
h2Tag = Tag(soup, "h2")
|
pTag = Tag(soup, "p")
|
||||||
|
pTag['class'] = 'title'
|
||||||
aTag = Tag(soup, "a")
|
aTag = Tag(soup, "a")
|
||||||
anchor_name = friendly_name.lower()
|
anchor_name = friendly_name.lower()
|
||||||
aTag['name'] = anchor_name.replace(" ","")
|
aTag['name'] = anchor_name.replace(" ","")
|
||||||
h2Tag.insert(0,aTag)
|
pTag.insert(0,aTag)
|
||||||
h2Tag.insert(1,NavigableString('%s (%d)' % (friendly_name, book_count)))
|
#h2Tag.insert(1,NavigableString('%s (%d)' % (friendly_name, book_count)))
|
||||||
body.insert(btc,h2Tag)
|
pTag.insert(1,NavigableString('%s' % (friendly_name)))
|
||||||
|
body.insert(btc,pTag)
|
||||||
btc += 1
|
btc += 1
|
||||||
'''
|
|
||||||
|
|
||||||
# Add the divTag to the body
|
# Add the divTag to the body
|
||||||
body.insert(btc, divTag)
|
body.insert(btc, divTag)
|
||||||
@ -2023,15 +2071,14 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
current_series = None
|
current_series = None
|
||||||
pAuthorTag = Tag(soup, "p")
|
pAuthorTag = Tag(soup, "p")
|
||||||
pAuthorTag['class'] = "author_index"
|
pAuthorTag['class'] = "author_index"
|
||||||
emTag = Tag(soup, "em")
|
|
||||||
aTag = Tag(soup, "a")
|
aTag = Tag(soup, "a")
|
||||||
aTag['name'] = "%s" % self.generateAuthorAnchor(current_author)
|
aTag['name'] = "%s" % self.generateAuthorAnchor(current_author)
|
||||||
aTag.insert(0,NavigableString(current_author))
|
aTag.insert(0,NavigableString(current_author))
|
||||||
emTag.insert(0,aTag)
|
pAuthorTag.insert(0,aTag)
|
||||||
pAuthorTag.insert(0,emTag)
|
|
||||||
divTag.insert(dtc,pAuthorTag)
|
divTag.insert(dtc,pAuthorTag)
|
||||||
dtc += 1
|
dtc += 1
|
||||||
|
|
||||||
|
'''
|
||||||
# Insert an <hr /> between non-series and series
|
# Insert an <hr /> between non-series and series
|
||||||
if not current_series and non_series_books and new_entry['series']:
|
if not current_series and non_series_books and new_entry['series']:
|
||||||
# Insert an <hr />
|
# Insert an <hr />
|
||||||
@ -2039,6 +2086,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
hrTag['class'] = "series_divider"
|
hrTag['class'] = "series_divider"
|
||||||
divTag.insert(dtc,hrTag)
|
divTag.insert(dtc,hrTag)
|
||||||
dtc += 1
|
dtc += 1
|
||||||
|
'''
|
||||||
|
|
||||||
# Check for series
|
# Check for series
|
||||||
if new_entry['series'] and new_entry['series'] != current_series:
|
if new_entry['series'] and new_entry['series'] != current_series:
|
||||||
@ -2046,7 +2094,14 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
current_series = new_entry['series']
|
current_series = new_entry['series']
|
||||||
pSeriesTag = Tag(soup,'p')
|
pSeriesTag = Tag(soup,'p')
|
||||||
pSeriesTag['class'] = "series"
|
pSeriesTag['class'] = "series"
|
||||||
pSeriesTag.insert(0,NavigableString(self.NOT_READ_SYMBOL + new_entry['series']))
|
if self.opts.generate_series:
|
||||||
|
aTag = Tag(soup,'a')
|
||||||
|
aTag['href'] = "%s.html#%s_series" % ('BySeries',
|
||||||
|
re.sub('\W','',new_entry['series']).lower())
|
||||||
|
aTag.insert(0, new_entry['series'])
|
||||||
|
pSeriesTag.insert(0, aTag)
|
||||||
|
else:
|
||||||
|
pSeriesTag.insert(0,NavigableString('%s' % new_entry['series']))
|
||||||
divTag.insert(dtc,pSeriesTag)
|
divTag.insert(dtc,pSeriesTag)
|
||||||
dtc += 1
|
dtc += 1
|
||||||
if current_series and not new_entry['series']:
|
if current_series and not new_entry['series']:
|
||||||
@ -2160,18 +2215,18 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
aTag['name'] = anchor_name.replace(" ","")
|
aTag['name'] = anchor_name.replace(" ","")
|
||||||
body.insert(btc, aTag)
|
body.insert(btc, aTag)
|
||||||
btc += 1
|
btc += 1
|
||||||
'''
|
|
||||||
# We don't need this because the kindle inserts section titles
|
if not self.__generateForKindle:
|
||||||
#<h2><a name="byalphaauthor" id="byalphaauthor"></a>By Author</h2>
|
#<h2><a name="byalphaauthor" id="byalphaauthor"></a>By Author</h2>
|
||||||
h2Tag = Tag(soup, "h2")
|
pTag = Tag(soup, "p")
|
||||||
|
pTag['class'] = 'title'
|
||||||
aTag = Tag(soup, "a")
|
aTag = Tag(soup, "a")
|
||||||
anchor_name = friendly_name.lower()
|
anchor_name = friendly_name.lower()
|
||||||
aTag['name'] = anchor_name.replace(" ","")
|
aTag['name'] = anchor_name.replace(" ","")
|
||||||
h2Tag.insert(0,aTag)
|
pTag.insert(0,aTag)
|
||||||
h2Tag.insert(1,NavigableString('%s' % friendly_name))
|
pTag.insert(1,NavigableString('%s' % friendly_name))
|
||||||
body.insert(btc,h2Tag)
|
body.insert(btc,pTag)
|
||||||
btc += 1
|
btc += 1
|
||||||
'''
|
|
||||||
|
|
||||||
# <p class="letter_index">
|
# <p class="letter_index">
|
||||||
# <p class="author_index">
|
# <p class="author_index">
|
||||||
@ -2186,14 +2241,13 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
nspt = deepcopy(self.booksByTitle)
|
nspt = deepcopy(self.booksByTitle)
|
||||||
for book in nspt:
|
for book in nspt:
|
||||||
if book['series']:
|
if book['series']:
|
||||||
tokens = book['title'].split(': ')
|
tokens = book['title'].partition(':')
|
||||||
book['title'] = '%s (%s)' % (tokens[1], tokens[0])
|
book['title'] = '%s (%s)' % (tokens[2].strip(), tokens[0])
|
||||||
book['title_sort'] = self.generateSortTitle(book['title'])
|
book['title_sort'] = self.generateSortTitle(book['title'])
|
||||||
self.booksByDateRange = sorted(nspt, key=lambda x:(x['timestamp'], x['timestamp']),reverse=True)
|
self.booksByDateRange = sorted(nspt, key=lambda x:(x['timestamp'], x['timestamp']),reverse=True)
|
||||||
|
|
||||||
date_range_list = []
|
date_range_list = []
|
||||||
today_time = nowf().replace(hour=23, minute=59, second=59)
|
today_time = nowf().replace(hour=23, minute=59, second=59)
|
||||||
books_added_in_date_range = False
|
|
||||||
for (i, date) in enumerate(self.DATE_RANGE):
|
for (i, date) in enumerate(self.DATE_RANGE):
|
||||||
date_range_limit = self.DATE_RANGE[i]
|
date_range_limit = self.DATE_RANGE[i]
|
||||||
if i:
|
if i:
|
||||||
@ -2206,18 +2260,20 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
delta = today_time-book_time
|
delta = today_time-book_time
|
||||||
if delta.days <= date_range_limit:
|
if delta.days <= date_range_limit:
|
||||||
date_range_list.append(book)
|
date_range_list.append(book)
|
||||||
books_added_in_date_range = True
|
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
dtc = add_books_to_HTML_by_date_range(date_range_list, date_range, dtc)
|
dtc = add_books_to_HTML_by_date_range(date_range_list, date_range, dtc)
|
||||||
date_range_list = [book]
|
date_range_list = [book]
|
||||||
|
|
||||||
|
'''
|
||||||
if books_added_in_date_range:
|
if books_added_in_date_range:
|
||||||
# Add an <hr> separating date ranges from months
|
# Add an <hr> separating date ranges from months
|
||||||
hrTag = Tag(soup,'hr')
|
hrTag = Tag(soup,'hr')
|
||||||
|
hrTag['class'] = "description_divider"
|
||||||
divTag.insert(dtc,hrTag)
|
divTag.insert(dtc,hrTag)
|
||||||
dtc += 1
|
dtc += 1
|
||||||
|
'''
|
||||||
|
|
||||||
# >>>> Books by month <<<<
|
# >>>> Books by month <<<<
|
||||||
# Sort titles case-insensitive for by month using series prefix
|
# Sort titles case-insensitive for by month using series prefix
|
||||||
@ -2437,6 +2493,174 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
outfile.close()
|
outfile.close()
|
||||||
self.htmlFileList.append("content/ByDateRead.html")
|
self.htmlFileList.append("content/ByDateRead.html")
|
||||||
|
|
||||||
|
def generateHTMLBySeries(self):
|
||||||
|
'''
|
||||||
|
Generate a list of series
|
||||||
|
'''
|
||||||
|
self.updateProgressFullStep("Fetching series")
|
||||||
|
|
||||||
|
self.opts.sort_by = 'series'
|
||||||
|
|
||||||
|
# Merge opts.exclude_tags with opts.search_text
|
||||||
|
# Updated to use exact match syntax
|
||||||
|
empty_exclude_tags = False if len(self.opts.exclude_tags) else True
|
||||||
|
search_phrase = 'series:true '
|
||||||
|
if not empty_exclude_tags:
|
||||||
|
exclude_tags = self.opts.exclude_tags.split(',')
|
||||||
|
search_terms = []
|
||||||
|
for tag in exclude_tags:
|
||||||
|
search_terms.append("tag:=%s" % tag)
|
||||||
|
search_phrase += "not (%s)" % " or ".join(search_terms)
|
||||||
|
|
||||||
|
# If a list of ids are provided, don't use search_text
|
||||||
|
if self.opts.ids:
|
||||||
|
self.opts.search_text = search_phrase
|
||||||
|
else:
|
||||||
|
if self.opts.search_text:
|
||||||
|
self.opts.search_text += " " + search_phrase
|
||||||
|
else:
|
||||||
|
self.opts.search_text = search_phrase
|
||||||
|
|
||||||
|
# Fetch the database as a dictionary
|
||||||
|
self.booksBySeries = self.plugin.search_sort_db(self.db, self.opts)
|
||||||
|
|
||||||
|
friendly_name = "Series"
|
||||||
|
|
||||||
|
soup = self.generateHTMLEmptyHeader(friendly_name)
|
||||||
|
body = soup.find('body')
|
||||||
|
|
||||||
|
btc = 0
|
||||||
|
|
||||||
|
# Insert section tag
|
||||||
|
aTag = Tag(soup,'a')
|
||||||
|
aTag['name'] = 'section_start'
|
||||||
|
body.insert(btc, aTag)
|
||||||
|
btc += 1
|
||||||
|
|
||||||
|
# Insert the anchor
|
||||||
|
aTag = Tag(soup, "a")
|
||||||
|
anchor_name = friendly_name.lower()
|
||||||
|
aTag['name'] = anchor_name.replace(" ","")
|
||||||
|
body.insert(btc, aTag)
|
||||||
|
btc += 1
|
||||||
|
|
||||||
|
# <p class="letter_index">
|
||||||
|
# <p class="author_index">
|
||||||
|
divTag = Tag(soup, "div")
|
||||||
|
dtc = 0
|
||||||
|
current_letter = ""
|
||||||
|
current_series = None
|
||||||
|
|
||||||
|
# Loop through booksBySeries
|
||||||
|
series_count = 0
|
||||||
|
for book in self.booksBySeries:
|
||||||
|
# Check for initial letter change
|
||||||
|
sort_title = self.generateSortTitle(book['series'])
|
||||||
|
if self.letter_or_symbol(sort_title[0].upper()) != current_letter :
|
||||||
|
'''
|
||||||
|
# Start a new letter - anchor only, hidden
|
||||||
|
current_letter = book['author_sort'][0].upper()
|
||||||
|
aTag = Tag(soup, "a")
|
||||||
|
aTag['name'] = "%sseries" % current_letter
|
||||||
|
divTag.insert(dtc, aTag)
|
||||||
|
dtc += 1
|
||||||
|
'''
|
||||||
|
# Start a new letter with Index letter
|
||||||
|
current_letter = self.letter_or_symbol(sort_title[0].upper())
|
||||||
|
pIndexTag = Tag(soup, "p")
|
||||||
|
pIndexTag['class'] = "letter_index"
|
||||||
|
aTag = Tag(soup, "a")
|
||||||
|
aTag['name'] = "%s_series" % self.letter_or_symbol(current_letter)
|
||||||
|
pIndexTag.insert(0,aTag)
|
||||||
|
pIndexTag.insert(1,NavigableString(self.letter_or_symbol(sort_title[0].upper())))
|
||||||
|
divTag.insert(dtc,pIndexTag)
|
||||||
|
dtc += 1
|
||||||
|
|
||||||
|
# Check for series change
|
||||||
|
if book['series'] != current_series:
|
||||||
|
# Start a new series
|
||||||
|
series_count += 1
|
||||||
|
current_series = book['series']
|
||||||
|
pSeriesTag = Tag(soup,'p')
|
||||||
|
pSeriesTag['class'] = "series"
|
||||||
|
aTag = Tag(soup, 'a')
|
||||||
|
aTag['name'] = "%s_series" % re.sub('\W','',book['series']).lower()
|
||||||
|
pSeriesTag.insert(0,aTag)
|
||||||
|
pSeriesTag.insert(1,NavigableString(self.NOT_READ_SYMBOL + '%s' % book['series']))
|
||||||
|
divTag.insert(dtc,pSeriesTag)
|
||||||
|
dtc += 1
|
||||||
|
|
||||||
|
# Add books
|
||||||
|
pBookTag = Tag(soup, "p")
|
||||||
|
ptc = 0
|
||||||
|
|
||||||
|
# book with read/reading/unread symbol
|
||||||
|
if 'read' in book and book['read']:
|
||||||
|
# check mark
|
||||||
|
pBookTag.insert(ptc,NavigableString(self.READ_SYMBOL))
|
||||||
|
pBookTag['class'] = "read_book"
|
||||||
|
ptc += 1
|
||||||
|
elif book['id'] in self.bookmarked_books:
|
||||||
|
pBookTag.insert(ptc,NavigableString(self.READING_SYMBOL))
|
||||||
|
pBookTag['class'] = "read_book"
|
||||||
|
ptc += 1
|
||||||
|
else:
|
||||||
|
# hidden check mark
|
||||||
|
pBookTag['class'] = "unread_book"
|
||||||
|
pBookTag.insert(ptc,NavigableString(self.NOT_READ_SYMBOL))
|
||||||
|
ptc += 1
|
||||||
|
|
||||||
|
aTag = Tag(soup, "a")
|
||||||
|
aTag['href'] = "book_%d.html" % (int(float(book['id'])))
|
||||||
|
# Use series, series index if avail else just title
|
||||||
|
#aTag.insert(0,'%d. %s · %s' % (book['series_index'],escape(book['title']), ' & '.join(book['authors'])))
|
||||||
|
|
||||||
|
# Link to book
|
||||||
|
aTag.insert(0,'%d. %s (%s)' % (book['series_index'],
|
||||||
|
escape(book['title']),
|
||||||
|
strftime(u'%Y', book['pubdate'].timetuple())))
|
||||||
|
pBookTag.insert(ptc, aTag)
|
||||||
|
ptc += 1
|
||||||
|
|
||||||
|
# ·
|
||||||
|
pBookTag.insert(ptc, NavigableString(' · '))
|
||||||
|
ptc += 1
|
||||||
|
|
||||||
|
# Link to author
|
||||||
|
aTag = Tag(soup, "a")
|
||||||
|
aTag['href'] = "%s.html#%s" % ("ByAlphaAuthor",
|
||||||
|
self.generateAuthorAnchor(escape(' & '.join(book['authors']))))
|
||||||
|
aTag.insert(0, NavigableString(' & '.join(book['authors'])))
|
||||||
|
pBookTag.insert(ptc, aTag)
|
||||||
|
ptc += 1
|
||||||
|
|
||||||
|
divTag.insert(dtc, pBookTag)
|
||||||
|
dtc += 1
|
||||||
|
|
||||||
|
if not self.__generateForKindle:
|
||||||
|
# Insert the <h2> tag with book_count at the head
|
||||||
|
#<h2><a name="byseries" id="byseries"></a>By Series</h2>
|
||||||
|
pTag = Tag(soup, "p")
|
||||||
|
pTag['class'] = 'title'
|
||||||
|
aTag = Tag(soup, "a")
|
||||||
|
anchor_name = friendly_name.lower()
|
||||||
|
aTag['name'] = anchor_name.replace(" ","")
|
||||||
|
pTag.insert(0,aTag)
|
||||||
|
#h2Tag.insert(1,NavigableString('%s (%d)' % (friendly_name, series_count)))
|
||||||
|
pTag.insert(1,NavigableString('%s' % friendly_name))
|
||||||
|
body.insert(btc,pTag)
|
||||||
|
btc += 1
|
||||||
|
|
||||||
|
# Add the divTag to the body
|
||||||
|
body.insert(btc, divTag)
|
||||||
|
|
||||||
|
# Write the generated file to contentdir
|
||||||
|
outfile_spec = "%s/BySeries.html" % (self.contentDir)
|
||||||
|
outfile = open(outfile_spec, 'w')
|
||||||
|
outfile.write(soup.prettify())
|
||||||
|
outfile.close()
|
||||||
|
self.htmlFileList.append("content/BySeries.html")
|
||||||
|
|
||||||
def generateHTMLByTags(self):
|
def generateHTMLByTags(self):
|
||||||
# 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[]
|
||||||
@ -2683,22 +2907,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
# HTML files - add books to manifest and spine
|
# HTML files - add books to manifest and spine
|
||||||
sort_descriptions_by = self.booksByAuthor if self.opts.sort_descriptions_by_author \
|
sort_descriptions_by = self.booksByAuthor if self.opts.sort_descriptions_by_author \
|
||||||
else self.booksByTitle
|
else self.booksByTitle
|
||||||
for book in sort_descriptions_by:
|
# Add html_files to manifest and spine
|
||||||
# manifest
|
|
||||||
itemTag = Tag(soup, "item")
|
|
||||||
itemTag['href'] = "content/book_%d.html" % int(book['id'])
|
|
||||||
itemTag['id'] = "book%d" % int(book['id'])
|
|
||||||
itemTag['media-type'] = "application/xhtml+xml"
|
|
||||||
manifest.insert(mtc, itemTag)
|
|
||||||
mtc += 1
|
|
||||||
|
|
||||||
# spine
|
|
||||||
itemrefTag = Tag(soup, "itemref")
|
|
||||||
itemrefTag['idref'] = "book%d" % int(book['id'])
|
|
||||||
spine.insert(stc, itemrefTag)
|
|
||||||
stc += 1
|
|
||||||
|
|
||||||
# Add other html_files to manifest and spine
|
|
||||||
|
|
||||||
for file in self.htmlFileList:
|
for file in self.htmlFileList:
|
||||||
itemTag = Tag(soup, "item")
|
itemTag = Tag(soup, "item")
|
||||||
@ -2734,6 +2943,21 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
spine.insert(stc, itemrefTag)
|
spine.insert(stc, itemrefTag)
|
||||||
stc += 1
|
stc += 1
|
||||||
|
|
||||||
|
for book in sort_descriptions_by:
|
||||||
|
# manifest
|
||||||
|
itemTag = Tag(soup, "item")
|
||||||
|
itemTag['href'] = "content/book_%d.html" % int(book['id'])
|
||||||
|
itemTag['id'] = "book%d" % int(book['id'])
|
||||||
|
itemTag['media-type'] = "application/xhtml+xml"
|
||||||
|
manifest.insert(mtc, itemTag)
|
||||||
|
mtc += 1
|
||||||
|
|
||||||
|
# spine
|
||||||
|
itemrefTag = Tag(soup, "itemref")
|
||||||
|
itemrefTag['idref'] = "book%d" % int(book['id'])
|
||||||
|
spine.insert(stc, itemrefTag)
|
||||||
|
stc += 1
|
||||||
|
|
||||||
# Guide
|
# Guide
|
||||||
referenceTag = Tag(soup, "reference")
|
referenceTag = Tag(soup, "reference")
|
||||||
referenceTag['type'] = 'masthead'
|
referenceTag['type'] = 'masthead'
|
||||||
@ -2769,7 +2993,8 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
navLabelTag.insert(0, textTag)
|
navLabelTag.insert(0, textTag)
|
||||||
navPointTag.insert(0, navLabelTag)
|
navPointTag.insert(0, navLabelTag)
|
||||||
contentTag = Tag(soup, 'content')
|
contentTag = Tag(soup, 'content')
|
||||||
contentTag['src'] = "content/book_%d.html" % int(self.booksByTitle[0]['id'])
|
#contentTag['src'] = "content/book_%d.html" % int(self.booksByTitle[0]['id'])
|
||||||
|
contentTag['src'] = "content/ByAlphaAuthor.html"
|
||||||
navPointTag.insert(1, contentTag)
|
navPointTag.insert(1, contentTag)
|
||||||
cmiTag = Tag(soup, '%s' % 'calibre:meta-img')
|
cmiTag = Tag(soup, '%s' % 'calibre:meta-img')
|
||||||
cmiTag['name'] = "mastheadImage"
|
cmiTag['name'] = "mastheadImage"
|
||||||
@ -2821,15 +3046,15 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
navLabelTag = Tag(ncx_soup, "navLabel")
|
navLabelTag = Tag(ncx_soup, "navLabel")
|
||||||
textTag = Tag(ncx_soup, "text")
|
textTag = Tag(ncx_soup, "text")
|
||||||
if book['series']:
|
if book['series']:
|
||||||
tokens = book['title'].split(': ')
|
tokens = list(book['title'].partition(':'))
|
||||||
if self.generateForKindle:
|
if self.generateForKindle:
|
||||||
# Don't include Author for Kindle
|
# Don't include Author for Kindle
|
||||||
textTag.insert(0, NavigableString(self.formatNCXText('%s (%s)' % \
|
textTag.insert(0, NavigableString(self.formatNCXText('%s (%s)' % \
|
||||||
(tokens[1], tokens[0]), dest='title')))
|
(tokens[2].strip(), tokens[0]), dest='title')))
|
||||||
else:
|
else:
|
||||||
# Include Author for non-Kindle
|
# Include Author for non-Kindle
|
||||||
textTag.insert(0, NavigableString(self.formatNCXText('%s · %s (%s)' % \
|
textTag.insert(0, NavigableString(self.formatNCXText('%s · %s (%s)' % \
|
||||||
(tokens[1], book['author'], tokens[0]), dest='title')))
|
(tokens[2].strip(), book['author'], tokens[0]), dest='title')))
|
||||||
else:
|
else:
|
||||||
if self.generateForKindle:
|
if self.generateForKindle:
|
||||||
# Don't include Author for Kindle
|
# Don't include Author for Kindle
|
||||||
@ -2882,6 +3107,98 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
|
|
||||||
self.ncxSoup = ncx_soup
|
self.ncxSoup = ncx_soup
|
||||||
|
|
||||||
|
def generateNCXBySeries(self, tocTitle):
|
||||||
|
self.updateProgressFullStep("NCX 'Series'")
|
||||||
|
|
||||||
|
def add_to_series_by_letter(current_series_list):
|
||||||
|
current_series_list = " • ".join(current_series_list)
|
||||||
|
current_series_list = self.formatNCXText(current_series_list, dest="description")
|
||||||
|
series_by_letter.append(current_series_list)
|
||||||
|
|
||||||
|
soup = self.ncxSoup
|
||||||
|
output = "BySeries"
|
||||||
|
body = soup.find("navPoint")
|
||||||
|
btc = len(body.contents)
|
||||||
|
|
||||||
|
# --- Construct the 'Books By Series' section ---
|
||||||
|
navPointTag = Tag(soup, 'navPoint')
|
||||||
|
navPointTag['class'] = "section"
|
||||||
|
navPointTag['id'] = "byseries-ID"
|
||||||
|
navPointTag['playOrder'] = self.playOrder
|
||||||
|
self.playOrder += 1
|
||||||
|
navLabelTag = Tag(soup, 'navLabel')
|
||||||
|
textTag = Tag(soup, 'text')
|
||||||
|
textTag.insert(0, NavigableString(tocTitle))
|
||||||
|
navLabelTag.insert(0, textTag)
|
||||||
|
nptc = 0
|
||||||
|
navPointTag.insert(nptc, navLabelTag)
|
||||||
|
nptc += 1
|
||||||
|
contentTag = Tag(soup,"content")
|
||||||
|
contentTag['src'] = "content/%s.html#section_start" % (output)
|
||||||
|
navPointTag.insert(nptc, contentTag)
|
||||||
|
nptc += 1
|
||||||
|
|
||||||
|
series_by_letter = []
|
||||||
|
|
||||||
|
# Loop over the series titles, find start of each letter, add description_preview_count books
|
||||||
|
# Special switch for using different title list
|
||||||
|
title_list = self.booksBySeries
|
||||||
|
current_letter = self.letter_or_symbol(title_list[0]['series'][0])
|
||||||
|
title_letters = [current_letter]
|
||||||
|
current_series_list = []
|
||||||
|
current_series = ""
|
||||||
|
for book in title_list:
|
||||||
|
sort_title = self.generateSortTitle(book['series'])
|
||||||
|
if self.letter_or_symbol(sort_title[0]) != current_letter:
|
||||||
|
# Save the old list
|
||||||
|
add_to_series_by_letter(current_series_list)
|
||||||
|
|
||||||
|
# Start the new list
|
||||||
|
current_letter = self.letter_or_symbol(sort_title[0])
|
||||||
|
title_letters.append(current_letter)
|
||||||
|
current_series = book['series']
|
||||||
|
current_series_list = [book['series']]
|
||||||
|
else:
|
||||||
|
if len(current_series_list) < self.descriptionClip and \
|
||||||
|
book['series'] != current_series :
|
||||||
|
current_series = book['series']
|
||||||
|
current_series_list.append(book['series'])
|
||||||
|
|
||||||
|
# Add the last book list
|
||||||
|
add_to_series_by_letter(current_series_list)
|
||||||
|
|
||||||
|
# Add *article* entries for each populated series title letter
|
||||||
|
for (i,books) in enumerate(series_by_letter):
|
||||||
|
navPointByLetterTag = Tag(soup, 'navPoint')
|
||||||
|
navPointByLetterTag['class'] = "article"
|
||||||
|
navPointByLetterTag['id'] = "%sSeries-ID" % (title_letters[i].upper())
|
||||||
|
navPointTag['playOrder'] = self.playOrder
|
||||||
|
self.playOrder += 1
|
||||||
|
navLabelTag = Tag(soup, 'navLabel')
|
||||||
|
textTag = Tag(soup, 'text')
|
||||||
|
textTag.insert(0, NavigableString(u"Series beginning with %s" % \
|
||||||
|
(title_letters[i] if len(title_letters[i])>1 else "'" + title_letters[i] + "'")))
|
||||||
|
navLabelTag.insert(0, textTag)
|
||||||
|
navPointByLetterTag.insert(0,navLabelTag)
|
||||||
|
contentTag = Tag(soup, 'content')
|
||||||
|
contentTag['src'] = "content/%s.html#%s_series" % (output, title_letters[i])
|
||||||
|
navPointByLetterTag.insert(1,contentTag)
|
||||||
|
|
||||||
|
if self.generateForKindle:
|
||||||
|
cmTag = Tag(soup, '%s' % 'calibre:meta')
|
||||||
|
cmTag['name'] = "description"
|
||||||
|
cmTag.insert(0, NavigableString(self.formatNCXText(books, dest='description')))
|
||||||
|
navPointByLetterTag.insert(2, cmTag)
|
||||||
|
|
||||||
|
navPointTag.insert(nptc, navPointByLetterTag)
|
||||||
|
nptc += 1
|
||||||
|
|
||||||
|
# Add this section to the body
|
||||||
|
body.insert(btc, navPointTag)
|
||||||
|
btc += 1
|
||||||
|
|
||||||
|
self.ncxSoup = soup
|
||||||
|
|
||||||
def generateNCXByTitle(self, tocTitle):
|
def generateNCXByTitle(self, tocTitle):
|
||||||
self.updateProgressFullStep("NCX 'Titles'")
|
self.updateProgressFullStep("NCX 'Titles'")
|
||||||
|
|
||||||
@ -3713,7 +4030,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
btc += 1
|
btc += 1
|
||||||
|
|
||||||
titleTag = body.find(attrs={'class':'title'})
|
titleTag = body.find(attrs={'class':'title'})
|
||||||
titleTag.insert(0,NavigableString('<b><i>%s</i></b>' % escape(self.getFriendlyGenreTag(genre))))
|
titleTag.insert(0,NavigableString('%s' % escape(self.getFriendlyGenreTag(genre))))
|
||||||
|
|
||||||
# Insert the books by author list
|
# Insert the books by author list
|
||||||
divTag = body.find(attrs={'class':'authors'})
|
divTag = body.find(attrs={'class':'authors'})
|
||||||
@ -3729,15 +4046,14 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
current_series = None
|
current_series = None
|
||||||
pAuthorTag = Tag(soup, "p")
|
pAuthorTag = Tag(soup, "p")
|
||||||
pAuthorTag['class'] = "author_index"
|
pAuthorTag['class'] = "author_index"
|
||||||
emTag = Tag(soup, "em")
|
|
||||||
aTag = Tag(soup, "a")
|
aTag = Tag(soup, "a")
|
||||||
aTag['href'] = "%s.html#%s" % ("ByAlphaAuthor", self.generateAuthorAnchor(book['author']))
|
aTag['href'] = "%s.html#%s" % ("ByAlphaAuthor", self.generateAuthorAnchor(book['author']))
|
||||||
aTag.insert(0, book['author'])
|
aTag.insert(0, book['author'])
|
||||||
emTag.insert(0,aTag)
|
pAuthorTag.insert(0,aTag)
|
||||||
pAuthorTag.insert(0,emTag)
|
|
||||||
divTag.insert(dtc,pAuthorTag)
|
divTag.insert(dtc,pAuthorTag)
|
||||||
dtc += 1
|
dtc += 1
|
||||||
|
|
||||||
|
'''
|
||||||
# Insert an <hr /> between non-series and series
|
# Insert an <hr /> between non-series and series
|
||||||
if not current_series and non_series_books and book['series']:
|
if not current_series and non_series_books and book['series']:
|
||||||
# Insert an <hr />
|
# Insert an <hr />
|
||||||
@ -3745,6 +4061,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
hrTag['class'] = "series_divider"
|
hrTag['class'] = "series_divider"
|
||||||
divTag.insert(dtc,hrTag)
|
divTag.insert(dtc,hrTag)
|
||||||
dtc += 1
|
dtc += 1
|
||||||
|
'''
|
||||||
|
|
||||||
# Check for series
|
# Check for series
|
||||||
if book['series'] and book['series'] != current_series:
|
if book['series'] and book['series'] != current_series:
|
||||||
@ -3752,7 +4069,14 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
current_series = book['series']
|
current_series = book['series']
|
||||||
pSeriesTag = Tag(soup,'p')
|
pSeriesTag = Tag(soup,'p')
|
||||||
pSeriesTag['class'] = "series"
|
pSeriesTag['class'] = "series"
|
||||||
pSeriesTag.insert(0,NavigableString(self.NOT_READ_SYMBOL + book['series']))
|
if self.opts.generate_series:
|
||||||
|
aTag = Tag(soup,'a')
|
||||||
|
aTag['href'] = "%s.html#%s_series" % ('BySeries',
|
||||||
|
re.sub('\W','',book['series']).lower())
|
||||||
|
aTag.insert(0, book['series'])
|
||||||
|
pSeriesTag.insert(0, aTag)
|
||||||
|
else:
|
||||||
|
pSeriesTag.insert(0,NavigableString('%s' % book['series']))
|
||||||
divTag.insert(dtc,pSeriesTag)
|
divTag.insert(dtc,pSeriesTag)
|
||||||
dtc += 1
|
dtc += 1
|
||||||
|
|
||||||
@ -3809,7 +4133,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
def generateHTMLDescriptionHeader(self, title):
|
def generateHTMLDescriptionHeader(self, title):
|
||||||
|
|
||||||
title_border = '' if self.opts.fmt == 'epub' else \
|
title_border = '' if self.opts.fmt == 'epub' else \
|
||||||
'<div class="hr"><blockquote><hr/></blockquote></div>'
|
'<hr class="description_divider"/>'
|
||||||
header = '''
|
header = '''
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:calibre="http://calibre.kovidgoyal.net/2009/metadata">
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:calibre="http://calibre.kovidgoyal.net/2009/metadata">
|
||||||
@ -3855,7 +4179,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
<td> </td>
|
<td> </td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<blockquote><hr/></blockquote>
|
<hr class="description_divider" />
|
||||||
<div class="description"></div>
|
<div class="description"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@ -3897,7 +4221,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p class="title"></p>
|
<p class="title"></p>
|
||||||
<div class="hr"><blockquote><hr/></blockquote></div>
|
<!--div class="hr"><blockquote><hr/></blockquote></div-->
|
||||||
<div class="authors"></div>
|
<div class="authors"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@ -4049,6 +4373,12 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
except:
|
except:
|
||||||
self.opts.log.error("generateThumbnail(): Error with %s" % title['title'])
|
self.opts.log.error("generateThumbnail(): Error with %s" % title['title'])
|
||||||
|
|
||||||
|
def getFriendlyGenreTag(self, genre):
|
||||||
|
# Find the first instance of friendly_tag matching genre
|
||||||
|
for friendly_tag in self.genre_tags_dict:
|
||||||
|
if self.genre_tags_dict[friendly_tag] == genre:
|
||||||
|
return friendly_tag
|
||||||
|
|
||||||
def getMarkerTags(self):
|
def getMarkerTags(self):
|
||||||
''' Return a list of special marker tags to be excluded from genre list '''
|
''' Return a list of special marker tags to be excluded from genre list '''
|
||||||
markerTags = []
|
markerTags = []
|
||||||
@ -4063,12 +4393,6 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
else:
|
else:
|
||||||
return char
|
return char
|
||||||
|
|
||||||
def getFriendlyGenreTag(self, genre):
|
|
||||||
# Find the first instance of friendly_tag matching genre
|
|
||||||
for friendly_tag in self.genre_tags_dict:
|
|
||||||
if self.genre_tags_dict[friendly_tag] == genre:
|
|
||||||
return friendly_tag
|
|
||||||
|
|
||||||
def markdownComments(self, comments):
|
def markdownComments(self, comments):
|
||||||
'''
|
'''
|
||||||
Convert random comment text to normalized, xml-legal block of <p>s
|
Convert random comment text to normalized, xml-legal block of <p>s
|
||||||
@ -4224,13 +4548,15 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
opts.fmt = self.fmt = path_to_output.rpartition('.')[2]
|
opts.fmt = self.fmt = path_to_output.rpartition('.')[2]
|
||||||
|
|
||||||
# Add local options
|
# Add local options
|
||||||
opts.creator = "calibre"
|
opts.creator = '%s, %s %s, %s' % (strftime('%A'), strftime('%B'), strftime('%d').lstrip('0'), strftime('%Y'))
|
||||||
|
opts.creator_sort_as = '%s %s' % ('calibre', strftime('%Y-%m-%d'))
|
||||||
opts.connected_kindle = False
|
opts.connected_kindle = False
|
||||||
|
|
||||||
# Finalize output_profile
|
# Finalize output_profile
|
||||||
op = opts.output_profile
|
op = opts.output_profile
|
||||||
if op is None:
|
if op is None:
|
||||||
op = 'default'
|
op = 'default'
|
||||||
|
|
||||||
if opts.connected_device['name'] and 'kindle' in opts.connected_device['name'].lower():
|
if opts.connected_device['name'] and 'kindle' in opts.connected_device['name'].lower():
|
||||||
opts.connected_kindle = True
|
opts.connected_kindle = True
|
||||||
if opts.connected_device['serial'] and opts.connected_device['serial'][:4] in ['B004','B005']:
|
if opts.connected_device['serial'] and opts.connected_device['serial'][:4] in ['B004','B005']:
|
||||||
@ -4256,7 +4582,8 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
opts.exclude_genre = '\[^.\]'
|
opts.exclude_genre = '\[^.\]'
|
||||||
build_log.append(" converting empty exclude_genre to '\[^.\]'")
|
build_log.append(" converting empty exclude_genre to '\[^.\]'")
|
||||||
|
|
||||||
if opts.connected_device['name']:
|
if opts.connected_device['is_device_connected'] and \
|
||||||
|
opts.connected_device['kind'] == 'device':
|
||||||
if opts.connected_device['serial']:
|
if opts.connected_device['serial']:
|
||||||
build_log.append(u" connected_device: '%s' #%s%s " % \
|
build_log.append(u" connected_device: '%s' #%s%s " % \
|
||||||
(opts.connected_device['name'],
|
(opts.connected_device['name'],
|
||||||
@ -4267,9 +4594,14 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
build_log.append(u" mount point: %s" % storage)
|
build_log.append(u" mount point: %s" % storage)
|
||||||
else:
|
else:
|
||||||
build_log.append(u" connected_device: '%s'" % opts.connected_device['name'])
|
build_log.append(u" connected_device: '%s'" % opts.connected_device['name'])
|
||||||
|
try:
|
||||||
for storage in opts.connected_device['storage']:
|
for storage in opts.connected_device['storage']:
|
||||||
if storage:
|
if storage:
|
||||||
build_log.append(u" mount point: %s" % storage)
|
build_log.append(u" mount point: %s" % storage)
|
||||||
|
except:
|
||||||
|
build_log.append(u" (no mount points)")
|
||||||
|
else:
|
||||||
|
build_log.append(u" connected_device: '%s'" % opts.connected_device['name'])
|
||||||
|
|
||||||
opts_dict = vars(opts)
|
opts_dict = vars(opts)
|
||||||
if opts_dict['ids']:
|
if opts_dict['ids']:
|
||||||
|
@ -674,7 +674,14 @@ def command_catalog(args, dbpath):
|
|||||||
|
|
||||||
# No support for connected device in CLI environment
|
# No support for connected device in CLI environment
|
||||||
# Parallel initialization in calibre.gui2.tools:generate_catalog()
|
# Parallel initialization in calibre.gui2.tools:generate_catalog()
|
||||||
opts.connected_device = { 'storage':None,'serial':None,'save_template':None,'name':None}
|
opts.connected_device = {
|
||||||
|
'is_device_connected': False,
|
||||||
|
'kind': None,
|
||||||
|
'name': None,
|
||||||
|
'save_template': None,
|
||||||
|
'serial': None,
|
||||||
|
'storage': None,
|
||||||
|
}
|
||||||
|
|
||||||
with plugin:
|
with plugin:
|
||||||
plugin.run(args[1], opts, get_db(dbpath, opts))
|
plugin.run(args[1], opts, get_db(dbpath, opts))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user