Improved enums and error handling
This commit is contained in:
parent
bfcdcce11d
commit
062a38ceec
@ -1,5 +1,6 @@
|
|||||||
from os import path
|
from os import path
|
||||||
from tkinter import NSEW, NW, E, N, S, W, PhotoImage, messagebox, ttk
|
from tkinter import NSEW, NW, E, N, S, W, PhotoImage, messagebox, ttk
|
||||||
|
from traceback import format_exc
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import sv_ttk
|
import sv_ttk
|
||||||
@ -7,6 +8,7 @@ from ttkthemes import ThemedTk
|
|||||||
|
|
||||||
from classes.custom.scrollable_frame import FIT_HEIGHT, FIT_WIDTH
|
from classes.custom.scrollable_frame import FIT_HEIGHT, FIT_WIDTH
|
||||||
from classes.custom.themed_frame import ThemedFrame
|
from classes.custom.themed_frame import ThemedFrame
|
||||||
|
from classes.enums import ConnectionState, Theme
|
||||||
from classes.frames.devices import FrameDevices, FrameDevicesEmpty
|
from classes.frames.devices import FrameDevices, FrameDevicesEmpty
|
||||||
from classes.frames.errors import FrameErrorConnection, FrameErrorFirstStart, FrameErrorSavesFolder, FrameErrorUnconfigured
|
from classes.frames.errors import FrameErrorConnection, FrameErrorFirstStart, FrameErrorSavesFolder, FrameErrorUnconfigured
|
||||||
from classes.frames.saves import FrameSaves, FrameSavesEmpty
|
from classes.frames.saves import FrameSaves, FrameSavesEmpty
|
||||||
@ -14,6 +16,7 @@ from classes.frames.settings import FrameSettings
|
|||||||
from classes.toplevel.welcome import ToplevelWelcome
|
from classes.toplevel.welcome import ToplevelWelcome
|
||||||
from modules.theme_titlebar import theme_title_bar
|
from modules.theme_titlebar import theme_title_bar
|
||||||
from modules.utils import configGet, get_string_mode, resize_window, set_icon, use_dark_mode
|
from modules.utils import configGet, get_string_mode, resize_window, set_icon, use_dark_mode
|
||||||
|
from modules.logger import logger
|
||||||
|
|
||||||
|
|
||||||
class App(ThemedTk):
|
class App(ThemedTk):
|
||||||
@ -33,7 +36,7 @@ class App(ThemedTk):
|
|||||||
sv_ttk.init_theme(self)
|
sv_ttk.init_theme(self)
|
||||||
|
|
||||||
if use_dark_mode():
|
if use_dark_mode():
|
||||||
theme_title_bar(self, mode="dark")
|
theme_title_bar(self, mode=Theme.DARK)
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
set_icon(self)
|
set_icon(self)
|
||||||
@ -43,14 +46,11 @@ class App(ThemedTk):
|
|||||||
self.draw_main()
|
self.draw_main()
|
||||||
|
|
||||||
|
|
||||||
def verify_authorization(self):
|
def verify_authorization(self) -> ConnectionState:
|
||||||
try:
|
try:
|
||||||
if requests.get(configGet("address")+"/apikey", headers={"apikey": configGet("apikey")}, verify=not configGet("allow_self_signed")).status_code == 200:
|
return ConnectionState.UNAUTHORIZED if requests.get(configGet("address")+"/apikey", headers={"apikey": configGet("apikey")}, verify=not configGet("allow_self_signed")).status_code == 403 else ConnectionState.OK
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
except:
|
except:
|
||||||
return False
|
return ConnectionState.BAD
|
||||||
|
|
||||||
def verify_saves_dir(self):
|
def verify_saves_dir(self):
|
||||||
|
|
||||||
@ -63,7 +63,14 @@ class App(ThemedTk):
|
|||||||
def frame_saves(self):
|
def frame_saves(self):
|
||||||
self.grid_rowconfigure(0, weight=1)
|
self.grid_rowconfigure(0, weight=1)
|
||||||
self.grid_columnconfigure(1, weight=1)
|
self.grid_columnconfigure(1, weight=1)
|
||||||
|
try:
|
||||||
self.frame_saves_saves = requests.get(f'{configGet("address")}/saves?only_ids=True&sort={(configGet("prefer_saves").split())[1]}', headers={"apikey": configGet("apikey")}, verify=not configGet("allow_self_signed"))
|
self.frame_saves_saves = requests.get(f'{configGet("address")}/saves?only_ids=True&sort={(configGet("prefer_saves").split())[1]}', headers={"apikey": configGet("apikey")}, verify=not configGet("allow_self_signed"))
|
||||||
|
except Exception as exp:
|
||||||
|
messagebox.showerror(title="Connection error", message=f"We could not reach the server to check for save entries\n\n{exp}")
|
||||||
|
logger.error(format_exc())
|
||||||
|
self.frame_saves_object = FrameErrorConnection(self)
|
||||||
|
self.frame_saves_object.grid(column=1, row=0, sticky=NSEW)
|
||||||
|
return
|
||||||
if self.frame_saves_saves.status_code == 200 and isinstance(self.frame_saves_saves.json(), list) is True and len(self.frame_saves_saves.json()) > 0:
|
if self.frame_saves_saves.status_code == 200 and isinstance(self.frame_saves_saves.json(), list) is True and len(self.frame_saves_saves.json()) > 0:
|
||||||
self.frame_saves_object = FrameSaves(self, self.frame_saves_saves.json(), vscroll=True)
|
self.frame_saves_object = FrameSaves(self, self.frame_saves_saves.json(), vscroll=True)
|
||||||
else:
|
else:
|
||||||
@ -74,7 +81,14 @@ class App(ThemedTk):
|
|||||||
def frame_devices(self):
|
def frame_devices(self):
|
||||||
self.grid_rowconfigure(0, weight=1)
|
self.grid_rowconfigure(0, weight=1)
|
||||||
self.grid_columnconfigure(1, weight=1)
|
self.grid_columnconfigure(1, weight=1)
|
||||||
|
try:
|
||||||
self.frame_devices_devices = requests.get(f'{configGet("address")}/devices', headers={"apikey": configGet("apikey")}, verify=not configGet("allow_self_signed"))
|
self.frame_devices_devices = requests.get(f'{configGet("address")}/devices', headers={"apikey": configGet("apikey")}, verify=not configGet("allow_self_signed"))
|
||||||
|
except Exception as exp:
|
||||||
|
messagebox.showerror(title="Connection error", message=f"We could not reach the server to check the devices list\n\n{exp}")
|
||||||
|
logger.error(format_exc())
|
||||||
|
self.frame_devices_object = FrameErrorConnection(self)
|
||||||
|
self.frame_devices_object.grid(column=1, row=0, sticky=NSEW)
|
||||||
|
return
|
||||||
if self.frame_devices_devices.status_code == 200 and isinstance(self.frame_devices_devices.json(), list) is True and len(self.frame_devices_devices.json()) > 0:
|
if self.frame_devices_devices.status_code == 200 and isinstance(self.frame_devices_devices.json(), list) is True and len(self.frame_devices_devices.json()) > 0:
|
||||||
self.frame_devices_object = FrameDevices(self, self.frame_devices_devices.json(), vscroll=True)
|
self.frame_devices_object = FrameDevices(self, self.frame_devices_devices.json(), vscroll=True)
|
||||||
else:
|
else:
|
||||||
@ -136,14 +150,19 @@ class App(ThemedTk):
|
|||||||
# messagebox.showerror(title="Configuration error", message="Your client is not properly configured.")
|
# messagebox.showerror(title="Configuration error", message="Your client is not properly configured.")
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.verify_authorization() is False:
|
self.verified = self.verify_authorization()
|
||||||
|
|
||||||
|
if self.verified in [ConnectionState.BAD, ConnectionState.UNAUTHORIZED]:
|
||||||
self.item_saves.state(["disabled"])
|
self.item_saves.state(["disabled"])
|
||||||
self.item_devices.state(["disabled"])
|
self.item_devices.state(["disabled"])
|
||||||
self.grid_rowconfigure(0, weight=1)
|
self.grid_rowconfigure(0, weight=1)
|
||||||
self.grid_columnconfigure(1, weight=1)
|
self.grid_columnconfigure(1, weight=1)
|
||||||
self.connection_error = FrameErrorConnection(self)
|
self.connection_error = FrameErrorConnection(self)
|
||||||
self.connection_error.grid(column=1, row=0, rowspan=2, sticky=N+S+W+E)
|
self.connection_error.grid(column=1, row=0, rowspan=2, sticky=N+S+W+E)
|
||||||
|
if self.verified == ConnectionState.UNAUTHORIZED:
|
||||||
messagebox.showerror(title="Authentication error", message="Your API key seems to be invalid.")
|
messagebox.showerror(title="Authentication error", message="Your API key seems to be invalid.")
|
||||||
|
else:
|
||||||
|
messagebox.showerror(title="Connection error", message="Server is not reachable or your client configuration is incorrect. Please check your network connection and client configuration.")
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.verify_saves_dir() is False:
|
if self.verify_saves_dir() is False:
|
||||||
|
24
classes/enums.py
Normal file
24
classes/enums.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
class SavesPreference(Enum):
|
||||||
|
LATEST_UPLOAD = "latest upload"
|
||||||
|
LATEST_PROGRESS = "latest progress"
|
||||||
|
|
||||||
|
class SavesPreferenceButton(Enum):
|
||||||
|
LATEST_UPLOAD = "Latest upload "
|
||||||
|
LATEST_PROGRESS = "Latest progress "
|
||||||
|
|
||||||
|
class Theme(Enum):
|
||||||
|
AUTO = "auto"
|
||||||
|
LIGHT = "light"
|
||||||
|
DARK = "dark"
|
||||||
|
|
||||||
|
class ThemeButton(Enum):
|
||||||
|
AUTO = "Auto "
|
||||||
|
LIGHT = "Light "
|
||||||
|
DARK = "Dark "
|
||||||
|
|
||||||
|
class ConnectionState(Enum):
|
||||||
|
OK = "ok"
|
||||||
|
BAD = "bad"
|
||||||
|
UNAUTHORIZED = "unauthorized"
|
@ -11,13 +11,13 @@ from modules.utils import configGet, get_string_mode
|
|||||||
|
|
||||||
def try_connecting(master: Any):
|
def try_connecting(master: Any):
|
||||||
try:
|
try:
|
||||||
if requests.get(configGet("address")+"/apikey", headers={"apikey": configGet("apikey")}, verify=not configGet("allow_self_signed")).status_code != 200:
|
if requests.get(configGet("address")+"/apikey", headers={"apikey": configGet("apikey")}, verify=not configGet("allow_self_signed")).status_code == 403:
|
||||||
messagebox.showerror(title="Authentication error", message="Your API key seems to be invalid.")
|
messagebox.showerror(title="Authentication error", message="Your API key seems to be invalid.")
|
||||||
return
|
return
|
||||||
# messagebox.showinfo(title="Connection succeeded", message="Server is reachable, apikey is valid, so your client is now ready to be used!")
|
# messagebox.showinfo(title="Connection succeeded", message="Server is reachable, apikey is valid, so your client is now ready to be used!")
|
||||||
master.destroy_everything()
|
master.destroy_everything()
|
||||||
except:
|
except:
|
||||||
messagebox.showerror(title="Configuration error", message="Your client configuration is incorrect.")
|
messagebox.showerror(title="Connection error", message="Server is not reachable or your client configuration is incorrect. Please check your network connection and client configuration.")
|
||||||
# master.destroy_everything()
|
# master.destroy_everything()
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ from tkinter import N, NSEW, S, W, E, END, IntVar, StringVar, filedialog, messag
|
|||||||
|
|
||||||
from ttkthemes import ThemedTk
|
from ttkthemes import ThemedTk
|
||||||
from classes.custom.themed_frame import ThemedFrame
|
from classes.custom.themed_frame import ThemedFrame
|
||||||
|
from classes.enums import SavesPreference, SavesPreferenceButton, Theme
|
||||||
from modules.theme_titlebar import theme_title_bar
|
from modules.theme_titlebar import theme_title_bar
|
||||||
|
|
||||||
from modules.utils import configGet, configSet, get_string_mode, use_dark_mode
|
from modules.utils import configGet, configSet, get_string_mode, use_dark_mode
|
||||||
@ -92,10 +93,10 @@ class FrameSettings(ThemedFrame):
|
|||||||
self.saves_preference_label = ttk.Label(self, text="Saves preference:")
|
self.saves_preference_label = ttk.Label(self, text="Saves preference:")
|
||||||
self.saves_preference_label.grid(column=0, row=4, sticky=W, padx=9, pady=9)
|
self.saves_preference_label.grid(column=0, row=4, sticky=W, padx=9, pady=9)
|
||||||
|
|
||||||
self.default_preference = "Latest upload " if configGet("prefer_saves") == "latest upload" else "Latest progress "
|
self.default_preference = SavesPreferenceButton.LATEST_UPLOAD.value if configGet("prefer_saves") == SavesPreference.LATEST_UPLOAD.value else SavesPreferenceButton.LATEST_PROGRESS.value
|
||||||
|
|
||||||
self.chosen_preference = StringVar()
|
self.chosen_preference = StringVar()
|
||||||
self.preferences = ("Latest upload ", "Latest progress ")
|
self.preferences = (SavesPreferenceButton.LATEST_UPLOAD.value, SavesPreferenceButton.LATEST_PROGRESS.value)
|
||||||
self.saves_preference_button = ttk.OptionMenu(self, self.chosen_preference, self.default_preference, *self.preferences, direction="below")
|
self.saves_preference_button = ttk.OptionMenu(self, self.chosen_preference, self.default_preference, *self.preferences, direction="below")
|
||||||
self.saves_preference_button.grid(column=1, row=4, sticky=W, padx=9, pady=9)
|
self.saves_preference_button.grid(column=1, row=4, sticky=W, padx=9, pady=9)
|
||||||
# ================
|
# ================
|
||||||
@ -127,10 +128,13 @@ class FrameSettings(ThemedFrame):
|
|||||||
|
|
||||||
def change_theme(self, *args):
|
def change_theme(self, *args):
|
||||||
|
|
||||||
if self.chosen_theme.get().strip().lower() == "auto":
|
if self.chosen_theme.get().strip().lower() == Theme.AUTO.value:
|
||||||
self.chosen_theme_real = "dark" if use_dark_mode(no_config=True) is True else "light"
|
self.chosen_theme_real = Theme.DARK if use_dark_mode(no_config=True) is True else Theme.LIGHT
|
||||||
else:
|
else:
|
||||||
self.chosen_theme_real = self.chosen_theme.get().strip().lower()
|
if self.chosen_theme.get().strip().lower() == Theme.LIGHT.value:
|
||||||
|
self.chosen_theme_real = Theme.LIGHT
|
||||||
|
else:
|
||||||
|
self.chosen_theme_real = Theme.DARK
|
||||||
theme_title_bar(self.master, self.chosen_theme_real)
|
theme_title_bar(self.master, self.chosen_theme_real)
|
||||||
|
|
||||||
def select_location(self, entry: ttk.Entry):
|
def select_location(self, entry: ttk.Entry):
|
||||||
|
@ -9,6 +9,7 @@ from classes.custom.image_label import ImageLabel
|
|||||||
from classes.custom.themed_frame import ThemedFrame
|
from classes.custom.themed_frame import ThemedFrame
|
||||||
|
|
||||||
from classes.custom.themed_toplevel import ThemedToplevel
|
from classes.custom.themed_toplevel import ThemedToplevel
|
||||||
|
from classes.enums import Theme
|
||||||
from modules.logger import logger
|
from modules.logger import logger
|
||||||
from modules.theme_titlebar import theme_title_bar
|
from modules.theme_titlebar import theme_title_bar
|
||||||
from modules.utils import configGet, configSet, resize_window, set_icon, use_dark_mode
|
from modules.utils import configGet, configSet, resize_window, set_icon, use_dark_mode
|
||||||
@ -31,7 +32,7 @@ class ToplevelWelcome(ThemedToplevel):
|
|||||||
sv_ttk.init_theme(self)
|
sv_ttk.init_theme(self)
|
||||||
|
|
||||||
if use_dark_mode():
|
if use_dark_mode():
|
||||||
theme_title_bar(self, mode="dark")
|
theme_title_bar(self, mode=Theme.DARK)
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
set_icon(self)
|
set_icon(self)
|
||||||
@ -287,20 +288,23 @@ class ToplevelWelcome(ThemedToplevel):
|
|||||||
|
|
||||||
def change_theme(self, *args):
|
def change_theme(self, *args):
|
||||||
|
|
||||||
if self.stage_option_menu_var.get().strip().lower() == "auto":
|
if self.stage_option_menu_var.get().strip().lower() == Theme.AUTO.value:
|
||||||
self.stage_option_menu_var_real = "dark" if use_dark_mode(no_config=True) is True else "light"
|
self.stage_option_menu_var_real = Theme.DARK if use_dark_mode(no_config=True) is True else Theme.LIGHT
|
||||||
else:
|
else:
|
||||||
self.stage_option_menu_var_real = self.stage_option_menu_var.get().strip().lower()
|
if self.stage_option_menu_var.get().strip().lower() == Theme.LIGHT.value:
|
||||||
|
self.stage_option_menu_var_real = Theme.LIGHT
|
||||||
|
else:
|
||||||
|
self.stage_option_menu_var_real = Theme.DARK
|
||||||
theme_title_bar(self, self.stage_option_menu_var_real)
|
theme_title_bar(self, self.stage_option_menu_var_real)
|
||||||
theme_title_bar(self.master, self.stage_option_menu_var_real)
|
theme_title_bar(self.master, self.stage_option_menu_var_real)
|
||||||
|
|
||||||
def stage_theme_validate(self):
|
def stage_theme_validate(self):
|
||||||
|
|
||||||
if self.stage_option_menu_var.get().strip().lower() == "auto":
|
if self.stage_option_menu_var.get().strip().lower() == Theme.AUTO.value:
|
||||||
configSet(["dark_mode_auto"], True)
|
configSet(["dark_mode_auto"], True)
|
||||||
else:
|
else:
|
||||||
configSet(["dark_mode_auto"], False)
|
configSet(["dark_mode_auto"], False)
|
||||||
if self.stage_option_menu_var.get().strip().lower() == "dark":
|
if self.stage_option_menu_var.get().strip().lower() == Theme.DARK.value:
|
||||||
configSet(["dark_mode"], True)
|
configSet(["dark_mode"], True)
|
||||||
else:
|
else:
|
||||||
configSet(["dark_mode"], False)
|
configSet(["dark_mode"], False)
|
||||||
|
@ -3,25 +3,27 @@ import sys
|
|||||||
import sv_ttk
|
import sv_ttk
|
||||||
from distutils.version import StrictVersion as Version
|
from distutils.version import StrictVersion as Version
|
||||||
from os import system
|
from os import system
|
||||||
from tkinter import Tcl, Toplevel
|
from tkinter import Misc, Tcl, Toplevel
|
||||||
from typing import Literal, Union
|
from typing import Literal, Union
|
||||||
|
|
||||||
from ttkthemes import ThemedTk
|
from ttkthemes import ThemedTk
|
||||||
|
|
||||||
|
from classes.enums import Theme
|
||||||
|
|
||||||
if sys.platform.startswith("win"):
|
if sys.platform.startswith("win"):
|
||||||
from ctypes import byref, c_int, sizeof, windll
|
from ctypes import byref, c_int, sizeof, windll
|
||||||
|
|
||||||
|
|
||||||
def theme_title_bar(window: Union[ThemedTk, Toplevel], mode: Literal["dark", "light"]) -> None:
|
def theme_title_bar(window: Union[ThemedTk, Toplevel, Misc], mode: Literal[Theme.DARK, Theme.LIGHT]) -> None:
|
||||||
"""
|
"""
|
||||||
MORE INFO:
|
MORE INFO:
|
||||||
https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
|
https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if mode == "dark":
|
if mode.value == "dark":
|
||||||
value = 1
|
value = 1
|
||||||
#window.configure(background="#1c1c1c")
|
#window.configure(background="#1c1c1c")
|
||||||
elif mode == "light":
|
elif mode.value == "light":
|
||||||
value = 0
|
value = 0
|
||||||
#window.configure(background="#ffffff")
|
#window.configure(background="#ffffff")
|
||||||
else:
|
else:
|
||||||
@ -29,7 +31,7 @@ def theme_title_bar(window: Union[ThemedTk, Toplevel], mode: Literal["dark", "li
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
sv_ttk.set_theme(mode)
|
sv_ttk.set_theme(mode.value)
|
||||||
|
|
||||||
window.update()
|
window.update()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user