aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Taylor <user234683@users.noreply.github.com>2019-08-01 00:24:30 -0700
committerJames Taylor <user234683@users.noreply.github.com>2019-08-01 00:24:30 -0700
commit865e5a6bce786824add16a852043f3a36cdbb630 (patch)
tree020849562c9c14fd7fe40160529f03fcc3247911
parent642484bbb228cbbf0030dc93646dc92ae25d5fb4 (diff)
downloadyt-local-865e5a6bce786824add16a852043f3a36cdbb630.tar.lz
yt-local-865e5a6bce786824add16a852043f3a36cdbb630.tar.xz
yt-local-865e5a6bce786824add16a852043f3a36cdbb630.zip
Add upgrade system for settings and automatically add missing settings to file
-rw-r--r--settings.py191
1 files changed, 159 insertions, 32 deletions
diff --git a/settings.py b/settings.py
index 5b9520d..4aedd19 100644
--- a/settings.py
+++ b/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''',
+ }),
-def log_ignored_line(line_number, message):
- print("settings.txt: Ignoring line " + str(node.lineno) + " (" + message + ")")
+ ('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("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")