148 lines
7.4 KiB
Python
148 lines
7.4 KiB
Python
|
import platform
|
||
|
from datetime import datetime
|
||
|
from functools import partial
|
||
|
from tkinter import LEFT, NSEW, E, Misc, W, messagebox, ttk
|
||
|
from tkinter.messagebox import askyesno
|
||
|
from urllib.parse import quote, urlencode
|
||
|
|
||
|
import requests
|
||
|
|
||
|
from classes.custom.themed_frame import ThemedFrame
|
||
|
from modules.logger import logger
|
||
|
from modules.utils import configGet, configSet
|
||
|
|
||
|
|
||
|
class FrameDevice(ThemedFrame):
|
||
|
|
||
|
def __init__(self, master: Misc, device_dict: str, **kwargs) -> None:
|
||
|
|
||
|
super().__init__(master, style="Card.TFrame", **kwargs)
|
||
|
|
||
|
self.grid_columnconfigure(0, weight=1)
|
||
|
self.grid_columnconfigure(1, weight=3)
|
||
|
self.grid_columnconfigure(2, weight=3)
|
||
|
|
||
|
self.name = device_dict["name"]
|
||
|
|
||
|
self.title = ttk.Label(self, text=self.name, font=("SunValleyBodyStrongFont", 12, "bold"), justify=LEFT, width=46)
|
||
|
self.title.grid(column=0, row=0, padx=9, pady=9, sticky=W)
|
||
|
|
||
|
last_upload = "N/A" if device_dict["last_save"] == 0 else datetime.utcfromtimestamp(device_dict["last_save"]).strftime("%d.%m.%Y %H:%M")
|
||
|
self.description = ttk.Label(self, text=f'OS: {device_dict["os"]}\nClient: {device_dict["client"]}\nLast upload: {last_upload}', width=46)
|
||
|
self.description.grid(column=0, row=1, padx=9, pady=9, sticky=W)
|
||
|
|
||
|
self.buttons = ThemedFrame(self)
|
||
|
self.buttons.grid(column=0, columnspan=2, row=2, sticky=NSEW, padx=9, pady=9)
|
||
|
self.buttons.grid_columnconfigure(0, weight=1)
|
||
|
|
||
|
self.button_device_rename_action = partial(self.rename)
|
||
|
self.button_device_rename = ttk.Button(self.buttons, text="Rename", width=11, command=self.button_device_rename_action)
|
||
|
self.button_device_rename.grid(column=0, row=0, padx=9, sticky=E)
|
||
|
|
||
|
self.button_device_delete_action = partial(self.delete)
|
||
|
self.button_device_delete = ttk.Button(self.buttons, text="Delete", style="Accent.TButton", width=11, command=self.button_device_delete_action)
|
||
|
self.button_device_delete.grid(column=1, row=0, sticky=W)
|
||
|
|
||
|
if self.name == configGet("name"):
|
||
|
self.button_device_delete.state(["disabled"])
|
||
|
|
||
|
def rename(self):
|
||
|
|
||
|
self.rename_entry = ttk.Entry(self, font=("SunValleyBodyFont", 12), justify=LEFT, width=27)
|
||
|
self.rename_entry.insert(0, self.name)
|
||
|
self.rename_entry.grid(column=0, row=0, padx=9, pady=9, sticky=W)
|
||
|
|
||
|
button_device_cancel_action = partial(self.rename_cancel)
|
||
|
button_device_cancel = ttk.Button(self.buttons, text="Cancel", width=11, command=button_device_cancel_action)
|
||
|
button_device_cancel.grid(column=0, row=0, padx=9, sticky=E)
|
||
|
|
||
|
button_device_save_action = partial(self.rename_verify)
|
||
|
button_device_save = ttk.Button(self.buttons, text="Save", style="Accent.TButton", width=11, command=button_device_save_action)
|
||
|
button_device_save.grid(column=1, row=0, sticky=W)
|
||
|
|
||
|
def rename_verify(self):
|
||
|
|
||
|
self.name_before = configGet("name")
|
||
|
|
||
|
if (self.rename_entry.get().strip() == "") or ("?" in self.rename_entry.get().strip()) or ("/" in self.rename_entry.get().strip()):
|
||
|
logger.error(f"Name {self.rename_entry.get().strip()} is not a valid name")
|
||
|
messagebox.showerror(title="Name error", message="Provided device name is not valid. Please provide a valid one.")
|
||
|
return
|
||
|
|
||
|
try:
|
||
|
quote(self.rename_entry.get().strip())
|
||
|
except:
|
||
|
logger.error(f"Name {self.rename_entry.get().strip()} is not a valid name")
|
||
|
messagebox.showerror(title="Name error", message="Provided device name is not valid. Please provide a valid one.")
|
||
|
return
|
||
|
|
||
|
existing_device_before = requests.get(f'{configGet("address")}/devices/{self.name}', headers={"apikey": configGet("apikey")}, verify=not configGet("allow_self_signed"))
|
||
|
if existing_device_before.status_code == 200:
|
||
|
response = requests.patch(f'{configGet("address")}/devices/{self.name}?{urlencode({"new_name": self.rename_entry.get().strip(), "os": platform.system()+" "+platform.release(), "client": f"SyncTk {self.master.master.master.master.__version__}"})}', headers={"apikey": configGet("apikey")}, verify=not configGet("allow_self_signed"))
|
||
|
if response.status_code != 204:
|
||
|
logger.error(f"Name {self.rename_entry.get().strip()} could not be set because server returned {response.status_code}")
|
||
|
messagebox.showerror(title="Name error", message=f"Provided device name is not valid.\n\nServer response: {response.json()}")
|
||
|
return
|
||
|
else:
|
||
|
logger.error(f"Tried to rename {self.name} into {self.rename_entry.get().strip()} but server returned {existing_device_before.status_code}")
|
||
|
messagebox.showerror(title="Rename error", message="It seems like this device no longer exists.")
|
||
|
return
|
||
|
|
||
|
self.name = self.rename_entry.get().strip()
|
||
|
|
||
|
for widget in self.winfo_children():
|
||
|
if isinstance(widget, ttk.Entry):
|
||
|
widget.destroy()
|
||
|
|
||
|
device_title = ttk.Label(self, text=self.name, font=("SunValleyBodyStrongFont", 12, "bold"), justify=LEFT, width=46)
|
||
|
device_title.grid(column=0, row=0, padx=9, pady=9, sticky=W)
|
||
|
|
||
|
button_device_rename_action = partial(self.rename)
|
||
|
button_device_rename = ttk.Button(self.buttons, text="Rename", width=11, command=button_device_rename_action)
|
||
|
button_device_rename.grid(column=0, row=0, padx=9, sticky=E)
|
||
|
|
||
|
button_device_delete_action = partial(self.delete)
|
||
|
button_device_delete = ttk.Button(self.buttons, text="Delete", style="Accent.TButton", width=11, command=button_device_delete_action)
|
||
|
button_device_delete.grid(column=1, row=0, sticky=W)
|
||
|
|
||
|
if self.name_before == configGet("name"):
|
||
|
configSet(["name"], self.name)
|
||
|
|
||
|
if self.name == configGet("name"):
|
||
|
button_device_delete.state(["disabled"])
|
||
|
|
||
|
def rename_cancel(self):
|
||
|
|
||
|
for widget in self.winfo_children():
|
||
|
if isinstance(widget, ttk.Entry):
|
||
|
widget.destroy()
|
||
|
|
||
|
device_title = ttk.Label(self, text=self.name, font=("SunValleyBodyStrongFont", 12, "bold"), justify=LEFT, width=46)
|
||
|
device_title.grid(column=0, row=0, padx=9, pady=9, sticky=W)
|
||
|
|
||
|
button_device_rename_action = partial(self.rename)
|
||
|
button_device_rename = ttk.Button(self.buttons, text="Rename", width=11, command=button_device_rename_action)
|
||
|
button_device_rename.grid(column=0, row=0, padx=9, sticky=E)
|
||
|
|
||
|
button_device_delete_action = partial(self.delete)
|
||
|
button_device_delete = ttk.Button(self.buttons, text="Delete", style="Accent.TButton", width=11, command=button_device_delete_action)
|
||
|
button_device_delete.grid(column=1, row=0, sticky=W)
|
||
|
|
||
|
if self.name == configGet("name"):
|
||
|
button_device_delete.state(["disabled"])
|
||
|
|
||
|
def delete(self):
|
||
|
|
||
|
decision = askyesno(title="Device removal", message=f"You are about to remove the device '{self.name}' and this will also remove all the save files uploaded by this device. Are you sure you want to continue?")
|
||
|
|
||
|
if decision is False:
|
||
|
return
|
||
|
|
||
|
requests.delete(f'{configGet("address")}/devices/{self.name}', headers={"apikey": configGet("apikey")}, verify=not configGet("allow_self_signed"))
|
||
|
|
||
|
for k in range(len(self.master.devices)):
|
||
|
if self.master.devices[k]["name"] == self.name:
|
||
|
del self.master.devices[k]
|
||
|
break
|
||
|
|
||
|
self.destroy()
|