189 lines
8.2 KiB
Python
189 lines
8.2 KiB
Python
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
|
|
|
|
# Copyright 2014-2018 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
|
|
|
# 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 <http://www.gnu.org/licenses/>.
|
|
|
|
"""Early initialization and main entry point.
|
|
|
|
qutebrowser's initialization process roughly looks like this:
|
|
|
|
- This file gets imported, either via the setuptools entry point or
|
|
__main__.py.
|
|
- At import time, we check for the correct Python version and show an error if
|
|
it's too old.
|
|
- The main() function in this file gets invoked
|
|
- Argument parsing takes place
|
|
- earlyinit.early_init() gets invoked to do various low-level initialization
|
|
and checks whether all dependencies are met.
|
|
- app.run() gets called, which takes over.
|
|
See the docstring of app.py for details.
|
|
"""
|
|
|
|
import sys
|
|
import json
|
|
|
|
import qutebrowser
|
|
try:
|
|
from qutebrowser.misc.checkpyver import check_python_version
|
|
except ImportError:
|
|
try:
|
|
# python2
|
|
from .misc.checkpyver import check_python_version
|
|
except (SystemError, ValueError):
|
|
# Import without module - SystemError on Python3, ValueError (?!?) on
|
|
# Python2
|
|
sys.stderr.write("Please don't run this script directly, do something "
|
|
"like python3 -m qutebrowser instead.\n")
|
|
sys.stderr.flush()
|
|
sys.exit(100)
|
|
check_python_version()
|
|
from qutebrowser.utils import log
|
|
|
|
import argparse # pylint: disable=wrong-import-order
|
|
from qutebrowser.misc import earlyinit
|
|
|
|
|
|
def get_argparser():
|
|
"""Get the argparse parser."""
|
|
parser = argparse.ArgumentParser(prog='qutebrowser',
|
|
description=qutebrowser.__description__)
|
|
parser.add_argument('--basedir', help="Base directory for all storage.")
|
|
parser.add_argument('-V', '--version', help="Show version and quit.",
|
|
action='store_true')
|
|
parser.add_argument('-s', '--set', help="Set a temporary setting for "
|
|
"this session.", nargs=2, action='append',
|
|
dest='temp_settings', default=[],
|
|
metavar=('OPTION', 'VALUE'))
|
|
parser.add_argument('-r', '--restore', help="Restore a named session.",
|
|
dest='session')
|
|
parser.add_argument('-R', '--override-restore', help="Don't restore a "
|
|
"session even if one would be restored.",
|
|
action='store_true')
|
|
parser.add_argument('--target', choices=['auto', 'tab', 'tab-bg',
|
|
'tab-silent', 'tab-bg-silent',
|
|
'window'],
|
|
help="How URLs should be opened if there is already a "
|
|
"qutebrowser instance running.")
|
|
parser.add_argument('--backend', choices=['webkit', 'webengine'],
|
|
help="Which backend to use.")
|
|
parser.add_argument('--enable-webengine-inspector', action='store_true',
|
|
help="Enable the web inspector for QtWebEngine. Note "
|
|
"that this is a SECURITY RISK and you should not "
|
|
"visit untrusted websites with the inspector turned "
|
|
"on. See https://bugreports.qt.io/browse/QTBUG-50725 "
|
|
"for more details.")
|
|
|
|
parser.add_argument('--json-args', help=argparse.SUPPRESS)
|
|
parser.add_argument('--temp-basedir-restarted', help=argparse.SUPPRESS)
|
|
|
|
debug = parser.add_argument_group('debug arguments')
|
|
debug.add_argument('-l', '--loglevel', dest='loglevel',
|
|
help="Set loglevel", default='info',
|
|
choices=['critical', 'error', 'warning', 'info',
|
|
'debug', 'vdebug'])
|
|
debug.add_argument('--logfilter', type=logfilter_error,
|
|
help="Comma-separated list of things to be logged "
|
|
"to the debug log on stdout.")
|
|
debug.add_argument('--loglines',
|
|
help="How many lines of the debug log to keep in RAM "
|
|
"(-1: unlimited).",
|
|
default=2000, type=int)
|
|
debug.add_argument('--debug', help="Turn on debugging options.",
|
|
action='store_true')
|
|
debug.add_argument('--json-logging', action='store_true', help="Output log"
|
|
" lines in JSON format (one object per line).")
|
|
debug.add_argument('--nocolor', help="Turn off colored logging.",
|
|
action='store_false', dest='color')
|
|
debug.add_argument('--force-color', help="Force colored logging",
|
|
action='store_true')
|
|
debug.add_argument('--nowindow', action='store_true', help="Don't show "
|
|
"the main window.")
|
|
debug.add_argument('--temp-basedir', action='store_true', help="Use a "
|
|
"temporary basedir.")
|
|
debug.add_argument('--no-err-windows', action='store_true', help="Don't "
|
|
"show any error windows (used for tests/smoke.py).")
|
|
debug.add_argument('--qt-arg', help="Pass an argument with a value to Qt. "
|
|
"For example, you can do "
|
|
"`--qt-arg geometry 650x555+200+300` to set the window "
|
|
"geometry.", nargs=2, metavar=('NAME', 'VALUE'),
|
|
action='append')
|
|
debug.add_argument('--qt-flag', help="Pass an argument to Qt as flag.",
|
|
nargs=1, action='append')
|
|
debug.add_argument('--debug-flag', type=debug_flag_error, default=[],
|
|
help="Pass name of debugging feature to be turned on.",
|
|
action='append', dest='debug_flags')
|
|
parser.add_argument('command', nargs='*', help="Commands to execute on "
|
|
"startup.", metavar=':command')
|
|
# URLs will actually be in command
|
|
parser.add_argument('url', nargs='*', help="URLs to open on startup "
|
|
"(empty as a window separator).")
|
|
return parser
|
|
|
|
|
|
def directory(arg):
|
|
if not arg:
|
|
raise argparse.ArgumentTypeError("Invalid empty value")
|
|
|
|
|
|
def logfilter_error(logfilter):
|
|
"""Validate logger names passed to --logfilter.
|
|
|
|
Args:
|
|
logfilter: A comma separated list of logger names.
|
|
"""
|
|
if set(logfilter.split(',')).issubset(log.LOGGER_NAMES):
|
|
return logfilter
|
|
else:
|
|
raise argparse.ArgumentTypeError(
|
|
"filters: Invalid value {} - expected a list of: {}".format(
|
|
logfilter, ', '.join(log.LOGGER_NAMES)))
|
|
|
|
|
|
def debug_flag_error(flag):
|
|
"""Validate flags passed to --debug-flag.
|
|
|
|
Available flags:
|
|
debug-exit: Turn on debugging of late exit.
|
|
pdb-postmortem: Drop into pdb on exceptions.
|
|
"""
|
|
valid_flags = ['debug-exit', 'pdb-postmortem', 'no-sql-history',
|
|
'no-scroll-filtering']
|
|
|
|
if flag in valid_flags:
|
|
return flag
|
|
else:
|
|
raise argparse.ArgumentTypeError("Invalid debug flag - valid flags: {}"
|
|
.format(', '.join(valid_flags)))
|
|
|
|
|
|
def main():
|
|
parser = get_argparser()
|
|
argv = sys.argv[1:]
|
|
args = parser.parse_args(argv)
|
|
if args.json_args is not None:
|
|
# Restoring after a restart.
|
|
# When restarting, we serialize the argparse namespace into json, and
|
|
# construct a "fake" argparse.Namespace here based on the data loaded
|
|
# from json.
|
|
data = json.loads(args.json_args)
|
|
args = argparse.Namespace(**data)
|
|
earlyinit.early_init(args)
|
|
# We do this imports late as earlyinit needs to be run first (because of
|
|
# version checking and other early initialization)
|
|
from qutebrowser import app
|
|
return app.run(args)
|