* feat(udiskie): add Udiskie service for real-time device monitoring, notifications, and IPC * feat(udiskie): add main manager panel for drives and partitions * feat(udiskie): add plugin manifest, status widget, and english translation * feat(udiskie): add Makefile for testing and linting translations * feat(udiskie): add error handling for missing udiskie package * feat(udiskie): add right-click functionality to refresh Udiskie service * feat(udiskie): add option to hide widget when no devices are connected * feat(udiskie): add settings button to the panel for quick access to configuration * feat(udiskie): add button to copy mount path to clipboard in partition row * fix(udiskie): duplicated notifications when removing or unmounting devices * feat(udiskie): add disk usage information for mounted partitions in device state * feat(udiskie): update partition row status colors and enhance UI for status display * fix(udiskie): adjust timeout to give time for sudo tasks such as LUKS unlock * feat(udiskie): update partition row status color for LUKS devices and adjust panel width * fix(udiskie): scroll not working properly and items overflow container * feat(udiskie): add missing translations and remove hardcoded strings messages * feat(udiskie): add README and thumbnail * docs(udiskie): add performance section to README with resource usage comparison * fix(udiskie): update output parsing to use safe tab delimiters for device information * fix(udiskie): improve device hierarchy parsing to correctly identify partitions * feat(udiskie): centralize open with file manager code, and close panel on auto-open on mount (like manually open) * fix(udiskie): exclude LUKS containers from "Drive Connected" notifications * fix(udiskie): quote paths and device names in shell commands * fix(udiskie): improve error message cleaning regex * feat(udiskie): enhance README with device attributes and update service to suppress errors * fix(udiskie): use shell quoting for device paths in panel async commands * feat(udiskie): add spanish translations and update tests to check every translation
82 lines
3.1 KiB
Python
Executable File
82 lines
3.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
def main():
|
|
plugin_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
trans_dir = os.path.join(plugin_dir, "translations")
|
|
en_file = os.path.join(trans_dir, "en.json")
|
|
|
|
if not os.path.exists(en_file):
|
|
print(f"Error: Translation file not found at {en_file}")
|
|
sys.exit(1)
|
|
|
|
def flatten_keys(d, prefix=""):
|
|
keys = []
|
|
for k, v in d.items():
|
|
full_key = f"{prefix}.{k}" if prefix else k
|
|
if isinstance(v, dict):
|
|
keys.extend(flatten_keys(v, full_key))
|
|
else:
|
|
keys.append(full_key)
|
|
return keys
|
|
|
|
with open(en_file, "r", encoding="utf-8") as f:
|
|
en_translations = json.load(f)
|
|
|
|
en_keys = set(flatten_keys(en_translations))
|
|
errors = []
|
|
|
|
# Code and manifest files to scan (checked against en.json, the reference).
|
|
scan_files = ["plugin.toml", "service.luau", "status.luau", "panel.luau"]
|
|
combined_content = ""
|
|
|
|
for fname in scan_files:
|
|
fpath = os.path.join(plugin_dir, fname)
|
|
if os.path.exists(fpath):
|
|
with open(fpath, "r", encoding="utf-8") as f:
|
|
combined_content += f.read() + "\n"
|
|
|
|
# 1. Every en.json key must be used somewhere in the codebase.
|
|
missing_keys = []
|
|
for key in sorted(en_keys):
|
|
# Setting label_key and description_key append .label and .description automatically.
|
|
base_key = key.replace(".label", "").replace(".description", "")
|
|
if key not in combined_content and base_key not in combined_content:
|
|
missing_keys.append(key)
|
|
|
|
if missing_keys:
|
|
errors.append("Unused translation key(s) found in translations/en.json:\n - " + "\n - ".join(missing_keys))
|
|
|
|
# 2. Every other translation file must have exactly the same keys as en.json.
|
|
for fname in sorted(os.listdir(trans_dir)):
|
|
if not fname.endswith(".json") or fname == "en.json":
|
|
continue
|
|
fpath = os.path.join(trans_dir, fname)
|
|
with open(fpath, "r", encoding="utf-8") as f:
|
|
try:
|
|
other = json.load(f)
|
|
except json.JSONDecodeError as e:
|
|
errors.append(f"Invalid JSON in translations/{fname}: {e}")
|
|
continue
|
|
other_keys = set(flatten_keys(other))
|
|
missing = sorted(en_keys - other_keys)
|
|
extra = sorted(other_keys - en_keys)
|
|
if missing:
|
|
errors.append(f"translations/{fname} is missing key(s):\n - " + "\n - ".join(missing))
|
|
if extra:
|
|
errors.append(f"translations/{fname} has extra key(s) not in en.json:\n - " + "\n - ".join(extra))
|
|
|
|
if errors:
|
|
for e in errors:
|
|
print(e)
|
|
sys.exit(1)
|
|
|
|
other_count = len([f for f in os.listdir(trans_dir) if f.endswith(".json") and f != "en.json"])
|
|
print(f"✓ All {len(en_keys)} translation keys in translations/en.json are active and used in codebase.")
|
|
if other_count:
|
|
print(f"✓ {other_count} other translation file(s) match the en.json key set exactly.")
|
|
|
|
if __name__ == "__main__":
|
|
main() |