diff --git a/.idea/PyQt6_LaTaniere.iml b/.idea/PyQt6_LaTaniere.iml index 3c24ad6..88a8457 100644 --- a/.idea/PyQt6_LaTaniere.iml +++ b/.idea/PyQt6_LaTaniere.iml @@ -5,7 +5,7 @@ - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 82828b5..eb498d8 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/src/config/constants.py b/src/config/constants.py index 53c46f0..7f3e03e 100644 --- a/src/config/constants.py +++ b/src/config/constants.py @@ -13,11 +13,11 @@ AUTENTICATION_SUCCESS_MESSAGE = """ -

Authentication réussie

+

 La Tenière : Authentication réussie

Vous pouvez maintenant fermer cette fenêtre et revenir au launcher de La Tanière.

- """.encode('utf-8') + """ # --------------------------------------------------------------------------- # ENUMS # --------------------------------------------------------------------------- diff --git a/src/discord/discord_oauth.py b/src/discord/discord_oauth.py index 441cdda..cb5abdd 100644 --- a/src/discord/discord_oauth.py +++ b/src/discord/discord_oauth.py @@ -1,5 +1,8 @@ import os import webbrowser +import base64 +import resources +from tools.qt_resources import get_resource_as_data_url from http.server import BaseHTTPRequestHandler, HTTPServer from urllib.parse import parse_qs, urlencode, urlparse @@ -36,7 +39,7 @@ class OAuthCallbackHandler(BaseHTTPRequestHandler): self.send_response(200) self.send_header("Content-type", "text/html") self.end_headers() - self.wfile.write(AUTENTICATION_SUCCESS_MESSAGE) + self.wfile.write(AUTENTICATION_SUCCESS_MESSAGE.replace("$LOGO$", get_resource_as_data_url(":/assets/logo.png")).encode('utf-8')) # return discord application id (client id) def get_discord_client_id() -> str: diff --git a/src/fivemserver/whitelistmanager.py b/src/fivemserver/whitelistmanager.py index a2ee6ad..8266339 100644 --- a/src/fivemserver/whitelistmanager.py +++ b/src/fivemserver/whitelistmanager.py @@ -1,6 +1,7 @@ +from config.constants import ApiEndPoints from config.constants import PlayerServerInfo from tools.http_client import ApiError, http_get -from config.constants import ApiEndPoints + class WhiteList: @staticmethod diff --git a/src/tools/qt_resources.py b/src/tools/qt_resources.py new file mode 100644 index 0000000..e06bdc8 --- /dev/null +++ b/src/tools/qt_resources.py @@ -0,0 +1,63 @@ +import base64 +from PySide6.QtCore import QFile + + +def get_resource_as_base64(resource_path: str) -> str: + """ + Extrait une ressource Qt et la retourne encodée en base64. + + :param resource_path: Chemin de la ressource (ex: ":/assets/logo_rond.png") + :return: Chaîne base64 de la ressource + :raises FileNotFoundError: Si la ressource n'existe pas + :raises RuntimeError: Si la ressource ne peut pas être lue + """ + file = QFile(resource_path) + + if not file.exists(): + raise FileNotFoundError(f"Ressource Qt introuvable : {resource_path}") + + if not file.open(QFile.OpenModeFlag.ReadOnly): + raise RuntimeError(f"Impossible d'ouvrir la ressource Qt : {resource_path}") + + try: + data = bytes(file.readAll()) + finally: + file.close() + + if not data: + raise RuntimeError(f"Ressource vide : {resource_path}") + + return base64.b64encode(data).decode("utf-8") + + +def get_resource_as_data_url(resource_path: str, mime_type: str = None) -> str: + """ + Extrait une ressource Qt et la retourne sous forme de data URL utilisable en HTML. + + :param resource_path: Chemin de la ressource (ex: ":/assets/logo.png") + :param mime_type: Type MIME (ex: "image/png"). Déduit depuis l'extension si non fourni. + :return: Data URL (ex: "data:image/png;base64,...") + """ + if mime_type is None: + mime_type = _guess_mime_type(resource_path) + + b64 = get_resource_as_base64(resource_path) + return f"data:{mime_type};base64,{b64}" + + +def _guess_mime_type(resource_path: str) -> str: + """Déduit le type MIME depuis l'extension du fichier.""" + MIME_TYPES = { + ".png": "image/png", + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + ".gif": "image/gif", + ".svg": "image/svg+xml", + ".webp": "image/webp", + ".ico": "image/x-icon", + ".pdf": "application/pdf", + ".json": "application/json", + ".txt": "text/plain", + } + ext = "." + resource_path.rsplit(".", 1)[-1].lower() if "." in resource_path else "" + return MIME_TYPES.get(ext, "application/octet-stream")