mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
...
This commit is contained in:
parent
9155f7c0cb
commit
ebe5b28567
@ -253,10 +253,10 @@ def identify(log, abort, # {{{
|
|||||||
plugins = [p for p in metadata_plugins(['identify']) if p.is_configured()]
|
plugins = [p for p in metadata_plugins(['identify']) if p.is_configured()]
|
||||||
|
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'title': title,
|
'title': title,
|
||||||
'authors': authors,
|
'authors': authors,
|
||||||
'identifiers': identifiers,
|
'identifiers': identifiers,
|
||||||
'timeout': timeout,
|
'timeout': timeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
log('Running identify query with parameters:')
|
log('Running identify query with parameters:')
|
||||||
|
@ -11,23 +11,16 @@ from threading import Thread, Event
|
|||||||
|
|
||||||
from PyQt4.Qt import (QStyledItemDelegate, QTextDocument, QRectF, QIcon, Qt,
|
from PyQt4.Qt import (QStyledItemDelegate, QTextDocument, QRectF, QIcon, Qt,
|
||||||
QStyle, QApplication, QDialog, QVBoxLayout, QLabel, QDialogButtonBox,
|
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 PyQt4.QtWebKit import QWebView
|
||||||
|
|
||||||
from calibre.customize.ui import metadata_plugins
|
from calibre.customize.ui import metadata_plugins
|
||||||
from calibre.ebooks.metadata import authors_to_string
|
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.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): # {{{
|
class RichTextDelegate(QStyledItemDelegate): # {{{
|
||||||
|
|
||||||
@ -56,10 +49,11 @@ class RichTextDelegate(QStyledItemDelegate): # {{{
|
|||||||
painter.restore()
|
painter.restore()
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class ResultsView(QTableView):
|
class ResultsView(QTableView): # {{{
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
QTableView.__init__(self, parent)
|
QTableView.__init__(self, parent)
|
||||||
|
# }}}
|
||||||
|
|
||||||
class Comments(QWebView): # {{{
|
class Comments(QWebView): # {{{
|
||||||
|
|
||||||
@ -109,7 +103,7 @@ class Comments(QWebView): # {{{
|
|||||||
self.setHtml(templ%html)
|
self.setHtml(templ%html)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class IdentifyWorker(Thread):
|
class IdentifyWorker(Thread): # {{{
|
||||||
|
|
||||||
def __init__(self, log, abort, title, authors, identifiers):
|
def __init__(self, log, abort, title, authors, identifiers):
|
||||||
Thread.__init__(self)
|
Thread.__init__(self)
|
||||||
@ -131,8 +125,11 @@ class IdentifyWorker(Thread):
|
|||||||
except:
|
except:
|
||||||
import traceback
|
import traceback
|
||||||
self.error = traceback.format_exc()
|
self.error = traceback.format_exc()
|
||||||
|
# }}}
|
||||||
|
|
||||||
class IdentifyWidget(QWidget):
|
class IdentifyWidget(QWidget): # {{{
|
||||||
|
|
||||||
|
rejected = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, log, parent=None):
|
def __init__(self, log, parent=None):
|
||||||
QWidget.__init__(self, parent)
|
QWidget.__init__(self, parent)
|
||||||
@ -199,6 +196,40 @@ class IdentifyWidget(QWidget):
|
|||||||
|
|
||||||
# self.worker.start()
|
# 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): # {{{
|
class FullFetch(QDialog): # {{{
|
||||||
|
|
||||||
def __init__(self, log, parent=None):
|
def __init__(self, log, parent=None):
|
||||||
@ -218,6 +249,7 @@ class FullFetch(QDialog): # {{{
|
|||||||
self.bb.rejected.connect(self.reject)
|
self.bb.rejected.connect(self.reject)
|
||||||
|
|
||||||
self.identify_widget = IdentifyWidget(log, self)
|
self.identify_widget = IdentifyWidget(log, self)
|
||||||
|
self.identify_widget.rejected.connect(self.reject)
|
||||||
self.stack.addWidget(self.identify_widget)
|
self.stack.addWidget(self.identify_widget)
|
||||||
self.resize(850, 500)
|
self.resize(850, 500)
|
||||||
|
|
||||||
@ -225,6 +257,10 @@ class FullFetch(QDialog): # {{{
|
|||||||
# Prevent pressing Enter from closing the dialog
|
# Prevent pressing Enter from closing the dialog
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def reject(self):
|
||||||
|
self.identify_widget.cancel()
|
||||||
|
return QDialog.reject(self)
|
||||||
|
|
||||||
def start(self, title=None, authors=None, identifiers={}):
|
def start(self, title=None, authors=None, identifiers={}):
|
||||||
self.identify_widget.start(title=title, authors=authors,
|
self.identify_widget.start(title=title, authors=authors,
|
||||||
identifiers=identifiers)
|
identifiers=identifiers)
|
||||||
|
@ -108,10 +108,13 @@ class UnicodeHTMLStream(HTMLStream):
|
|||||||
elif not isinstance(arg, unicode):
|
elif not isinstance(arg, unicode):
|
||||||
arg = as_unicode(arg)
|
arg = as_unicode(arg)
|
||||||
self.data.append(arg+sep)
|
self.data.append(arg+sep)
|
||||||
|
self.plain_text.append(arg+sep)
|
||||||
self.data.append(end)
|
self.data.append(end)
|
||||||
|
self.plain_text.append(end)
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self.data = []
|
self.data = []
|
||||||
|
self.plain_text = []
|
||||||
self.last_col = self.color[INFO]
|
self.last_col = self.color[INFO]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -162,4 +165,25 @@ class ThreadSafeLog(Log):
|
|||||||
with self._lock:
|
with self._lock:
|
||||||
Log.prints(self, *args, **kwargs)
|
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()
|
default_log = Log()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user