Add progress indication when adding books to the library

This commit is contained in:
Kovid Goyal 2008-12-23 22:25:13 -08:00
parent 660fa430f8
commit 5769ce558c
2 changed files with 91 additions and 47 deletions

View File

@ -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):
'''

View File

@ -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):