def apply_downloaded_metadata(self, review, payload, *args): good_ids, tdir, log_file, lm_map, failed_ids = payload if not good_ids: return restrict_to_failed = False modified = set() db = self.gui.current_db for i in good_ids: lm = db.metadata_last_modified(i, index_is_id=True) if lm is not None and lm_map[i] is not None and lm > lm_map[i]: title = db.title(i, index_is_id=True) authors = db.authors(i, index_is_id=True) if authors: authors = [x.replace('|', ',') for x in authors.split(',')] title += ' - ' + authors_to_string(authors) modified.add(title) if modified: from calibre.utils.icu import lower modified = sorted(modified, key=lower) if not question_dialog(self.gui, _('Some books changed'), '<p>' + _( 'The metadata for some books in your library has' ' changed since you started the download. If you' ' proceed, some of those changes may be overwritten. ' 'Click "Show details" to see the list of changed books. ' 'Do you want to proceed?'), det_msg='\n'.join(modified)): return id_map = {} for bid in good_ids: opf = os.path.join(tdir, '%d.mi'%bid) if not os.path.exists(opf): opf = None cov = os.path.join(tdir, '%d.cover'%bid) if not os.path.exists(cov): cov = None id_map[bid] = (opf, cov) if review: def get_metadata(book_id): oldmi = db.get_metadata(book_id, index_is_id=True, get_cover=True, cover_as_data=True) opf, cov = id_map[book_id] if opf is None: newmi = Metadata(oldmi.title, authors=tuple(oldmi.authors)) else: with open(opf, 'rb') as f: newmi = OPF(f, basedir=os.path.dirname(opf), populate_spine=False).to_book_metadata() newmi.cover, newmi.cover_data = None, (None, None) for x in ('title', 'authors'): if newmi.is_null(x): # Title and author are set to null if they are # the same as the originals as an optimization, # we undo that, as it is confusing. newmi.set(x, copy.copy(oldmi.get(x))) if cov: with open(cov, 'rb') as f: newmi.cover_data = ('jpg', f.read()) return oldmi, newmi from calibre.gui2.metadata.diff import CompareMany d = CompareMany( set(id_map), get_metadata, db.field_metadata, parent=self.gui, window_title=_('Review downloaded metadata'), reject_button_tooltip=_('Discard downloaded metadata for this book'), accept_all_tooltip=_('Use the downloaded metadata for all remaining books'), reject_all_tooltip=_('Discard downloaded metadata for all remaining books'), revert_tooltip=_('Discard the downloaded value for: %s'), intro_msg=_('The downloaded metadata is on the left and the original metadata' ' is on the right. If a downloaded value is blank or unknown,' ' the original value is used.'), action_button=(_('&View Book'), I('view.png'), self.gui.iactions['View'].view_historical), db=db ) if d.exec_() == d.Accepted: if d.mark_rejected: failed_ids |= d.rejected_ids restrict_to_failed = True nid_map = {} for book_id, (changed, mi) in d.accepted.iteritems(): if mi is None: # discarded continue if changed: opf, cov = id_map[book_id] cfile = mi.cover mi.cover, mi.cover_data = None, (None, None) if opf is not None: with open(opf, 'wb') as f: f.write(metadata_to_opf(mi)) if cfile and cov: shutil.copyfile(cfile, cov) os.remove(cfile) nid_map[book_id] = id_map[book_id] id_map = nid_map else: id_map = {} restrict_to_failed = restrict_to_failed or bool(args and args[0]) restrict_to_failed = restrict_to_failed and bool(failed_ids) if restrict_to_failed: db.data.set_marked_ids(failed_ids) self.apply_metadata_changes( id_map, merge_comments=msprefs['append_comments'], icon='download-metadata.png', callback=partial(self.downloaded_metadata_applied, tdir, restrict_to_failed))
def apply_downloaded_metadata(self, review, payload, *args): good_ids, tdir, log_file, lm_map, failed_ids = payload if not good_ids: return restrict_to_failed = False modified = set() db = self.gui.current_db for i in good_ids: lm = db.metadata_last_modified(i, index_is_id=True) if lm is not None and lm_map[i] is not None and lm > lm_map[i]: title = db.title(i, index_is_id=True) authors = db.authors(i, index_is_id=True) if authors: authors = [x.replace('|', ',') for x in authors.split(',')] title += ' - ' + authors_to_string(authors) modified.add(title) if modified: from calibre.utils.icu import lower modified = sorted(modified, key=lower) if not question_dialog( self.gui, _('Some books changed'), '<p>' + _('The metadata for some books in your library has' ' changed since you started the download. If you' ' proceed, some of those changes may be overwritten. ' 'Click "Show details" to see the list of changed books. ' 'Do you want to proceed?'), det_msg='\n'.join(modified)): return id_map = {} for bid in good_ids: opf = os.path.join(tdir, '%d.mi' % bid) if not os.path.exists(opf): opf = None cov = os.path.join(tdir, '%d.cover' % bid) if not os.path.exists(cov): cov = None id_map[bid] = (opf, cov) if review: def get_metadata(book_id): oldmi = db.get_metadata(book_id, index_is_id=True, get_cover=True, cover_as_data=True) opf, cov = id_map[book_id] if opf is None: newmi = Metadata(oldmi.title, authors=tuple(oldmi.authors)) else: with open(opf, 'rb') as f: newmi = OPF(f, basedir=os.path.dirname(opf), populate_spine=False).to_book_metadata() newmi.cover, newmi.cover_data = None, (None, None) for x in ('title', 'authors'): if newmi.is_null(x): # Title and author are set to null if they are # the same as the originals as an optimization, # we undo that, as it is confusing. newmi.set(x, copy.copy(oldmi.get(x))) if cov: with open(cov, 'rb') as f: newmi.cover_data = ('jpg', f.read()) return oldmi, newmi from calibre.gui2.metadata.diff import CompareMany d = CompareMany( set(id_map), get_metadata, db.field_metadata, parent=self.gui, window_title=_('Review downloaded metadata'), reject_button_tooltip=_( 'Discard downloaded metadata for this book'), accept_all_tooltip=_( 'Use the downloaded metadata for all remaining books'), reject_all_tooltip=_( 'Discard downloaded metadata for all remaining books'), revert_tooltip=_('Discard the downloaded value for: %s'), intro_msg= _('The downloaded metadata is on the left and the original metadata' ' is on the right. If a downloaded value is blank or unknown,' ' the original value is used.'), action_button=(_('&View book'), I('view.png'), self.gui.iactions['View'].view_historical), db=db) if d.exec() == QDialog.DialogCode.Accepted: if d.mark_rejected: failed_ids |= d.rejected_ids restrict_to_failed = True nid_map = {} for book_id, (changed, mi) in iteritems(d.accepted): if mi is None: # discarded continue if changed: opf, cov = id_map[book_id] cfile = mi.cover mi.cover, mi.cover_data = None, (None, None) if opf is not None: with open(opf, 'wb') as f: f.write(metadata_to_opf(mi)) if cfile and cov: shutil.copyfile(cfile, cov) os.remove(cfile) nid_map[book_id] = id_map[book_id] id_map = nid_map else: id_map = {} restrict_to_failed = restrict_to_failed or bool(args and args[0]) restrict_to_failed = restrict_to_failed and bool(failed_ids) if restrict_to_failed: db.data.set_marked_ids(failed_ids) self.apply_metadata_changes(id_map, merge_comments=msprefs['append_comments'], icon='download-metadata.png', callback=partial( self.downloaded_metadata_applied, tdir, restrict_to_failed))
def apply_downloaded_metadata(self, review, payload, *args): good_ids, tdir, log_file, lm_map, failed_ids = payload if not good_ids: return modified = set() db = self.gui.current_db for i in good_ids: lm = db.metadata_last_modified(i, index_is_id=True) if lm is not None and lm_map[i] is not None and lm > lm_map[i]: title = db.title(i, index_is_id=True) authors = db.authors(i, index_is_id=True) if authors: authors = [x.replace("|", ",") for x in authors.split(",")] title += " - " + authors_to_string(authors) modified.add(title) if modified: from calibre.utils.icu import lower modified = sorted(modified, key=lower) if not question_dialog( self.gui, _("Some books changed"), "<p>" + _( "The metadata for some books in your library has" " changed since you started the download. If you" " proceed, some of those changes may be overwritten. " 'Click "Show details" to see the list of changed books. ' "Do you want to proceed?" ), det_msg="\n".join(modified), ): return id_map = {} for bid in good_ids: opf = os.path.join(tdir, "%d.mi" % bid) if not os.path.exists(opf): opf = None cov = os.path.join(tdir, "%d.cover" % bid) if not os.path.exists(cov): cov = None id_map[bid] = (opf, cov) if review: def get_metadata(book_id): oldmi = db.get_metadata(book_id, index_is_id=True, get_cover=True, cover_as_data=True) opf, cov = id_map[book_id] if opf is None: newmi = Metadata(oldmi.title, authors=tuple(oldmi.authors)) else: with open(opf, "rb") as f: newmi = OPF(f, basedir=os.path.dirname(opf), populate_spine=False).to_book_metadata() newmi.cover, newmi.cover_data = None, (None, None) for x in ("title", "authors"): if newmi.is_null(x): # Title and author are set to null if they are # the same as the originals as an optimization, # we undo that, as it is confusing. newmi.set(x, copy.copy(oldmi.get(x))) if cov: with open(cov, "rb") as f: newmi.cover_data = ("jpg", f.read()) return oldmi, newmi from calibre.gui2.metadata.diff import CompareMany d = CompareMany( set(id_map), get_metadata, db.field_metadata, parent=self.gui, window_title=_("Review downloaded metadata"), reject_button_tooltip=_("Discard downloaded metadata for this book"), accept_all_tooltip=_("Use the downloaded metadata for all remaining books"), reject_all_tooltip=_("Discard downloaded metadata for all remaining books"), revert_tooltip=_("Discard the downloaded value for: %s"), intro_msg=_( "The downloaded metadata is on the left and the original metadata" " is on the right. If a downloaded value is blank or unknown," " the original value is used." ), action_button=(_("&View Book"), I("view.png"), self.gui.iactions["View"].view_historical), ) if d.exec_() == d.Accepted: nid_map = {} for book_id, (changed, mi) in d.accepted.iteritems(): if mi is None: # discarded continue if changed: opf, cov = id_map[book_id] cfile = mi.cover mi.cover, mi.cover_data = None, (None, None) if opf is not None: with open(opf, "wb") as f: f.write(metadata_to_opf(mi)) if cfile and cov: shutil.copyfile(cfile, cov) os.remove(cfile) nid_map[book_id] = id_map[book_id] id_map = nid_map else: id_map = {} restrict_to_failed = bool(args and args[0]) if restrict_to_failed: db.data.set_marked_ids(failed_ids) self.apply_metadata_changes( id_map, callback=partial(self.downloaded_metadata_applied, tdir, restrict_to_failed) )