Refactor the downloading social metadata message box to allow canceling. Fixes #8234 (Calibre crashes while editing metadata)

This commit is contained in:
Kovid Goyal 2011-01-13 19:01:48 -07:00
parent ab0bde42fa
commit 4e9070019a
2 changed files with 35 additions and 10 deletions

View File

@ -790,7 +790,13 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
if d.opt_get_social_metadata.isChecked():
d2 = SocialMetadata(book, self)
d2.exec_()
if d2.exceptions:
if d2.timed_out:
warning_dialog(self, _('Timed out'),
_('The download of social'
' metadata timed out, the servers are'
' probably busy. Try again later.'),
show=True)
elif d2.exceptions:
det = '\n'.join([x[0]+'\n\n'+x[-1]+'\n\n\n' for
x in d2.exceptions])
warning_dialog(self, _('There were errors'),

View File

@ -6,16 +6,19 @@ __license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import time
from threading import Thread
from PyQt4.Qt import QDialog, QDialogButtonBox, Qt, QLabel, QVBoxLayout, \
SIGNAL, QThread
QTimer
from calibre.ebooks.metadata import MetaInformation
class Worker(QThread):
class Worker(Thread):
def __init__(self, mi, parent):
QThread.__init__(self, parent)
def __init__(self, mi):
Thread.__init__(self)
self.daemon = True
self.mi = MetaInformation(mi)
self.exceptions = []
@ -25,10 +28,12 @@ class Worker(QThread):
class SocialMetadata(QDialog):
TIMEOUT = 300 # seconds
def __init__(self, mi, parent):
QDialog.__init__(self, parent)
self.bbox = QDialogButtonBox(QDialogButtonBox.Ok, Qt.Horizontal, self)
self.bbox = QDialogButtonBox(QDialogButtonBox.Cancel, Qt.Horizontal, self)
self.mi = mi
self.layout = QVBoxLayout(self)
self.label = QLabel(_('Downloading social metadata, please wait...'), self)
@ -36,15 +41,29 @@ class SocialMetadata(QDialog):
self.layout.addWidget(self.label)
self.layout.addWidget(self.bbox)
self.worker = Worker(mi, self)
self.connect(self.worker, SIGNAL('finished()'), self.accept)
self.connect(self.bbox, SIGNAL('rejected()'), self.reject)
self.worker = Worker(mi)
self.bbox.rejected.connect(self.reject)
self.worker.start()
self.start_time = time.time()
self.timed_out = False
self.rejected = False
QTimer.singleShot(50, self.update)
def reject(self):
self.disconnect(self.worker, SIGNAL('finished()'), self.accept)
self.rejected = True
QDialog.reject(self)
def update(self):
if self.rejected:
return
if time.time() - self.start_time > self.TIMEOUT:
self.timed_out = True
self.reject()
return
if not self.worker.is_alive():
self.accept()
QTimer.singleShot(50, self.update)
def accept(self):
self.mi.tags = self.worker.mi.tags
self.mi.rating = self.worker.mi.rating