mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Allow setting the cover for a book from one of the book's formats by right clicking on the format in the Book details panel. See #1515411 (Extract cover via book details and edit metadata)
This commit is contained in:
parent
438f5a8d88
commit
692500b852
@ -7,6 +7,7 @@ __docformat__ = 'restructuredtext en'
|
||||
|
||||
import os, shutil, copy
|
||||
from functools import partial
|
||||
from io import BytesIO
|
||||
|
||||
from PyQt5.Qt import QMenu, QModelIndex, QTimer, QIcon, QApplication
|
||||
|
||||
@ -785,3 +786,55 @@ class EditMetadataAction(InterfaceAction):
|
||||
affected_books = db.set_field(field, {book_id:''})
|
||||
if affected_books:
|
||||
self.refresh_books_after_metadata_edit(affected_books)
|
||||
|
||||
def set_cover_from_format(self, book_id, fmt):
|
||||
from calibre.utils.config import prefs
|
||||
from calibre.ebooks.metadata.meta import get_metadata
|
||||
fmt = fmt.lower()
|
||||
cdata = None
|
||||
db = self.gui.current_db.new_api
|
||||
if fmt == 'pdf':
|
||||
pdfpath = db.format_abspath(book_id, fmt)
|
||||
if pdfpath is None:
|
||||
return error_dialog(self.gui, _('Format file missing'), _(
|
||||
'Cannot read cover as the %s file is missing from this book') % 'PDF', show=True)
|
||||
from calibre.gui2.metadata.pdf_covers import PDFCovers
|
||||
d = PDFCovers(pdfpath, parent=self.gui)
|
||||
if d.exec_() == d.Accepted:
|
||||
cpath = d.cover_path
|
||||
if cpath:
|
||||
with open(cpath, 'rb') as f:
|
||||
cdata = f.read()
|
||||
d.cleanup()
|
||||
else:
|
||||
stream = BytesIO()
|
||||
try:
|
||||
db.copy_format_to(book_id, fmt, stream)
|
||||
except NoSuchFormat:
|
||||
return error_dialog(self.gui, _('Format file missing'), _(
|
||||
'Cannot read cover as the %s file is missing from this book') % fmt.upper(), show=True)
|
||||
old = prefs['read_file_metadata']
|
||||
if not old:
|
||||
prefs['read_file_metadata'] = True
|
||||
try:
|
||||
stream.seek(0)
|
||||
mi = get_metadata(stream, fmt)
|
||||
except Exception:
|
||||
import traceback
|
||||
return error_dialog(self.gui, _('Could not read metadata'),
|
||||
_('Could not read metadata from %s format')%fmt.upper(),
|
||||
det_msg=traceback.format_exc(), show=True)
|
||||
finally:
|
||||
if old != prefs['read_file_metadata']:
|
||||
prefs['read_file_metadata'] = old
|
||||
if mi.cover and os.access(mi.cover, os.R_OK):
|
||||
cdata = open(mi.cover).read()
|
||||
elif mi.cover_data[1] is not None:
|
||||
cdata = mi.cover_data[1]
|
||||
if cdata is None:
|
||||
return error_dialog(self.gui, _('Could not read cover'),
|
||||
_('Could not read cover from %s format')%fmt.upper(), show=True)
|
||||
db.set_cover({book_id:cdata})
|
||||
current_idx = self.gui.library_view.currentIndex()
|
||||
self.gui.library_view.model().current_changed(current_idx, current_idx)
|
||||
self.gui.refresh_cover_browser()
|
||||
|
@ -130,10 +130,12 @@ def details_context_menu_event(view, ev, book_info): # {{{
|
||||
ofmt = fmt.upper() if fmt.startswith('ORIGINAL_') else 'ORIGINAL_' + fmt
|
||||
nfmt = ofmt[len('ORIGINAL_'):]
|
||||
fmts = {x.upper() for x in db.formats(book_id)}
|
||||
for a, t in [('remove', _('Delete the %s format')),
|
||||
('save', _('Save the %s format to disk')),
|
||||
('restore', _('Restore the %s format')),
|
||||
('compare', ''),
|
||||
for a, t in [
|
||||
('remove', _('Delete the %s format')),
|
||||
('save', _('Save the %s format to disk')),
|
||||
('restore', _('Restore the %s format')),
|
||||
('compare', ''),
|
||||
('set_cover', _('Set the book cover from the %s file')),
|
||||
]:
|
||||
if a == 'restore' and not fmt.startswith('ORIGINAL_'):
|
||||
continue
|
||||
@ -401,6 +403,7 @@ class BookInfo(QWebView):
|
||||
save_format = pyqtSignal(int, object)
|
||||
restore_format = pyqtSignal(int, object)
|
||||
compare_format = pyqtSignal(int, object)
|
||||
set_cover_format = pyqtSignal(int, object)
|
||||
copy_link = pyqtSignal(object)
|
||||
manage_author = pyqtSignal(object)
|
||||
open_fmt_with = pyqtSignal(int, object, object)
|
||||
@ -422,7 +425,9 @@ class BookInfo(QWebView):
|
||||
for x, icon in [
|
||||
('remove_format', 'trash.png'), ('save_format', 'save.png'),
|
||||
('restore_format', 'edit-undo.png'), ('copy_link','edit-copy.png'),
|
||||
('manage_author', 'user_profile.png'), ('compare_format', 'diff.png')]:
|
||||
('manage_author', 'user_profile.png'), ('compare_format', 'diff.png'),
|
||||
('set_cover_format', 'book.png'),
|
||||
]:
|
||||
ac = QAction(QIcon(I(icon)), '', self)
|
||||
ac.current_fmt = None
|
||||
ac.current_url = None
|
||||
@ -459,6 +464,9 @@ class BookInfo(QWebView):
|
||||
def compare_format_triggerred(self):
|
||||
self.context_action_triggered('compare_format')
|
||||
|
||||
def set_cover_format_triggerred(self):
|
||||
self.context_action_triggered('set_cover_format')
|
||||
|
||||
def copy_link_triggerred(self):
|
||||
self.context_action_triggered('copy_link')
|
||||
|
||||
@ -603,6 +611,7 @@ class BookDetails(QWidget): # {{{
|
||||
remove_metadata_item = pyqtSignal(int, object, object)
|
||||
save_specific_format = pyqtSignal(int, object)
|
||||
restore_specific_format = pyqtSignal(int, object)
|
||||
set_cover_from_format = pyqtSignal(int, object)
|
||||
compare_specific_format = pyqtSignal(int, object)
|
||||
copy_link = pyqtSignal(object)
|
||||
remote_file_dropped = pyqtSignal(object, object)
|
||||
@ -680,6 +689,7 @@ class BookDetails(QWidget): # {{{
|
||||
self.book_info.open_fmt_with.connect(self.open_fmt_with)
|
||||
self.book_info.save_format.connect(self.save_specific_format)
|
||||
self.book_info.restore_format.connect(self.restore_specific_format)
|
||||
self.book_info.set_cover_format.connect(self.set_cover_from_format)
|
||||
self.book_info.compare_format.connect(self.compare_specific_format)
|
||||
self.book_info.copy_link.connect(self.copy_link)
|
||||
self.book_info.manage_author.connect(self.manage_author)
|
||||
|
@ -528,6 +528,8 @@ class LayoutMixin(object): # {{{
|
||||
self.iactions['Save To Disk'].save_library_format_by_ids)
|
||||
self.book_details.restore_specific_format.connect(
|
||||
self.iactions['Remove Books'].restore_format)
|
||||
self.book_details.set_cover_from_format.connect(
|
||||
self.iactions['Edit Metadata'].set_cover_from_format)
|
||||
self.book_details.copy_link.connect(self.bd_copy_link,
|
||||
type=Qt.QueuedConnection)
|
||||
self.book_details.view_device_book.connect(
|
||||
|
Loading…
x
Reference in New Issue
Block a user