diff --git a/src/calibre/gui2/dialogs/metadata_single.py b/src/calibre/gui2/dialogs/metadata_single.py index 4f04590b1d..42785e3f3e 100644 --- a/src/calibre/gui2/dialogs/metadata_single.py +++ b/src/calibre/gui2/dialogs/metadata_single.py @@ -156,7 +156,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): self.formats.takeItem(row.row()) self.formats_changed = True - def set_cover(self): + def get_selected_format_metadata(self): row = self.formats.currentRow() fmt = self.formats.item(row) if fmt is None: @@ -165,7 +165,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): if fmt is None: error_dialog(self, _('No format selected'), _('No format selected')).exec_() - return + return None, None ext = fmt.ext.lower() if fmt.path is None: stream = self.db.format(self.row, ext, as_file=True) @@ -173,9 +173,44 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): 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 + + def set_metadata_from_format(self): + mi, ext = self.get_selected_format_metadata() + if mi is None: + return + if mi.title: + self.title.setText(mi.title) + if mi.authors: + self.authors.setEditText(authors_to_string(mi.authors)) + if mi.author_sort: + self.author_sort.setText(mi.author_sort) + if mi.rating is not None: + try: + self.rating.setValue(mi.rating) + except: + pass + if mi.publisher: + self.publisher.setEditText(mi.publisher) + if mi.tags: + self.tags.setText(', '.join(mi.tags)) + if mi.isbn: + self.isbn.setText(mi.isbn) + if mi.pubdate: + self.pubdate.setDate(QDate(mi.pubdate.year, mi.pubdate.month, + mi.pubdate.day)) + if mi.series: + self.series.setEditText(mi.series) + if mi.series_index is not None: + self.series_index.setValue(float(mi.series_index)) + + def set_cover(self): + mi, ext = self.get_selected_format_metadata() + if mi is None: return cdata = None if mi.cover and os.access(mi.cover, os.R_OK): @@ -253,6 +288,8 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): self.connect(self.formats, SIGNAL('itemDoubleClicked(QListWidgetItem*)'), self.show_format) self.connect(self.button_set_cover, SIGNAL('clicked()'), self.set_cover) + self.connect(self.button_set_metadata, SIGNAL('clicked()'), + self.set_metadata_from_format) self.connect(self.reset_cover, SIGNAL('clicked()'), self.do_reset_cover) self.connect(self.swap_button, SIGNAL('clicked()'), self.swap_title_author) self.timeout = float(prefs['network_timeout']) diff --git a/src/calibre/gui2/dialogs/metadata_single.ui b/src/calibre/gui2/dialogs/metadata_single.ui index f7cd6738d0..a20348885d 100644 --- a/src/calibre/gui2/dialogs/metadata_single.ui +++ b/src/calibre/gui2/dialogs/metadata_single.ui @@ -44,7 +44,7 @@ 0 0 879 - 710 + 711 @@ -415,7 +415,7 @@ - + @@ -437,7 +437,7 @@ - + Add a new format for this book to the database @@ -457,7 +457,7 @@ - + Remove the selected formats for this book from the database. @@ -477,7 +477,7 @@ - + Set the cover for the book from the selected format @@ -497,6 +497,26 @@ + + + + Update metadata from the metadata in the selected format + + + + + + + :/images/edit_input.svg:/images/edit_input.svg + + + + 32 + 32 + + + + @@ -680,7 +700,6 @@ fetch_metadata_button formats add_format_button - button_set_cover remove_format_button cover_path cover_button diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 3ab4f97f83..f1a9ea18dd 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -27,15 +27,12 @@ from calibre.library.sqlite import connect, IntegrityError from calibre.utils.search_query_parser import SearchQueryParser from calibre.ebooks.metadata import string_to_authors, authors_to_string, \ MetaInformation, authors_to_sort_string -from calibre.ebooks.metadata.meta import get_metadata, set_metadata, \ - metadata_from_formats -from calibre.ebooks.metadata.opf2 import metadata_to_opf +from calibre.ebooks.metadata.meta import get_metadata, metadata_from_formats from calibre.constants import preferred_encoding, iswindows, isosx, filesystem_encoding from calibre.ptempfile import PersistentTemporaryFile from calibre.customize.ui import run_plugins_on_import -from calibre.utils.filenames import ascii_filename, shorten_components_to, \ - supports_long_names +from calibre.utils.filenames import ascii_filename from calibre.ebooks import BOOK_EXTENSIONS if iswindows: @@ -1587,124 +1584,6 @@ books_series_link feeds progress.reset() return len(books) - def export_to_dir(self, dir, indices, byauthor=False, single_dir=False, - index_is_id=False, callback=None): - if not os.path.exists(dir): - raise IOError('Target directory does not exist: '+dir) - by_author = {} - count = 0 - path_len, au_len = (1000, 500) if supports_long_names(dir) else (240, 50) - for index in indices: - id = index if index_is_id else self.id(index) - au = self.conn.get('SELECT author_sort FROM books WHERE id=?', - (id,), all=False) - if not au: - au = self.authors(index, index_is_id=index_is_id) - if not au: - au = _('Unknown') - au = au.split(',')[0] - if not by_author.has_key(au): - by_author[au] = [] - by_author[au].append(index) - for au in by_author.keys(): - aname = ascii_filename(au)[:au_len] - apath = os.path.abspath(os.path.join(dir, aname)) - if not single_dir and not os.path.exists(apath): - os.mkdir(apath) - for idx in by_author[au]: - title = re.sub(r'\s', ' ', self.title(idx, index_is_id=index_is_id)) - name = au + ' - ' + title if byauthor else title + ' - ' + au - name = ascii_filename(name) - tname = ascii_filename(title) - tname, name = shorten_components_to(path_len-len(apath), (tname, - name)) - name += '_'+str(id) - - tpath = os.path.join(apath, tname) - id = idx if index_is_id else self.id(idx) - id = str(id) - if not single_dir and not os.path.exists(tpath): - os.makedirs(tpath) - - base = dir if single_dir else tpath - mi = self.get_metadata(idx, index_is_id=index_is_id, get_cover=True) - if not mi.authors: - mi.authors = [_('Unknown')] - cdata = self.cover(int(id), index_is_id=True) - if cdata is not None: - cname = name+'.jpg' - open(os.path.join(base, cname), 'wb').write(cdata) - mi.cover = cname - with open(os.path.join(base, name+'.opf'), - 'wb') as f: - f.write(metadata_to_opf(mi)) - - fmts = self.formats(idx, index_is_id=index_is_id) - if not fmts: - fmts = '' - for fmt in fmts.split(','): - data = self.format(idx, fmt, index_is_id=index_is_id) - if not data: - continue - fname = name +'.'+fmt.lower() - f = open(os.path.join(base, fname), 'w+b') - f.write(data) - f.flush() - f.seek(0) - try: - set_metadata(f, mi, fmt.lower()) - except: - pass - f.close() - count += 1 - if callable(callback): - if not callback(int(id), mi.title): - return - - def export_single_format_to_dir(self, dir, indices, format, - index_is_id=False, callback=None): - dir = os.path.abspath(dir) - if not index_is_id: - indices = map(self.id, indices) - failures = [] - plen = 1000 if supports_long_names(dir) else 245 - for count, id in enumerate(indices): - try: - data = self.format(id, format, index_is_id=True) - if not data: - failures.append((id, self.title(id, index_is_id=True))) - continue - except: - failures.append((id, self.title(id, index_is_id=True))) - continue - title = self.title(id, index_is_id=True) - au = self.authors(id, index_is_id=True) - if not au: - au = _('Unknown') - fname = '%s - %s'%(title, au) - while fname.endswith('.'): - fname = fname[:-1] - fname = ascii_filename(fname) - fname = fname + '.' + format.lower() - dir = os.path.abspath(dir) - fname = shorten_components_to(plen - len(dir), (fname,))[0] - if not os.path.exists(dir): - os.makedirs(dir) - f = open(os.path.join(dir, fname), 'w+b') - f.write(data) - f.flush() - f.seek(0) - try: - set_metadata(f, self.get_metadata(id, index_is_id=True, get_cover=True), - stream_type=format.lower()) - except: - pass - f.close() - if callable(callback): - if not callback(int(id), title): - break - return failures - def find_books_in_directory(self, dirpath, single_book_per_directory): dirpath = os.path.abspath(dirpath) if single_book_per_directory: