diff --git a/TODO b/TODO index da3b133fd..293093d2a 100644 --- a/TODO +++ b/TODO @@ -122,7 +122,6 @@ Minor features - Hiding scrollbars - Ctrl+A/X to increase/decrease last number in URL - logging contexts -- catch import errors for PyQt and QtWebKit - Add more element-selection-detection code (with options?) based on: -> javascript: http://stackoverflow.com/a/2848120/2085149 -> microFocusChanged and check active element via: diff --git a/qutebrowser/app.py b/qutebrowser/app.py index e2ec19048..3c27b9768 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -17,6 +17,26 @@ """Initialization of qutebrowser and application-wide things.""" +### Things we want to do before normal imports ### + +# Print a nice traceback on segfault -- only available on Python 3.3+, but if +# it's unavailable, it doesn't matter much. +try: + import faulthandler # pylint: disable=import-error +except ImportError: + pass +else: + faulthandler.enable() + +# See https://bugreports.qt-project.org/browse/QTBUG-36099 +# We need to do this before importing PyQt +import qutebrowser.utils.harfbuzz as harfbuzz +harfbuzz.fix() + +# Check if everything we should be able to import is there +import qutebrowser.utils.dependencies as dependencies +dependencies.check() + import os import sys import logging @@ -27,20 +47,6 @@ from functools import partial from signal import signal, SIGINT from argparse import ArgumentParser from base64 import b64encode -# Print a nice traceback on segfault -- only available on Python 3.3+, but if -# it's unavailable, it doesn't matter much. -try: - import faulthandler # pylint: disable=import-error -except ImportError: - pass -else: - faulthandler.enable() - -# This is a really odd place to do this, but we have to do this before -# importing PyQt or it won't work. -# See https://bugreports.qt-project.org/browse/QTBUG-36099 -import qutebrowser.utils.harfbuzz as harfbuzz -harfbuzz.fix() from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox from PyQt5.QtCore import pyqtSlot, QTimer, QEventLoop diff --git a/qutebrowser/utils/dependencies.py b/qutebrowser/utils/dependencies.py new file mode 100644 index 000000000..5ad9a7a53 --- /dev/null +++ b/qutebrowser/utils/dependencies.py @@ -0,0 +1,90 @@ +# Copyright 2014 Florian Bruhin (The Compiler) +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + +"""Check if everything needed for qutebrowser is there. + +In a separate file because this needs to be done early before any imports. +""" + +import sys + + +def check(): + """Check if all dependencies are met.""" + if sys.hexversion < 0x03030000: + print("Fatal error: At least Python 3.3 is required to run " + "qutebrowser, but {} is installed!".format( + '.'.join(map(str, sys.version_info[:3])))) + sys.exit(1) + import textwrap + try: + import PyQt5.QtCore # pylint: disable=unused-variable + except ImportError: + print(textwrap.dedent(""" + Fatal error: PyQt5 is required to run qutebrowser but could not + be imported! Maybe it's not installed? + + On Debian: + apt-get install python3-pyqt5 python3-pyqt5.qtwebkit + + On Archlinux: + pacman -S python-pyqt5 qt5-webkit + or install the qutebrowser package from AUR + + On Windows: + Use the installer by Riverbank computing or the standalone + qutebrowser exe. + + http://www.riverbankcomputing.co.uk/software/pyqt/download5 + + For other distributions: + Check your package manager for similiarly named packages. + """).strip()) + if '--debug' in sys.argv: + import traceback + print() + traceback.print_exc() + sys.exit(1) + # At this point we can rely on QtCore being available, so we can display an + # error dialog + try: + import PyQt5.QtWebKit + except ImportError: + from PyQt5.QtWidgets import QApplication, QMessageBox + app = QApplication(sys.argv) + msgbox = QMessageBox(QMessageBox.Critical, "qutebrowser: Fatal error!", + textwrap.dedent(""" + Fatal error: QtWebKit is required to run qutebrowser but could not + be imported! Maybe it's not installed? + + On Debian: + apt-get install python3-pyqt5.qtwebkit + + On Archlinux: + pacman -S qt5-webkit + + For other distributions: + Check your package manager for similiarly named packages. + """).strip()) + if '--debug' in sys.argv: + import traceback + print() + traceback.print_exc() + msgbox.resize(msgbox.sizeHint()) + msgbox.exec_() + app.quit() + # At this point we have everything we need.