mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add progress indication when adding books to the library
This commit is contained in:
parent
660fa430f8
commit
5769ce558c
@ -6,7 +6,8 @@ from functools import partial
|
||||
from PyQt4.QtCore import Qt, SIGNAL, QObject, QCoreApplication, QUrl, QTimer
|
||||
from PyQt4.QtGui import QPixmap, QColor, QPainter, QMenu, QIcon, QMessageBox, \
|
||||
QToolButton, QDialog, QDesktopServices, QFileDialog, \
|
||||
QSystemTrayIcon, QApplication, QKeySequence, QAction
|
||||
QSystemTrayIcon, QApplication, QKeySequence, QAction, \
|
||||
QProgressDialog
|
||||
from PyQt4.QtSvg import QSvgRenderer
|
||||
|
||||
from calibre import __version__, __appname__, islinux, sanitize_file_name, \
|
||||
@ -566,8 +567,23 @@ class Main(MainWindow, Ui_MainWindow):
|
||||
root = choose_dir(self, 'recursive book import root dir dialog', 'Select root folder')
|
||||
if not root:
|
||||
return
|
||||
duplicates = self.library_view.model().db.recursive_import(root, single)
|
||||
|
||||
progress = QProgressDialog('', '&'+_('Stop'),
|
||||
0, 0, self)
|
||||
progress.setWindowModality(Qt.ApplicationModal)
|
||||
progress.setWindowTitle(_('Adding books recursively...'))
|
||||
progress.show()
|
||||
def callback(msg):
|
||||
if msg != '.':
|
||||
progress.setLabelText((_('Added ')+msg) if msg else _('Searching...'))
|
||||
stop = progress.wasCanceled()
|
||||
QApplication.processEvents()
|
||||
QApplication.sendPostedEvents()
|
||||
QApplication.flush()
|
||||
return stop
|
||||
try:
|
||||
duplicates = self.library_view.model().db.recursive_import(root, single, callback=callback)
|
||||
finally:
|
||||
progress.close()
|
||||
if duplicates:
|
||||
files = _('<p>Books with the same title as the following already exist in the database. Add them anyway?<ul>')
|
||||
for mi, formats in duplicates:
|
||||
@ -634,49 +650,61 @@ class Main(MainWindow, Ui_MainWindow):
|
||||
def _add_books(self, paths, to_device, on_card=None):
|
||||
if on_card is None:
|
||||
on_card = self.stack.currentIndex() == 2
|
||||
if not paths:
|
||||
return
|
||||
# Get format and metadata information
|
||||
formats, metadata, names, infos = [], [], [], []
|
||||
for book in paths:
|
||||
format = os.path.splitext(book)[1]
|
||||
format = format[1:] if format else None
|
||||
stream = open(book, 'rb')
|
||||
try:
|
||||
mi = get_metadata(stream, stream_type=format, use_libprs_metadata=True)
|
||||
except:
|
||||
mi = MetaInformation(None, None)
|
||||
if not mi.title:
|
||||
mi.title = os.path.splitext(os.path.basename(book))[0]
|
||||
if not mi.authors:
|
||||
mi.authors = [_('Unknown')]
|
||||
formats.append(format)
|
||||
metadata.append(mi)
|
||||
names.append(os.path.basename(book))
|
||||
infos.append({'title':mi.title, 'authors':', '.join(mi.authors),
|
||||
'cover':self.default_thumbnail, 'tags':[]})
|
||||
|
||||
if not to_device:
|
||||
model = self.library_view.model()
|
||||
progress = QProgressDialog(_('Reading metadata...'), _('Stop'), 0, len(paths), self)
|
||||
progress.setWindowTitle(_('Adding books...'))
|
||||
progress.setWindowModality(Qt.ApplicationModal)
|
||||
progress.setLabelText(_('Reading metadata...'))
|
||||
progress.show()
|
||||
try:
|
||||
for c, book in enumerate(paths):
|
||||
progress.setValue(c)
|
||||
if progress.wasCanceled():
|
||||
return
|
||||
format = os.path.splitext(book)[1]
|
||||
format = format[1:] if format else None
|
||||
stream = open(book, 'rb')
|
||||
try:
|
||||
mi = get_metadata(stream, stream_type=format, use_libprs_metadata=True)
|
||||
except:
|
||||
mi = MetaInformation(None, None)
|
||||
if not mi.title:
|
||||
mi.title = os.path.splitext(os.path.basename(book))[0]
|
||||
if not mi.authors:
|
||||
mi.authors = [_('Unknown')]
|
||||
formats.append(format)
|
||||
metadata.append(mi)
|
||||
names.append(os.path.basename(book))
|
||||
infos.append({'title':mi.title, 'authors':', '.join(mi.authors),
|
||||
'cover':self.default_thumbnail, 'tags':[]})
|
||||
title = mi.title if isinstance(mi.title, unicode) else mi.title.decode(preferred_encoding, 'replace')
|
||||
progress.setLabelText(_('Read metadata from ')+title)
|
||||
|
||||
paths = list(paths)
|
||||
#for i, path in enumerate(paths):
|
||||
# npath, fmt = import_format(path)
|
||||
# if npath is not None:
|
||||
# paths[i] = npath
|
||||
# formats[i] = fmt
|
||||
duplicates, number_added = model.add_books(paths, formats, metadata)
|
||||
if duplicates:
|
||||
files = _('<p>Books with the same title as the following already exist in the database. Add them anyway?<ul>')
|
||||
for mi in duplicates[2]:
|
||||
files += '<li>'+mi.title+'</li>\n'
|
||||
d = WarningDialog(_('Duplicates found!'), _('Duplicates found!'), files+'</ul></p>', parent=self)
|
||||
if d.exec_() == QDialog.Accepted:
|
||||
num = model.add_books(*duplicates, **dict(add_duplicates=True))[1]
|
||||
number_added += num
|
||||
#self.library_view.sortByColumn(3, Qt.DescendingOrder)
|
||||
#model.research()
|
||||
model.books_added(number_added)
|
||||
else:
|
||||
self.upload_books(paths, list(map(sanitize_file_name, names)), infos, on_card=on_card)
|
||||
if not to_device:
|
||||
progress.setLabelText(_('Adding books to database...'))
|
||||
model = self.library_view.model()
|
||||
|
||||
paths = list(paths)
|
||||
duplicates, number_added = model.add_books(paths, formats, metadata)
|
||||
progress.cancel()
|
||||
if duplicates:
|
||||
files = _('<p>Books with the same title as the following already exist in the database. Add them anyway?<ul>')
|
||||
for mi in duplicates[2]:
|
||||
files += '<li>'+mi.title+'</li>\n'
|
||||
d = WarningDialog(_('Duplicates found!'), _('Duplicates found!'), files+'</ul></p>', parent=self)
|
||||
if d.exec_() == QDialog.Accepted:
|
||||
num = model.add_books(*duplicates, **dict(add_duplicates=True))[1]
|
||||
number_added += num
|
||||
#self.library_view.sortByColumn(3, Qt.DescendingOrder)
|
||||
#model.research()
|
||||
model.books_added(number_added)
|
||||
else:
|
||||
self.upload_books(paths, list(map(sanitize_file_name, names)), infos, on_card=on_card)
|
||||
finally:
|
||||
progress.setValue(len(paths))
|
||||
|
||||
def upload_books(self, files, names, metadata, on_card=False, memory=None):
|
||||
'''
|
||||
|
@ -1471,11 +1471,13 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE;
|
||||
(usize, data, id, ext))
|
||||
self.conn.commit()
|
||||
|
||||
def import_book_directory_multiple(self, dirpath):
|
||||
def import_book_directory_multiple(self, dirpath, callback=None):
|
||||
dirpath = os.path.abspath(dirpath)
|
||||
duplicates = []
|
||||
books = {}
|
||||
for path in os.listdir(dirpath):
|
||||
if callable(callback):
|
||||
callback('.')
|
||||
path = os.path.abspath(os.path.join(dirpath, path))
|
||||
if os.path.isdir(path) or not os.access(path, os.R_OK):
|
||||
continue
|
||||
@ -1500,13 +1502,18 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE;
|
||||
duplicates.append((mi, formats))
|
||||
continue
|
||||
self.import_book(mi, formats)
|
||||
if callable(callback):
|
||||
if callback(mi.title):
|
||||
break
|
||||
return duplicates
|
||||
|
||||
|
||||
def import_book_directory(self, dirpath):
|
||||
def import_book_directory(self, dirpath, callback=None):
|
||||
dirpath = os.path.abspath(dirpath)
|
||||
formats = []
|
||||
for path in os.listdir(dirpath):
|
||||
if callable(callback):
|
||||
callback('.')
|
||||
path = os.path.abspath(os.path.join(dirpath, path))
|
||||
if os.path.isdir(path) or not os.access(path, os.R_OK):
|
||||
continue
|
||||
@ -1527,6 +1534,9 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE;
|
||||
if self.has_book(mi):
|
||||
return [(mi, formats)]
|
||||
self.import_book(mi, formats)
|
||||
if callable(callback):
|
||||
callback(mi.title)
|
||||
|
||||
|
||||
|
||||
def has_book(self, mi):
|
||||
@ -1535,13 +1545,19 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE;
|
||||
def has_id(self, id):
|
||||
return self.conn.get('SELECT id FROM books where id=?', (id,), all=False) is not None
|
||||
|
||||
def recursive_import(self, root, single_book_per_directory=True):
|
||||
def recursive_import(self, root, single_book_per_directory=True, callback=None):
|
||||
root = os.path.abspath(root)
|
||||
duplicates = []
|
||||
for dirpath in os.walk(root):
|
||||
res = self.import_book_directory(dirpath[0]) if single_book_per_directory else self.import_book_directory_multiple(dirpath[0])
|
||||
res = self.import_book_directory(dirpath[0], callback=callback) if \
|
||||
single_book_per_directory else \
|
||||
self.import_book_directory_multiple(dirpath[0], callback=callback)
|
||||
if res is not None:
|
||||
duplicates.extend(res)
|
||||
if callable(callback):
|
||||
if callback(''):
|
||||
break
|
||||
|
||||
return duplicates
|
||||
|
||||
def export_single_format_to_dir(self, dir, indices, format, index_is_id=False):
|
||||
|
Loading…
x
Reference in New Issue
Block a user