mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
GwR catalog UI revisions
This commit is contained in:
parent
3c254aca3f
commit
230d92dcb5
@ -108,6 +108,13 @@ p.date_read {
|
||||
text-indent:-6em;
|
||||
}
|
||||
|
||||
hr.annotations_divider {
|
||||
width:50%;
|
||||
margin-left:1em;
|
||||
margin-top:0em;
|
||||
margin-bottom:0em;
|
||||
}
|
||||
|
||||
hr.description_divider {
|
||||
width:90%;
|
||||
margin-left:5%;
|
||||
@ -117,18 +124,20 @@ hr.description_divider {
|
||||
border-left: solid white 0px;
|
||||
}
|
||||
|
||||
hr.annotations_divider {
|
||||
width:50%;
|
||||
margin-left:1em;
|
||||
margin-top:0em;
|
||||
margin-bottom:0em;
|
||||
hr.merged_comments_divider {
|
||||
width:80%;
|
||||
margin-left:10%;
|
||||
border-top: solid white 0px;
|
||||
border-right: solid white 0px;
|
||||
border-bottom: dotted grey 2px;
|
||||
border-left: solid white 0px;
|
||||
}
|
||||
|
||||
td.publisher, td.date {
|
||||
font-weight:bold;
|
||||
text-align:center;
|
||||
}
|
||||
td.rating {
|
||||
td.rating, td.notes {
|
||||
text-align: center;
|
||||
}
|
||||
td.thumbnail img {
|
||||
|
@ -57,7 +57,7 @@ class GenerateCatalogAction(InterfaceAction):
|
||||
if job.result:
|
||||
# Search terms nulled catalog results
|
||||
return error_dialog(self.gui, _('No books found'),
|
||||
_("No books to catalog\nCheck exclude tags"),
|
||||
_("No books to catalog\nCheck exclusion criteria"),
|
||||
show=True)
|
||||
if job.failed:
|
||||
return self.gui.job_exception(job)
|
||||
|
@ -17,18 +17,55 @@ class PluginWidget(QWidget,Ui_Form):
|
||||
|
||||
TITLE = _('E-book options')
|
||||
HELP = _('Options specific to')+' EPUB/MOBI '+_('output')
|
||||
OPTION_FIELDS = [('exclude_genre','\[.+\]'),
|
||||
('exclude_tags','~,'+_('Catalog')),
|
||||
('generate_titles', True),
|
||||
('generate_series', True),
|
||||
('generate_recently_added', True),
|
||||
('note_tag','*'),
|
||||
('numbers_as_text', False),
|
||||
('read_pattern','+'),
|
||||
('read_source_field_cb','Tag'),
|
||||
('wishlist_tag','Wishlist'),
|
||||
]
|
||||
|
||||
CheckBoxControls = [
|
||||
'generate_titles',
|
||||
'generate_series',
|
||||
'generate_genres',
|
||||
'generate_recently_added',
|
||||
'generate_descriptions',
|
||||
'include_hr'
|
||||
]
|
||||
ComboBoxControls = [
|
||||
'read_source_field',
|
||||
'exclude_source_field',
|
||||
'header_note_source_field',
|
||||
'merge_source_field'
|
||||
]
|
||||
LineEditControls = [
|
||||
'exclude_genre',
|
||||
'exclude_pattern',
|
||||
'exclude_tags',
|
||||
'read_pattern',
|
||||
'wishlist_tag'
|
||||
]
|
||||
RadioButtonControls = [
|
||||
'merge_before',
|
||||
'merge_after'
|
||||
]
|
||||
SpinBoxControls = [
|
||||
'thumb_width'
|
||||
]
|
||||
|
||||
OPTION_FIELDS = zip(CheckBoxControls,
|
||||
[True for i in CheckBoxControls],
|
||||
['check_box' for i in CheckBoxControls])
|
||||
OPTION_FIELDS += zip(ComboBoxControls,
|
||||
[None for i in ComboBoxControls],
|
||||
['combo_box' for i in ComboBoxControls])
|
||||
OPTION_FIELDS += zip(RadioButtonControls,
|
||||
[None for i in RadioButtonControls],
|
||||
['radio_button' for i in RadioButtonControls])
|
||||
|
||||
# LineEditControls
|
||||
OPTION_FIELDS += zip(['exclude_genre'],['\[.+\]'],['line_edit'])
|
||||
OPTION_FIELDS += zip(['exclude_pattern'],[None],['line_edit'])
|
||||
OPTION_FIELDS += zip(['exclude_tags'],['~,'+_('Catalog')],['line_edit'])
|
||||
OPTION_FIELDS += zip(['read_pattern'],['+'],['line_edit'])
|
||||
OPTION_FIELDS += zip(['wishlist_tag'],['Wishlist'],['line_edit'])
|
||||
|
||||
# SpinBoxControls
|
||||
OPTION_FIELDS += zip(['thumb_width'],[1.00],['spin_box'])
|
||||
|
||||
# Output synced to the connected device?
|
||||
sync_enabled = True
|
||||
@ -42,105 +79,203 @@ class PluginWidget(QWidget,Ui_Form):
|
||||
|
||||
def initialize(self, name, db):
|
||||
self.name = name
|
||||
|
||||
# Populate the 'Read book' source fields
|
||||
all_custom_fields = db.custom_field_keys()
|
||||
custom_fields = {}
|
||||
custom_fields['Tag'] = {'field':'tag', 'datatype':u'text'}
|
||||
for custom_field in all_custom_fields:
|
||||
field_md = db.metadata_for_field(custom_field)
|
||||
if field_md['datatype'] in ['bool','composite','datetime','text']:
|
||||
custom_fields[field_md['name']] = {'field':custom_field,
|
||||
'datatype':field_md['datatype']}
|
||||
|
||||
# Add the sorted eligible fields to the combo box
|
||||
for cf in sorted(custom_fields):
|
||||
self.read_source_field_cb.addItem(cf)
|
||||
|
||||
self.read_source_fields = custom_fields
|
||||
self.read_source_field_cb.currentIndexChanged.connect(self.read_source_field_changed)
|
||||
self.db = db
|
||||
self.populateComboBoxes()
|
||||
|
||||
# Update dialog fields from stored options
|
||||
for opt in self.OPTION_FIELDS:
|
||||
opt_value = gprefs.get(self.name + '_' + opt[0], opt[1])
|
||||
if opt[0] in [
|
||||
'generate_recently_added',
|
||||
'generate_series',
|
||||
'generate_titles',
|
||||
'numbers_as_text',
|
||||
]:
|
||||
getattr(self, opt[0]).setChecked(opt_value)
|
||||
c_name, c_def, c_type = opt
|
||||
opt_value = gprefs.get(self.name + '_' + c_name, c_def)
|
||||
if c_type in ['check_box']:
|
||||
getattr(self, c_name).setChecked(eval(str(opt_value)))
|
||||
elif c_type in ['combo_box'] and opt_value is not None:
|
||||
# *** Test this code with combo boxes ***
|
||||
#index = self.read_source_field.findText(opt_value)
|
||||
index = getattr(self,c_name).findText(opt_value)
|
||||
if index == -1 and c_name == 'read_source_field':
|
||||
index = self.read_source_field.findText('Tag')
|
||||
#self.read_source_field.setCurrentIndex(index)
|
||||
getattr(self,c_name).setCurrentIndex(index)
|
||||
elif c_type in ['line_edit']:
|
||||
getattr(self, c_name).setText(opt_value)
|
||||
elif c_type in ['radio_button'] and opt_value is not None:
|
||||
getattr(self, c_name).setChecked(opt_value)
|
||||
elif c_type in ['spin_box']:
|
||||
getattr(self, c_name).setValue(float(opt_value))
|
||||
|
||||
# Combo box
|
||||
elif opt[0] in ['read_source_field_cb']:
|
||||
# Look for last-stored combo box value
|
||||
index = self.read_source_field_cb.findText(opt_value)
|
||||
if index == -1:
|
||||
index = self.read_source_field_cb.findText('Tag')
|
||||
self.read_source_field_cb.setCurrentIndex(index)
|
||||
|
||||
# Text fields
|
||||
else:
|
||||
getattr(self, opt[0]).setText(opt_value)
|
||||
|
||||
# Init self.read_source_field
|
||||
cs = unicode(self.read_source_field_cb.currentText())
|
||||
# Init self.read_source_field_name
|
||||
cs = unicode(self.read_source_field.currentText())
|
||||
read_source_spec = self.read_source_fields[cs]
|
||||
self.read_source_field = read_source_spec['field']
|
||||
self.read_source_field_name = read_source_spec['field']
|
||||
|
||||
# Init self.exclude_source_field_name
|
||||
self.exclude_source_field_name = ''
|
||||
cs = unicode(self.exclude_source_field.currentText())
|
||||
if cs > '':
|
||||
exclude_source_spec = self.exclude_source_fields[cs]
|
||||
self.exclude_source_field_name = exclude_source_spec['field']
|
||||
|
||||
# Init self.merge_source_field_name
|
||||
self.merge_source_field_name = ''
|
||||
cs = unicode(self.merge_source_field.currentText())
|
||||
if cs > '':
|
||||
merge_source_spec = self.merge_source_fields[cs]
|
||||
self.merge_source_field_name = merge_source_spec['field']
|
||||
|
||||
# Init self.header_note_source_field_name
|
||||
self.header_note_source_field_name = ''
|
||||
cs = unicode(self.header_note_source_field.currentText())
|
||||
if cs > '':
|
||||
header_note_source_spec = self.header_note_source_fields[cs]
|
||||
self.header_note_source_field_name = header_note_source_spec['field']
|
||||
|
||||
# Hook changes to thumb_width
|
||||
self.thumb_width.valueChanged.connect(self.thumb_width_changed)
|
||||
|
||||
def options(self):
|
||||
# Save/return the current options
|
||||
# exclude_genre stores literally
|
||||
# generate_titles, generate_recently_added, numbers_as_text stores as True/False
|
||||
# others store as lists
|
||||
|
||||
opts_dict = {}
|
||||
# Save values to gprefs
|
||||
for opt in self.OPTION_FIELDS:
|
||||
# Save values to gprefs
|
||||
if opt[0] in [
|
||||
'generate_recently_added',
|
||||
'generate_series',
|
||||
'generate_titles',
|
||||
'numbers_as_text',
|
||||
]:
|
||||
opt_value = getattr(self,opt[0]).isChecked()
|
||||
c_name, c_def, c_type = opt
|
||||
if c_type in ['check_box', 'radio_button']:
|
||||
opt_value = getattr(self, c_name).isChecked()
|
||||
elif c_type in ['combo_box']:
|
||||
opt_value = unicode(getattr(self,c_name).currentText())
|
||||
elif c_type in ['line_edit']:
|
||||
opt_value = unicode(getattr(self, c_name).text())
|
||||
elif c_type in ['spin_box']:
|
||||
opt_value = unicode(getattr(self, c_name).cleanText())
|
||||
gprefs.set(self.name + '_' + c_name, opt_value)
|
||||
|
||||
# Combo box uses .currentText()
|
||||
elif opt[0] in ['read_source_field_cb']:
|
||||
opt_value = unicode(getattr(self, opt[0]).currentText())
|
||||
|
||||
# text fields use .text()
|
||||
# Construct opts object
|
||||
if c_name == 'exclude_tags':
|
||||
# store as list
|
||||
opts_dict[c_name] = opt_value.split(',')
|
||||
else:
|
||||
opt_value = unicode(getattr(self, opt[0]).text())
|
||||
gprefs.set(self.name + '_' + opt[0], opt_value)
|
||||
opts_dict[c_name] = opt_value
|
||||
|
||||
# Construct opts
|
||||
if opt[0] in [
|
||||
'exclude_genre',
|
||||
'generate_recently_added',
|
||||
'generate_series',
|
||||
'generate_titles',
|
||||
'numbers_as_text',
|
||||
]:
|
||||
opts_dict[opt[0]] = opt_value
|
||||
else:
|
||||
opts_dict[opt[0]] = opt_value.split(',')
|
||||
# Generate markers for hybrids
|
||||
opts_dict['read_book_marker'] = "%s:%s" % (self.read_source_field_name,
|
||||
self.read_pattern.text())
|
||||
opts_dict['exclude_book_marker'] = "%s:%s" % (self.exclude_source_field_name,
|
||||
self.exclude_pattern.text())
|
||||
|
||||
# Generate read_book_marker
|
||||
opts_dict['read_book_marker'] = "%s:%s" % (self.read_source_field, self.read_pattern.text())
|
||||
# Generate specs for merge_comments, header_note_source_field
|
||||
checked = ''
|
||||
if self.merge_before.isChecked():
|
||||
checked = 'before'
|
||||
elif self.merge_after.isChecked():
|
||||
checked = 'after'
|
||||
include_hr = self.include_hr.isChecked()
|
||||
opts_dict['merge_comments'] = "%s:%s:%s" % \
|
||||
(self.merge_source_field_name, checked, include_hr)
|
||||
|
||||
opts_dict['header_note_source_field'] = self.header_note_source_field_name
|
||||
|
||||
# Append the output profile
|
||||
opts_dict['output_profile'] = [load_defaults('page_setup')['output_profile']]
|
||||
if False:
|
||||
print "opts_dict"
|
||||
for opt in sorted(opts_dict.keys()):
|
||||
print " %s: %s" % (opt, repr(opts_dict[opt]))
|
||||
return opts_dict
|
||||
|
||||
def populateComboBoxes(self):
|
||||
# Custom column types declared in
|
||||
# gui2.preferences.create_custom_column:CreateCustomColumn()
|
||||
# As of 0.7.34:
|
||||
# bool Yes/No
|
||||
# comments Long text, like comments, not shown in tag browser
|
||||
# composite Column built from other columns
|
||||
# datetime Date
|
||||
# enumeration Text, but with a fixed set of permitted values
|
||||
# float Floating point numbers
|
||||
# int Integers
|
||||
# rating Ratings, shown with stars
|
||||
# series Text column for keeping series-like information
|
||||
# text Column shown in the tag browser
|
||||
# *text Comma-separated text, like tags, shown in tag browser
|
||||
|
||||
all_custom_fields = self.db.custom_field_keys()
|
||||
# Populate the 'Read book' hybrid
|
||||
custom_fields = {}
|
||||
custom_fields['Tag'] = {'field':'tag', 'datatype':u'text'}
|
||||
for custom_field in all_custom_fields:
|
||||
field_md = self.db.metadata_for_field(custom_field)
|
||||
if field_md['datatype'] in ['bool','composite','datetime','enumeration','text']:
|
||||
custom_fields[field_md['name']] = {'field':custom_field,
|
||||
'datatype':field_md['datatype']}
|
||||
# Add the sorted eligible fields to the combo box
|
||||
for cf in sorted(custom_fields):
|
||||
self.read_source_field.addItem(cf)
|
||||
self.read_source_fields = custom_fields
|
||||
self.read_source_field.currentIndexChanged.connect(self.read_source_field_changed)
|
||||
|
||||
|
||||
# Populate the 'Excluded books' hybrid
|
||||
custom_fields = {}
|
||||
for custom_field in all_custom_fields:
|
||||
field_md = self.db.metadata_for_field(custom_field)
|
||||
if field_md['datatype'] in ['bool','composite','datetime','enumeration','text']:
|
||||
custom_fields[field_md['name']] = {'field':custom_field,
|
||||
'datatype':field_md['datatype']}
|
||||
# Blank field first
|
||||
self.exclude_source_field.addItem('')
|
||||
# Add the sorted eligible fields to the combo box
|
||||
for cf in sorted(custom_fields):
|
||||
self.exclude_source_field.addItem(cf)
|
||||
self.exclude_source_fields = custom_fields
|
||||
self.exclude_source_field.currentIndexChanged.connect(self.exclude_source_field_changed)
|
||||
|
||||
|
||||
# Populate the 'Header note' combo box
|
||||
custom_fields = {}
|
||||
for custom_field in all_custom_fields:
|
||||
field_md = self.db.metadata_for_field(custom_field)
|
||||
if field_md['datatype'] in ['composite','datetime','enumeration','text']:
|
||||
custom_fields[field_md['name']] = {'field':custom_field,
|
||||
'datatype':field_md['datatype']}
|
||||
# Blank field first
|
||||
self.header_note_source_field.addItem('')
|
||||
# Add the sorted eligible fields to the combo box
|
||||
for cf in sorted(custom_fields):
|
||||
self.header_note_source_field.addItem(cf)
|
||||
self.header_note_source_fields = custom_fields
|
||||
self.header_note_source_field.currentIndexChanged.connect(self.header_note_source_field_changed)
|
||||
|
||||
|
||||
# Populate the 'Merge with Comments' combo box
|
||||
custom_fields = {}
|
||||
for custom_field in all_custom_fields:
|
||||
field_md = self.db.metadata_for_field(custom_field)
|
||||
if field_md['datatype'] in ['text','comments']:
|
||||
custom_fields[field_md['name']] = {'field':custom_field,
|
||||
'datatype':field_md['datatype']}
|
||||
# Blank field first
|
||||
self.merge_source_field.addItem('')
|
||||
# Add the sorted eligible fields to the combo box
|
||||
for cf in sorted(custom_fields):
|
||||
self.merge_source_field.addItem(cf)
|
||||
self.merge_source_fields = custom_fields
|
||||
self.merge_source_field.currentIndexChanged.connect(self.merge_source_field_changed)
|
||||
self.merge_before.setEnabled(False)
|
||||
self.merge_after.setEnabled(False)
|
||||
self.include_hr.setEnabled(False)
|
||||
|
||||
def read_source_field_changed(self,new_index):
|
||||
'''
|
||||
Process changes in the read_source_field combo box
|
||||
Currently using QLineEdit for all field types
|
||||
Possible to modify to switch QWidget type
|
||||
'''
|
||||
new_source = str(self.read_source_field_cb.currentText())
|
||||
new_source = str(self.read_source_field.currentText())
|
||||
read_source_spec = self.read_source_fields[str(new_source)]
|
||||
self.read_source_field = read_source_spec['field']
|
||||
self.read_source_field_name = read_source_spec['field']
|
||||
|
||||
# Change pattern input widget to match the source field datatype
|
||||
if read_source_spec['datatype'] in ['bool','composite','datetime','text']:
|
||||
@ -152,3 +287,62 @@ class PluginWidget(QWidget,Ui_Form):
|
||||
self.read_pattern = dw
|
||||
self.read_spec_hl.addWidget(dw)
|
||||
|
||||
def exclude_source_field_changed(self,new_index):
|
||||
'''
|
||||
Process changes in the exclude_source_field combo box
|
||||
Currently using QLineEdit for all field types
|
||||
Possible to modify to switch QWidget type
|
||||
'''
|
||||
new_source = str(self.exclude_source_field.currentText())
|
||||
self.exclude_source_field_name = new_source
|
||||
if new_source > '':
|
||||
exclude_source_spec = self.exclude_source_fields[str(new_source)]
|
||||
self.exclude_source_field_name = exclude_source_spec['field']
|
||||
|
||||
# Change pattern input widget to match the source field datatype
|
||||
if exclude_source_spec['datatype'] in ['bool','composite','datetime','text']:
|
||||
if not isinstance(self.exclude_pattern, QLineEdit):
|
||||
self.exclude_spec_hl.removeWidget(self.exclude_pattern)
|
||||
dw = QLineEdit(self)
|
||||
dw.setObjectName('exclude_pattern')
|
||||
dw.setToolTip('Exclusion pattern')
|
||||
self.exclude_pattern = dw
|
||||
self.exclude_spec_hl.addWidget(dw)
|
||||
else:
|
||||
self.exclude_pattern.setText('')
|
||||
|
||||
def header_note_source_field_changed(self,new_index):
|
||||
'''
|
||||
Process changes in the header_note_source_field combo box
|
||||
'''
|
||||
new_source = str(self.header_note_source_field.currentText())
|
||||
self.header_note_source_field_name = new_source
|
||||
if new_source > '':
|
||||
header_note_source_spec = self.header_note_source_fields[str(new_source)]
|
||||
self.header_note_source_field_name = header_note_source_spec['field']
|
||||
|
||||
def merge_source_field_changed(self,new_index):
|
||||
'''
|
||||
Process changes in the header_note_source_field combo box
|
||||
'''
|
||||
new_source = str(self.merge_source_field.currentText())
|
||||
self.merge_source_field_name = new_source
|
||||
if new_source > '':
|
||||
merge_source_spec = self.merge_source_fields[str(new_source)]
|
||||
self.merge_source_field_name = merge_source_spec['field']
|
||||
if not self.merge_before.isChecked() and not self.merge_after.isChecked():
|
||||
self.merge_after.setChecked(True)
|
||||
self.merge_before.setEnabled(True)
|
||||
self.merge_after.setEnabled(True)
|
||||
self.include_hr.setEnabled(True)
|
||||
|
||||
else:
|
||||
self.merge_before.setEnabled(False)
|
||||
self.merge_after.setEnabled(False)
|
||||
self.include_hr.setEnabled(False)
|
||||
|
||||
def thumb_width_changed(self,new_value):
|
||||
'''
|
||||
Process changes in the thumb_width spin box
|
||||
'''
|
||||
pass
|
||||
|
@ -6,163 +6,653 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>627</width>
|
||||
<height>549</height>
|
||||
<width>650</width>
|
||||
<height>582</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>'Don't include this book' tag:</string>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="includedSections">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="exclude_tags">
|
||||
<property name="toolTip">
|
||||
<string extracomment="Default: ~,Catalog"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Additional note tag prefix:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="note_tag">
|
||||
<property name="toolTip">
|
||||
<string extracomment="Default: *"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="exclude_genre">
|
||||
<property name="toolTip">
|
||||
<string extracomment="Default: \[[\w]*\]"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Regex pattern describing tags to exclude as genres:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::LogText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Regex tips:
|
||||
- The default regex - \[.+\] - excludes genre tags of the form [tag], e.g., [Amazon Freebie]
|
||||
- A regex pattern of a single dot excludes all genre tags, generating no Genre Section</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QCheckBox" name="generate_titles">
|
||||
<property name="text">
|
||||
<string>Include 'Titles' Section</string>
|
||||
<property name="toolTip">
|
||||
<string>Sections to include in generated catalog. A minimal catalog includes 'Books by Author'.</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Included sections (Books by Author included by default)</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="generate_titles">
|
||||
<property name="text">
|
||||
<string>Books by Title</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="generate_series">
|
||||
<property name="text">
|
||||
<string>Books by Series</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QCheckBox" name="generate_recently_added">
|
||||
<property name="text">
|
||||
<string>Recently Added</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="generate_genres">
|
||||
<property name="text">
|
||||
<string>Books by Genre</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QCheckBox" name="generate_descriptions">
|
||||
<property name="text">
|
||||
<string>Descriptions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QCheckBox" name="generate_recently_added">
|
||||
<property name="text">
|
||||
<string>Include 'Recently Added' Section</string>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="excludedGenres">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Default pattern </p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Courier New,courier';">\[.+\]</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">excludes tags of the form [<span style=" font-style:italic;">tag</span>]</p></body></html></string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Excluded genres</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::FieldsStayAtSizeHint</enum>
|
||||
</property>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>175</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Tags to exclude</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::AutoText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="exclude_genre">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string extracomment="Default: \[[\w]*\]"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<widget class="QCheckBox" name="numbers_as_text">
|
||||
<property name="text">
|
||||
<string>Sort numbers as text</string>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="excludedBooks">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Exclude matching books from generated catalog</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Excluded books</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>175</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Tags to exclude</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="exclude_tags">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Comma-separated list of tags to exclude.</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt;">Default:</span><span style=" font-family:'Courier New,courier'; font-size:12pt;"> ~,Catalog</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="exclude_spec_hl">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>175</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Column/value</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="exclude_source_field">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Column containing exclusion criteria</string>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
|
||||
</property>
|
||||
<property name="minimumContentsLength">
|
||||
<number>18</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="exclude_pattern">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Exclusion pattern</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QCheckBox" name="generate_series">
|
||||
<property name="text">
|
||||
<string>Include 'Series' Section</string>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="readBooks">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Matching books will be displayed with ✓</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Read books</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="read_spec_hl">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>175</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Column/value</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="read_source_field">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Column containing 'read' status</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
|
||||
</property>
|
||||
<property name="minimumContentsLength">
|
||||
<number>18</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="read_pattern">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>'read book' pattern</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="wishlist_tag"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Wishlist tag:</string>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="otherOptions">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="read_spec_hl">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinimumSize</enum>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QComboBox" name="read_source_field_cb">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Source column for read book</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="read_pattern">
|
||||
<property name="toolTip">
|
||||
<string>Pattern for read book</string>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Books marked as read:</string>
|
||||
<property name="title">
|
||||
<string>Other options</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_4">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::FieldsStayAtSizeHint</enum>
|
||||
</property>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>175</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Wishlist tag</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="wishlist_tag">
|
||||
<property name="toolTip">
|
||||
<string>Wishlist items will be displayed with ✕</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>175</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Thumbnail width</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="thumb_width">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Size hint for cover thumbnails included in Descriptions</string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string>"</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>2.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>175</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Header note</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="header_note_source_field">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Column containing header note</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>175</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Merge with Comments</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="merge_source_field">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Column containing additional content to merge</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="merge_before">
|
||||
<property name="toolTip">
|
||||
<string>Merge before Comments</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Before</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="merge_after">
|
||||
<property name="toolTip">
|
||||
<string>Merge after Comments</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>After</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="include_hr">
|
||||
<property name="toolTip">
|
||||
<string>Separate with horizontal rule</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><hr /></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>579</width>
|
||||
<height>411</height>
|
||||
<width>650</width>
|
||||
<height>575</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>611</width>
|
||||
<height>514</height>
|
||||
<width>674</width>
|
||||
<height>660</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -33,6 +33,18 @@
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QTabWidget" name="tabs">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>650</width>
|
||||
<height>575</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
@ -550,6 +550,13 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
"of the conversion process a bug is occurring.\n"
|
||||
"Default: '%default'None\n"
|
||||
"Applies to: ePub, MOBI output formats")),
|
||||
Option('--exclude-book-marker',
|
||||
default=':',
|
||||
dest='exclude_book_marker',
|
||||
action = None,
|
||||
help=_("field:pattern specifying custom field/contents indicating book should be excluded.\n"
|
||||
"Default: '%default'\n"
|
||||
"Applies to ePub, MOBI output formats")),
|
||||
Option('--exclude-genre',
|
||||
default='\[.+\]',
|
||||
dest='exclude_genre',
|
||||
@ -585,6 +592,23 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
help=_("Include 'Recently Added' section in catalog.\n"
|
||||
"Default: '%default'\n"
|
||||
"Applies to: ePub, MOBI output formats")),
|
||||
Option('--header-note-source-field',
|
||||
default='',
|
||||
dest='header_note_source_field',
|
||||
action = None,
|
||||
help=_("Custom field containing note text to insert in Description header.\n"
|
||||
"Default: '%default'\n"
|
||||
"Applies to: ePub, MOBI output formats")),
|
||||
Option('--merge-comments',
|
||||
default='::',
|
||||
dest='merge_comments',
|
||||
action = None,
|
||||
help=_("<custom field>:[before|after]:[True|False] specifying:\n"
|
||||
" <custom field> Custom field containing notes to merge with Comments\n"
|
||||
" [before|after] Placement of notes with respect to Comments\n"
|
||||
" [True|False] - A horizontal rule is inserted between notes and Comments\n"
|
||||
"Default: '%default'\n"
|
||||
"Applies to ePub, MOBI output formats")),
|
||||
Option('--note-tag',
|
||||
default='*',
|
||||
dest='note_tag',
|
||||
@ -845,6 +869,7 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
catalog.copyResources()
|
||||
catalog.buildSources()
|
||||
'''
|
||||
|
||||
# A single number creates 'Last x days' only.
|
||||
# Multiple numbers create 'Last x days', 'x to y days ago' ...
|
||||
# e.g, [7,15,30,60], [30]
|
||||
@ -889,6 +914,7 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
and self.generateForKindle \
|
||||
else False
|
||||
self.__genres = None
|
||||
self.genres = []
|
||||
self.__genre_tags_dict = None
|
||||
self.__htmlFileList = []
|
||||
self.__markerTags = self.getMarkerTags()
|
||||
@ -900,13 +926,15 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
self.__progressString = ''
|
||||
f, _, p = opts.read_book_marker.partition(':')
|
||||
self.__read_book_marker = {'field':f, 'pattern':p}
|
||||
f, p, hr = self.opts.merge_comments.split(':')
|
||||
self.__merge_comments = {'field':f, 'position':p, 'hr':hr}
|
||||
self.__reporter = report_progress
|
||||
self.__stylesheet = stylesheet
|
||||
self.__thumbs = None
|
||||
self.__thumbWidth = 0
|
||||
self.__thumbHeight = 0
|
||||
self.__title = opts.catalog_title
|
||||
self.__totalSteps = 11.0
|
||||
self.__totalSteps = 8.0
|
||||
self.__useSeriesPrefixInTitlesSection = False
|
||||
self.__verbose = opts.verbose
|
||||
|
||||
@ -916,17 +944,36 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
self.__output_profile = profile
|
||||
break
|
||||
|
||||
# Confirm/create thumbs archive
|
||||
# Confirm/create thumbs archive.
|
||||
if not os.path.exists(self.__cache_dir):
|
||||
self.opts.log.info(" creating new thumb cache '%s'" % self.__cache_dir)
|
||||
os.makedirs(self.__cache_dir)
|
||||
if not os.path.exists(self.__archive_path):
|
||||
self.opts.log.info(" creating thumbnail archive")
|
||||
self.opts.log.info(' creating thumbnail archive, thumb_width: %1.2f"' %
|
||||
float(self.opts.thumb_width))
|
||||
zfw = ZipFile(self.__archive_path, mode='w')
|
||||
zfw.writestr("Catalog Thumbs Archive",'')
|
||||
zfw.comment = "thumb_width: %1.2f" % float(self.opts.thumb_width)
|
||||
zfw.close()
|
||||
else:
|
||||
self.opts.log.info(" existing thumb cache at '%s'" % self.__archive_path)
|
||||
with closing(ZipFile(self.__archive_path, mode='r')) as zfr:
|
||||
try:
|
||||
cached_thumb_width = float(zfr.comment[len('thumb_width: '):])
|
||||
except:
|
||||
cached_thumb_width = "0.0"
|
||||
|
||||
if float(cached_thumb_width) != float(self.opts.thumb_width):
|
||||
self.opts.log.info(" invalidating cache at '%s'" % self.__archive_path)
|
||||
self.opts.log.info(' thumb_width: %1.2f" => %1.2f"' %
|
||||
(float(cached_thumb_width),float(self.opts.thumb_width)))
|
||||
os.remove(self.__archive_path)
|
||||
zfw = ZipFile(self.__archive_path, mode='w')
|
||||
zfw.writestr("Catalog Thumbs Archive",'')
|
||||
zfw.comment = "thumb_width: %1.2f" % float(self.opts.thumb_width)
|
||||
zfw.close()
|
||||
else:
|
||||
self.opts.log.info(' existing thumb cache at %s, cached_thumb_width: %1.2f"' %
|
||||
(self.__archive_path, float(cached_thumb_width)))
|
||||
|
||||
# Tweak build steps based on optional sections: 1 call for HTML, 1 for NCX
|
||||
if self.opts.generate_titles:
|
||||
@ -937,6 +984,9 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
self.__totalSteps += 2
|
||||
if self.opts.generate_series:
|
||||
self.__totalSteps += 2
|
||||
if self.opts.generate_descriptions:
|
||||
# +1 thumbs
|
||||
self.__totalSteps += 3
|
||||
|
||||
# Accessors
|
||||
if True:
|
||||
@ -1246,7 +1296,8 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
return False
|
||||
self.fetchBooksByAuthor()
|
||||
self.fetchBookmarks()
|
||||
self.generateHTMLDescriptions()
|
||||
if self.opts.generate_descriptions:
|
||||
self.generateHTMLDescriptions()
|
||||
self.generateHTMLByAuthor()
|
||||
if self.opts.generate_titles:
|
||||
self.generateHTMLByTitle()
|
||||
@ -1256,10 +1307,10 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
self.generateHTMLByDateAdded()
|
||||
if self.generateRecentlyRead:
|
||||
self.generateHTMLByDateRead()
|
||||
self.generateHTMLByTags()
|
||||
|
||||
self.generateThumbnails()
|
||||
|
||||
if self.opts.generate_genres:
|
||||
self.generateHTMLByTags()
|
||||
if self.opts.generate_descriptions:
|
||||
self.generateThumbnails()
|
||||
self.generateOPF()
|
||||
self.generateNCXHeader()
|
||||
self.generateNCXByAuthor("Authors")
|
||||
@ -1271,8 +1322,11 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
self.generateNCXByDateAdded("Recently Added")
|
||||
if self.generateRecentlyRead:
|
||||
self.generateNCXByDateRead("Recently Read")
|
||||
self.generateNCXByGenre("Genres")
|
||||
self.generateNCXDescriptions("Descriptions")
|
||||
if self.opts.generate_genres:
|
||||
self.generateNCXByGenre("Genres")
|
||||
if self.opts.generate_descriptions:
|
||||
self.generateNCXDescriptions("Descriptions")
|
||||
|
||||
self.writeNCX()
|
||||
return True
|
||||
|
||||
@ -1340,6 +1394,7 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
#print "fetchBooksByTitle(): opts.search_text: %s" % self.opts.search_text
|
||||
# Fetch the database as a dictionary
|
||||
data = self.plugin.search_sort_db(self.db, self.opts)
|
||||
data = self.processExclusions(data)
|
||||
|
||||
# Populate this_title{} from data[{},{}]
|
||||
titles = []
|
||||
@ -1388,6 +1443,8 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
record['comments'] = record['comments'][:ad_offset]
|
||||
|
||||
this_title['description'] = self.markdownComments(record['comments'])
|
||||
|
||||
# Create short description
|
||||
paras = BeautifulSoup(this_title['description']).findAll('p')
|
||||
tokens = []
|
||||
for p in paras:
|
||||
@ -1399,6 +1456,10 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
this_title['description'] = None
|
||||
this_title['short_description'] = None
|
||||
|
||||
# Merge with custom field/value
|
||||
if self.__merge_comments['field']:
|
||||
this_title['description'] = self.mergeComments(this_title)
|
||||
|
||||
if record['cover']:
|
||||
this_title['cover'] = re.sub('&', '&', record['cover'])
|
||||
|
||||
@ -1413,6 +1474,14 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
formats.append(self.convertHTMLEntities(format))
|
||||
this_title['formats'] = formats
|
||||
|
||||
# Add user notes to be displayed in header
|
||||
if self.opts.header_note_source_field:
|
||||
notes = self.__db.get_field(record['id'],
|
||||
self.opts.header_note_source_field,
|
||||
index_is_id=True)
|
||||
if notes:
|
||||
this_title['notes'] = notes
|
||||
|
||||
titles.append(this_title)
|
||||
|
||||
# Re-sort based on title_sort
|
||||
@ -1712,7 +1781,8 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
for tag in title.get('tags', []):
|
||||
aTag = Tag(soup,'a')
|
||||
#print "aTag: %s" % "Genre_%s.html" % re.sub("\W","",tag.lower())
|
||||
aTag['href'] = "Genre_%s.html" % re.sub("\W","",tag.lower())
|
||||
if self.opts.generate_genres:
|
||||
aTag['href'] = "Genre_%s.html" % re.sub("\W","",tag.lower())
|
||||
aTag.insert(0,escape(NavigableString(tag)))
|
||||
emTag = Tag(soup, "em")
|
||||
emTag.insert(0, aTag)
|
||||
@ -1771,7 +1841,6 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
#ratingLabel = body.find('td',text="Rating").replaceWith("Unrated")
|
||||
ratingTag.insert(0,NavigableString('<br/>'))
|
||||
|
||||
|
||||
# Insert user notes or remove Notes label. Notes > 1 line will push formatting down
|
||||
if 'notes' in title:
|
||||
notesTag = body.find(attrs={'class':'notes'})
|
||||
@ -1894,7 +1963,8 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
|
||||
# Link to book
|
||||
aTag = Tag(soup, "a")
|
||||
aTag['href'] = "book_%d.html" % (int(float(book['id'])))
|
||||
if self.opts.generate_descriptions:
|
||||
aTag['href'] = "book_%d.html" % (int(float(book['id'])))
|
||||
aTag.insert(0,escape(book['title']))
|
||||
pBookTag.insert(ptc, aTag)
|
||||
ptc += 1
|
||||
@ -2067,8 +2137,9 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
ptc += 1
|
||||
|
||||
aTag = Tag(soup, "a")
|
||||
aTag['href'] = "book_%d.html" % (int(float(book['id'])))
|
||||
# Use series, series index if avail else just title, + year of publication
|
||||
if self.opts.generate_descriptions:
|
||||
aTag['href'] = "book_%d.html" % (int(float(book['id'])))
|
||||
# Use series, series index if avail else title, + year of publication
|
||||
if current_series:
|
||||
aTag.insert(0,'%s (%s)' % (escape(book['title'][len(book['series'])+1:]),
|
||||
book['date'].split()[1]))
|
||||
@ -2079,7 +2150,6 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
pBookTag.insert(ptc, aTag)
|
||||
ptc += 1
|
||||
|
||||
|
||||
divTag.insert(dtc, pBookTag)
|
||||
dtc += 1
|
||||
|
||||
@ -2200,7 +2270,8 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
ptc += 1
|
||||
|
||||
aTag = Tag(soup, "a")
|
||||
aTag['href'] = "book_%d.html" % (int(float(new_entry['id'])))
|
||||
if self.opts.generate_descriptions:
|
||||
aTag['href'] = "book_%d.html" % (int(float(new_entry['id'])))
|
||||
if current_series:
|
||||
aTag.insert(0,escape(new_entry['title'][len(new_entry['series'])+1:]))
|
||||
else:
|
||||
@ -2251,7 +2322,8 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
ptc += 1
|
||||
|
||||
aTag = Tag(soup, "a")
|
||||
aTag['href'] = "book_%d.html" % (int(float(new_entry['id'])))
|
||||
if self.opts.generate_descriptions:
|
||||
aTag['href'] = "book_%d.html" % (int(float(new_entry['id'])))
|
||||
aTag.insert(0,escape(new_entry['title']))
|
||||
pBookTag.insert(ptc, aTag)
|
||||
ptc += 1
|
||||
@ -2411,7 +2483,8 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
ptc += 1
|
||||
|
||||
aTag = Tag(soup, "a")
|
||||
aTag['href'] = "book_%d.html" % (int(float(new_entry['id'])))
|
||||
if self.opts.generate_descriptions:
|
||||
aTag['href'] = "book_%d.html" % (int(float(new_entry['id'])))
|
||||
aTag.insert(0,escape(new_entry['title']))
|
||||
pBookTag.insert(ptc, aTag)
|
||||
ptc += 1
|
||||
@ -2458,7 +2531,8 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
ptc += 1
|
||||
|
||||
aTag = Tag(soup, "a")
|
||||
aTag['href'] = "book_%d.html" % (int(float(new_entry['id'])))
|
||||
if self.opts.generate_descriptions:
|
||||
aTag['href'] = "book_%d.html" % (int(float(new_entry['id'])))
|
||||
aTag.insert(0,escape(new_entry['title']))
|
||||
pBookTag.insert(ptc, aTag)
|
||||
ptc += 1
|
||||
@ -2699,7 +2773,8 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
ptc += 1
|
||||
|
||||
aTag = Tag(soup, "a")
|
||||
aTag['href'] = "book_%d.html" % (int(float(book['id'])))
|
||||
if self.opts.generate_descriptions:
|
||||
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'])))
|
||||
|
||||
@ -2983,18 +3058,20 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
manifest.insert(mtc, itemTag)
|
||||
mtc += 1
|
||||
|
||||
# Write the thumbnail images to the manifest
|
||||
for thumb in self.thumbs:
|
||||
itemTag = Tag(soup, "item")
|
||||
itemTag['href'] = "images/%s" % (thumb)
|
||||
end = thumb.find('.jpg')
|
||||
itemTag['id'] = "%s-image" % thumb[:end]
|
||||
itemTag['media-type'] = 'image/jpeg'
|
||||
manifest.insert(mtc, itemTag)
|
||||
mtc += 1
|
||||
# Write the thumbnail images, descriptions to the manifest
|
||||
sort_descriptions_by = []
|
||||
if self.opts.generate_descriptions:
|
||||
for thumb in self.thumbs:
|
||||
itemTag = Tag(soup, "item")
|
||||
itemTag['href'] = "images/%s" % (thumb)
|
||||
end = thumb.find('.jpg')
|
||||
itemTag['id'] = "%s-image" % thumb[:end]
|
||||
itemTag['media-type'] = 'image/jpeg'
|
||||
manifest.insert(mtc, itemTag)
|
||||
mtc += 1
|
||||
|
||||
# HTML files - add books to manifest and spine
|
||||
sort_descriptions_by = self.booksByAuthor if self.opts.sort_descriptions_by_author \
|
||||
# HTML files - add descriptions to manifest and spine
|
||||
sort_descriptions_by = self.booksByAuthor if self.opts.sort_descriptions_by_author \
|
||||
else self.booksByTitle
|
||||
# Add html_files to manifest and spine
|
||||
|
||||
@ -3970,15 +4047,15 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
from calibre.customize.ui import output_profiles
|
||||
for x in output_profiles():
|
||||
if x.short_name == self.opts.output_profile:
|
||||
# .9" width aspect ratio: 3:4
|
||||
self.thumbWidth = int(x.dpi * 1)
|
||||
self.thumbHeight = int(self.thumbWidth * 1.33)
|
||||
# aspect ratio: 3:4
|
||||
self.thumbWidth = x.dpi * float(self.opts.thumb_width)
|
||||
self.thumbHeight = self.thumbWidth * 1.33
|
||||
if 'kindle' in x.short_name and self.opts.fmt == 'mobi':
|
||||
# Kindle DPI appears to be off by a factor of 2
|
||||
self.thumbWidth = int(self.thumbWidth/2)
|
||||
self.thumbHeight = int(self.thumbHeight/2)
|
||||
self.thumbWidth = self.thumbWidth/2
|
||||
self.thumbHeight = self.thumbHeight/2
|
||||
break
|
||||
if False and self.verbose:
|
||||
if True and self.verbose:
|
||||
self.opts.log(" DPI = %d; thumbnail dimensions: %d x %d" % \
|
||||
(x.dpi, self.thumbWidth, self.thumbHeight))
|
||||
|
||||
@ -4238,7 +4315,8 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
|
||||
# Add the book title
|
||||
aTag = Tag(soup, "a")
|
||||
aTag['href'] = "book_%d.html" % (int(float(book['id'])))
|
||||
if self.opts.generate_descriptions:
|
||||
aTag['href'] = "book_%d.html" % (int(float(book['id'])))
|
||||
# Use series, series index if avail else just title
|
||||
if current_series:
|
||||
aTag.insert(0,escape(book['title'][len(book['series'])+1:]))
|
||||
@ -4460,7 +4538,9 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
# Leading numbers optionally translated to text equivalent
|
||||
# Capitalize leading sort word
|
||||
if i==0:
|
||||
if self.opts.numbers_as_text and re.match('[0-9]+',word[0]):
|
||||
# *** Keep this code in case we need to restore numbers_as_text ***
|
||||
if False:
|
||||
#if self.opts.numbers_as_text and re.match('[0-9]+',word[0]):
|
||||
translated.append(EPUB_MOBI.NumberToText(word).text.capitalize())
|
||||
else:
|
||||
if re.match('[0-9]+',word[0]):
|
||||
@ -4540,7 +4620,6 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
''' Return a list of special marker tags to be excluded from genre list '''
|
||||
markerTags = []
|
||||
markerTags.extend(self.opts.exclude_tags.split(','))
|
||||
markerTags.extend(self.opts.note_tag.split(','))
|
||||
return markerTags
|
||||
|
||||
def letter_or_symbol(self,char):
|
||||
@ -4663,13 +4742,63 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
|
||||
return result.renderContents(encoding=None)
|
||||
|
||||
def mergeComments(self, record):
|
||||
'''
|
||||
merge ['description'] with custom field contents to be displayed in Descriptions
|
||||
'''
|
||||
merged = ''
|
||||
if record['description']:
|
||||
addendum = self.__db.get_field(record['id'],
|
||||
self.__merge_comments['field'],
|
||||
index_is_id=True)
|
||||
include_hr = eval(self.__merge_comments['hr'])
|
||||
if self.__merge_comments['position'] == 'before':
|
||||
merged = addendum
|
||||
if include_hr:
|
||||
merged += '<hr class="merged_comments_divider"/>'
|
||||
else:
|
||||
merged += '\n'
|
||||
merged += record['description']
|
||||
else:
|
||||
merged = record['description']
|
||||
if include_hr:
|
||||
merged += '<hr class="merged_comments_divider"/>'
|
||||
else:
|
||||
merged += '\n'
|
||||
merged += addendum
|
||||
else:
|
||||
# Return the custom field contents
|
||||
merged = self.__db.get_field(record['id'],
|
||||
self.__merge_comments['field'],
|
||||
index_is_id=True)
|
||||
|
||||
return merged
|
||||
|
||||
def processExclusions(self, data_set):
|
||||
'''
|
||||
Remove excluded entries
|
||||
'''
|
||||
field, pat = self.opts.exclude_book_marker.split(':')
|
||||
if pat == '':
|
||||
return data_set
|
||||
filtered_data_set = []
|
||||
for record in data_set:
|
||||
field_contents = self.__db.get_field(record['id'],
|
||||
field,
|
||||
index_is_id=True)
|
||||
if field_contents:
|
||||
if re.search(pat, unicode(field_contents),
|
||||
re.IGNORECASE) is not None:
|
||||
continue
|
||||
filtered_data_set.append(record)
|
||||
|
||||
return filtered_data_set
|
||||
|
||||
def processSpecialTags(self, tags, this_title, opts):
|
||||
tag_list = []
|
||||
for tag in tags:
|
||||
tag = self.convertHTMLEntities(tag)
|
||||
if tag.startswith(opts.note_tag):
|
||||
this_title['notes'] = tag[len(self.opts.note_tag):]
|
||||
elif re.search(opts.exclude_genre, tag):
|
||||
if re.search(opts.exclude_genre, tag):
|
||||
continue
|
||||
elif self.__read_book_marker['field'] == 'tag' and \
|
||||
tag == self.__read_book_marker['pattern']:
|
||||
@ -4767,13 +4896,16 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
if opts_dict['ids']:
|
||||
build_log.append(" book count: %d" % len(opts_dict['ids']))
|
||||
|
||||
sections_list = ['Descriptions','Authors']
|
||||
sections_list = ['Authors']
|
||||
if opts.generate_titles:
|
||||
sections_list.append('Titles')
|
||||
if opts.generate_recently_added:
|
||||
sections_list.append('Recently Added')
|
||||
if not opts.exclude_genre.strip() == '.':
|
||||
if opts.generate_genres:
|
||||
sections_list.append('Genres')
|
||||
if opts.generate_descriptions:
|
||||
sections_list.append('Descriptions')
|
||||
|
||||
build_log.append(u" Sections: %s" % ', '.join(sections_list))
|
||||
|
||||
# Display opts
|
||||
@ -4782,11 +4914,12 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
build_log.append(" opts:")
|
||||
for key in keys:
|
||||
if key in ['catalog_title','authorClip','connected_kindle','descriptionClip',
|
||||
'exclude_genre','exclude_tags','note_tag','numbers_as_text',
|
||||
'exclude_book_marker','exclude_genre','exclude_tags',
|
||||
'header_note_source_field','merge_comments',
|
||||
'output_profile','read_book_marker',
|
||||
'search_text','sort_by','sort_descriptions_by_author','sync',
|
||||
'wishlist_tag']:
|
||||
build_log.append(" %s: %s" % (key, opts_dict[key]))
|
||||
'thumb_width','wishlist_tag']:
|
||||
build_log.append(" %s: %s" % (key, repr(opts_dict[key])))
|
||||
|
||||
if opts.verbose:
|
||||
log('\n'.join(line for line in build_log))
|
||||
@ -4801,6 +4934,7 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
catalog.copyResources()
|
||||
catalog.calculateThumbnailSize()
|
||||
catalog_source_built = catalog.buildSources()
|
||||
|
||||
if opts.verbose:
|
||||
if catalog_source_built:
|
||||
log.info(" Completed catalog source generation\n")
|
||||
|
Loading…
x
Reference in New Issue
Block a user