All checks were successful
Gitea/kapitanbooru-uploader/pipeline/head This commit looks good
185 lines
6.7 KiB
Python
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)
|