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