diff --git a/resources/recipes/economist.recipe b/resources/recipes/economist.recipe index 0f70a1e025..a5e43e360a 100644 --- a/resources/recipes/economist.recipe +++ b/resources/recipes/economist.recipe @@ -87,4 +87,6 @@ class Economist(BasicNewsRecipe): feeds[key].append(article) ans = [(key, feeds[key]) for key in ans if feeds.has_key(key)] + if not ans: + raise Exception('Could not find any articles. Has your subscription expired?') return ans diff --git a/src/calibre/ebooks/lrf/html/table_as_image.py b/src/calibre/ebooks/lrf/html/table_as_image.py index 08eaec0436..498f21fcb6 100644 --- a/src/calibre/ebooks/lrf/html/table_as_image.py +++ b/src/calibre/ebooks/lrf/html/table_as_image.py @@ -11,16 +11,15 @@ from PyQt4.Qt import QUrl, QApplication, QSize, QEventLoop, \ SIGNAL, QPainter, QImage, QObject, Qt from PyQt4.QtWebKit import QWebPage - class HTMLTableRenderer(QObject): def __init__(self, html, base_dir, width, height, dpi, factor): ''' `width, height`: page width and height in pixels - `base_dir`: The directory in which the HTML file that contains the table resides + `base_dir`: The directory in which the HTML file that contains the table resides ''' QObject.__init__(self) - + self.app = None self.width, self.height, self.dpi = width, height, dpi self.base_dir = base_dir @@ -30,10 +29,10 @@ class HTMLTableRenderer(QObject): self.page = QWebPage() self.connect(self.page, SIGNAL('loadFinished(bool)'), self.render_html) self.page.mainFrame().setTextSizeMultiplier(factor) - self.page.mainFrame().setHtml(html, + self.page.mainFrame().setHtml(html, QUrl('file:'+os.path.abspath(self.base_dir))) - - + + def render_html(self, ok): try: if not ok: @@ -61,7 +60,7 @@ class HTMLTableRenderer(QObject): self.images.append((f, img.width(), img.height())) finally: QApplication.quit() - + def render_table(soup, table, css, base_dir, width, height, dpi, factor=1.0): head = '' for e in soup.findAll(['link', 'style']): @@ -85,10 +84,11 @@ def render_table(soup, table, css, base_dir, width, height, dpi, factor=1.0): images, tdir = do_render(html, base_dir, width, height, dpi, factor) atexit.register(shutil.rmtree, tdir) return images - + def do_render(html, base_dir, width, height, dpi, factor): - if QApplication.instance() is None: - QApplication([]) + from calibre.gui2 import is_ok_to_use_qt + if not is_ok_to_use_qt(): + raise Exception('Not OK to use Qt') tr = HTMLTableRenderer(html, base_dir, width, height, dpi, factor) tr.loop.exec_() - return tr.images, tr.tdir \ No newline at end of file + return tr.images, tr.tdir diff --git a/src/calibre/ebooks/oeb/transforms/rasterize.py b/src/calibre/ebooks/oeb/transforms/rasterize.py index a4ebb0bb23..30357b10d2 100644 --- a/src/calibre/ebooks/oeb/transforms/rasterize.py +++ b/src/calibre/ebooks/oeb/transforms/rasterize.py @@ -18,7 +18,6 @@ from PyQt4.QtGui import QColor from PyQt4.QtGui import QImage from PyQt4.QtGui import QPainter from PyQt4.QtSvg import QSvgRenderer -from PyQt4.QtGui import QApplication from calibre.ebooks.oeb.base import XHTML, XLINK from calibre.ebooks.oeb.base import SVG_MIME, PNG_MIME from calibre.ebooks.oeb.base import xml2str, xpath @@ -30,8 +29,9 @@ KEEP_ATTRS = set(['class', 'style', 'width', 'height', 'align']) class SVGRasterizer(object): def __init__(self): - if QApplication.instance() is None: - QApplication([]) + from calibre.gui2 import is_ok_to_use_qt + if not is_ok_to_use_qt(): + raise Exception('Not OK to use Qt') @classmethod def config(cls, cfg): diff --git a/src/calibre/ebooks/pdf/writer.py b/src/calibre/ebooks/pdf/writer.py index 73ab16cdb6..9b5094ac95 100644 --- a/src/calibre/ebooks/pdf/writer.py +++ b/src/calibre/ebooks/pdf/writer.py @@ -18,7 +18,7 @@ from calibre.ebooks.metadata import authors_to_string from PyQt4 import QtCore from PyQt4.Qt import QUrl, QEventLoop, SIGNAL, QObject, \ - QApplication, QPrinter, QMetaObject, QSizeF, Qt + QPrinter, QMetaObject, QSizeF, Qt from PyQt4.QtWebKit import QWebView from pyPdf import PdfFileWriter, PdfFileReader @@ -37,8 +37,9 @@ class PDFMetadata(object): class PDFWriter(QObject): def __init__(self, opts, log): - if QApplication.instance() is None: - QApplication([]) + from calibre.gui2 import is_ok_to_use_qt + if not is_ok_to_use_qt(): + raise Exception('Not OK to use Qt') QObject.__init__(self) self.logger = log diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 14789332e4..2e965fb295 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -528,12 +528,14 @@ class Application(QApplication): if set_qt_translator(self._translator): self.installTranslator(self._translator) +_store_app = None + def is_ok_to_use_qt(): - global gui_thread + global gui_thread, _store_app if islinux and ':' not in os.environ.get('DISPLAY', ''): return False - if QApplication.instance() is None: - QApplication([]) + if _store_app is None and QApplication.instance() is None: + _store_app = QApplication([]) if gui_thread is None: gui_thread = QThread.currentThread() return gui_thread is QThread.currentThread() diff --git a/src/calibre/gui2/convert/font_key.py b/src/calibre/gui2/convert/font_key.py index 82d72d7e6d..39eb58dd48 100644 --- a/src/calibre/gui2/convert/font_key.py +++ b/src/calibre/gui2/convert/font_key.py @@ -98,7 +98,7 @@ class FontKeyChooser(QDialog, Ui_Dialog): if __name__ == '__main__': - from PyQt4.Qt import QApplication - QApplication([]) + from calibre.gui2 import is_ok_to_use_qt + is_ok_to_use_qt() d = FontKeyChooser() d.exec_() diff --git a/src/calibre/gui2/cover_flow.py b/src/calibre/gui2/cover_flow.py index 220e368a04..e1807d2ffa 100644 --- a/src/calibre/gui2/cover_flow.py +++ b/src/calibre/gui2/cover_flow.py @@ -20,9 +20,9 @@ if pictureflow is not None: class EmptyImageList(pictureflow.FlowImages): def __init__(self): pictureflow.FlowImages.__init__(self) - + class FileSystemImages(pictureflow.FlowImages): - + def __init__(self, dirpath): pictureflow.FlowImages.__init__(self) self.images = [] @@ -33,58 +33,58 @@ if pictureflow is not None: if not img.isNull(): self.images.append(img) self.captions.append(os.path.basename(f)) - + def count(self): return len(self.images) - + def image(self, index): return self.images[index] - + def caption(self, index): return self.captions[index] - + def currentChanged(self, index): print 'current changed:', index - + class DatabaseImages(pictureflow.FlowImages): - + def __init__(self, model, buffer=20): pictureflow.FlowImages.__init__(self) self.model = model QObject.connect(self.model, SIGNAL('modelReset()'), self.reset) - + def count(self): return self.model.count() - + def caption(self, index): return self.model.title(index) - + def reset(self): self.emit(SIGNAL('dataChanged()')) - + def image(self, index): return self.model.cover(index) - - - + + + class CoverFlow(pictureflow.PictureFlow): - + def __init__(self, height=300, parent=None, text_height=25): - pictureflow.PictureFlow.__init__(self, parent, + pictureflow.PictureFlow.__init__(self, parent, config['cover_flow_queue_length']+1) self.setSlideSize(QSize(int(2/3. * height), height)) self.setMinimumSize(QSize(int(2.35*0.67*height), (5/3.)*height+text_height)) self.setFocusPolicy(Qt.WheelFocus) self.setSizePolicy(QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)) - + def wheelEvent(self, ev): ev.accept() if ev.delta() < 0: self.showNext() elif ev.delta() > 0: self.showPrevious() - - + + else: CoverFlow = None DatabaseImages = None @@ -105,7 +105,7 @@ if __name__ == '__main__': cf.setImages(model) cf.connect(cf, SIGNAL('currentChanged(int)'), model.currentChanged) w.setCentralWidget(cf) - + w.show() cf.setFocus(Qt.OtherFocusReason) sys.exit(app.exec_()) diff --git a/src/calibre/gui2/dialogs/scheduler.py b/src/calibre/gui2/dialogs/scheduler.py index 798269f5cf..4e28ab870d 100644 --- a/src/calibre/gui2/dialogs/scheduler.py +++ b/src/calibre/gui2/dialogs/scheduler.py @@ -9,7 +9,7 @@ Scheduler for automated recipe downloads from datetime import datetime, timedelta -from PyQt4.Qt import QDialog, QApplication, SIGNAL, Qt, QTime, QObject, QMenu, \ +from PyQt4.Qt import QDialog, SIGNAL, Qt, QTime, QObject, QMenu, \ QAction, QIcon, QMutex, QTimer from calibre.gui2.dialogs.scheduler_ui import Ui_Dialog @@ -306,7 +306,8 @@ class Scheduler(QObject): self.download(urn) if __name__ == '__main__': - QApplication([]) + from calibre.gui2 import is_ok_to_use_qt + is_ok_to_use_qt() from calibre.library.database2 import LibraryDatabase2 d = SchedulerDialog(RecipeModel(LibraryDatabase2('/home/kovid/documents/library'))) d.exec_() diff --git a/src/calibre/gui2/dialogs/user_profiles.py b/src/calibre/gui2/dialogs/user_profiles.py index 4b2552e43f..08cb455997 100644 --- a/src/calibre/gui2/dialogs/user_profiles.py +++ b/src/calibre/gui2/dialogs/user_profiles.py @@ -314,8 +314,8 @@ class %(classname)s(%(base_class)s): self.source_code.setText('') if __name__ == '__main__': - from PyQt4.Qt import QApplication - QApplication([]) + from calibre.gui2 import is_ok_to_use_qt + is_ok_to_use_qt() from calibre.library.database2 import LibraryDatabase2 from calibre.web.feeds.recipes.model import RecipeModel d=UserProfiles(None, RecipeModel(LibraryDatabase2('/home/kovid/documents/library'))) diff --git a/src/calibre/gui2/status.py b/src/calibre/gui2/status.py index 6cd8e83db4..16ac1a7ce2 100644 --- a/src/calibre/gui2/status.py +++ b/src/calibre/gui2/status.py @@ -282,9 +282,10 @@ class StatusBar(QStatusBar): if __name__ == '__main__': # Used to create the animated status icon - from PyQt4.Qt import QApplication, QPainter, QSvgRenderer, QColor + from PyQt4.Qt import QPainter, QSvgRenderer, QColor from subprocess import check_call - app = QApplication([]) + from calibre.gui2 import is_ok_to_use_qt + is_ok_to_use_qt() def create_pixmaps(path, size=16, delta=20): r = QSvgRenderer(path) diff --git a/src/calibre/gui2/viewer/printing.py b/src/calibre/gui2/viewer/printing.py index c7167f0727..f32210a3b9 100644 --- a/src/calibre/gui2/viewer/printing.py +++ b/src/calibre/gui2/viewer/printing.py @@ -10,7 +10,7 @@ from BeautifulSoup import BeautifulSoup, Tag from PyQt4 import QtCore -from PyQt4.Qt import QUrl, QEventLoop, SIGNAL, QObject, QApplication, Qt, \ +from PyQt4.Qt import QUrl, QEventLoop, SIGNAL, QObject, Qt, \ QPrinter, QPrintPreviewDialog, QPrintDialog, QDialog, QMetaObject, Q_ARG from PyQt4.QtWebKit import QWebView @@ -18,8 +18,9 @@ PRINTCSS = 'body{width:100%;margin:0;padding:0;font-family:Arial;color:#000;back class Printing(QObject): def __init__(self, spine, preview): - if QApplication.instance() is None: - QApplication([]) + from calibre.gui2 import is_ok_to_use_qt + if not is_ok_to_use_qt(): + raise Exception('Not OK to use Qt') QObject.__init__(self) self.loop = QEventLoop()