diff --git a/src/calibre/ebooks/metadata/sources/amazon.py b/src/calibre/ebooks/metadata/sources/amazon.py index d48f502c29..b070132de9 100644 --- a/src/calibre/ebooks/metadata/sources/amazon.py +++ b/src/calibre/ebooks/metadata/sources/amazon.py @@ -279,7 +279,7 @@ class Worker(Thread): # Get details {{{ class Amazon(Source): - name = 'Amazon Metadata' + name = 'Amazon Store' description = _('Downloads metadata from Amazon') capabilities = frozenset(['identify', 'cover']) diff --git a/src/calibre/ebooks/metadata/sources/base.py b/src/calibre/ebooks/metadata/sources/base.py index faa7420081..d4e090084c 100644 --- a/src/calibre/ebooks/metadata/sources/base.py +++ b/src/calibre/ebooks/metadata/sources/base.py @@ -167,6 +167,13 @@ class Source(Plugin): # Configuration {{{ + def is_configured(self): + ''' + Return False if your plugin needs to be configured before it can be + used. For example, it might need a username/password/API key. + ''' + return True + @property def prefs(self): if self._config_obj is None: diff --git a/src/calibre/ebooks/metadata/sources/covers.py b/src/calibre/ebooks/metadata/sources/covers.py index 46b278397c..cf6ec90c54 100644 --- a/src/calibre/ebooks/metadata/sources/covers.py +++ b/src/calibre/ebooks/metadata/sources/covers.py @@ -76,7 +76,7 @@ def run_download(log, results, abort, (plugin, width, height, fmt, bytes) ''' - plugins = list(metadata_plugins(['cover'])) + plugins = [p for p in metadata_plugins(['cover']) if p.is_configured()] rq = Queue() workers = [Worker(p, abort, title, authors, identifiers, timeout, rq) for p diff --git a/src/calibre/ebooks/metadata/sources/identify.py b/src/calibre/ebooks/metadata/sources/identify.py index cbc12b6167..8c6172f0e2 100644 --- a/src/calibre/ebooks/metadata/sources/identify.py +++ b/src/calibre/ebooks/metadata/sources/identify.py @@ -250,7 +250,7 @@ def merge_identify_results(result_map, log): def identify(log, abort, # {{{ title=None, authors=None, identifiers={}, timeout=30): start_time = time.time() - plugins = list(metadata_plugins(['identify'])) + plugins = [p for p in metadata_plugins(['identify']) if p.is_configured()] kwargs = { 'title': title, diff --git a/src/calibre/ebooks/metadata/sources/isbndb.py b/src/calibre/ebooks/metadata/sources/isbndb.py index 3cd9d96c81..ab9342c6cb 100644 --- a/src/calibre/ebooks/metadata/sources/isbndb.py +++ b/src/calibre/ebooks/metadata/sources/isbndb.py @@ -37,4 +37,7 @@ class ISBNDB(Source): self.isbndb_key = prefs['isbndb_key'] + def is_configured(self): + return self.isbndb_key is not None + diff --git a/src/calibre/gui2/metadata/single_download.py b/src/calibre/gui2/metadata/single_download.py index ace4133d7a..be521b6000 100644 --- a/src/calibre/gui2/metadata/single_download.py +++ b/src/calibre/gui2/metadata/single_download.py @@ -7,8 +7,13 @@ __license__ = 'GPL v3' __copyright__ = '2011, Kovid Goyal ' __docformat__ = 'restructuredtext en' -from PyQt4.Qt import (QStyledItemDelegate, QTextDocument, QRectF, - QStyle, QApplication) +from PyQt4.Qt import (QStyledItemDelegate, QTextDocument, QRectF, QIcon, Qt, + QStyle, QApplication, QDialog, QVBoxLayout, QLabel, QDialogButtonBox, + QStackedWidget, QWidget, QTableView, QGridLayout, QFontInfo, QPalette) +from PyQt4.QtWebKit import QWebView + +from calibre.customize.ui import metadata_plugins +from calibre.ebooks.metadata import authors_to_string class RichTextDelegate(QStyledItemDelegate): # {{{ @@ -37,3 +42,148 @@ class RichTextDelegate(QStyledItemDelegate): # {{{ painter.restore() # }}} +class ResultsView(QTableView): + + def __init__(self, parent=None): + QTableView.__init__(self, parent) + +class Comments(QWebView): # {{{ + + def __init__(self, parent=None): + QWebView.__init__(self, parent) + self.setAcceptDrops(False) + self.setMaximumWidth(270) + self.setMinimumWidth(270) + + palette = self.palette() + palette.setBrush(QPalette.Base, Qt.transparent) + self.page().setPalette(palette) + self.setAttribute(Qt.WA_OpaquePaintEvent, False) + + def turnoff_scrollbar(self, *args): + self.page().mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff) + + def show_data(self, html): + def color_to_string(col): + ans = '#000000' + if col.isValid(): + col = col.toRgb() + if col.isValid(): + ans = unicode(col.name()) + return ans + + f = QFontInfo(QApplication.font(self.parent())).pixelSize() + c = color_to_string(QApplication.palette().color(QPalette.Normal, + QPalette.WindowText)) + templ = '''\ + + + + + +
+ %%s +
+ + + '''%(f, c) + self.setHtml(templ%html) +# }}} + +class IdentifyWidget(QWidget): + + def __init__(self, parent=None): + QWidget.__init__(self, parent) + + self.l = l = QGridLayout() + self.setLayout(l) + + names = [''+p.name+'' for p in metadata_plugins(['identify']) if + p.is_configured()] + self.top = QLabel('

'+_('calibre is downloading metadata from: ') + + ', '.join(names)) + self.top.setWordWrap(True) + l.addWidget(self.top, 0, 0) + + self.results_view = ResultsView(self) + l.addWidget(self.results_view, 1, 0) + + self.comments_view = Comments(self) + l.addWidget(self.comments_view, 1, 1) + + self.query = QLabel('download starting...') + f = self.query.font() + f.setPointSize(f.pointSize()-2) + self.query.setFont(f) + self.query.setWordWrap(True) + l.addWidget(self.query, 2, 0, 1, 2) + + def start(self, title=None, authors=None, identifiers={}): + parts = [] + if title: + parts.append('title:'+title) + if authors: + parts.append('authors:'+authors_to_string(authors)) + if identifiers: + x = ', '.join('%s:%s'%(k, v) for k, v in identifiers) + parts.append(x) + self.query.setText(_('Query: ')+'; '.join(parts)) + self.comments_view.show_data('

'+_('Downloading, please wait')+ + '.

'+ + ''' + + ''') + +class FullFetch(QDialog): # {{{ + + def __init__(self, parent=None): + QDialog.__init__(self, parent) + + self.setWindowTitle(_('Downloading metadata...')) + self.setWindowIcon(QIcon(I('metadata.png'))) + + self.stack = QStackedWidget() + self.l = l = QVBoxLayout() + self.setLayout(l) + l.addWidget(self.stack) + + self.bb = QDialogButtonBox(QDialogButtonBox.Cancel) + l.addWidget(self.bb) + self.bb.rejected.connect(self.reject) + + self.identify_widget = IdentifyWidget(self) + self.stack.addWidget(self.identify_widget) + self.resize(850, 500) + + def accept(self): + # Prevent pressing Enter from closing the dialog + pass + + def start(self, title=None, authors=None, identifiers={}): + self.identify_widget.start(title=title, authors=authors, + identifiers=identifiers) + self.exec_() +# }}} + +if __name__ == '__main__': + app = QApplication([]) + d = FullFetch() + d.start(title='great gatsby', authors=['Fitzgerald']) + diff --git a/src/calibre/manual/server.rst b/src/calibre/manual/server.rst index 6d1adc88cd..82ec5c2927 100644 --- a/src/calibre/manual/server.rst +++ b/src/calibre/manual/server.rst @@ -16,7 +16,7 @@ Here, we will show you how to integrate the |app| content server into another se Using a reverse proxy ----------------------- -This is the simplest approach as it allows you to use the binary calibre install with no external dependencies/system integration requirements. +A reverse proxy is when your normal server accepts incoming requests and passes them onto the calibre server. It then reads the response from the calibre server and forwards it to the client. This means that you can simply run the calibre server as normal without trying to integrate it closely with your main server, and you can take advantage of whatever authentication systems you main server has in place. This is the simplest approach as it allows you to use the binary calibre install with no external dependencies/system integration requirements. Below, is an example of how to achieve this with Apache as your main server, but it will work with any server that supports Reverse Proxies. First start the |app| content server as shown below:: @@ -33,7 +33,7 @@ The exact technique for enabling the proxy modules will vary depending on your A RewriteRule ^/calibre/(.*) http://localhost:8080/calibre/$1 [proxy] RewriteRule ^/calibre http://localhost:8080 [proxy] -That's all, you will now be able to access the |app| Content Server under the /calibre URL in your apache server. +That's all, you will now be able to access the |app| Content Server under the /calibre URL in your apache server. The above rules pass all requests under /calibre to the calibre server running on port 8080 and thanks to the --url-prefix option above, the calibre server handles them transparently. .. note:: If you are willing to devote an entire VirtualHost to the content server, then there is no need to use --url-prefix and RewriteRule, instead just use the ProxyPass directive.