mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
First implementation of plugboards
This commit is contained in:
parent
73cdb91e61
commit
1dee223f14
@ -796,6 +796,17 @@ class Sending(PreferencesPlugin):
|
|||||||
description = _('Control how calibre transfers files to your '
|
description = _('Control how calibre transfers files to your '
|
||||||
'ebook reader')
|
'ebook reader')
|
||||||
|
|
||||||
|
class Plugboard(PreferencesPlugin):
|
||||||
|
name = 'Plugboard'
|
||||||
|
icon = I('plugboard.png')
|
||||||
|
gui_name = _('Metadata plugboard')
|
||||||
|
category = 'Import/Export'
|
||||||
|
gui_category = _('Import/Export')
|
||||||
|
category_order = 3
|
||||||
|
name_order = 4
|
||||||
|
config_widget = 'calibre.gui2.preferences.plugboard'
|
||||||
|
description = _('Change metadata fields before saving/sending')
|
||||||
|
|
||||||
class Email(PreferencesPlugin):
|
class Email(PreferencesPlugin):
|
||||||
name = 'Email'
|
name = 'Email'
|
||||||
icon = I('mail.png')
|
icon = I('mail.png')
|
||||||
@ -856,8 +867,8 @@ class Misc(PreferencesPlugin):
|
|||||||
description = _('Miscellaneous advanced configuration')
|
description = _('Miscellaneous advanced configuration')
|
||||||
|
|
||||||
plugins += [LookAndFeel, Behavior, Columns, Toolbar, InputOptions,
|
plugins += [LookAndFeel, Behavior, Columns, Toolbar, InputOptions,
|
||||||
CommonOptions, OutputOptions, Adding, Saving, Sending, Email, Server,
|
CommonOptions, OutputOptions, Adding, Saving, Sending, Plugboard,
|
||||||
Plugins, Tweaks, Misc]
|
Email, Server, Plugins, Tweaks, Misc]
|
||||||
|
|
||||||
#}}}
|
#}}}
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ class Metadata(object):
|
|||||||
return metadata describing a standard or custom field.
|
return metadata describing a standard or custom field.
|
||||||
'''
|
'''
|
||||||
if key not in self.custom_field_keys():
|
if key not in self.custom_field_keys():
|
||||||
return self.get_standard_metadata(self, key, make_copy=False)
|
return self.get_standard_metadata(key, make_copy=False)
|
||||||
return self.get_user_metadata(key, make_copy=False)
|
return self.get_user_metadata(key, make_copy=False)
|
||||||
|
|
||||||
def all_non_none_fields(self):
|
def all_non_none_fields(self):
|
||||||
@ -294,6 +294,33 @@ class Metadata(object):
|
|||||||
_data = object.__getattribute__(self, '_data')
|
_data = object.__getattribute__(self, '_data')
|
||||||
_data['user_metadata'][field] = metadata
|
_data['user_metadata'][field] = metadata
|
||||||
|
|
||||||
|
def copy_specific_attributes(self, other, attrs):
|
||||||
|
'''
|
||||||
|
Takes a dict {src:dest, src:dest} and copys other[src] to self[dest].
|
||||||
|
This is on a best-efforts basis. Some assignments can make no sense.
|
||||||
|
'''
|
||||||
|
if not attrs:
|
||||||
|
return
|
||||||
|
for src in attrs:
|
||||||
|
try:
|
||||||
|
print src
|
||||||
|
sfm = other.metadata_for_field(src)
|
||||||
|
dfm = self.metadata_for_field(attrs[src])
|
||||||
|
if dfm['is_multiple']:
|
||||||
|
if sfm['is_multiple']:
|
||||||
|
self.set(attrs[src], other.get(src))
|
||||||
|
else:
|
||||||
|
self.set(attrs[src],
|
||||||
|
[f.strip() for f in other.get(src).split(',')
|
||||||
|
if f.strip()])
|
||||||
|
elif sfm['is_multiple']:
|
||||||
|
self.set(attrs[src], ','.join(other.get(src)))
|
||||||
|
else:
|
||||||
|
self.set(attrs[src], other.get(src))
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
pass
|
||||||
|
|
||||||
# Old Metadata API {{{
|
# Old Metadata API {{{
|
||||||
def print_all_attributes(self):
|
def print_all_attributes(self):
|
||||||
for x in STANDARD_METADATA_FIELDS:
|
for x in STANDARD_METADATA_FIELDS:
|
||||||
|
@ -317,19 +317,40 @@ class DeviceManager(Thread): # {{{
|
|||||||
args=[booklist, on_card],
|
args=[booklist, on_card],
|
||||||
description=_('Send collections to device'))
|
description=_('Send collections to device'))
|
||||||
|
|
||||||
def _upload_books(self, files, names, on_card=None, metadata=None):
|
def _upload_books(self, files, names, on_card=None, metadata=None, plugboards=None):
|
||||||
'''Upload books to device: '''
|
'''Upload books to device: '''
|
||||||
if metadata and files and len(metadata) == len(files):
|
if metadata and files and len(metadata) == len(files):
|
||||||
for f, mi in zip(files, metadata):
|
for f, mi in zip(files, metadata):
|
||||||
if isinstance(f, unicode):
|
if isinstance(f, unicode):
|
||||||
ext = f.rpartition('.')[-1].lower()
|
ext = f.rpartition('.')[-1].lower()
|
||||||
|
dev_name = self.connected_device.name
|
||||||
|
cpb = None
|
||||||
|
if ext in plugboards:
|
||||||
|
cpb = plugboards[ext]
|
||||||
|
elif ' any' in plugboards:
|
||||||
|
cpb = plugboards[' any']
|
||||||
|
if cpb is not None:
|
||||||
|
if dev_name in cpb:
|
||||||
|
cpb = cpb[dev_name]
|
||||||
|
elif ' any' in plugboards[ext]:
|
||||||
|
cpb = cpb[' any']
|
||||||
|
else:
|
||||||
|
cpb = None
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
prints('Using plugboard', cpb)
|
||||||
if ext:
|
if ext:
|
||||||
try:
|
try:
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
prints('Setting metadata in:', mi.title, 'at:',
|
prints('Setting metadata in:', mi.title, 'at:',
|
||||||
f, file=sys.__stdout__)
|
f, file=sys.__stdout__)
|
||||||
with open(f, 'r+b') as stream:
|
with open(f, 'r+b') as stream:
|
||||||
set_metadata(stream, mi, stream_type=ext)
|
if cpb:
|
||||||
|
newmi = mi.deepcopy()
|
||||||
|
newmi.copy_specific_attributes(mi, cpb)
|
||||||
|
else:
|
||||||
|
newmi = mi
|
||||||
|
set_metadata(stream, newmi, stream_type=ext)
|
||||||
except:
|
except:
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
prints(traceback.format_exc(), file=sys.__stdout__)
|
prints(traceback.format_exc(), file=sys.__stdout__)
|
||||||
@ -338,12 +359,12 @@ class DeviceManager(Thread): # {{{
|
|||||||
metadata=metadata, end_session=False)
|
metadata=metadata, end_session=False)
|
||||||
|
|
||||||
def upload_books(self, done, files, names, on_card=None, titles=None,
|
def upload_books(self, done, files, names, on_card=None, titles=None,
|
||||||
metadata=None):
|
metadata=None, plugboards=None):
|
||||||
desc = _('Upload %d books to device')%len(names)
|
desc = _('Upload %d books to device')%len(names)
|
||||||
if titles:
|
if titles:
|
||||||
desc += u':' + u', '.join(titles)
|
desc += u':' + u', '.join(titles)
|
||||||
return self.create_job(self._upload_books, done, args=[files, names],
|
return self.create_job(self._upload_books, done, args=[files, names],
|
||||||
kwargs={'on_card':on_card,'metadata':metadata}, description=desc)
|
kwargs={'on_card':on_card,'metadata':metadata,'plugboards':plugboards}, description=desc)
|
||||||
|
|
||||||
def add_books_to_metadata(self, locations, metadata, booklists):
|
def add_books_to_metadata(self, locations, metadata, booklists):
|
||||||
self.device.add_books_to_metadata(locations, metadata, booklists)
|
self.device.add_books_to_metadata(locations, metadata, booklists)
|
||||||
@ -1257,10 +1278,11 @@ class DeviceMixin(object): # {{{
|
|||||||
:param files: List of either paths to files or file like objects
|
:param files: List of either paths to files or file like objects
|
||||||
'''
|
'''
|
||||||
titles = [i.title for i in metadata]
|
titles = [i.title for i in metadata]
|
||||||
|
plugboards = self.library_view.model().db.prefs.get('plugboards', None)
|
||||||
job = self.device_manager.upload_books(
|
job = self.device_manager.upload_books(
|
||||||
Dispatcher(self.books_uploaded),
|
Dispatcher(self.books_uploaded),
|
||||||
files, names, on_card=on_card,
|
files, names, on_card=on_card,
|
||||||
metadata=metadata, titles=titles
|
metadata=metadata, titles=titles, plugboards=plugboards
|
||||||
)
|
)
|
||||||
self.upload_memory[job] = (metadata, on_card, memory, files)
|
self.upload_memory[job] = (metadata, on_card, memory, files)
|
||||||
|
|
||||||
|
257
src/calibre/gui2/preferences/plugboard.py
Normal file
257
src/calibre/gui2/preferences/plugboard.py
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
|
from PyQt4 import QtGui
|
||||||
|
|
||||||
|
from calibre.gui2 import error_dialog
|
||||||
|
from calibre.gui2.preferences import ConfigWidgetBase, test_widget, \
|
||||||
|
AbortCommit
|
||||||
|
from calibre.gui2.preferences.plugboard_ui import Ui_Form
|
||||||
|
from calibre.customize.ui import metadata_writers, device_plugins
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||||
|
|
||||||
|
def genesis(self, gui):
|
||||||
|
self.gui = gui
|
||||||
|
self.db = gui.library_view.model().db
|
||||||
|
self.current_plugboards = self.db.prefs.get('plugboards', {'epub': {' any': {'title':'authors', 'authors':'tags'}}})
|
||||||
|
self.current_device = None
|
||||||
|
self.current_format = None
|
||||||
|
# self.proxy = ConfigProxy(config())
|
||||||
|
#
|
||||||
|
# r = self.register
|
||||||
|
#
|
||||||
|
# for x in ('asciiize', 'update_metadata', 'save_cover', 'write_opf',
|
||||||
|
# 'replace_whitespace', 'to_lowercase', 'formats', 'timefmt'):
|
||||||
|
# r(x, self.proxy)
|
||||||
|
#
|
||||||
|
# self.save_template.changed_signal.connect(self.changed_signal.emit)
|
||||||
|
|
||||||
|
def clear_fields(self, edit_boxes=False, new_boxes=False):
|
||||||
|
self.ok_button.setEnabled(False)
|
||||||
|
for w in self.source_widgets:
|
||||||
|
w.clear()
|
||||||
|
for w in self.dest_widgets:
|
||||||
|
w.clear()
|
||||||
|
if edit_boxes:
|
||||||
|
self.edit_device.setCurrentIndex(0)
|
||||||
|
self.edit_format.setCurrentIndex(0)
|
||||||
|
if new_boxes:
|
||||||
|
self.new_device.setCurrentIndex(0)
|
||||||
|
self.new_format.setCurrentIndex(0)
|
||||||
|
|
||||||
|
def set_fields(self):
|
||||||
|
self.ok_button.setEnabled(True)
|
||||||
|
for w in self.source_widgets:
|
||||||
|
w.addItems(self.fields)
|
||||||
|
for w in self.dest_widgets:
|
||||||
|
w.addItems(self.fields)
|
||||||
|
|
||||||
|
def set_field(self, i, src, dst):
|
||||||
|
print i, src, dst
|
||||||
|
idx = self.fields.index(src)
|
||||||
|
self.source_widgets[i].setCurrentIndex(idx)
|
||||||
|
idx = self.fields.index(dst)
|
||||||
|
self.dest_widgets[i].setCurrentIndex(idx)
|
||||||
|
|
||||||
|
def edit_device_changed(self, txt):
|
||||||
|
if txt == '':
|
||||||
|
self.current_device = None
|
||||||
|
return
|
||||||
|
print 'edit device changed'
|
||||||
|
self.clear_fields(new_boxes=True)
|
||||||
|
self.current_device = unicode(txt)
|
||||||
|
fpb = self.current_plugboards.get(self.current_format, None)
|
||||||
|
if fpb is None:
|
||||||
|
print 'None format!'
|
||||||
|
return
|
||||||
|
dpb = fpb.get(self.current_device, None)
|
||||||
|
if dpb is None:
|
||||||
|
print 'none device!'
|
||||||
|
return
|
||||||
|
self.set_fields()
|
||||||
|
for i,src in enumerate(dpb):
|
||||||
|
self.set_field(i, src, dpb[src])
|
||||||
|
self.ok_button.setEnabled(True)
|
||||||
|
|
||||||
|
def edit_format_changed(self, txt):
|
||||||
|
if txt == '':
|
||||||
|
self.edit_device.setCurrentIndex(0)
|
||||||
|
self.current_format = None
|
||||||
|
self.current_device = None
|
||||||
|
return
|
||||||
|
print 'edit_format_changed'
|
||||||
|
self.clear_fields(new_boxes=True)
|
||||||
|
txt = unicode(txt)
|
||||||
|
fpb = self.current_plugboards.get(txt, None)
|
||||||
|
if fpb is None:
|
||||||
|
print 'None editable format!'
|
||||||
|
return
|
||||||
|
self.current_format = txt
|
||||||
|
devices = ['']
|
||||||
|
for d in fpb:
|
||||||
|
devices.append(d)
|
||||||
|
self.edit_device.clear()
|
||||||
|
self.edit_device.addItems(devices)
|
||||||
|
self.edit_device.setCurrentIndex(0)
|
||||||
|
|
||||||
|
def new_device_changed(self, txt):
|
||||||
|
if txt == '':
|
||||||
|
self.current_device = None
|
||||||
|
return
|
||||||
|
print 'new_device_changed'
|
||||||
|
self.clear_fields(edit_boxes=True)
|
||||||
|
self.current_device = unicode(txt)
|
||||||
|
error = False
|
||||||
|
if self.current_format == ' any':
|
||||||
|
for f in self.current_plugboards:
|
||||||
|
if self.current_device == ' any' and len(self.current_plugboards[f]):
|
||||||
|
error = True
|
||||||
|
break
|
||||||
|
if self.current_device in self.current_plugboards[f]:
|
||||||
|
error = True
|
||||||
|
break
|
||||||
|
if ' any' in self.current_plugboards[f]:
|
||||||
|
error = True
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
fpb = self.current_plugboards.get(self.current_format, None)
|
||||||
|
if fpb is not None:
|
||||||
|
if ' any' in fpb:
|
||||||
|
error = True
|
||||||
|
else:
|
||||||
|
dpb = fpb.get(self.current_device, None)
|
||||||
|
if dpb is not None:
|
||||||
|
error = True
|
||||||
|
|
||||||
|
if error:
|
||||||
|
error_dialog(self, '',
|
||||||
|
_('That format and device already has a plugboard'),
|
||||||
|
show=True)
|
||||||
|
self.new_device.setCurrentIndex(0)
|
||||||
|
return
|
||||||
|
self.set_fields()
|
||||||
|
|
||||||
|
def new_format_changed(self, txt):
|
||||||
|
if txt == '':
|
||||||
|
self.current_format = None
|
||||||
|
self.current_device = None
|
||||||
|
return
|
||||||
|
print 'new_format_changed'
|
||||||
|
self.clear_fields(edit_boxes=True)
|
||||||
|
self.current_format = unicode(txt)
|
||||||
|
self.new_device.setCurrentIndex(0)
|
||||||
|
|
||||||
|
def ok_clicked(self):
|
||||||
|
pb = {}
|
||||||
|
print self.current_format, self.current_device
|
||||||
|
for i in range(0, len(self.source_widgets)):
|
||||||
|
s = self.source_widgets[i].currentIndex()
|
||||||
|
if s != 0:
|
||||||
|
d = self.dest_widgets[i].currentIndex()
|
||||||
|
if d != 0:
|
||||||
|
pb[self.fields[s]] = self.fields[d]
|
||||||
|
if len(pb) == 0:
|
||||||
|
if self.current_format in self.current_plugboards:
|
||||||
|
fpb = self.current_plugboards[self.current_format]
|
||||||
|
if self.current_device in fpb:
|
||||||
|
del fpb[self.current_device]
|
||||||
|
if len(fpb) == 0:
|
||||||
|
del self.current_plugboards[self.current_format]
|
||||||
|
else:
|
||||||
|
if self.current_format not in self.current_plugboards:
|
||||||
|
self.current_plugboards[self.current_format] = {}
|
||||||
|
fpb = self.current_plugboards[self.current_format]
|
||||||
|
fpb[self.current_device] = pb
|
||||||
|
self.changed_signal.emit()
|
||||||
|
self.refill_all_boxes()
|
||||||
|
|
||||||
|
def refill_all_boxes(self):
|
||||||
|
self.current_device = None
|
||||||
|
self.current_format = None
|
||||||
|
self.clear_fields(new_boxes=True)
|
||||||
|
self.edit_format.clear()
|
||||||
|
self.edit_format.addItem('')
|
||||||
|
for format in self.current_plugboards:
|
||||||
|
self.edit_format.addItem(format)
|
||||||
|
self.edit_format.setCurrentIndex(0)
|
||||||
|
self.edit_device.clear()
|
||||||
|
self.ok_button.setEnabled(False)
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
def field_cmp(x, y):
|
||||||
|
if x.startswith('#'):
|
||||||
|
if y.startswith('#'):
|
||||||
|
return cmp(x.lower(), y.lower())
|
||||||
|
else:
|
||||||
|
return 1
|
||||||
|
elif y.startswith('#'):
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
return cmp(x.lower(), y.lower())
|
||||||
|
|
||||||
|
ConfigWidgetBase.initialize(self)
|
||||||
|
|
||||||
|
self.devices = ['', ' any', 'save to disk']
|
||||||
|
for device in device_plugins():
|
||||||
|
self.devices.append(device.name)
|
||||||
|
self.devices.sort(cmp=lambda x, y: cmp(x.lower(), y.lower()))
|
||||||
|
self.new_device.addItems(self.devices)
|
||||||
|
|
||||||
|
self.formats = ['', ' any']
|
||||||
|
for w in metadata_writers():
|
||||||
|
for f in w.file_types:
|
||||||
|
self.formats.append(f)
|
||||||
|
self.formats.sort()
|
||||||
|
self.new_format.addItems(self.formats)
|
||||||
|
|
||||||
|
self.fields = ['']
|
||||||
|
for f in self.db.all_field_keys():
|
||||||
|
if self.db.field_metadata[f].get('rec_index', None) is not None and\
|
||||||
|
self.db.field_metadata[f]['datatype'] is not None and \
|
||||||
|
self.db.field_metadata[f]['search_terms']:
|
||||||
|
self.fields.append(f)
|
||||||
|
self.fields.sort(cmp=field_cmp)
|
||||||
|
|
||||||
|
self.source_widgets = []
|
||||||
|
self.dest_widgets = []
|
||||||
|
for i in range(0, 10):
|
||||||
|
w = QtGui.QComboBox(self)
|
||||||
|
self.source_widgets.append(w)
|
||||||
|
self.fields_layout.addWidget(w, 5+i, 0, 1, 1)
|
||||||
|
w = QtGui.QComboBox(self)
|
||||||
|
self.dest_widgets.append(w)
|
||||||
|
self.fields_layout.addWidget(w, 5+i, 1, 1, 1)
|
||||||
|
|
||||||
|
self.edit_device.currentIndexChanged[str].connect(self.edit_device_changed)
|
||||||
|
self.edit_format.currentIndexChanged[str].connect(self.edit_format_changed)
|
||||||
|
self.new_device.currentIndexChanged[str].connect(self.new_device_changed)
|
||||||
|
self.new_format.currentIndexChanged[str].connect(self.new_format_changed)
|
||||||
|
self.ok_button.clicked.connect(self.ok_clicked)
|
||||||
|
|
||||||
|
self.refill_all_boxes()
|
||||||
|
|
||||||
|
def restore_defaults(self):
|
||||||
|
ConfigWidgetBase.restore_defaults(self)
|
||||||
|
self.current_plugboards = {}
|
||||||
|
self.refill_all_boxes()
|
||||||
|
self.changed_signal.emit()
|
||||||
|
|
||||||
|
def commit(self):
|
||||||
|
self.db.prefs.set('plugboards', self.current_plugboards)
|
||||||
|
return ConfigWidgetBase.commit(self)
|
||||||
|
|
||||||
|
def refresh_gui(self, gui):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
from PyQt4.Qt import QApplication
|
||||||
|
app = QApplication([])
|
||||||
|
test_widget('Import/Export', 'plugboards')
|
||||||
|
|
138
src/calibre/gui2/preferences/plugboard.ui
Normal file
138
src/calibre/gui2/preferences/plugboard.ui
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Form</class>
|
||||||
|
<widget class="QWidget" name="Form">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>707</width>
|
||||||
|
<height>340</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Here you can control what metadata calibre uses when saving or sending books:</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Add new plugboard</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Edit existing plugboard</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="new_format"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QComboBox" name="new_device"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QComboBox" name="edit_format"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QComboBox" name="edit_device"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Format (choose first)</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Device (choose second)</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<layout class="QGridLayout" name="fields_layout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Source field</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Destination field</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="20" column="0">
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="19" column="0" colspan="2">
|
||||||
|
<widget class="QPushButton" name="ok_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Done</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -232,6 +232,21 @@ def save_book_to_disk(id, db, root, opts, length):
|
|||||||
|
|
||||||
written = False
|
written = False
|
||||||
for fmt in formats:
|
for fmt in formats:
|
||||||
|
dev_name = 'save to disk'
|
||||||
|
plugboards = db.prefs.get('plugboards', None)
|
||||||
|
cpb = None
|
||||||
|
if fmt in plugboards:
|
||||||
|
cpb = plugboards[fmt]
|
||||||
|
elif ' any' in plugboards:
|
||||||
|
cpb = plugboards[' any']
|
||||||
|
if cpb is not None:
|
||||||
|
if dev_name in cpb:
|
||||||
|
cpb = cpb[dev_name]
|
||||||
|
elif ' any' in plugboards[fmt]:
|
||||||
|
cpb = cpb[' any']
|
||||||
|
else:
|
||||||
|
cpb = None
|
||||||
|
|
||||||
data = db.format(id, fmt, index_is_id=True)
|
data = db.format(id, fmt, index_is_id=True)
|
||||||
if data is None:
|
if data is None:
|
||||||
continue
|
continue
|
||||||
@ -242,7 +257,12 @@ def save_book_to_disk(id, db, root, opts, length):
|
|||||||
stream.write(data)
|
stream.write(data)
|
||||||
stream.seek(0)
|
stream.seek(0)
|
||||||
try:
|
try:
|
||||||
set_metadata(stream, mi, fmt)
|
if cpb:
|
||||||
|
newmi = mi.deepcopy()
|
||||||
|
newmi.copy_specific_attributes(mi, cpb)
|
||||||
|
else:
|
||||||
|
newmi = mi
|
||||||
|
set_metadata(stream, newmi, fmt)
|
||||||
except:
|
except:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
stream.seek(0)
|
stream.seek(0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user