actually works
Some checks failed
Gitea/kapitanbooru-uploader/pipeline/head There was a failure building this commit
Some checks failed
Gitea/kapitanbooru-uploader/pipeline/head There was a failure building this commit
Now with tagger Miejsce na zdjęcie Linki do wiki Zapis ustawień Tagger działa w tle Kolorujemy pliki po ratingu Tagger cache Tagi w bazie Pobranie implikacji tagów Autocomplete Podział na pliki i skrypty + nowe API Structure for package Version 0.1.0
This commit is contained in:
179
kapitanbooru_uploader/settings.py
Normal file
179
kapitanbooru_uploader/settings.py
Normal file
@@ -0,0 +1,179 @@
|
||||
import base64
|
||||
import importlib
|
||||
import json
|
||||
import os
|
||||
import sqlite3
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
# 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.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 = ""
|
||||
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 = ""
|
||||
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,
|
||||
}
|
||||
# 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)
|
||||
Reference in New Issue
Block a user