From 111b1f7f1ee49678020d96a46897c39bb6d71ef4 Mon Sep 17 00:00:00 2001 From: dazedanon Date: Sat, 14 Mar 2026 02:33:38 -0500 Subject: [PATCH] bunch of fixes --- gui/translation_tab.py | 2 +- gui/workflow_tab.py | 61 +++++++++++++++++++++++++++++------------- modules/main.py | 1 - util/dazedformat.py | 48 +++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 21 deletions(-) create mode 100644 util/dazedformat.py diff --git a/gui/translation_tab.py b/gui/translation_tab.py index 01419f0..f656da8 100644 --- a/gui/translation_tab.py +++ b/gui/translation_tab.py @@ -275,7 +275,7 @@ class TranslationWorker(QThread): clear_cache() # Check for required environment variables - required_envs = ["api", "key", "organization", "model", "language", "timeout", "fileThreads", "threads", "width", "listWidth"] + required_envs = ["api", "key", "model", "language", "timeout", "fileThreads", "threads", "width", "listWidth"] env_missing = False for env in required_envs: diff --git a/gui/workflow_tab.py b/gui/workflow_tab.py index 9b7ff66..13a38c7 100644 --- a/gui/workflow_tab.py +++ b/gui/workflow_tab.py @@ -261,6 +261,30 @@ class _SubprocessWorker(QThread): self.done.emit(False, f"{self.label}: {exc}") +class _JsonFormatWorker(QThread): + """Format all JSON files in a directory using the bundled dazedformat utility.""" + done = pyqtSignal(bool, str) + log = pyqtSignal(str) + + def __init__(self, data_path: str): + super().__init__() + self.data_path = data_path + + def run(self): + try: + from util.dazedformat import format_json_files + self.log.emit(f"Formatting JSON files in {self.data_path} …") + count, errors = format_json_files(self.data_path, log=self.log.emit) + for e in errors: + self.log.emit(f" ⚠ {e}") + if errors: + self.done.emit(False, f"dazedformat: {count} formatted, {len(errors)} error(s).") + else: + self.done.emit(True, f"dazedformat: {count} file(s) formatted successfully.") + except Exception as exc: + self.done.emit(False, f"dazedformat error: {exc}") + + class _FileCopyWorker(QThread): """Recursively copy a source folder into a destination folder.""" done = pyqtSignal(int, list) # count_copied, errors @@ -533,11 +557,6 @@ class WorkflowTab(QWidget): row1.addWidget(sel_core) row1.addStretch() - - self.import_btn = _make_btn("⬇ Import Selected → files/", "#007acc") - self.import_btn.setEnabled(False) - self.import_btn.clicked.connect(self._import_files) - row1.addWidget(self.import_btn) layout.addLayout(row1) # ── Step 1: Vocab / Glossary ──────────────────────────────────────────── @@ -933,13 +952,14 @@ class WorkflowTab(QWidget): tb.setSpacing(10) # ---- Task A: dazedformat ----------------------------------------- - ta = QGroupBox("A — Format JSON files with dazedformat") + ta = QGroupBox("A — Format JSON files (dazedformat)") ta.setStyleSheet(self._task_box_style()) ta_inner = QVBoxLayout(ta) ta_inner.setSpacing(4) ta_desc = QLabel( - "Runs dazedformat . in the game\'s data folder to " - "normalise all JSON files before importing." + "Normalises all JSON files in the game's data folder by round-tripping them " + "through json.load / json.dump. " + "Bundled — no external install required." ) ta_desc.setTextFormat(Qt.RichText) ta_desc.setWordWrap(True) @@ -1043,14 +1063,18 @@ class WorkflowTab(QWidget): layout.addWidget(tasks_box) - # ---- Run All button ------------------------------------------ - run_all_row = QHBoxLayout() - run_all_btn = _make_btn("▶▶ Run All 3 Tasks", "#007acc") + # ---- Run All + Import button row -------------------------------- + bottom_row = QHBoxLayout() + bottom_row.addStretch() + run_all_btn = _make_btn("▶▶ Run All 3 Tasks", "#3a4a6a") run_all_btn.setToolTip("Run dazedformat, prettier, and gameupdate copy in sequence") run_all_btn.clicked.connect(self._run_all_preprocess) - run_all_row.addStretch() - run_all_row.addWidget(run_all_btn) - layout.addLayout(run_all_row) + bottom_row.addWidget(run_all_btn) + self.import_btn = _make_btn("⬇ Import Selected → files/", "#3a4a6a") + self.import_btn.setEnabled(False) + self.import_btn.clicked.connect(self._import_files) + bottom_row.addWidget(self.import_btn) + layout.addLayout(bottom_row) @staticmethod def _task_box_style() -> str: @@ -2393,7 +2417,7 @@ class WorkflowTab(QWidget): if not data_path: self._log("⚠ No data folder detected. Complete Step 0 first.") return - w = _SubprocessWorker(["dazedformat", "."], cwd=data_path, label="dazedformat") + w = _JsonFormatWorker(data_path) w.log.connect(self._log) w.done.connect(lambda ok, msg: self._log(("✅ " if ok else "❌ ") + msg)) self._worker = w @@ -2445,13 +2469,12 @@ class WorkflowTab(QWidget): gameupdate_src = self.pp_gameupdate_edit.text().strip() skipped: list[str] = [] - # A — dazedformat - if data_path and _shutil.which("dazedformat"): + # A — dazedformat (bundled, no PATH check needed) + if data_path: self._log("▶ [A] dazedformat …") self._run_dazedformat() else: - reason = "data folder missing" if not data_path else "dazedformat not on PATH" - skipped.append(f"A (dazedformat): {reason}") + skipped.append("A (dazedformat): data folder missing") # B — jsbeautifier (pure Python, no Node required) if plugins_js and Path(plugins_js).is_file(): diff --git a/modules/main.py b/modules/main.py index 0c979e3..92a167d 100644 --- a/modules/main.py +++ b/modules/main.py @@ -15,7 +15,6 @@ load_dotenv() for env in [ "api", "key", - "organization", "model", "language", "timeout", diff --git a/util/dazedformat.py b/util/dazedformat.py new file mode 100644 index 0000000..4049b7d --- /dev/null +++ b/util/dazedformat.py @@ -0,0 +1,48 @@ +"""Bundled JSON formatter (dazedformat). + +Normalises all .json files in a directory tree by round-tripping them +through json.load / json.dump with indent=4, which ensures consistent +formatting before importing into files/. +""" +from __future__ import annotations + +import json +import os +from pathlib import Path +from typing import Callable + + +def format_json_files( + directory: str | Path, + log: Callable[[str], None] | None = None, +) -> tuple[int, list[str]]: + """Format every .json file found under *directory* in-place. + + Returns (formatted_count, error_list). + """ + directory = Path(directory) + formatted = 0 + errors: list[str] = [] + + for root, _, files in os.walk(directory): + for name in files: + if not name.lower().endswith(".json"): + continue + fp = Path(root) / name + try: + text = fp.read_text(encoding="utf-8") + data = json.loads(text) + pretty = json.dumps(data, indent=4, ensure_ascii=False) + # Only write if the content actually changed + if pretty != text: + fp.write_text(pretty, encoding="utf-8") + formatted += 1 + if log: + log(f" Formatted: {fp.relative_to(directory)}") + except Exception as exc: + msg = f"Error in {fp}: {exc}" + errors.append(msg) + if log: + log(f" ⚠ {msg}") + + return formatted, errors