diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py
index dee1b2bfa8..e6b23d8157 100644
--- a/src/calibre/gui2/main.py
+++ b/src/calibre/gui2/main.py
@@ -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 = _('
Books with the same title as the following already exist in the database. Add them anyway?
')
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 = _('Books with the same title as the following already exist in the database. Add them anyway?
')
- for mi in duplicates[2]:
- files += '- '+mi.title+'
\n'
- d = WarningDialog(_('Duplicates found!'), _('Duplicates found!'), files+'
', 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 = _('Books with the same title as the following already exist in the database. Add them anyway?
')
+ for mi in duplicates[2]:
+ files += '- '+mi.title+'
\n'
+ d = WarningDialog(_('Duplicates found!'), _('Duplicates found!'), files+'
', 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):
'''
diff --git a/src/calibre/library/database.py b/src/calibre/library/database.py
index 1c1129db6b..122bded333 100644
--- a/src/calibre/library/database.py
+++ b/src/calibre/library/database.py
@@ -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):