SyncTk/src/classes/app.py

197 lines
8.8 KiB
Python

from os import path
from tkinter import NSEW, NW, E, N, S, W, PhotoImage, messagebox, ttk
from traceback import format_exc
import requests
import sv_ttk
from ttkthemes import ThemedTk
from classes.custom.scrollable_frame import FIT_HEIGHT, FIT_WIDTH
from classes.custom.themed_frame import ThemedFrame
from classes.enums import ConnectionState, Theme
from classes.frames.devices import FrameDevices, FrameDevicesEmpty
from classes.frames.errors import FrameErrorConnection, FrameErrorFirstStart, FrameErrorSavesFolder, FrameErrorUnconfigured
from classes.frames.saves import FrameSaves
from classes.frames.settings import FrameSettings
from classes.toplevel.welcome import ToplevelWelcome
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.logger import logger
class App(ThemedTk):
def __init__(self):
super().__init__()
self.__version__ = "0.1.0"
resize_window(self, 610, 400)
self.resizable(True, True)
self.minsize(610, 200)
self.title("Stardew Sync")
sv_ttk.init_theme(self)
if use_dark_mode():
theme_title_bar(self, mode=Theme.DARK)
self.update()
set_icon(self)
self.focus_set()
self.draw_main()
def verify_authorization(self) -> ConnectionState:
try:
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
except:
return ConnectionState.BAD
def verify_saves_dir(self):
if configGet("saves_location") is None or path.exists(configGet("saves_location")) is False:
return False
else:
return True
def frame_saves(self):
self.grid_rowconfigure(0, 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"))
# 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)
self.frame_saves_object.grid(column=1, row=0, sticky=NSEW)
return
def frame_devices(self):
self.grid_rowconfigure(0, 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"))
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:
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)
return
def frame_settings(self):
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
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):
sv_ttk.set_theme(get_string_mode())
# 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
if configGet("first_run") is True:
self.welcome_window = ToplevelWelcome(self)
self.welcome_window.grab_set()
self.frame_sidebar = ThemedFrame(self)
self.frame_sidebar.grid(column=0, row=0, columnspan=1, sticky=N+S+W+E)
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)
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
if configGet("address") in ["", None] or configGet("apikey") in ["", None]:
self.item_saves.state(["disabled"])
self.item_devices.state(["disabled"])
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
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
self.verified = self.verify_authorization()
if self.verified in [ConnectionState.BAD, ConnectionState.UNAUTHORIZED]:
self.item_saves.state(["disabled"])
self.item_devices.state(["disabled"])
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
self.connection_error = FrameErrorConnection(self)
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.")
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
if self.verify_saves_dir() is False:
self.item_saves.state(["disabled"])
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
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
self.frame_saves()
def destroy_everything(self, draw=True):
for widget in self.winfo_children():
widget.destroy()
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)