示例#1
0
    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))
示例#2
0
    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))
示例#3
0
    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)
        )