This commit is contained in:
Kovid Goyal 2011-04-07 11:01:08 -06:00
parent 9155f7c0cb
commit ebe5b28567
3 changed files with 78 additions and 18 deletions

View File

@ -253,10 +253,10 @@ def identify(log, abort, # {{{
plugins = [p for p in metadata_plugins(['identify']) if p.is_configured()]
kwargs = {
'title': title,
'authors': authors,
'identifiers': identifiers,
'timeout': timeout,
'title': title,
'authors': authors,
'identifiers': identifiers,
'timeout': timeout,
}
log('Running identify query with parameters:')

View File

@ -11,23 +11,16 @@ from threading import Thread, Event
from PyQt4.Qt import (QStyledItemDelegate, QTextDocument, QRectF, QIcon, Qt,
QStyle, QApplication, QDialog, QVBoxLayout, QLabel, QDialogButtonBox,
QStackedWidget, QWidget, QTableView, QGridLayout, QFontInfo, QPalette)
QStackedWidget, QWidget, QTableView, QGridLayout, QFontInfo, QPalette,
QTimer, pyqtSignal)
from PyQt4.QtWebKit import QWebView
from calibre.customize.ui import metadata_plugins
from calibre.ebooks.metadata import authors_to_string
from calibre.utils.logging import ThreadSafeLog, UnicodeHTMLStream
from calibre.utils.logging import GUILog as Log
from calibre.ebooks.metadata.sources.identify import identify
from calibre.gui2 import error_dialog
class Log(ThreadSafeLog): # {{{
def __init__(self):
ThreadSafeLog.__init__(self, level=self.DEBUG)
self.outputs = [UnicodeHTMLStream()]
def clear(self):
self.outputs[0].clear()
# }}}
class RichTextDelegate(QStyledItemDelegate): # {{{
@ -56,10 +49,11 @@ class RichTextDelegate(QStyledItemDelegate): # {{{
painter.restore()
# }}}
class ResultsView(QTableView):
class ResultsView(QTableView): # {{{
def __init__(self, parent=None):
QTableView.__init__(self, parent)
# }}}
class Comments(QWebView): # {{{
@ -109,7 +103,7 @@ class Comments(QWebView): # {{{
self.setHtml(templ%html)
# }}}
class IdentifyWorker(Thread):
class IdentifyWorker(Thread): # {{{
def __init__(self, log, abort, title, authors, identifiers):
Thread.__init__(self)
@ -131,8 +125,11 @@ class IdentifyWorker(Thread):
except:
import traceback
self.error = traceback.format_exc()
# }}}
class IdentifyWidget(QWidget):
class IdentifyWidget(QWidget): # {{{
rejected = pyqtSignal()
def __init__(self, log, parent=None):
QWidget.__init__(self, parent)
@ -199,6 +196,40 @@ class IdentifyWidget(QWidget):
# self.worker.start()
QTimer.singleShot(50, self.update)
def update(self):
if self.worker.is_alive():
QTimer.singleShot(50, self.update)
return
self.process_results()
def process_results(self):
if self.worker.error is not None:
error_dialog(self, _('Download failed'),
_('Failed to download metadata. Click '
'Show Details to see details'),
show=True, det_msg=self.wroker.error)
self.rejected.emit()
return
if not self.worker.results:
log = ''.join(self.log.plain_text)
error_dialog(self, _('No matches found'), '<p>' +
_('Failed to find any books that '
'match your search. Try making the search <b>less '
'specific</b>. For example, use only the author\'s '
'last name and a single distinctive word from '
'the title.<p>To see the full log, click Show Details.'),
show=True, det_msg=log)
self.rejected.emit()
return
def cancel(self):
self.abort.set()
# }}}
class FullFetch(QDialog): # {{{
def __init__(self, log, parent=None):
@ -218,6 +249,7 @@ class FullFetch(QDialog): # {{{
self.bb.rejected.connect(self.reject)
self.identify_widget = IdentifyWidget(log, self)
self.identify_widget.rejected.connect(self.reject)
self.stack.addWidget(self.identify_widget)
self.resize(850, 500)
@ -225,6 +257,10 @@ class FullFetch(QDialog): # {{{
# Prevent pressing Enter from closing the dialog
pass
def reject(self):
self.identify_widget.cancel()
return QDialog.reject(self)
def start(self, title=None, authors=None, identifiers={}):
self.identify_widget.start(title=title, authors=authors,
identifiers=identifiers)

View File

@ -108,10 +108,13 @@ class UnicodeHTMLStream(HTMLStream):
elif not isinstance(arg, unicode):
arg = as_unicode(arg)
self.data.append(arg+sep)
self.plain_text.append(arg+sep)
self.data.append(end)
self.plain_text.append(end)
def clear(self):
self.data = []
self.plain_text = []
self.last_col = self.color[INFO]
@property
@ -162,4 +165,25 @@ class ThreadSafeLog(Log):
with self._lock:
Log.prints(self, *args, **kwargs)
class GUILog(ThreadSafeLog):
'''
Logs in HTML and plain text as unicode. Ideal for display in a GUI context.
'''
def __init__(self):
ThreadSafeLog.__init__(self, level=self.DEBUG)
self.outputs = [UnicodeHTMLStream()]
def clear(self):
self.outputs[0].clear()
@property
def html(self):
return self.outputs[0].html
@property
def plain_text(self):
return u''.join(self.outputs[0].plain_text)
default_log = Log()