diff --git a/config.json b/config.json new file mode 100644 index 0000000..a37b1f3 --- /dev/null +++ b/config.json @@ -0,0 +1,7 @@ +{ + "app_name": "fcco Converter", + "app_version": "2.0.0", + "repo_owner": "public", + "repo_name": "fcco-Converter", + "gitea_api_base": "https://git.joelunger.de/api/v1" +} diff --git a/fcco_converter/config.py b/fcco_converter/config.py index 7cbfac8..c18713f 100644 --- a/fcco_converter/config.py +++ b/fcco_converter/config.py @@ -7,8 +7,59 @@ Verwendet pathlib für alle Pfadoperationen. import json import platform +import sys from pathlib import Path +# ---- Globale App-Informationen (aus config.json) ---- +APP_INFO = { + "app_name": "fcco Converter", + "app_version": "2.0.0", + "repo_owner": "public", + "repo_name": "fcco-Converter", + "gitea_api_base": "https://git.joelunger.de/api/v1" +} + +def _load_app_info(): + try: + # Finde config.json relativ zum Skript oder im PyInstaller Bundle + if getattr(sys, "frozen", False): + base_dir = Path(sys.executable).parent + else: + base_dir = Path(__file__).parent.parent + + config_path = base_dir / "config.json" + if config_path.exists(): + with open(config_path, "r", encoding="utf-8") as f: + data = json.load(f) + APP_INFO.update(data) + except Exception: + pass + +_load_app_info() + +# ========================================================================= +# Farbschema +# ========================================================================= + +T = { + "bg": "#000000", + "surface": "#111111", + "elevated": "#1a1a1a", + "card": "#222222", + "input": "#000000", + "accent": "#ffffff", + "accent_h": "#e6e6e6", + "success": "#ffffff", + "success_h": "#e6e6e6", + "warn": "#ffffff", + "error": "#ffffff", + "text": "#ffffff", + "text2": "#b3b3b3", + "muted": "#808080", + "border": "#333333", + "btn2": "#1a1a1a", + "btn2_h": "#333333", +} # Standardmäßige Export-Kategorien DEFAULT_EXPORT_PATHS = { diff --git a/fcco_converter/gui.py b/fcco_converter/gui.py index 7a01dbe..ff8da02 100644 --- a/fcco_converter/gui.py +++ b/fcco_converter/gui.py @@ -29,6 +29,8 @@ from .config import ( load_settings, save_settings, save_export_history, + T, + APP_INFO, ) from .converter import run_batch_conversion, _ensure_ffmpeg from .metadata import ( @@ -50,25 +52,7 @@ IS_MACOS = platform.system() == "Darwin" # Farbschema # ========================================================================= -T = { - "bg": "#000000", - "surface": "#111111", - "elevated": "#1a1a1a", - "card": "#222222", - "input": "#000000", - "accent": "#ffffff", - "accent_h": "#e6e6e6", - "success": "#ffffff", - "success_h": "#e6e6e6", - "warn": "#ffffff", - "error": "#ffffff", - "text": "#ffffff", - "text2": "#b3b3b3", - "muted": "#808080", - "border": "#333333", - "btn2": "#1a1a1a", - "btn2_h": "#333333", -} +# (Farben werden jetzt aus config.T importiert) # ========================================================================= @@ -82,7 +66,7 @@ class App(ctk.CTk): ctk.set_appearance_mode("dark") ctk.set_default_color_theme("blue") - self.title(f"fcco Converter v{get_current_version()}") + self.title(f"{APP_INFO['app_name']} V{APP_INFO['app_version']}") self.geometry("900x700") self.minsize(700, 500) self.configure(fg_color=T["bg"]) @@ -227,8 +211,8 @@ class App(ctk.CTk): self.conv_btn = self._btn( tb, text=" Konvertieren", command=self._convert, image=self.icons.play, width=160, height=36, - fg_color=T["accent"], hover_color=T["accent_h"], - text_color="#000000", font=ctk.CTkFont(size=14, weight="bold")) + fg_color=T["btn2"], hover_color=T["btn2_h"], + text_color="#ffffff", font=ctk.CTkFont(size=14, weight="bold")) self.conv_btn.grid(row=0, column=3, sticky="e") def _make_filelist(self): @@ -576,7 +560,7 @@ class App(ctk.CTk): ctype_var = ctk.StringVar(value="Gottesdienst") for i, opt in enumerate(["Gottesdienst", "Hochzeit", "Weissagung", "Jugend", "Sonstiges"]): ctk.CTkRadioButton(mid, text=opt, variable=ctype_var, value=opt, - fg_color=T["accent"], hover_color=T["accent_h"], + fg_color=T["btn2"], hover_color=T["btn2_h"], checkmark_color="#ffffff", border_color=T["border"], text_color=T["text"], font=ctk.CTkFont(size=12) ).grid(row=i+1, column=0, sticky="w", pady=1, padx=(0, 24)) @@ -623,8 +607,8 @@ class App(ctk.CTk): self._btn(bf, text=" Konvertieren starten", command=_ok, image=self.icons.play, width=180, height=34, - fg_color=T["accent"], hover_color=T["accent_h"], - text_color="#000000", font=ctk.CTkFont(weight="bold") + fg_color=T["btn2"], hover_color=T["btn2_h"], + text_color="#ffffff", font=ctk.CTkFont(weight="bold") ).pack(side="right") # Fokus (KEIN grab_set auf macOS!) @@ -650,10 +634,11 @@ class App(ctk.CTk): tabs = ctk.CTkTabview(w, fg_color=T["surface"], segmented_button_fg_color=T["elevated"], - segmented_button_selected_color=T["accent"], - segmented_button_selected_hover_color=T["accent_h"], + segmented_button_selected_color=T["border"], + segmented_button_selected_hover_color=T["btn2_h"], segmented_button_unselected_color=T["elevated"], - segmented_button_unselected_hover_color=T["btn2_h"]) + segmented_button_unselected_hover_color=T["btn2_h"], + text_color=T["text"]) tabs.pack(fill="both", expand=True, padx=12, pady=(12, 4)) t1 = tabs.add("Allgemein") @@ -681,8 +666,8 @@ class App(ctk.CTk): font=ctk.CTkFont(size=12)).pack(anchor="w") av = ctk.StringVar(value=self.settings.get("appearance_mode", "Dark")) ctk.CTkOptionMenu(s1, values=["Dark", "Light", "System"], variable=av, - fg_color=T["input"], button_color=T["accent"], - button_hover_color=T["accent_h"], text_color=T["text"], + fg_color=T["input"], button_color=T["btn2"], + button_hover_color=T["btn2_h"], text_color=T["text"], command=lambda v: ctk.set_appearance_mode(v) ).pack(anchor="w", pady=(2, 10)) wg["appearance"] = av @@ -690,7 +675,7 @@ class App(ctk.CTk): self._slabel(s1, "Updates") uv = ctk.BooleanVar(value=self.settings.get("check_updates_on_start", True)) ctk.CTkCheckBox(s1, text="Beim Start auf Updates prüfen", variable=uv, - fg_color=T["accent"], hover_color=T["accent_h"], + fg_color=T["btn2"], hover_color=T["btn2_h"], checkmark_color="#ffffff", border_color=T["border"], text_color=T["text"], font=ctk.CTkFont(size=12)).pack(anchor="w", pady=4) wg["auto_update"] = uv @@ -702,16 +687,16 @@ class App(ctk.CTk): self._slabel(s2, "Ausgabeformat") fv = ctk.StringVar(value=self.settings.get("audio", {}).get("output_format", "mp3")) ctk.CTkOptionMenu(s2, values=OUTPUT_FORMAT_OPTIONS, variable=fv, - fg_color=T["input"], button_color=T["accent"], - button_hover_color=T["accent_h"], text_color=T["text"] + fg_color=T["input"], button_color=T["btn2"], + button_hover_color=T["btn2_h"], text_color=T["text"] ).pack(anchor="w", pady=(2, 10)) wg["fmt"] = fv self._slabel(s2, "Encoding") mv = ctk.StringVar(value=self.settings.get("audio", {}).get("encoding_mode", "CBR")) ctk.CTkOptionMenu(s2, values=ENCODING_MODE_OPTIONS, variable=mv, - fg_color=T["input"], button_color=T["accent"], - button_hover_color=T["accent_h"], text_color=T["text"] + fg_color=T["input"], button_color=T["btn2"], + button_hover_color=T["btn2_h"], text_color=T["text"] ).pack(anchor="w", pady=(2, 6)) wg["mode"] = mv @@ -719,8 +704,8 @@ class App(ctk.CTk): font=ctk.CTkFont(size=12)).pack(anchor="w", pady=(4, 0)) bv = ctk.StringVar(value=self.settings.get("audio", {}).get("bitrate", "192")) ctk.CTkOptionMenu(s2, values=BITRATE_OPTIONS, variable=bv, - fg_color=T["input"], button_color=T["accent"], - button_hover_color=T["accent_h"], text_color=T["text"] + fg_color=T["input"], button_color=T["btn2"], + button_hover_color=T["btn2_h"], text_color=T["text"] ).pack(anchor="w", pady=(2, 6)) wg["br"] = bv @@ -728,8 +713,8 @@ class App(ctk.CTk): font=ctk.CTkFont(size=12)).pack(anchor="w", pady=(4, 0)) vv = ctk.StringVar(value=self.settings.get("audio", {}).get("vbr_quality", "2")) ctk.CTkOptionMenu(s2, values=VBR_QUALITY_OPTIONS, variable=vv, - fg_color=T["input"], button_color=T["accent"], - button_hover_color=T["accent_h"], text_color=T["text"] + fg_color=T["input"], button_color=T["btn2"], + button_hover_color=T["btn2_h"], text_color=T["text"] ).pack(anchor="w", pady=(2, 10)) wg["vbr"] = vv @@ -738,8 +723,8 @@ class App(ctk.CTk): font=ctk.CTkFont(size=12)).pack(anchor="w") sv = ctk.StringVar(value=self.settings.get("audio", {}).get("sample_rate", "Original")) ctk.CTkOptionMenu(s2, values=SAMPLERATE_OPTIONS, variable=sv, - fg_color=T["input"], button_color=T["accent"], - button_hover_color=T["accent_h"], text_color=T["text"] + fg_color=T["input"], button_color=T["btn2"], + button_hover_color=T["btn2_h"], text_color=T["text"] ).pack(anchor="w", pady=(2, 6)) wg["sr"] = sv @@ -747,15 +732,15 @@ class App(ctk.CTk): font=ctk.CTkFont(size=12)).pack(anchor="w", pady=(4, 0)) cv = ctk.StringVar(value=self.settings.get("audio", {}).get("channels", "Original")) ctk.CTkOptionMenu(s2, values=CHANNEL_OPTIONS, variable=cv, - fg_color=T["input"], button_color=T["accent"], - button_hover_color=T["accent_h"], text_color=T["text"] + fg_color=T["input"], button_color=T["btn2"], + button_hover_color=T["btn2_h"], text_color=T["text"] ).pack(anchor="w", pady=(2, 10)) wg["ch"] = cv self._slabel(s2, "Optionen") ov = ctk.BooleanVar(value=self.settings.get("audio", {}).get("overwrite_existing", True)) ctk.CTkCheckBox(s2, text="Bestehende Dateien überschreiben", variable=ov, - fg_color=T["accent"], hover_color=T["accent_h"], + fg_color=T["btn2"], hover_color=T["btn2_h"], checkmark_color="#ffffff", border_color=T["border"], text_color=T["text"], font=ctk.CTkFont(size=12)).pack(anchor="w", pady=3) wg["ow"] = ov @@ -796,14 +781,14 @@ class App(ctk.CTk): self._slabel(s3, "Automatisierung") atv = ctk.BooleanVar(value=self.settings.get("metadata", {}).get("auto_track_number", True)) ctk.CTkCheckBox(s3, text="Tracknummer automatisch vergeben", variable=atv, - fg_color=T["accent"], hover_color=T["accent_h"], + fg_color=T["btn2"], hover_color=T["btn2_h"], checkmark_color="#ffffff", border_color=T["border"], text_color=T["text"], font=ctk.CTkFont(size=12)).pack(anchor="w", pady=3) wg["auto_track"] = atv aav = ctk.BooleanVar(value=self.settings.get("metadata", {}).get("auto_album_from_folder", True)) ctk.CTkCheckBox(s3, text="Albumname aus Ordnername ableiten", variable=aav, - fg_color=T["accent"], hover_color=T["accent_h"], + fg_color=T["btn2"], hover_color=T["btn2_h"], checkmark_color="#ffffff", border_color=T["border"], text_color=T["text"], font=ctk.CTkFont(size=12)).pack(anchor="w", pady=3) wg["auto_album"] = aav @@ -848,8 +833,8 @@ class App(ctk.CTk): self._btn(bf, text=" Speichern", command=lambda: self._save_s(wg, w), image=self.icons.save, width=140, height=34, - fg_color=T["accent"], hover_color=T["accent_h"], - text_color="#000000", font=ctk.CTkFont(weight="bold") + fg_color=T["btn2"], hover_color=T["btn2_h"], + text_color="#ffffff", font=ctk.CTkFont(weight="bold") ).pack(side="right") w.after(50, lambda: (w.lift(), w.focus_force())) diff --git a/fcco_converter/updater.py b/fcco_converter/updater.py index b286062..a1d6082 100644 --- a/fcco_converter/updater.py +++ b/fcco_converter/updater.py @@ -17,14 +17,13 @@ from typing import Callable from urllib.request import urlopen, Request from urllib.error import URLError import json +from .config import APP_INFO -# Aktuelle Version des Programms -CURRENT_VERSION = "2.0.0" - -# Gitea API-URL für Releases -GITEA_API_BASE = "https://git.joelunger.de/api/v1" -REPO_OWNER = "public" -REPO_NAME = "fcco-Converter" +# Aktuelle Version des Programms und Repos (aus config.json) +CURRENT_VERSION = APP_INFO["app_version"] +GITEA_API_BASE = APP_INFO["gitea_api_base"] +REPO_OWNER = APP_INFO["repo_owner"] +REPO_NAME = APP_INFO["repo_name"] RELEASES_URL = f"{GITEA_API_BASE}/repos/{REPO_OWNER}/{REPO_NAME}/releases"