This commit is contained in:
Kovid Goyal 2011-04-06 22:53:08 -06:00
parent fc1e9175fc
commit 2befe1eb58
2 changed files with 116 additions and 29 deletions

View File

@ -7,6 +7,8 @@ __license__ = 'GPL v3'
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
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)
@ -14,6 +16,18 @@ 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.ebooks.metadata.sources.identify import identify
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): # {{{
@ -95,10 +109,35 @@ class Comments(QWebView): # {{{
self.setHtml(templ%html) self.setHtml(templ%html)
# }}} # }}}
class IdentifyWorker(Thread):
def __init__(self, log, abort, title, authors, identifiers):
Thread.__init__(self)
self.daemon = True
self.log, self.abort = log, abort
self.title, self.authors, self.identifiers = (title, authors.
identifiers)
self.results = []
self.error = None
def run(self):
try:
self.results = identify(self.log, self.abort, title=self.title,
authors=self.authors, identifiers=self.identifiers)
for i, result in enumerate(self.results):
result.gui_rank = i
except:
import traceback
self.error = traceback.format_exc()
class IdentifyWidget(QWidget): class IdentifyWidget(QWidget):
def __init__(self, parent=None): def __init__(self, log, parent=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.log = log
self.abort = Event()
self.l = l = QGridLayout() self.l = l = QGridLayout()
self.setLayout(l) self.setLayout(l)
@ -123,7 +162,27 @@ class IdentifyWidget(QWidget):
self.query.setWordWrap(True) self.query.setWordWrap(True)
l.addWidget(self.query, 2, 0, 1, 2) l.addWidget(self.query, 2, 0, 1, 2)
self.comments_view.show_data('<h2>'+_('Downloading')+
'<br><span id="dots">.</span></h2>'+
'''
<script type="text/javascript">
window.onload=function(){
var dotspan = document.getElementById('dots');
window.setInterval(function(){
if(dotspan.textContent == '............'){
dotspan.textContent = '.';
}
else{
dotspan.textContent += '.';
}
}, 400);
}
</script>
''')
def start(self, title=None, authors=None, identifiers={}): def start(self, title=None, authors=None, identifiers={}):
self.log.clear()
self.log('Starting download')
parts = [] parts = []
if title: if title:
parts.append('title:'+title) parts.append('title:'+title)
@ -133,28 +192,18 @@ class IdentifyWidget(QWidget):
x = ', '.join('%s:%s'%(k, v) for k, v in identifiers) x = ', '.join('%s:%s'%(k, v) for k, v in identifiers)
parts.append(x) parts.append(x)
self.query.setText(_('Query: ')+'; '.join(parts)) self.query.setText(_('Query: ')+'; '.join(parts))
self.comments_view.show_data('<h2>'+_('Downloading, please wait')+ self.log(unicode(self.query.text()))
'<span id="dots">.</span></h2>'+
''' self.worker = IdentifyWorker(self.log, self.abort, self.title,
<script type="text/javascript"> self.authors, self.identifiers)
window.onload=function(){
var dotspan = document.getElementById('dots'); # self.worker.start()
window.setInterval(function(){
if(dotspan.textContent == '...'){
dotspan.textContent = '.';
}
else{
dotspan.textContent += '.';
}
}, 500);
}
</script>
''')
class FullFetch(QDialog): # {{{ class FullFetch(QDialog): # {{{
def __init__(self, parent=None): def __init__(self, log, parent=None):
QDialog.__init__(self, parent) QDialog.__init__(self, parent)
self.log = log
self.setWindowTitle(_('Downloading metadata...')) self.setWindowTitle(_('Downloading metadata...'))
self.setWindowIcon(QIcon(I('metadata.png'))) self.setWindowIcon(QIcon(I('metadata.png')))
@ -168,7 +217,7 @@ class FullFetch(QDialog): # {{{
l.addWidget(self.bb) l.addWidget(self.bb)
self.bb.rejected.connect(self.reject) self.bb.rejected.connect(self.reject)
self.identify_widget = IdentifyWidget(self) self.identify_widget = IdentifyWidget(log, self)
self.stack.addWidget(self.identify_widget) self.stack.addWidget(self.identify_widget)
self.resize(850, 500) self.resize(850, 500)
@ -184,6 +233,6 @@ class FullFetch(QDialog): # {{{
if __name__ == '__main__': if __name__ == '__main__':
app = QApplication([]) app = QApplication([])
d = FullFetch() d = FullFetch(Log())
d.start(title='great gatsby', authors=['Fitzgerald']) d.start(title='great gatsby', authors=['Fitzgerald'])

View File

@ -14,7 +14,7 @@ import sys, traceback, cStringIO
from functools import partial from functools import partial
from threading import RLock from threading import RLock
from calibre import isbytestring, force_unicode, as_unicode
class Stream(object): class Stream(object):
@ -63,15 +63,16 @@ class FileStream(Stream):
class HTMLStream(Stream): class HTMLStream(Stream):
def __init__(self, stream=sys.stdout): color = {
Stream.__init__(self, stream)
self.color = {
DEBUG: '<span style="color:green">', DEBUG: '<span style="color:green">',
INFO:'<span>', INFO:'<span>',
WARN: '<span style="color:yellow">', WARN: '<span style="color:yellow">',
ERROR: '<span style="color:red">' ERROR: '<span style="color:red">'
} }
self.normal = '</span>' normal = '</span>'
def __init__(self, stream=sys.stdout):
Stream.__init__(self, stream)
def prints(self, level, *args, **kwargs): def prints(self, level, *args, **kwargs):
self.stream.write(self.color[level]) self.stream.write(self.color[level])
@ -82,6 +83,43 @@ class HTMLStream(Stream):
def flush(self): def flush(self):
self.stream.flush() self.stream.flush()
class UnicodeHTMLStream(HTMLStream):
def __init__(self):
self.clear()
def flush(self):
pass
def prints(self, level, *args, **kwargs):
col = self.color[level]
if col != self.last_col:
if self.data:
self.data.append(self.normal)
self.data.append(col)
self.last_col = col
sep = kwargs.get(u'sep', u' ')
end = kwargs.get(u'end', u'\n')
for arg in args:
if isbytestring(arg):
arg = force_unicode(arg)
elif not isinstance(arg, unicode):
arg = as_unicode(arg)
self.data.append(arg+sep)
self.data.append(end)
def clear(self):
self.data = []
self.last_col = self.color[INFO]
@property
def html(self):
end = self.normal if self.data else u''
return u''.join(self.data) + end
class Log(object): class Log(object):
DEBUG = DEBUG DEBUG = DEBUG