mirror of
https://github.com/zen-browser/theme-store.git
synced 2025-07-07 08:55:31 +02:00
refactor(scripts): added compatibility layer with old prefs style, convert prefs to new style on theme rebuild (#424)
* refactor(scripts): replaced hyphens with underscores in script names * test(rebuild_themes): debug logs * Rebuild themes.json after theme submission * refactor(rebuild_themes): added preferences loading * fix(submit-pr): fixed dependencies * debug(rebuild_themes): add pre print * feature(rebuild_themes): save preferences to file * feature(rebuild_themes): add ident * Rebuild themes.json after theme submission --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
640f563c73
commit
80842c45a7
22 changed files with 647 additions and 178 deletions
|
@ -1,69 +0,0 @@
|
|||
|
||||
import os
|
||||
import json
|
||||
|
||||
THEMES_FOLDER = './themes'
|
||||
THEMES_DATA_FILE = './themes.json'
|
||||
|
||||
def get_color_css_variable(color):
|
||||
if color == "primaryColor":
|
||||
return '--zen-colors-primary'
|
||||
if color == "secondaryColor":
|
||||
return '--zen-colors-secondary'
|
||||
if color == "tertiaryColor":
|
||||
return '--zen-colors-tertiary'
|
||||
if color == "colorsBorder":
|
||||
return '--zen-colors-border'
|
||||
if color == "dialogBg":
|
||||
return '--zen-dialog-background'
|
||||
if color == "accentColor":
|
||||
return '--zen-primary-color'
|
||||
print(f"Unknown color: {color}")
|
||||
exit(1)
|
||||
|
||||
def write_colors(colors_file, output_file):
|
||||
with open(colors_file, 'r') as f:
|
||||
colors = json.load(f)
|
||||
with open(output_file, 'w') as f:
|
||||
f.write('/* This is an auto generated color theme. */\n')
|
||||
f.write(':root {\n')
|
||||
for color in colors:
|
||||
if color == "isDarkMode":
|
||||
continue
|
||||
f.write(f' {get_color_css_variable(color)}: {colors[color]} !important;\n')
|
||||
f.write('}\n')
|
||||
return colors
|
||||
|
||||
def main():
|
||||
with open(THEMES_DATA_FILE, 'w') as f:
|
||||
json.dump({}, f, indent=4)
|
||||
for theme in os.listdir(THEMES_FOLDER):
|
||||
theme_folder = os.path.join(THEMES_FOLDER, theme)
|
||||
if not os.path.isdir(theme_folder):
|
||||
continue
|
||||
theme_data_file = os.path.join(theme_folder, 'theme.json')
|
||||
if not os.path.exists(theme_data_file):
|
||||
continue
|
||||
with open(theme_data_file, 'r') as f:
|
||||
theme_data = json.load(f)
|
||||
with open(theme_data_file, 'w') as f:
|
||||
json.dump(theme_data, f, indent=4) # format the json file
|
||||
with open(THEMES_DATA_FILE, 'r') as f:
|
||||
themes_data = json.load(f)
|
||||
theme_colors_file = os.path.join(theme_folder, 'colors.json')
|
||||
if os.path.exists(theme_colors_file):
|
||||
print(f" Found colors.json in theme: {theme}")
|
||||
theme_colors_output = os.path.join(theme_folder, 'chrome.css')
|
||||
colors = write_colors(theme_colors_file, theme_colors_output)
|
||||
if 'isDarkMode' in colors:
|
||||
theme_data['isDarkMode'] = colors['isDarkMode']
|
||||
theme_data['isColorTheme'] = True
|
||||
themes_data[theme] = theme_data
|
||||
with open(THEMES_DATA_FILE, 'w') as f:
|
||||
json.dump(themes_data, f)
|
||||
del themes_data
|
||||
print(f"Rebuilt theme: {theme}")
|
||||
print("Rebuilt all themes!")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
109
scripts/rebuild_themes.py
Normal file
109
scripts/rebuild_themes.py
Normal file
|
@ -0,0 +1,109 @@
|
|||
import os
|
||||
import json
|
||||
from submit_theme import convert_legacy_preferences
|
||||
|
||||
THEMES_FOLDER = "./themes"
|
||||
THEMES_DATA_FILE = "./themes.json"
|
||||
|
||||
|
||||
def get_color_css_variable(color):
|
||||
if color == "primaryColor":
|
||||
return "--zen-colors-primary"
|
||||
if color == "secondaryColor":
|
||||
return "--zen-colors-secondary"
|
||||
if color == "tertiaryColor":
|
||||
return "--zen-colors-tertiary"
|
||||
if color == "colorsBorder":
|
||||
return "--zen-colors-border"
|
||||
if color == "dialogBg":
|
||||
return "--zen-dialog-background"
|
||||
if color == "accentColor":
|
||||
return "--zen-primary-color"
|
||||
print(f"Unknown color: {color}")
|
||||
exit(1)
|
||||
|
||||
|
||||
def write_colors(colors_file, output_file):
|
||||
with open(colors_file, "r") as f:
|
||||
colors = json.load(f)
|
||||
|
||||
with open(output_file, "w") as f:
|
||||
f.write("/* This is an auto generated color theme. */\n")
|
||||
f.write(":root {\n")
|
||||
|
||||
for color in colors:
|
||||
if color == "isDarkMode":
|
||||
continue
|
||||
f.write(
|
||||
f" {get_color_css_variable(color)}: {colors[color]} !important;\n"
|
||||
)
|
||||
|
||||
f.write("}\n")
|
||||
return colors
|
||||
|
||||
|
||||
def main():
|
||||
with open(THEMES_DATA_FILE, "w") as f:
|
||||
json.dump({}, f, indent=4)
|
||||
for theme in os.listdir(THEMES_FOLDER):
|
||||
theme_folder = os.path.join(THEMES_FOLDER, theme)
|
||||
|
||||
if not os.path.isdir(theme_folder):
|
||||
continue
|
||||
|
||||
theme_data_file = os.path.join(theme_folder, "theme.json")
|
||||
|
||||
if not os.path.exists(theme_data_file):
|
||||
continue
|
||||
|
||||
with open(theme_data_file, "r") as f:
|
||||
theme_data = json.load(f)
|
||||
|
||||
with open(theme_data_file, "w") as f:
|
||||
json.dump(theme_data, f, indent=4) # format the json file
|
||||
|
||||
with open(THEMES_DATA_FILE, "r") as f:
|
||||
themes_data = json.load(f)
|
||||
theme_colors_file = os.path.join(theme_folder, "colors.json")
|
||||
|
||||
if os.path.exists(theme_colors_file):
|
||||
print(f" Found colors.json in theme: {theme}")
|
||||
|
||||
theme_colors_output = os.path.join(theme_folder, "chrome.css")
|
||||
colors = write_colors(theme_colors_file, theme_colors_output)
|
||||
|
||||
if "isDarkMode" in colors:
|
||||
theme_data["isDarkMode"] = colors["isDarkMode"]
|
||||
|
||||
theme_data["isColorTheme"] = True
|
||||
|
||||
themes_data[theme] = theme_data
|
||||
|
||||
with open(THEMES_DATA_FILE, "w") as f:
|
||||
json.dump(themes_data, f)
|
||||
del themes_data
|
||||
|
||||
preferences_data_file = os.path.join(theme_folder, "preferences.json")
|
||||
|
||||
if os.path.exists(preferences_data_file):
|
||||
print(f"Found preferences.json in theme: {theme}")
|
||||
|
||||
with open(preferences_data_file, "r") as f:
|
||||
preferences_data = json.load(f)
|
||||
|
||||
if isinstance(preferences_data, dict):
|
||||
print(
|
||||
"Legacy preferences found, performing transformation into new structure."
|
||||
)
|
||||
preferences_data = convert_legacy_preferences(preferences_data)
|
||||
|
||||
with open(preferences_data_file, "w") as f:
|
||||
json.dump(preferences_data, f, indent=4)
|
||||
del preferences_data
|
||||
|
||||
print(f"Rebuilt theme: {theme}")
|
||||
print("Rebuilt all themes!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -150,7 +150,9 @@ def validate_preferences(preferences):
|
|||
)
|
||||
)
|
||||
|
||||
if not set(properties.keys()).issuperset(REQUIRED_FIELDS):
|
||||
if not len(set(properties).intersection(REQUIRED_FIELDS)) == len(
|
||||
REQUIRED_FIELDS
|
||||
):
|
||||
panic(f"Required fields ({", ".join(REQUIRED_FIELDS)}) are not in {entry}.")
|
||||
|
||||
current_type = parse_type(properties[PreferenceFields.TYPE])
|
||||
|
@ -206,10 +208,12 @@ def validate_preferences(preferences):
|
|||
panic(
|
||||
f"Field disabledOn in {current_property} is expecting an array"
|
||||
)
|
||||
elif len(value) != 0 and not set(value).issuperset(VALID_OS):
|
||||
panic(
|
||||
f"Field disabledOn in {current_property} is expecting one or more of {", ".join(VALID_OS)} but received {", ".join(value)}"
|
||||
)
|
||||
elif len(value) != 0:
|
||||
for possibleOs in value:
|
||||
if possibleOs not in VALID_OS:
|
||||
panic(
|
||||
f"Field disabledOn in {current_property} is expecting one or more of {", ".join(VALID_OS)} but received {possibleOs}"
|
||||
)
|
||||
|
||||
case PreferenceFields.PLACEHOLDER:
|
||||
if not current_type in PLACEHOLDER_TYPES:
|
||||
|
@ -223,6 +227,33 @@ def validate_preferences(preferences):
|
|||
return preferences
|
||||
|
||||
|
||||
def convert_legacy_preferences(preferences):
|
||||
key_regex = re.compile(r"(!?)(?:(macos|windows|linux):)?([A-z0-9-_.]+)")
|
||||
new_preferences = []
|
||||
for key, label in preferences.items():
|
||||
negated, osValue, property = key_regex.search(key).groups()
|
||||
|
||||
disabledOn = []
|
||||
|
||||
if negated == "!" and osValue:
|
||||
disabledOn = [osValue]
|
||||
elif osValue:
|
||||
disabledOn = [i for i in VALID_OS if i != osValue]
|
||||
|
||||
new_preferences.append(
|
||||
dict(
|
||||
[
|
||||
("property", property),
|
||||
("label", label),
|
||||
("type", "checkbox"),
|
||||
("disabledOn", disabledOn),
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
return new_preferences
|
||||
|
||||
|
||||
def get_preferences():
|
||||
with open(TEMPLATE_PREFERENCES_FILE, "r") as f:
|
||||
try:
|
||||
|
@ -231,7 +262,16 @@ def get_preferences():
|
|||
return {}
|
||||
content = re.sub(r"```json\n*", "", content)
|
||||
content = re.sub(r"\n*```\n*", "", content)
|
||||
return validate_preferences(json.loads(content))
|
||||
|
||||
if content.startswith("{") and content.endswith("}"):
|
||||
print(
|
||||
"Warning: Detected legacy preferences syntax, converting them into new syntax"
|
||||
)
|
||||
content = convert_legacy_preferences(json.loads(content))
|
||||
else:
|
||||
content = json.loads(content)
|
||||
|
||||
return validate_preferences(content)
|
||||
except json.JSONDecodeError as e:
|
||||
panic("Preferences file is invalid.", e)
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue