From b65ce306a2094e7f6205342ad2f792ab555c0c40 Mon Sep 17 00:00:00 2001 From: Kibi Kelburton Date: Tue, 11 Aug 2026 22:12:35 +0200 Subject: [PATCH] update gui --- gui.py | 178 ++++++++++++++++++--------------------------------------- 1 file changed, 55 insertions(+), 123 deletions(-) diff --git a/gui.py b/gui.py index c8b7477..4445117 100644 --- a/gui.py +++ b/gui.py @@ -9,6 +9,7 @@ import urllib.error import time import mimetypes import urllib.parse +import re def normalize_file_path(path_str: str) -> str: if not path_str: @@ -38,7 +39,8 @@ DEFAULT_CONFIG = { "api_url": "", "api_key": "", "default_rating": "", - "default_tags": "", + "default_visibility": "0", + "default_tags": "screenshot", "default_is_oc": False, "enable_notifications": True, "show_progress_dialog": True, @@ -59,7 +61,7 @@ def load_config(): return DEFAULT_CONFIG.copy() def get_env_config(): - config = load_config() + config = DEFAULT_CONFIG.copy() script_dir = os.path.dirname(os.path.abspath(__file__)) candidates = [ os.path.join(script_dir, ".env"), @@ -97,6 +99,13 @@ def get_env_config(): config["icon_theme"] = val.lower() except Exception as e: print(f"Error reading .env from {dotenv_path}: {e}") + + # Override with GUI config.json (User GUI Settings have priority over .env) + user_cfg = load_config() + if os.path.exists(CONFIG_PATH): + for k, v in user_cfg.items(): + config[k] = v + return config def save_config(config): @@ -183,120 +192,20 @@ class ConnectionTester(QObject): except Exception as e: self.finished.emit(False, f"Error: {str(e)}") -# ========================================== -# Premium Style Sheet -# ========================================== -STYLE_SHEET = """ -QDialog { - background-color: #121216; - color: #fffffe; - font-family: "Segoe UI", "Inter", "Roboto", "Noto Sans", sans-serif; - font-size: 13px; -} -QLabel { - color: #e2e2e9; -} -QLabel#title { - font-size: 18px; - font-weight: bold; - color: #7f5af0; - margin-bottom: 5px; -} -QGroupBox { - background-color: #1a1a24; - border: 1px solid #2f2f3d; - border-radius: 8px; - margin-top: 15px; - padding-top: 15px; - font-weight: bold; -} -QGroupBox::title { - subcontrol-origin: margin; - subcontrol-position: top left; - left: 15px; - padding: 0 5px; - background-color: #121216; - color: #7f5af0; -} -QLineEdit { - background-color: #242432; - border: 1px solid #2f2f3d; - border-radius: 6px; - padding: 6px 10px; - color: #fffffe; - selection-background-color: #7f5af0; -} -QLineEdit:focus { - border: 1px solid #7f5af0; -} -QComboBox { - background-color: #242432; - border: 1px solid #2f2f3d; - border-radius: 6px; - padding: 6px 10px; - color: #fffffe; -} -QComboBox:focus { - border: 1px solid #7f5af0; -} -QComboBox::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right; - width: 25px; - border-left-width: 0px; -} -QComboBox QAbstractItemView { - background-color: #242432; - border: 1px solid #2f2f3d; - selection-background-color: #7f5af0; - selection-color: #fffffe; - color: #fffffe; -} -QCheckBox { - color: #e2e2e9; -} -QCheckBox:hover { - color: #ffffff; -} -QPushButton { - background-color: #242432; - border: 1px solid #2f2f3d; - border-radius: 6px; - padding: 8px 16px; - color: #fffffe; - font-weight: bold; -} -QPushButton:hover { - background-color: #2f2f42; - border: 1px solid #42425a; -} -QPushButton:pressed { - background-color: #1a1a24; -} -QPushButton#primary { - background-color: #7f5af0; - border: 1px solid #7f5af0; -} -QPushButton#primary:hover { - background-color: #9272f2; - border: 1px solid #9272f2; -} -QPushButton#primary:pressed { - background-color: #694ad4; -} -QPushButton#test { - background-color: #2cb67d; - border: 1px solid #2cb67d; - color: #fffffe; -} -QPushButton#test:hover { - background-color: #34cf8f; - border: 1px solid #34cf8f; -} -QPushButton#test:pressed { - background-color: #249a68; -} -""" +def get_app_icon() -> QIcon: + script_dir = os.path.dirname(os.path.abspath(__file__)) + candidates = [ + os.path.join(script_dir, "icon_app.svg"), + os.path.join(script_dir, "icon_app.png"), + "/home/kibi/Projects/f0ckm-uploader/icon_app.svg", + os.path.expanduser("~/.local/bin/icon_app.svg"), + os.path.expanduser("~/.local/share/icons/hicolor/scalable/apps/f0ckm-uploader.svg"), + os.path.expanduser("~/.local/share/icons/hicolor/128x128/apps/f0ckm-uploader.png") + ] + for c in candidates: + if os.path.exists(c): + return QIcon(c) + return QIcon.fromTheme("f0ckm-uploader") # ========================================== # Settings Dialog Window @@ -307,7 +216,10 @@ class SettingsDialog(QDialog): self.tray_app = tray_app self.setWindowTitle("f0ckm Uploader Settings") self.resize(520, 560) - self.setStyleSheet(STYLE_SHEET) + + app_icon = get_app_icon() + if not app_icon.isNull(): + self.setWindowIcon(app_icon) self.tester_thread = None self.tester = None @@ -327,9 +239,9 @@ class SettingsDialog(QDialog): header_text_layout = QVBoxLayout() header_title = QLabel("f0ckm Uploader") - header_title.setObjectName("title") + header_title.setStyleSheet("font-size: 16px; font-weight: bold;") header_subtitle = QLabel("Configure connection settings and default options") - header_subtitle.setStyleSheet("color: #94a1b2; font-size: 11px;") + header_subtitle.setStyleSheet("font-size: 11px; opacity: 0.7;") header_text_layout.addWidget(header_title) header_text_layout.addWidget(header_subtitle) @@ -377,9 +289,13 @@ class SettingsDialog(QDialog): defaults_layout.setSpacing(10) self.cb_rating = QComboBox() - self.cb_rating.addItems(["(None / Default)", "safe", "questionable", "explicit"]) + self.cb_rating.addItems(["(None / Default)", "SFW", "NSFW", "NSFL"]) defaults_layout.addRow("Default Rating:", self.cb_rating) + self.cb_visibility = QComboBox() + self.cb_visibility.addItems(["Public", "Unlisted", "Private"]) + defaults_layout.addRow("Default Visibility:", self.cb_visibility) + self.txt_tags = QLineEdit() self.txt_tags.setPlaceholderText("comma-separated tags (e.g., meme, anime)") defaults_layout.addRow("Default Tags:", self.txt_tags) @@ -445,10 +361,14 @@ class SettingsDialog(QDialog): self.txt_url.setText(config.get("api_url", "")) self.txt_key.setText(config.get("api_key", "")) - rating = config.get("default_rating", "") - rating_map = {"": 0, "safe": 1, "questionable": 2, "explicit": 3} + rating = config.get("default_rating", "").lower() + rating_map = {"": 0, "s": 1, "sfw": 1, "safe": 1, "q": 2, "nsfw": 2, "questionable": 2, "e": 3, "nsfl": 3, "explicit": 3} self.cb_rating.setCurrentIndex(rating_map.get(rating, 0)) + vis = str(config.get("default_visibility", "0")).lower() + vis_map = {"0": 0, "public": 0, "1": 1, "unlisted": 1, "2": 2, "private": 2} + self.cb_visibility.setCurrentIndex(vis_map.get(vis, 0)) + self.txt_tags.setText(config.get("default_tags", "")) self.chk_oc.setChecked(config.get("default_is_oc", False)) self.chk_notifications.setChecked(config.get("enable_notifications", True)) @@ -490,7 +410,8 @@ class SettingsDialog(QDialog): config = { "api_url": self.txt_url.text().strip(), "api_key": self.txt_key.text().strip(), - "default_rating": ["", "safe", "questionable", "explicit"][self.cb_rating.currentIndex()], + "default_rating": ["", "s", "q", "e"][self.cb_rating.currentIndex()], + "default_visibility": ["0", "1", "2"][self.cb_visibility.currentIndex()], "default_tags": self.txt_tags.text().strip(), "default_is_oc": self.chk_oc.isChecked(), "enable_notifications": self.chk_notifications.isChecked(), @@ -712,6 +633,11 @@ class SystemTrayApp(QObject): api_key = config.get("api_key", "") rating = config.get("default_rating", "") tags = config.get("default_tags", "") + if tags: + # Format tags as clean comma-separated string ("tag1, tag2") for f0ckm API tagsRaw.split(',') compatibility + tag_list = [t.strip() for t in re.split(r'[,]+', tags) if t.strip()] + tags = ", ".join(tag_list) + visibility = str(config.get("default_visibility", "0")) is_oc = "1" if config.get("default_is_oc", False) else "0" @@ -908,8 +834,14 @@ class SingleInstanceApp: def main(): app = QApplication(sys.argv) + app.setApplicationName("f0ckm Uploader") + app.setDesktopFileName("kde-uploader-gui") app.setQuitOnLastWindowClosed(False) + app_icon = get_app_icon() + if not app_icon.isNull(): + app.setWindowIcon(app_icon) + instance_name = "f0ckm-uploader-gui-lock" single_instance = SingleInstanceApp(instance_name)