diff options
| author | Nippy <nippy@rp1.hu> | 2026-05-09 13:33:09 +0200 |
|---|---|---|
| committer | Nippy <nippy@rp1.hu> | 2026-05-09 13:33:09 +0200 |
| commit | a2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5 (patch) | |
| tree | 1a8769217f84bfe9d6216fafaadaf8cdd876d457 /raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/translations/extract_settings_index.py | |
| parent | 34b9c34f982b2596cfa9e368a2d7f74e9a17477c (diff) | |
| download | RaveOS-PKGBUILD-a2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5.tar.gz RaveOS-PKGBUILD-a2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5.zip | |
raveos update
Diffstat (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/translations/extract_settings_index.py')
| -rwxr-xr-x | raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/translations/extract_settings_index.py | 522 |
1 files changed, 0 insertions, 522 deletions
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/translations/extract_settings_index.py b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/translations/extract_settings_index.py deleted file mode 100755 index 8a7b935..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/translations/extract_settings_index.py +++ /dev/null @@ -1,522 +0,0 @@ -#!/usr/bin/env python3 -import json -import re -from collections import Counter -from pathlib import Path - -ABBREVIATIONS = { - "on-screen displays": ["osd"], - "on-screen display": ["osd"], - "do not disturb": ["dnd"], - "keyboard shortcuts": ["keybinds", "hotkeys", "bindings", "keys"], - "notifications": ["notif", "notifs", "alerts"], - "notification": ["notif", "alert"], - "wallpaper": ["background", "bg", "image", "picture", "desktop"], - "transparency": ["opacity", "alpha", "translucent", "transparent"], - "visibility": ["visible", "hide", "show", "hidden", "autohide", "auto-hide"], - "temperature": ["temp", "celsius", "fahrenheit"], - "configuration": ["config", "configure", "setup"], - "applications": ["apps", "programs"], - "application": ["app", "program"], - "animation": ["motion", "transition", "animate", "animations"], - "typography": ["font", "fonts", "text", "typeface"], - "workspaces": ["workspace", "desktops", "virtual"], - "workspace": ["desktop", "virtual"], - "bluetooth": ["bt"], - "network": ["wifi", "wi-fi", "ethernet", "internet", "connection", "wireless"], - "display": ["monitor", "screen", "output"], - "displays": ["monitors", "screens", "outputs"], - "brightness": ["bright", "dim", "backlight"], - "volume": ["audio", "sound", "speaker", "loudness"], - "battery": ["power", "charge", "charging"], - "clock": ["time", "watch"], - "calendar": ["date", "day", "month", "year"], - "launcher": ["app drawer", "app menu", "start menu", "applications"], - "dock": ["taskbar", "panel"], - "bar": ["panel", "taskbar", "topbar", "statusbar"], - "theme": ["appearance", "look", "style", "colors", "colour"], - "color": ["colour", "hue", "tint"], - "colors": ["colours", "palette"], - "dark": ["night", "dark mode"], - "light": ["day", "light mode"], - "lock screen": ["lockscreen", "login", "security"], - "power": ["shutdown", "reboot", "restart", "suspend", "hibernate", "sleep"], - "idle": ["afk", "inactive", "timeout", "screensaver"], - "gamma": ["color temperature", "night light", "blue light", "redshift"], - "media player": ["mpris", "music", "audio", "playback"], - "clipboard": ["copy", "paste", "cliphist", "history"], - "updater": ["updates", "upgrade", "packages"], - "plugins": ["extensions", "addons", "widgets"], - "spacing": ["gap", "gaps", "margin", "margins", "padding"], - "corner": ["corners", "rounded", "radius", "round"], - "matugen": ["dynamic", "wallpaper colors", "material"], - "running apps": ["taskbar", "windows", "active", "open"], - "weather": ["forecast", "temperature", "climate"], - "sounds": ["audio", "effects", "sfx"], - "printers": ["print", "cups", "printing"], - "widgets": ["components", "modules"], -} - -CATEGORY_KEYWORDS = { - "Personalization": ["customize", "custom", "personal", "appearance"], - "Time & Weather": ["clock", "forecast", "date"], - "Keyboard Shortcuts": ["keys", "bindings", "hotkey"], - "Dank Bar": ["panel", "topbar", "statusbar"], - "Workspaces": ["virtual desktops", "spaces"], - "Dock": ["taskbar", "launcher bar"], - "Network": ["connectivity", "online"], - "System": ["os", "linux"], - "Launcher": ["start", "menu", "drawer"], - "Theme & Colors": ["appearance", "look", "style", "scheme"], - "Lock Screen": ["security", "login", "password"], - "Plugins": ["extend", "addon"], - "About": ["info", "version", "credits", "help"], - "Typography & Motion": ["fonts", "animation", "text"], - "Sounds": ["audio", "sfx", "effects"], - "Media Player": ["music", "spotify", "mpris"], - "Notifications": ["alerts", "messages", "toast"], - "On-screen Displays": ["osd", "indicator", "popup"], - "Running Apps": ["windows", "tasks", "active"], - "System Updater": ["packages", "upgrade"], - "Power & Sleep": ["shutdown", "suspend", "energy"], - "Displays": ["monitor", "screen", "resolution"], - "Desktop Widgets": ["conky", "desktop clock"], - "Audio": ["sound", "volume", "speaker", "microphone", "headphones", "pipewire"], - "Window Rules": [ - "window", - "rules", - "matching", - "floating", - "fullscreen", - "opacity", - ], - "Locale": ["locale", "language", "country"], -} - -TAB_INDEX_MAP = { - "WallpaperTab.qml": 0, - "TimeWeatherTab.qml": 1, - "KeybindsTab.qml": 2, - "DankBarTab.qml": 3, - "WorkspacesTab.qml": 4, - "DockTab.qml": 5, - "NetworkTab.qml": 7, - "PrinterTab.qml": 8, - "LauncherTab.qml": 9, - "ThemeColorsTab.qml": 10, - "LockScreenTab.qml": 11, - "PluginsTab.qml": 12, - "AboutTab.qml": 13, - "TypographyMotionTab.qml": 14, - "SoundsTab.qml": 15, - "MediaPlayerTab.qml": 16, - "NotificationsTab.qml": 17, - "OSDTab.qml": 18, - "RunningAppsTab.qml": 19, - "SystemUpdaterTab.qml": 20, - "PowerSleepTab.qml": 21, - "WidgetsTab.qml": 22, - "ClipboardTab.qml": 23, - "DisplayConfigTab.qml": 24, - "GammaControlTab.qml": 25, - "DisplayWidgetsTab.qml": 26, - "DesktopWidgetsTab.qml": 27, - "WindowRulesTab.qml": 28, - "AudioTab.qml": 29, - "LocaleTab.qml": 30, -} - -TAB_CATEGORY_MAP = { - 0: "Personalization", - 1: "Time & Weather", - 2: "Keyboard Shortcuts", - 3: "Dank Bar", - 4: "Workspaces", - 5: "Dock", - 7: "Network", - 8: "System", - 9: "Launcher", - 10: "Theme & Colors", - 11: "Lock Screen", - 12: "Plugins", - 13: "About", - 14: "Typography & Motion", - 15: "Sounds", - 16: "Media Player", - 17: "Notifications", - 18: "On-screen Displays", - 19: "Running Apps", - 20: "System Updater", - 21: "Power & Sleep", - 22: "Dank Bar", - 23: "System", - 24: "Displays", - 25: "Displays", - 26: "Displays", - 27: "Desktop Widgets", - 28: "Window Rules", - 29: "Audio", - 30: "Locale", -} - -SEARCHABLE_COMPONENTS = [ - "SettingsCard", - "SettingsToggleRow", - "SettingsSliderCard", - "SettingsDropdownRow", - "SettingsButtonGroupRow", - "SettingsSliderRow", - "SettingsToggleCard", -] - -STOPWORDS = { - "the", - "and", - "for", - "with", - "from", - "this", - "that", - "are", - "was", - "will", - "can", - "has", - "have", - "been", - "when", - "your", - "use", - "used", - "using", - "instead", - "like", - "such", - "also", - "only", - "which", - "each", - "other", - "some", - "into", - "than", - "then", - "them", - "these", - "those", -} - - -def enrich_keywords(label, description, category, existing_tags): - keywords = set(existing_tags) - - label_lower = label.lower() - label_words = re.split(r"[\s\-_&/]+", label_lower) - keywords.update(w for w in label_words if len(w) > 2) - - for term, aliases in ABBREVIATIONS.items(): - if term in label_lower: - keywords.update(aliases) - - if description: - desc_lower = description.lower() - desc_words = re.split(r"[\s\-_&/,.]+", desc_lower) - keywords.update(w for w in desc_words if len(w) > 3 and w.isalpha()) - for term, aliases in ABBREVIATIONS.items(): - if term in desc_lower: - keywords.update(aliases) - - if category in CATEGORY_KEYWORDS: - keywords.update(CATEGORY_KEYWORDS[category]) - - cat_lower = category.lower() - cat_words = re.split(r"[\s\-_&/]+", cat_lower) - keywords.update(w for w in cat_words if len(w) > 2) - - keywords = {k for k in keywords if k not in STOPWORDS and len(k) > 1} - return sorted(keywords) - - -def extract_i18n_string(value): - match = re.search(r'I18n\.tr\(["\']([^"\']+)["\']', value) - if match: - return match.group(1) - match = re.search(r'^["\']([^"\']+)["\']$', value.strip()) - if match: - return match.group(1) - return None - - -def extract_tags(value): - match = re.search(r"\[([^\]]+)\]", value) - if not match: - return [] - content = match.group(1) - tags = re.findall(r'["\']([^"\']+)["\']', content) - return tags - - -def parse_component_block(content, start_pos, component_name): - brace_count = 0 - started = False - block_start = start_pos - - for i in range(start_pos, len(content)): - if content[i] == "{": - if not started: - block_start = i - started = True - brace_count += 1 - elif content[i] == "}": - brace_count -= 1 - if started and brace_count == 0: - return content[block_start : i + 1] - return "" - - -def extract_property(block, prop_name): - pattern = rf"{prop_name}\s*:\s*([^\n]+)" - match = re.search(pattern, block) - if match: - return match.group(1).strip() - return None - - -def find_settings_components(content, filename): - results = [] - tab_index = TAB_INDEX_MAP.get(filename, -1) - - if tab_index == -1: - return results - - for component in SEARCHABLE_COMPONENTS: - pattern = rf"\b{component}\s*\{{" - for match in re.finditer(pattern, content): - block = parse_component_block(content, match.start(), component) - if not block: - continue - - setting_key = extract_property(block, "settingKey") - if setting_key: - setting_key = setting_key.strip("\"'") - - if not setting_key: - continue - - title_raw = extract_property(block, "title") - text_raw = extract_property(block, "text") - label = None - if title_raw: - label = extract_i18n_string(title_raw) - if not label and text_raw: - label = extract_i18n_string(text_raw) - - if not label: - continue - - icon_raw = extract_property(block, "iconName") - icon = None - if icon_raw: - icon = icon_raw.strip("\"'") - if icon.startswith("{") or "?" in icon: - icon = None - - tags_raw = extract_property(block, "tags") - tags = [] - if tags_raw: - tags = extract_tags(tags_raw) - - desc_raw = extract_property(block, "description") - description = None - if desc_raw: - description = extract_i18n_string(desc_raw) - - visible_raw = extract_property(block, "visible") - condition_key = None - if visible_raw: - if "CompositorService.isNiri" in visible_raw: - condition_key = "isNiri" - elif "CompositorService.isHyprland" in visible_raw: - condition_key = "isHyprland" - elif "KeybindsService.available" in visible_raw: - condition_key = "keybindsAvailable" - elif "AudioService.soundsAvailable" in visible_raw: - condition_key = "soundsAvailable" - elif "CupsService.cupsAvailable" in visible_raw: - condition_key = "cupsAvailable" - elif "NetworkService.usingLegacy" in visible_raw: - condition_key = "networkNotLegacy" - elif "DMSService.isConnected" in visible_raw: - condition_key = "dmsConnected" - elif "Theme.matugenAvailable" in visible_raw: - condition_key = "matugenAvailable" - elif "CompositorService.isDwl" in visible_raw: - condition_key = "isDwl" - - category = TAB_CATEGORY_MAP.get(tab_index, "Settings") - enriched_keywords = enrich_keywords(label, description, category, tags) - - entry = { - "section": setting_key, - "label": label, - "tabIndex": tab_index, - "category": category, - "keywords": enriched_keywords, - } - - if icon: - entry["icon"] = icon - if description: - entry["description"] = description - if condition_key: - entry["conditionKey"] = condition_key - - results.append(entry) - - return results - - -def parse_tabs_from_sidebar(sidebar_file): - with open(sidebar_file, "r", encoding="utf-8") as f: - content = f.read() - - pattern = r'"text"\s*:\s*I18n\.tr\("([^"]+)"(?:,\s*"[^"]+")?\).*?"icon"\s*:\s*"([^"]+)".*?"tabIndex"\s*:\s*(\d+)' - tabs = [] - - for match in re.finditer(pattern, content, re.DOTALL): - label, icon, tab_idx = match.group(1), match.group(2), int(match.group(3)) - - before_text = content[: match.start()] - parent_match = re.search( - r'"text"\s*:\s*I18n\.tr\("([^"]+)"\)[^{]*"children"[^[]*\[[^{]*$', - before_text, - ) - parent = parent_match.group(1) if parent_match else None - - cond = None - after_pos = match.end() - snippet = content[match.start() : min(after_pos + 200, len(content))] - for qml_cond, key in [ - ("shortcutsOnly", "keybindsAvailable"), - ("soundsOnly", "soundsAvailable"), - ("cupsOnly", "cupsAvailable"), - ("dmsOnly", "dmsConnected"), - ("hyprlandNiriOnly", "isHyprlandOrNiri"), - ("clipboardOnly", "dmsConnected"), - ("niriOnly", "isNiri"), - ]: - if f'"{qml_cond}": true' in snippet: - cond = key - break - - tabs.append( - { - "tabIndex": tab_idx, - "label": label, - "icon": icon, - "parent": parent, - "conditionKey": cond, - } - ) - - return tabs - - -def generate_tab_entries(sidebar_file): - tabs = parse_tabs_from_sidebar(sidebar_file) - - label_counts = Counter([t["label"] for t in tabs]) - - entries = [] - for tab in tabs: - label = ( - f"{tab['parent']}: {tab['label']}" - if label_counts[tab["label"]] > 1 and tab["parent"] - else tab["label"] - ) - category = TAB_CATEGORY_MAP.get(tab["tabIndex"], "Settings") - - keywords = enrich_keywords(tab["label"], None, category, []) - - if tab["parent"]: - parent_keywords = [ - w for w in re.split(r"[\s\-_&/]+", tab["parent"].lower()) if len(w) > 2 - ] - keywords = sorted( - set( - keywords - + parent_keywords - + [k for p in parent_keywords for k in ABBREVIATIONS.get(p, [])] - ) - ) - - entry = { - "section": f"_tab_{tab['tabIndex']}", - "label": label, - "tabIndex": tab["tabIndex"], - "category": category, - "keywords": keywords, - "icon": tab["icon"], - } - if tab["conditionKey"]: - entry["conditionKey"] = tab["conditionKey"] - entries.append(entry) - - return entries - - -def extract_settings_index(root_dir): - settings_dir = Path(root_dir) / "Modules" / "Settings" - all_entries = [] - seen_keys = set() - - for qml_file in settings_dir.glob("*.qml"): - if not qml_file.name.endswith("Tab.qml"): - continue - - with open(qml_file, "r", encoding="utf-8") as f: - content = f.read() - - entries = find_settings_components(content, qml_file.name) - for entry in entries: - key = entry["section"] - if key not in seen_keys: - seen_keys.add(key) - all_entries.append(entry) - - return all_entries - - -def main(): - script_dir = Path(__file__).parent - root_dir = script_dir.parent - sidebar_file = root_dir / "Modals" / "Settings" / "SettingsSidebar.qml" - - print("Extracting settings search index...") - settings_entries = extract_settings_index(root_dir) - tab_entries = generate_tab_entries(sidebar_file) - - all_entries = tab_entries + settings_entries - - all_entries.sort(key=lambda x: (x["tabIndex"], x["label"])) - - output_path = script_dir / "settings_search_index.json" - with open(output_path, "w", encoding="utf-8") as f: - json.dump(all_entries, f, indent=2, ensure_ascii=False) - - print(f"Found {len(settings_entries)} searchable settings") - print(f"Found {len(tab_entries)} tab entries") - print(f"Total: {len(all_entries)} entries") - print(f"Output: {output_path}") - - conditions = set() - for entry in all_entries: - if "conditionKey" in entry: - conditions.add(entry["conditionKey"]) - - if conditions: - print(f"Condition keys found: {', '.join(sorted(conditions))}") - - -if __name__ == "__main__": - main() |