Kapitan 9361bc0363
All checks were successful
Gitea/kapitanbooru-uploader/pipeline/head This commit looks good
Translations, suggestion box, UX
2025-03-03 00:47:38 +01:00

185 lines
6.7 KiB
Python

import base64
import json
import os
import subprocess
import sys
from .I18N import _
# Na Windowsie używamy DPAPI
if sys.platform.startswith("win"):
try:
import win32crypt
import winreg
except ImportError:
win32crypt = None # Upewnij się, że masz zainstalowany pywin32
winreg = None # Upewnij się, że masz zainstalowany pywin32
def get_browser_paths_windows():
"""Returns a dictionary of browsers and their executable paths from Windows registry and Start Menu."""
browsers = {"Default": None} # "Default" for default system browser
# Check the registry for installed browsers
registry_paths = [
r"SOFTWARE\Clients\StartMenuInternet", # 64-bit Windows
r"SOFTWARE\WOW6432Node\Clients\StartMenuInternet", # 32-bit applications
]
for reg_path in registry_paths:
try:
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, reg_path) as key:
for i in range(winreg.QueryInfoKey(key)[0]): # Iterate over subkeys
browser_name = winreg.EnumKey(key, i)
try:
browser_key_path = os.path.join(
reg_path, browser_name, r"shell\open\command"
)
with winreg.OpenKey(
winreg.HKEY_LOCAL_MACHINE, browser_key_path
) as subkey:
command, _ = winreg.QueryValueEx(subkey, None)
browsers[browser_name] = command.strip(
'"'
) # Clean command string
except FileNotFoundError:
pass # Skip if no command found
except FileNotFoundError:
pass # Registry path not found, continue
return browsers
def get_browsers_linux():
"""Detects installed browsers on Linux by checking available executables."""
browsers = {"Default": None}
browser_names = [
"firefox",
"google-chrome",
"chromium",
"opera",
"brave",
"vivaldi",
]
for browser in browser_names:
if (
subprocess.run(
["which", browser], stdout=subprocess.PIPE, stderr=subprocess.PIPE
).returncode
== 0
):
browsers[browser] = browser
return browsers
def detect_installed_browsers():
"""Detects available browsers depending on the OS."""
if sys.platform == "win32" and winreg: # Windows and winreg is available
browsers = get_browser_paths_windows()
elif sys.platform.startswith("linux"): # Linux
browsers = get_browsers_linux()
return browsers
# --- Funkcje pomocnicze do szyfrowania/odszyfrowania hasła na Windowsie ---
def encrypt_password(password):
"""Szyfruje hasło przy użyciu DPAPI i zwraca zakodowaną base64 postać."""
if win32crypt is None:
return password # jeśli brak win32crypt, zwróć hasło w postaci jawnej
blob = win32crypt.CryptProtectData(
password.encode("utf-8"), None, None, None, None, 0
)
return base64.b64encode(blob).decode("utf-8")
def decrypt_password(enc_password):
"""Odszyfrowuje hasło zapisane w formacie base64 przy użyciu DPAPI."""
if win32crypt is None:
return enc_password
enc_data = base64.b64decode(enc_password)
data = win32crypt.CryptUnprotectData(enc_data, None, None, None, 0)
return data[1].decode("utf-8")
class Settings:
def __init__(self):
# Ustawienia domyślne
self.username = ""
self.password = ""
self.base_url = "http://192.168.1.11:8001"
self.default_tags = "artist:kapitan meta:ai-generated"
self.cache_expiry = 604800 # 7 dni w sekundach
self.browser = ""
self.i18n = _
self.installed_browsers = detect_installed_browsers()
self.load_settings()
self.installed_browsers_reverse = {
v: k for k, v in self.installed_browsers.items()
}
def get_settings_path(self):
"""Ustala ścieżkę do pliku ustawień w zależności od systemu."""
if sys.platform.startswith("win"):
base_dir = os.path.join(os.environ.get("APPDATA", ""), "Kapitanbooru")
else:
base_dir = os.path.expanduser("~/.kapitanbooru")
if not os.path.exists(base_dir):
os.makedirs(base_dir)
return os.path.join(base_dir, "settings.json")
def load_settings(self):
"""Ładuje ustawienia z pliku, jeżeli plik istnieje."""
# Ustawienia domyślne
self.username = ""
self.password = ""
self.base_url = "http://192.168.1.11:8001"
self.default_tags = "artist:kapitan meta:ai-generated"
self.cache_expiry = 604800 # 7 dni w sekundach
self.browser = ""
self.i18n.set_language("en")
try:
if os.path.exists(self.get_settings_path()):
with open(self.get_settings_path(), "r", encoding="utf-8") as f:
data = json.load(f)
self.username = data.get("username", self.username)
# Jeśli system Windows, odszyfruj hasło
if sys.platform.startswith("win") and "password" in data:
self.password = decrypt_password(data["password"])
else:
self.password = data.get("password", self.password)
self.base_url = data.get("base_url", self.base_url)
self.default_tags = data.get("default_tags", self.default_tags)
self.cache_expiry = data.get("cache_expiry", self.cache_expiry)
self.browser = data.get("browser", self.browser)
if self.browser not in self.installed_browsers:
self.browser = ""
self.i18n.set_language(data.get("language", "en"))
except Exception as e:
print(_("Błąd podczas ładowania ustawień:"), e)
def save_settings(self):
"""Zapisuje ustawienia do pliku."""
data = {
"username": self.username,
"base_url": self.base_url,
"default_tags": self.default_tags,
"cache_expiry": self.cache_expiry,
"browser": self.browser,
"language": self.i18n.current_lang,
}
# Na Windowsie szyfrujemy hasło
if sys.platform.startswith("win"):
data["password"] = encrypt_password(self.password)
else:
data["password"] = self.password
try:
with open(self.get_settings_path(), "w", encoding="utf-8") as f:
json.dump(data, f, indent=4)
except Exception as e:
print(_("Błąd podczas zapisywania ustawień:"), e)