@@ -0,0 +1,98 @@
1+#!/usr/bin/env python
2+
3+# set path
4+from sys import path
5+from os.path import realpath, dirname, join
6+path.append(realpath(dirname(realpath(__file__)) + '/../'))
7+
8+import argparse
9+import sys
10+import string
11+import ruamel.yaml
12+import secrets
13+import collections
14+from ruamel.yaml.scalarstring import SingleQuotedScalarString, DoubleQuotedScalarString
15+from searx.settings import load_settings, check_settings_yml, get_default_settings_path
16+from searx.exceptions import SearxSettingsException
17+
18+
19+RANDOM_STRING_LETTERS = string.ascii_lowercase + string.digits + string.ascii_uppercase
20+
21+
22+def get_random_string():
23+ r = [secrets.choice(RANDOM_STRING_LETTERS) for _ in range(64)]
24+ return ''.join(r)
25+
26+
27+def main(prog_arg):
28+ yaml = ruamel.yaml.YAML()
29+ yaml.preserve_quotes = True
30+ yaml.indent(mapping=4, sequence=1, offset=2)
31+ user_settings_path = prog_args.get('user-settings-yaml')
32+
33+ try:
34+ default_settings, _ = load_settings(False)
35+ if check_settings_yml(user_settings_path):
36+ with open(user_settings_path, 'r', encoding='utf-8') as f:
37+ user_settings = yaml.load(f.read())
38+ new_user_settings = False
39+ else:
40+ user_settings = yaml.load('use_default_settings: True')
41+ new_user_settings = True
42+ except SearxSettingsException as e:
43+ sys.stderr.write(str(e))
44+ return
45+
46+ if not new_user_settings and not user_settings.get('use_default_settings'):
47+ sys.stderr.write('settings.yml already exists and use_default_settings is not True')
48+ return
49+
50+ user_settings['use_default_settings'] = True
51+ use_default_settings_comment = "settings based on " + get_default_settings_path()
52+ user_settings.yaml_add_eol_comment(use_default_settings_comment, 'use_default_settings')
53+
54+ if user_settings.get('server', {}).get('secret_key') in [None, 'ultrasecretkey']:
55+ user_settings.setdefault('server', {})['secret_key'] = DoubleQuotedScalarString(get_random_string())
56+
57+ user_engines = user_settings.get('engines')
58+ if user_engines:
59+ has_user_engines = True
60+ user_engines_dict = dict((definition['name'], definition) for definition in user_engines)
61+ else:
62+ has_user_engines = False
63+ user_engines_dict = {}
64+ user_engines = []
65+
66+ # remove old engines
67+ if prog_arg.get('add-engines') or has_user_engines:
68+ default_engines_dict = dict((definition['name'], definition) for definition in default_settings['engines'])
69+ for i, engine in enumerate(user_engines):
70+ if engine['name'] not in default_engines_dict:
71+ del user_engines[i]
72+
73+ # add new engines
74+ if prog_arg.get('add-engines'):
75+ for engine in default_settings.get('engines', {}):
76+ if engine['name'] not in user_engines_dict:
77+ user_engines.append({'name': engine['name']})
78+ user_settings['engines'] = user_engines
79+
80+ # output
81+ if prog_arg.get('dry-run'):
82+ yaml.dump(user_settings, sys.stdout)
83+ else:
84+ with open(user_settings_path, 'w', encoding='utf-8') as f:
85+ yaml.dump(user_settings, f)
86+
87+
88+def parse_args():
89+ parser = argparse.ArgumentParser(description='Update user settings.yml')
90+ parser.add_argument('--add-engines', dest='add-engines', default=False, action='store_true', help='Add new engines')
91+ parser.add_argument('--dry-run', dest='dry-run', default=False, action='store_true', help='Dry run')
92+ parser.add_argument('user-settings-yaml', type=str)
93+ return vars(parser.parse_args())
94+
95+
96+if __name__ == '__main__':
97+ prog_args = parse_args()
98+ main(prog_args)