Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

# 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)