SyncTk/src/classes/app.py

197 lines
8.8 KiB
Python
Raw Normal View History

2023-01-22 01:35:32 +02:00
from os import path
2023-01-23 13:22:54 +02:00
from tkinter import NSEW, NW, E, N, S, W, PhotoImage, messagebox, ttk
2023-01-26 14:29:30 +02:00
from traceback import format_exc
2023-01-22 01:35:32 +02:00
2023-01-22 01:22:08 +02:00
import requests
import sv_ttk
from ttkthemes import ThemedTk
2023-01-22 01:35:32 +02:00
2023-01-23 01:13:30 +02:00
from classes.custom.scrollable_frame import FIT_HEIGHT, FIT_WIDTH
from classes.custom.themed_frame import ThemedFrame
2023-01-26 14:29:30 +02:00
from classes.enums import ConnectionState, Theme
2023-01-23 01:13:30 +02:00
from classes.frames.devices import FrameDevices, FrameDevicesEmpty
2023-01-24 16:27:07 +02:00
from classes.frames.errors import FrameErrorConnection, FrameErrorFirstStart, FrameErrorSavesFolder, FrameErrorUnconfigured
2023-01-29 13:30:40 +02:00
from classes.frames.saves import FrameSaves
2023-01-22 18:53:55 +02:00
from classes.frames.settings import FrameSettings
2023-01-22 21:06:55 +02:00
from classes.toplevel.welcome import ToplevelWelcome
2023-01-22 01:35:32 +02:00
from modules.theme_titlebar import theme_title_bar
2023-01-23 17:38:47 +02:00
from modules.utils import configGet, get_string_mode, resize_window, set_icon, use_dark_mode
2023-01-26 14:29:30 +02:00
from modules.logger import logger
2023-01-22 01:35:32 +02:00
2023-01-22 01:22:08 +02:00
class App(ThemedTk):
def __init__(self):
super().__init__()
2023-01-23 01:13:30 +02:00
self.__version__ = "0.1.0"
2023-01-23 17:38:47 +02:00
resize_window(self, 610, 400)
2023-01-26 12:10:25 +02:00
self.resizable(True, True)
2023-01-25 17:23:18 +02:00
self.minsize(610, 200)
2023-01-22 01:22:08 +02:00
self.title("Stardew Sync")
2023-01-22 18:53:55 +02:00
2023-01-22 01:22:08 +02:00
sv_ttk.init_theme(self)
if use_dark_mode():
2023-01-26 14:29:30 +02:00
theme_title_bar(self, mode=Theme.DARK)
2023-01-22 18:53:55 +02:00
self.update()
2023-01-22 01:22:08 +02:00
2023-01-23 13:22:54 +02:00
set_icon(self)
2023-01-22 01:22:08 +02:00
2023-01-22 18:53:55 +02:00
self.focus_set()
2023-01-22 01:22:08 +02:00
2023-01-22 18:53:55 +02:00
self.draw_main()
2023-01-22 01:22:08 +02:00
2023-01-26 14:29:30 +02:00
def verify_authorization(self) -> ConnectionState:
2023-01-22 01:22:08 +02:00
try:
2023-01-26 14:29:30 +02:00
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
2023-01-22 18:53:55 +02:00
except:
2023-01-26 14:29:30 +02:00
return ConnectionState.BAD
2023-01-22 01:22:08 +02:00
2023-01-22 18:53:55 +02:00
def verify_saves_dir(self):
2023-01-22 01:22:08 +02:00
2023-01-22 18:53:55 +02:00
if configGet("saves_location") is None or path.exists(configGet("saves_location")) is False:
return False
else:
return True
2023-01-22 01:22:08 +02:00
def frame_saves(self):
2023-01-23 01:13:30 +02:00
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
2023-01-29 13:30:40 +02:00
# 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"))
# 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:
# self.frame_saves_object = FrameSaves(self, self.frame_saves_saves.json(), vscroll=True)
# else:
# self.frame_saves_object = FrameSaves(self, [], vscroll=True)
self.frame_saves_object = FrameSaves(self, vscroll=True)
2023-01-23 01:13:30 +02:00
self.frame_saves_object.grid(column=1, row=0, sticky=NSEW)
2023-01-22 01:22:08 +02:00
return
def frame_devices(self):
2023-01-23 01:13:30 +02:00
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
2023-01-26 14:29:30 +02:00
try:
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
2023-01-23 01:13:30 +02:00
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)
else:
self.frame_devices_object = FrameDevicesEmpty(self)
self.frame_devices_object.grid(column=1, row=0, sticky=NSEW)
2023-01-22 01:22:08 +02:00
return
def frame_settings(self):
2023-01-23 01:13:30 +02:00
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
2023-01-22 01:22:08 +02:00
self.frame_settings_object = FrameSettings(self)
self.frame_settings_object.grid(column=1, row=0, sticky=N+S+W+E)
return
def draw_main(self):
2023-01-22 18:53:55 +02:00
sv_ttk.set_theme(get_string_mode())
2023-01-22 01:22:08 +02:00
2023-01-22 18:53:55 +02:00
# self.grid_rowconfigure(1, weight=2)
# self.grid_rowconfigure(0, weight=2)
# self.grid_columnconfigure(1, weight=1)
# self.setup_label = ttk.Label(self, text="Your client seems to be unconfigured")
# self.setup_label.grid(column=1, row=0, padx=9, pady=9, sticky=S)
# self.setup_button = ttk.Button(self, text="Set up", style="Accent.TButton", width=10, command=self.open_window_config)
# self.setup_button.grid(column=1, row=1, padx=9, pady=9, sticky=N)
# return
2023-01-22 21:06:55 +02:00
if configGet("first_run") is True:
self.welcome_window = ToplevelWelcome(self)
self.welcome_window.grab_set()
2023-01-22 01:22:08 +02:00
2023-01-22 18:53:55 +02:00
self.frame_sidebar = ThemedFrame(self)
self.frame_sidebar.grid(column=0, row=0, columnspan=1, sticky=N+S+W+E)
2023-01-22 01:22:08 +02:00
self.item_saves = ttk.Button(self.frame_sidebar, text="Saves", width=10, command=self.frame_saves)
self.item_saves.grid(column=0, row=0, sticky=W, padx=9, pady=9)
self.item_devices = ttk.Button(self.frame_sidebar, text="Devices", width=10, command=self.frame_devices)
self.item_devices.grid(column=0, row=1, sticky=W, padx=9, pady=3)
self.item_settings = ttk.Button(self.frame_sidebar, text="Settings", width=10, command=self.frame_settings)
self.item_settings.grid(column=0, row=2, sticky=W+S, padx=9, pady=9)
2023-01-22 18:53:55 +02:00
2023-01-24 16:27:07 +02:00
if configGet("first_run") is True:
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
self.connection_error = FrameErrorFirstStart(self)
self.connection_error.grid(column=1, row=0, rowspan=2, sticky=N+S+W+E)
return
2023-01-22 18:53:55 +02:00
if configGet("address") in ["", None] or configGet("apikey") in ["", None]:
self.item_saves.state(["disabled"])
self.item_devices.state(["disabled"])
2023-01-23 01:13:30 +02:00
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
2023-01-22 18:53:55 +02:00
self.connection_error = FrameErrorUnconfigured(self)
self.connection_error.grid(column=1, row=0, rowspan=2, sticky=N+S+W+E)
# messagebox.showerror(title="Configuration error", message="Your client is not properly configured.")
return
2023-01-26 14:29:30 +02:00
self.verified = self.verify_authorization()
if self.verified in [ConnectionState.BAD, ConnectionState.UNAUTHORIZED]:
2023-01-22 18:53:55 +02:00
self.item_saves.state(["disabled"])
self.item_devices.state(["disabled"])
2023-01-23 01:13:30 +02:00
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
2023-01-22 18:53:55 +02:00
self.connection_error = FrameErrorConnection(self)
self.connection_error.grid(column=1, row=0, rowspan=2, sticky=N+S+W+E)
2023-01-26 14:29:30 +02:00
if self.verified == ConnectionState.UNAUTHORIZED:
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.")
2023-01-22 18:53:55 +02:00
return
2023-01-22 01:22:08 +02:00
2023-01-22 18:53:55 +02:00
if self.verify_saves_dir() is False:
self.item_saves.state(["disabled"])
2023-01-23 01:13:30 +02:00
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
2023-01-22 18:53:55 +02:00
self.connection_error = FrameErrorSavesFolder(self)
self.connection_error.grid(column=1, row=0, rowspan=2, sticky=N+S+W+E)
messagebox.showerror(title="Configuration error", message="Saves folder seems to be invalid.")
return
2023-01-22 01:22:08 +02:00
self.frame_saves()
2023-01-22 18:53:55 +02:00
def destroy_everything(self, draw=True):
2023-01-22 01:22:08 +02:00
for widget in self.winfo_children():
widget.destroy()
2023-01-22 18:53:55 +02:00
if draw is True:
self.draw_main()
# def open_window_config(self):
# window = WindowConfig(self)
# window.grab_set()
# self.setup_button.destroy()
# self.setup_label.destroy()
# self.grid_rowconfigure(1, weight=2)
# self.grid_rowconfigure(0, weight=2)
# self.grid_columnconfigure(1, weight=1)
# ttk.Label(self, text="Client configured, try to connect").grid(column=1, row=0, padx=9, pady=9, sticky=S)
# ttk.Button(self, text="Connect", style="Accent.TButton", width=10, command=self.try_connecting).grid(column=1, row=1, padx=9, pady=9, sticky=N)