Add upgrade system for settings and automatically add missing settings to file
This commit is contained in:
parent
642484bbb2
commit
865e5a6bce
191
settings.py
191
settings.py
@ -1,39 +1,139 @@
|
||||
import ast
|
||||
import re
|
||||
import os
|
||||
import collections
|
||||
|
||||
default_settings = '''route_tor = False
|
||||
port_number = 8080
|
||||
allow_foreign_addresses = False
|
||||
settings_info = collections.OrderedDict([
|
||||
('route_tor', {
|
||||
'type': bool,
|
||||
'default': False,
|
||||
'comment': '',
|
||||
}),
|
||||
|
||||
# 0 - off by default
|
||||
# 1 - only manually created subtitles on by default
|
||||
# 2 - enable even if automatically generated is all that's available
|
||||
subtitles_mode = 0
|
||||
('port_number', {
|
||||
'type': int,
|
||||
'default': 8080,
|
||||
'comment': '',
|
||||
}),
|
||||
|
||||
# ISO 639 language code: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
|
||||
subtitles_language = "en"
|
||||
('allow_foreign_addresses', {
|
||||
'type': bool,
|
||||
'default': False,
|
||||
'comment': '''This will allow others to connect to your Youtube Local instance as a website.
|
||||
For security reasons, enabling this is not recommended.''',
|
||||
}),
|
||||
|
||||
enable_related_videos = True
|
||||
enable_comments = True
|
||||
enable_comment_avatars = True
|
||||
('subtitles_mode', {
|
||||
'type': int,
|
||||
'default': 0,
|
||||
'comment': '''0 - off by default
|
||||
1 - only manually created subtitles on by default
|
||||
2 - enable even if automatically generated is all that's available''',
|
||||
}),
|
||||
|
||||
# 0 to sort by top
|
||||
# 1 to sort by newest
|
||||
default_comment_sorting = 0
|
||||
('subtitles_language', {
|
||||
'type': str,
|
||||
'default': 'en',
|
||||
'comment': '''ISO 639 language code: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes''',
|
||||
}),
|
||||
|
||||
# developer use to debug 403s
|
||||
gather_googlevideo_domains = False
|
||||
('related_videos_mode', {
|
||||
'type': int,
|
||||
'default': 1,
|
||||
'comment': '''0 - Related videos disabled
|
||||
1 - Related videos always shown
|
||||
2 - Related videos hidden; shown by clicking a button'''
|
||||
}),
|
||||
|
||||
# save all responses from youtube for debugging
|
||||
debugging_save_responses = False
|
||||
'''
|
||||
exec(default_settings)
|
||||
allowed_targets = set(("route_tor", "port_number", "allow_foreign_addresses", "subtitles_mode", "subtitles_language", "enable_related_videos", "enable_comments", "enable_comment_avatars", "default_comment_sorting", "gather_googlevideo_domains", "debugging_save_responses"))
|
||||
('comments_mode', {
|
||||
'type': int,
|
||||
'default': 1,
|
||||
'comment': '''0 - Video comments disabled
|
||||
1 - Video comments always shown
|
||||
2 - Video comments hidden; shown by clicking a button''',
|
||||
}),
|
||||
|
||||
('enable_comment_avatars', {
|
||||
'type': bool,
|
||||
'default': True,
|
||||
'comment': '',
|
||||
}),
|
||||
|
||||
('default_comment_sorting', {
|
||||
'type': int,
|
||||
'default': 0,
|
||||
'comment': '''0 to sort by top
|
||||
1 to sort by newest''',
|
||||
}),
|
||||
|
||||
('gather_googlevideo_domains', {
|
||||
'type': bool,
|
||||
'default': False,
|
||||
'comment': '''Developer use to debug 403s''',
|
||||
}),
|
||||
|
||||
('debugging_save_responses', {
|
||||
'type': bool,
|
||||
'default': False,
|
||||
'comment': '''Save all responses from youtube for debugging''',
|
||||
}),
|
||||
|
||||
('settings_version', {
|
||||
'type': int,
|
||||
'default': 2,
|
||||
'comment': '''Do not change, remove, or comment out this value, or else your settings may be lost or corrupted'''
|
||||
}),
|
||||
])
|
||||
|
||||
acceptable_targets = settings_info.keys() | {'enable_comments', 'enable_related_videos'}
|
||||
|
||||
|
||||
def comment_string(comment):
|
||||
result = ''
|
||||
for line in comment.splitlines():
|
||||
result += '# ' + line + '\n'
|
||||
return result
|
||||
|
||||
|
||||
def create_missing_settings_string(current_settings):
|
||||
result = ''
|
||||
for setting_name, setting_dict in settings_info.items():
|
||||
if setting_name not in current_settings:
|
||||
result += comment_string(setting_dict['comment']) + setting_name + ' = ' + repr(setting_dict['default']) + '\n\n'
|
||||
return result
|
||||
|
||||
def create_default_settings_string():
|
||||
return settings_to_string({})
|
||||
|
||||
def default_settings():
|
||||
return {key: setting_info['default'] for key, setting_info in settings_info.items()}
|
||||
|
||||
def settings_to_string(settings):
|
||||
'''Given a dictionary with the setting names/setting values for the keys/values, outputs a settings file string.
|
||||
Fills in missing values from the defaults.'''
|
||||
result = ''
|
||||
for setting_name, default_setting_dict in settings_info.items():
|
||||
if setting_name in settings:
|
||||
value = settings[setting_name]
|
||||
else:
|
||||
value = default_setting_dict['default']
|
||||
result += comment_string(default_setting_dict['comment']) + setting_name + ' = ' + repr(value) + '\n\n'
|
||||
return result
|
||||
|
||||
|
||||
def upgrade_to_2(current_settings):
|
||||
'''Upgrade to settings version 2'''
|
||||
new_settings = current_settings.copy()
|
||||
if 'enable_comments' in current_settings:
|
||||
new_settings['comments_mode'] = int(current_settings['enable_comments'])
|
||||
del new_settings['enable_comments']
|
||||
if 'enable_related_videos' in current_settings:
|
||||
new_settings['related_videos_mode'] = int(current_settings['enable_related_videos'])
|
||||
del new_settings['enable_related_videos']
|
||||
return new_settings
|
||||
|
||||
def log_ignored_line(line_number, message):
|
||||
print("settings.txt: Ignoring line " + str(node.lineno) + " (" + message + ")")
|
||||
|
||||
print("WARNING: Ignoring settings.txt line " + str(node.lineno) + " (" + message + ")")
|
||||
|
||||
if os.path.isfile("settings.txt"):
|
||||
print("Running in portable mode")
|
||||
@ -46,18 +146,23 @@ else:
|
||||
if not os.path.exists(settings_dir):
|
||||
os.makedirs(settings_dir)
|
||||
|
||||
settings_file_path = os.path.join(settings_dir, 'settings.txt')
|
||||
|
||||
locals().update(default_settings())
|
||||
|
||||
try:
|
||||
with open(os.path.join(settings_dir, 'settings.txt'), 'r', encoding='utf-8') as file:
|
||||
with open(settings_file_path, 'r', encoding='utf-8') as file:
|
||||
settings_text = file.read()
|
||||
except FileNotFoundError:
|
||||
with open(os.path.join(settings_dir, 'settings.txt'), 'a', encoding='utf-8') as file:
|
||||
file.write(default_settings)
|
||||
with open(settings_file_path, 'w', encoding='utf-8') as file:
|
||||
file.write(create_default_settings_string())
|
||||
else:
|
||||
if re.fullmatch(r'\s*', settings_text): # blank file
|
||||
with open(os.path.join(settings_dir, 'settings.txt'), 'a', encoding='utf-8') as file:
|
||||
file.write(default_settings)
|
||||
with open(settings_file_path, 'w', encoding='utf-8') as file:
|
||||
file.write(create_default_settings_string())
|
||||
else:
|
||||
# parse settings in a safe way, without exec
|
||||
current_settings = {}
|
||||
attributes = {
|
||||
ast.NameConstant: 'value',
|
||||
ast.Num: 'n',
|
||||
@ -78,15 +183,37 @@ else:
|
||||
log_ignored_line(node.lineno, "only simple single-variable assignments allowed")
|
||||
continue
|
||||
|
||||
if target.id not in allowed_targets:
|
||||
log_ignored_line(node.lineno, "target is not a valid setting")
|
||||
if target.id not in acceptable_targets:
|
||||
log_ignored_line(node.lineno, target.id + " is not a valid setting")
|
||||
continue
|
||||
|
||||
if type(node.value) not in (ast.NameConstant, ast.Num, ast.Str):
|
||||
log_ignored_line(node.lineno, "only literals allowed for values")
|
||||
continue
|
||||
|
||||
locals()[target.id] = node.value.__getattribute__(attributes[type(node.value)])
|
||||
current_settings[target.id] = node.value.__getattribute__(attributes[type(node.value)])
|
||||
|
||||
|
||||
if 'settings_version' not in current_settings:
|
||||
print('Upgrading settings.txt')
|
||||
new_settings = upgrade_to_2(current_settings)
|
||||
locals().update(new_settings)
|
||||
new_settings_string = settings_to_string(new_settings)
|
||||
with open(settings_file_path, 'w', encoding='utf-8') as file:
|
||||
file.write(new_settings_string)
|
||||
|
||||
# some settings not in the file, add those missing settings to the file
|
||||
elif len(settings_info.keys() - current_settings.keys()) != 0:
|
||||
print('Adding missing settings to settings.txt')
|
||||
append_text = create_missing_settings_string(current_settings)
|
||||
with open(settings_file_path, 'a', encoding='utf-8') as file:
|
||||
file.write('\n\n' + append_text)
|
||||
locals().update(current_settings)
|
||||
else:
|
||||
locals().update(current_settings)
|
||||
|
||||
|
||||
|
||||
|
||||
if route_tor:
|
||||
print("Tor routing is ON")
|
||||
|
Loading…
x
Reference in New Issue
Block a user