mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add button to read metadata from a particular format to the Edit meta informationn dialog
This commit is contained in:
parent
059ad61377
commit
470b6792a9
@ -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'])
|
||||
|
@ -44,7 +44,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>879</width>
|
||||
<height>710</height>
|
||||
<height>711</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
@ -415,7 +415,7 @@
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" rowspan="3">
|
||||
<item row="0" column="1" rowspan="3">
|
||||
<widget class="QListWidget" name="formats">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
@ -437,7 +437,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<item row="0" column="2">
|
||||
<widget class="QToolButton" name="add_format_button">
|
||||
<property name="toolTip">
|
||||
<string>Add a new format for this book to the database</string>
|
||||
@ -457,7 +457,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="2" column="2">
|
||||
<widget class="QToolButton" name="remove_format_button">
|
||||
<property name="toolTip">
|
||||
<string>Remove the selected formats for this book from the database.</string>
|
||||
@ -477,7 +477,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<item row="0" column="0">
|
||||
<widget class="QToolButton" name="button_set_cover">
|
||||
<property name="toolTip">
|
||||
<string>Set the cover for the book from the selected format</string>
|
||||
@ -497,6 +497,26 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QToolButton" name="button_set_metadata">
|
||||
<property name="toolTip">
|
||||
<string>Update metadata from the metadata in the selected format</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/edit_input.svg</normaloff>:/images/edit_input.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
@ -680,7 +700,6 @@
|
||||
<tabstop>fetch_metadata_button</tabstop>
|
||||
<tabstop>formats</tabstop>
|
||||
<tabstop>add_format_button</tabstop>
|
||||
<tabstop>button_set_cover</tabstop>
|
||||
<tabstop>remove_format_button</tabstop>
|
||||
<tabstop>cover_path</tabstop>
|
||||
<tabstop>cover_button</tabstop>
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user