Refacto, enum, utils, WIP
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -400,3 +400,4 @@ http-client.private.env.json
|
|||||||
# Github Copilot persisted session migrations, see: https://github.com/microsoft/copilot-intellij-feedback/issues/712#issuecomment-3322062215
|
# Github Copilot persisted session migrations, see: https://github.com/microsoft/copilot-intellij-feedback/issues/712#issuecomment-3322062215
|
||||||
.idea/**/copilot.data.migration.*.xml
|
.idea/**/copilot.data.migration.*.xml
|
||||||
src/config.json
|
src/config.json
|
||||||
|
config.json
|
||||||
|
|||||||
@@ -2,20 +2,7 @@ import json
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Callable, NotRequired, TypedDict, cast
|
from typing import Any, Callable, NotRequired, TypedDict, cast
|
||||||
|
|
||||||
# Configuration du chemin du fichier de configuration avec son nom.
|
from utils import get_bundle_dir
|
||||||
def _get_config_path() -> Path:
|
|
||||||
from sys import argv, executable
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
# Si l'app est packagée (PyInstaller)
|
|
||||||
if getattr(sys, "frozen", False):
|
|
||||||
base_path = Path(executable).parent
|
|
||||||
else:
|
|
||||||
base_path = Path(os.path.realpath(argv[0])).parent
|
|
||||||
|
|
||||||
return base_path / "config.json"
|
|
||||||
|
|
||||||
class ConfigData(TypedDict):
|
class ConfigData(TypedDict):
|
||||||
discord_user_id: NotRequired[str]
|
discord_user_id: NotRequired[str]
|
||||||
@@ -29,7 +16,7 @@ class ConfigField(TypedDict):
|
|||||||
validator: Validator
|
validator: Validator
|
||||||
normalizer: Normalizer
|
normalizer: Normalizer
|
||||||
|
|
||||||
CONFIG_PATH = _get_config_path()
|
CONFIG_PATH = get_bundle_dir() / "config.json"
|
||||||
|
|
||||||
DISCORD_USER_KEY = "discord_user_id"
|
DISCORD_USER_KEY = "discord_user_id"
|
||||||
VOLUME_KEY = "volume"
|
VOLUME_KEY = "volume"
|
||||||
@@ -49,7 +36,7 @@ CONFIG_SCHEMA: dict[str, ConfigField] = {
|
|||||||
|
|
||||||
class ConfigManager:
|
class ConfigManager:
|
||||||
def __init__(self, path: Path | None = None) -> None:
|
def __init__(self, path: Path | None = None) -> None:
|
||||||
self.path = path or _get_config_path()
|
self.path = path or CONFIG_PATH
|
||||||
self._data: ConfigData = self._load()
|
self._data: ConfigData = self._load()
|
||||||
self._dirty = False
|
self._dirty = False
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,27 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
from PySide6.QtGui import QColor
|
from PySide6.QtGui import QColor
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Constants
|
# Constants
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
URLS = {
|
|
||||||
"discord": "https://discord.gg/A7eanmSkp2",
|
|
||||||
"intranet": "https://la-taniere.fun/connexion/",
|
|
||||||
}
|
|
||||||
|
|
||||||
RESOURCES_MP3 = ":/assets/the-beat-of-nature.mp3"
|
|
||||||
RESOURCES_FONT = ":/assets/Avocado-Cake-Demo.otf"
|
|
||||||
|
|
||||||
GLOW_COLOR = QColor(255, 140, 0, 255)
|
|
||||||
GLOW_BLUR_BASE = 15
|
|
||||||
GLOW_BLUR_PEAK = 70
|
|
||||||
GLOW_ANIM_DURATION = 1200
|
|
||||||
|
|
||||||
NO_STAFF = True
|
NO_STAFF = True
|
||||||
NO_DISCORD = True
|
NO_DISCORD = True
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# ENUMS
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
class Resources(Enum):
|
||||||
|
MP3 = ":/assets/the-beat-of-nature.mp3"
|
||||||
|
FONT = ":/assets/Avocado-Cake-Demo.otf"
|
||||||
|
|
||||||
|
class Urls(Enum):
|
||||||
|
DISCORD = "https://discord.gg/A7eanmSkp2"
|
||||||
|
INTRANET = "https://la-taniere.fun/connexion/"
|
||||||
|
|
||||||
|
class Glow(Enum):
|
||||||
|
COLOR = QColor(255, 140, 0, 255)
|
||||||
|
BLUR_BASE = 15
|
||||||
|
BLUR_PEAK = 70
|
||||||
|
ANIM_DURATION = 1200
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from PySide6.QtMultimedia import QMediaPlayer, QAudioOutput
|
|||||||
|
|
||||||
from config.config_manager import ConfigManager, VOLUME_KEY
|
from config.config_manager import ConfigManager, VOLUME_KEY
|
||||||
|
|
||||||
from constants import RESOURCES_MP3
|
from constants import Resources
|
||||||
|
|
||||||
class AudioController:
|
class AudioController:
|
||||||
# Encapsule toute la logique audio : lecture, volume, mute.
|
# Encapsule toute la logique audio : lecture, volume, mute.
|
||||||
@@ -20,7 +20,7 @@ class AudioController:
|
|||||||
self._player.setLoops(-1)
|
self._player.setLoops(-1)
|
||||||
|
|
||||||
# Chargement du MP3 depuis les ressources Qt
|
# Chargement du MP3 depuis les ressources Qt
|
||||||
mp3file = QFile(RESOURCES_MP3)
|
mp3file = QFile(Resources.MP3.value)
|
||||||
mp3file.open(QFile.ReadOnly)
|
mp3file.open(QFile.ReadOnly)
|
||||||
mp3data = mp3file.readAll()
|
mp3data = mp3file.readAll()
|
||||||
mp3file.close()
|
mp3file.close()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from PySide6.QtCore import QPropertyAnimation, QEasingCurve
|
from PySide6.QtCore import QPropertyAnimation, QEasingCurve
|
||||||
from PySide6.QtWidgets import QGraphicsDropShadowEffect
|
from PySide6.QtWidgets import QGraphicsDropShadowEffect
|
||||||
|
|
||||||
from constants import GLOW_COLOR, GLOW_BLUR_BASE, GLOW_BLUR_PEAK, GLOW_ANIM_DURATION
|
from constants import Glow
|
||||||
|
|
||||||
|
|
||||||
class GlowAnimator:
|
class GlowAnimator:
|
||||||
@@ -11,15 +11,15 @@ class GlowAnimator:
|
|||||||
self._widget = widget
|
self._widget = widget
|
||||||
|
|
||||||
self._effect = QGraphicsDropShadowEffect(widget)
|
self._effect = QGraphicsDropShadowEffect(widget)
|
||||||
self._effect.setBlurRadius(GLOW_BLUR_BASE)
|
self._effect.setBlurRadius(Glow.BLUR_BASE.value)
|
||||||
self._effect.setOffset(0, 0)
|
self._effect.setOffset(0, 0)
|
||||||
self._effect.setColor(GLOW_COLOR)
|
self._effect.setColor(Glow.COLOR.value)
|
||||||
|
|
||||||
self._anim = QPropertyAnimation(self._effect, b"blurRadius")
|
self._anim = QPropertyAnimation(self._effect, b"blurRadius")
|
||||||
self._anim.setDuration(GLOW_ANIM_DURATION)
|
self._anim.setDuration(Glow.ANIM_DURATION.value)
|
||||||
self._anim.setStartValue(GLOW_BLUR_BASE)
|
self._anim.setStartValue(Glow.BLUR_BASE.value)
|
||||||
self._anim.setKeyValueAt(0.5, GLOW_BLUR_PEAK)
|
self._anim.setKeyValueAt(0.5, Glow.BLUR_PEAK.value)
|
||||||
self._anim.setEndValue(GLOW_BLUR_BASE)
|
self._anim.setEndValue(Glow.BLUR_BASE.value)
|
||||||
self._anim.setEasingCurve(QEasingCurve.InOutQuad)
|
self._anim.setEasingCurve(QEasingCurve.InOutQuad)
|
||||||
self._anim.setLoopCount(-1)
|
self._anim.setLoopCount(-1)
|
||||||
|
|
||||||
|
|||||||
11
src/main.py
11
src/main.py
@@ -1,5 +1,5 @@
|
|||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from utils import get_bundle_dir
|
||||||
|
|
||||||
from PySide6.QtCore import QResource
|
from PySide6.QtCore import QResource
|
||||||
from PySide6.QtGui import QFontDatabase, QFont
|
from PySide6.QtGui import QFontDatabase, QFont
|
||||||
@@ -9,16 +9,13 @@ from PySide6.QtWidgets import QApplication
|
|||||||
import resources # noqa: F401 - required to register Qt resources
|
import resources # noqa: F401 - required to register Qt resources
|
||||||
|
|
||||||
from ui.main_window import MainWindow
|
from ui.main_window import MainWindow
|
||||||
from constants import RESOURCES_FONT
|
from constants import Resources
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Bundle path resolution
|
# Bundle path resolution
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
|
bundle_dir = get_bundle_dir()
|
||||||
bundle_dir = Path(sys._MEIPASS)
|
|
||||||
else:
|
|
||||||
bundle_dir = Path(__file__).resolve().parent.parent
|
|
||||||
|
|
||||||
QResource.registerResource(f"{bundle_dir}/resources.py")
|
QResource.registerResource(f"{bundle_dir}/resources.py")
|
||||||
|
|
||||||
@@ -28,7 +25,7 @@ QResource.registerResource(f"{bundle_dir}/resources.py")
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def load_custom_font() -> str:
|
def load_custom_font() -> str:
|
||||||
font_id = QFontDatabase.addApplicationFont(RESOURCES_FONT)
|
font_id = QFontDatabase.addApplicationFont(Resources.FONT.value)
|
||||||
if font_id == -1:
|
if font_id == -1:
|
||||||
raise RuntimeError("Failed to load font from resources.")
|
raise RuntimeError("Failed to load font from resources.")
|
||||||
font_families = QFontDatabase.applicationFontFamilies(font_id)
|
font_families = QFontDatabase.applicationFontFamilies(font_id)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from PySide6.QtUiTools import QUiLoader
|
|||||||
from PySide6.QtWidgets import QMainWindow, QSizePolicy
|
from PySide6.QtWidgets import QMainWindow, QSizePolicy
|
||||||
|
|
||||||
from config.config_manager import ConfigManager
|
from config.config_manager import ConfigManager
|
||||||
from constants import NO_DISCORD, URLS, NO_STAFF
|
from constants import NO_DISCORD, NO_STAFF, Urls
|
||||||
from controllers.audio_controller import AudioController
|
from controllers.audio_controller import AudioController
|
||||||
from controllers.glow_animator import GlowAnimator
|
from controllers.glow_animator import GlowAnimator
|
||||||
from controllers.window_dragger import WindowDragger
|
from controllers.window_dragger import WindowDragger
|
||||||
@@ -91,10 +91,10 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _on_discord() -> None:
|
def _on_discord() -> None:
|
||||||
webbrowser.open(URLS["discord"])
|
webbrowser.open(Urls.DISCORD.value)
|
||||||
|
|
||||||
def _on_intranet(self) -> None:
|
def _on_intranet(self) -> None:
|
||||||
webbrowser.open(URLS["intranet"])
|
webbrowser.open(Urls.INTRANET.value)
|
||||||
self._glow.start()
|
self._glow.start()
|
||||||
|
|
||||||
def _on_discord_auth_btn(self) -> None:
|
def _on_discord_auth_btn(self) -> None:
|
||||||
|
|||||||
7
src/utils.py
Normal file
7
src/utils.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
def get_bundle_dir() -> Path:
|
||||||
|
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
|
||||||
|
return Path(sys._MEIPASS)
|
||||||
|
return Path(__file__).resolve().parent.parent
|
||||||
Reference in New Issue
Block a user