From ebe5b28567e467df846ca15bb8c31123b5106026 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 7 Apr 2011 11:01:08 -0600 Subject: [PATCH] ... --- .../ebooks/metadata/sources/identify.py | 8 +-- src/calibre/gui2/metadata/single_download.py | 64 +++++++++++++++---- src/calibre/utils/logging.py | 24 +++++++ 3 files changed, 78 insertions(+), 18 deletions(-) diff --git a/src/calibre/ebooks/metadata/sources/identify.py b/src/calibre/ebooks/metadata/sources/identify.py index 8c6172f0e2..075c780596 100644 --- a/src/calibre/ebooks/metadata/sources/identify.py +++ b/src/calibre/ebooks/metadata/sources/identify.py @@ -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:') diff --git a/src/calibre/gui2/metadata/single_download.py b/src/calibre/gui2/metadata/single_download.py index 049ac611c5..19e92adf4f 100644 --- a/src/calibre/gui2/metadata/single_download.py +++ b/src/calibre/gui2/metadata/single_download.py @@ -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'), '

' + + _('Failed to find any books that ' + 'match your search. Try making the search less ' + 'specific. For example, use only the author\'s ' + 'last name and a single distinctive word from ' + 'the title.

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) diff --git a/src/calibre/utils/logging.py b/src/calibre/utils/logging.py index 45e21ded39..dbbca6806b 100644 --- a/src/calibre/utils/logging.py +++ b/src/calibre/utils/logging.py @@ -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()