mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Start work on porting the bulk metadata dialog to the new API
This commit is contained in:
parent
a5e32b4ad4
commit
b2733f6052
@ -333,6 +333,12 @@ class Cache(object):
|
|||||||
except (KeyError, IndexError):
|
except (KeyError, IndexError):
|
||||||
return default_value
|
return default_value
|
||||||
|
|
||||||
|
@read_api
|
||||||
|
def all_field_for(self, field, book_ids, default_value=None):
|
||||||
|
' Same as field_for, except that it operates on multiple books at once '
|
||||||
|
field_obj = self.fields[field]
|
||||||
|
return {book_id:self._fast_field_for(field_obj, book_id, default_value=default_value) for book_id in book_ids}
|
||||||
|
|
||||||
@read_api
|
@read_api
|
||||||
def composite_for(self, name, book_id, mi=None, default_value=''):
|
def composite_for(self, name, book_id, mi=None, default_value=''):
|
||||||
try:
|
try:
|
||||||
|
@ -5,6 +5,7 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
|
|
||||||
import re, os, inspect
|
import re, os, inspect
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
from PyQt4.Qt import Qt, QDialog, QGridLayout, QVBoxLayout, QFont, QLabel, \
|
from PyQt4.Qt import Qt, QDialog, QGridLayout, QVBoxLayout, QFont, QLabel, \
|
||||||
pyqtSignal, QDialogButtonBox, QInputDialog, QLineEdit, \
|
pyqtSignal, QDialogButtonBox, QInputDialog, QLineEdit, \
|
||||||
@ -58,6 +59,106 @@ Settings = namedtuple('Settings', 'remove_all remove add au aus do_aus rating pu
|
|||||||
'remove_format do_swap_ta do_remove_conv do_auto_author series do_series_restart series_start_value '
|
'remove_format do_swap_ta do_remove_conv do_auto_author series do_series_restart series_start_value '
|
||||||
'do_title_case cover_action clear_series pubdate adddate do_title_sort languages clear_languages restore_original')
|
'do_title_case cover_action clear_series pubdate adddate do_title_sort languages clear_languages restore_original')
|
||||||
|
|
||||||
|
class MyBlockingBusyNew(QDialog):
|
||||||
|
|
||||||
|
all_done = pyqtSignal()
|
||||||
|
|
||||||
|
def __init__(self, args, ids, db, cc_widgets, s_r_func,
|
||||||
|
parent=None, window_title=_('Working')):
|
||||||
|
QDialog.__init__(self, parent)
|
||||||
|
|
||||||
|
self._layout = l = QVBoxLayout()
|
||||||
|
self.setLayout(l)
|
||||||
|
|
||||||
|
self.msg = QLabel(_('Processing %d books, please wait...') % len(ids))
|
||||||
|
self.font = QFont()
|
||||||
|
self.font.setPointSize(self.font.pointSize() + 8)
|
||||||
|
self.msg.setFont(self.font)
|
||||||
|
self.pi = ProgressIndicator(self)
|
||||||
|
self.pi.setDisplaySize(100)
|
||||||
|
self._layout.addWidget(self.pi, 0, Qt.AlignHCenter)
|
||||||
|
self._layout.addSpacing(15)
|
||||||
|
self._layout.addWidget(self.msg, 0, Qt.AlignHCenter)
|
||||||
|
self.setWindowTitle(window_title + '...')
|
||||||
|
self.setMinimumWidth(200)
|
||||||
|
self.resize(self.sizeHint())
|
||||||
|
self.error = None
|
||||||
|
self.all_done.connect(self.on_all_done, type=Qt.QueuedConnection)
|
||||||
|
self.args, self.ids, self.s_r_func = args, ids, s_r_func
|
||||||
|
self.db, self.cc_widgets = db, cc_widgets
|
||||||
|
|
||||||
|
def accept(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def reject(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def on_all_done(self):
|
||||||
|
QDialog.accept(self)
|
||||||
|
|
||||||
|
def exec_(self):
|
||||||
|
self.thread = Thread(target=self.do_it)
|
||||||
|
self.thread.start()
|
||||||
|
return QDialog.exec_(self)
|
||||||
|
|
||||||
|
def do_it(self):
|
||||||
|
try:
|
||||||
|
self.do_all()
|
||||||
|
except Exception as err:
|
||||||
|
import traceback
|
||||||
|
try:
|
||||||
|
err = unicode(err)
|
||||||
|
except:
|
||||||
|
err = repr(err)
|
||||||
|
self.error = (err, traceback.format_exc())
|
||||||
|
|
||||||
|
self.all_done.emit()
|
||||||
|
|
||||||
|
def do_all(self):
|
||||||
|
cache = self.db.new_api
|
||||||
|
args = self.args
|
||||||
|
|
||||||
|
# Title and authors
|
||||||
|
if args.do_swap_ta:
|
||||||
|
title_map = cache.all_field_for('title', self.ids)
|
||||||
|
authors_map = cache.all_field_for('authors', self.ids)
|
||||||
|
def new_title(authors):
|
||||||
|
ans = authors_to_string(authors)
|
||||||
|
return titlecase(ans) if args.do_title_case else ans
|
||||||
|
new_title_map = {bid:new_title(authors) for bid, authors in authors_map.iteritems()}
|
||||||
|
new_authors_map = {bid:string_to_authors(title) for bid, title in title_map.iteritems()}
|
||||||
|
cache.set_field('authors', new_authors_map)
|
||||||
|
cache.set_field('title', new_title_map)
|
||||||
|
|
||||||
|
if args.do_title_case and not args.do_swap_ta:
|
||||||
|
title_map = cache.all_field_for('title', self.ids)
|
||||||
|
cache.set_field('title', {bid:titlecase(title) for bid, title in title_map.iteritems()})
|
||||||
|
|
||||||
|
if args.do_title_sort:
|
||||||
|
lang_map = cache.all_field_for('languages', self.ids)
|
||||||
|
title_map = cache.all_field_for('title', self.ids)
|
||||||
|
def get_sort(book_id):
|
||||||
|
if args.languages:
|
||||||
|
lang = args.languages[0]
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
lang = lang_map[book_id][0]
|
||||||
|
except (KeyError, IndexError, TypeError, AttributeError):
|
||||||
|
lang = 'eng'
|
||||||
|
return title_sort(title_map[book_id], lang=lang)
|
||||||
|
cache.set_field('sort', {bid:get_sort(bid) for bid in self.ids})
|
||||||
|
|
||||||
|
if args.au:
|
||||||
|
authors = string_to_authors(args.au)
|
||||||
|
cache.set_field('authors', {bid:authors for bid in self.ids})
|
||||||
|
|
||||||
|
if args.do_auto_author:
|
||||||
|
aus_map = cache.author_sort_strings_for_books(self.ids)
|
||||||
|
cache.set_field('author_sort', {book_id:' & '.join(aus_map[book_id]) for book_id in aus_map})
|
||||||
|
|
||||||
|
if args.aus and args.do_aus:
|
||||||
|
cache.set_field('author_sort', {bid:args.aus for bid in self.ids})
|
||||||
|
|
||||||
class MyBlockingBusy(QDialog): # {{{
|
class MyBlockingBusy(QDialog): # {{{
|
||||||
|
|
||||||
do_one_signal = pyqtSignal()
|
do_one_signal = pyqtSignal()
|
||||||
@ -1010,7 +1111,12 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
|
|||||||
pubdate, adddate, do_title_sort, languages, clear_languages,
|
pubdate, adddate, do_title_sort, languages, clear_languages,
|
||||||
restore_original)
|
restore_original)
|
||||||
|
|
||||||
bb = MyBlockingBusy(_('Applying changes to %d books.\nPhase {0} {1}%%.')
|
if hasattr(self.db, 'new_api'):
|
||||||
|
bb = MyBlockingBusyNew(args, self.ids, self.db,
|
||||||
|
getattr(self, 'custom_column_widgets', []),
|
||||||
|
self.do_search_replace, parent=self)
|
||||||
|
else:
|
||||||
|
bb = MyBlockingBusy(_('Applying changes to %d books.\nPhase {0} {1}%%.')
|
||||||
%len(self.ids), args, self.db, self.ids,
|
%len(self.ids), args, self.db, self.ids,
|
||||||
getattr(self, 'custom_column_widgets', []),
|
getattr(self, 'custom_column_widgets', []),
|
||||||
self.do_search_replace, parent=self)
|
self.do_search_replace, parent=self)
|
||||||
@ -1023,6 +1129,8 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
|
|||||||
finally:
|
finally:
|
||||||
self.model.start_metadata_backup()
|
self.model.start_metadata_backup()
|
||||||
|
|
||||||
|
bb.thread = bb.db = bb.cc_widgets = None
|
||||||
|
|
||||||
if bb.error is not None:
|
if bb.error is not None:
|
||||||
return error_dialog(self, _('Failed'),
|
return error_dialog(self, _('Failed'),
|
||||||
bb.error[0], det_msg=bb.error[1],
|
bb.error[0], det_msg=bb.error[1],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user