diff --git a/src/calibre/gui2/metadata/basic_widgets.py b/src/calibre/gui2/metadata/basic_widgets.py index 5d37e854da..96ea785ff2 100644 --- a/src/calibre/gui2/metadata/basic_widgets.py +++ b/src/calibre/gui2/metadata/basic_widgets.py @@ -15,9 +15,10 @@ from PyQt4.Qt import Qt, QDateEdit, QDate, \ from calibre.gui2.widgets import EnLineEdit, CompleteComboBox, \ EnComboBox, FormatList, ImageView, CompleteLineEdit from calibre.utils.icu import sort_key -from calibre.utils.config import tweaks +from calibre.utils.config import tweaks, prefs from calibre.ebooks.metadata import title_sort, authors_to_string, \ string_to_authors, check_isbn +from calibre.ebooks.metadata.meta import get_metadata from calibre.gui2 import file_icon_provider, UNDEFINED_QDATE, UNDEFINED_DATE, \ choose_files, error_dialog, choose_images, question_dialog from calibre.utils.date import local_tz, qt_to_dt @@ -440,7 +441,6 @@ class FormatsManager(QWidget): # {{{ self.metadata_from_format_button = QToolButton(self) self.metadata_from_format_button.setIcon(QIcon(I('edit_input.png'))) self.metadata_from_format_button.setIconSize(QSize(32, 32)) - # TODO: Implement the *_from_format buttons self.add_format_button = QToolButton(self) self.add_format_button.setIcon(QIcon(I('add_book.png'))) @@ -565,6 +565,36 @@ class FormatsManager(QWidget): # {{{ fmt = item.ext self.dialog.view_format.emit(fmt) + def get_selected_format_metadata(self, db, id_): + old = prefs['read_file_metadata'] + if not old: + prefs['read_file_metadata'] = True + try: + row = self.formats.currentRow() + fmt = self.formats.item(row) + if fmt is None: + if self.formats.count() == 1: + fmt = self.formats.item(0) + if fmt is None: + error_dialog(self, _('No format selected'), + _('No format selected')).exec_() + return None, None + ext = fmt.ext.lower() + if fmt.path is None: + stream = db.format(id_, ext, as_file=True, index_is_id=True) + else: + stream = open(fmt.path, 'r+b') + try: + mi = get_metadata(stream, ext) + return mi, ext + except: + error_dialog(self, _('Could not read metadata'), + _('Could not read metadata from %s format')%ext).exec_() + return None, None + finally: + if old != prefs['read_file_metadata']: + prefs['read_file_metadata'] = old + # }}} class Cover(ImageView): # {{{ diff --git a/src/calibre/gui2/metadata/single.py b/src/calibre/gui2/metadata/single.py index b53637d66a..c7b5e7f99b 100644 --- a/src/calibre/gui2/metadata/single.py +++ b/src/calibre/gui2/metadata/single.py @@ -5,6 +5,7 @@ __license__ = 'GPL v3' __copyright__ = '2011, Kovid Goyal ' __docformat__ = 'restructuredtext en' +import os from PyQt4.Qt import Qt, QVBoxLayout, QHBoxLayout, QWidget, QPushButton, \ QGridLayout, pyqtSignal, QDialogButtonBox, QScrollArea, QFont, \ @@ -101,7 +102,10 @@ class MetadataSingleDialog(ResizableDialog): self.formats_manager = FormatsManager(self) self.basic_metadata_widgets.append(self.formats_manager) - + self.formats_manager.metadata_from_format_button.clicked.connect( + self.metadata_from_format) + self.formats_manager.cover_from_format_button.clicked.connect( + self.cover_from_format) self.cover = Cover(self) self.basic_metadata_widgets.append(self.cover) @@ -263,6 +267,64 @@ class MetadataSingleDialog(ResizableDialog): def tags_editor(self, *args): self.tags.edit(self.db, self.book_id) + def metadata_from_format(self, *args): + mi, ext = self.formats_manager.get_selected_format_metadata(self.db, + self.book_id) + if mi is not None: + self.update_from_mi(mi) + + def cover_from_format(self, *args): + mi, ext = self.formats_manager.get_selected_format_metadata(self.db, + self.book_id) + if mi is None: + return + cdata = None + 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: + error_dialog(self, _('Could not read cover'), + _('Could not read cover from %s format')%ext).exec_() + return + orig = self.cover.current_val + self.cover.current_val = cdata + if self.cover.current_val is None: + self.cover.current_val = orig + return error_dialog(self, _('Could not read cover'), + _('The cover in the %s format is invalid')%ext, + show=True) + return + + def update_from_mi(self, mi): + if not mi.is_null('title'): + self.title.current_val = mi.title + if not mi.is_null('authors'): + self.authors.current_val = mi.authors + if not mi.is_null('author_sort'): + self.author_sort.current_val = mi.author_sort + if not mi.is_null('rating'): + try: + self.rating.current_val = mi.rating + except: + pass + if not mi.is_null('publisher'): + self.publisher.current_val = mi.publisher + if not mi.is_null('tags'): + self.tags.current_val = mi.tags + if not mi.is_null('isbn'): + self.isbn.current_val = mi.isbn + if not mi.is_null('pubdate'): + self.pubdate.current_val = mi.pubdate + if not mi.is_null('series') and mi.series.strip(): + self.series.current_val = mi.series + if mi.series_index is not None: + self.series_index.current_val = float(mi.series_index) + if mi.comments and mi.comments.strip(): + self.comments.current_val = mi.comments + + + def fetch_metadata(self, *args): pass # TODO: fetch metadata