2023-01-25 17:23:18 +02:00
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
2023-01-26 12:10:49 +02:00
from modules . utils import configGet , configSet , osname
2023-01-25 17:23:18 +02:00
class FrameDevice ( ThemedFrame ) :
def __init__ ( self , master : Misc , device_dict : str , * * kwargs ) - > None :
super ( ) . __init__ ( master , style = " Card.TFrame " , * * kwargs )
2023-01-26 12:10:49 +02:00
self . widget_width = 47 if osname == " nt " else 42
2023-01-25 17:23:18 +02:00
self . grid_columnconfigure ( 0 , weight = 1 )
self . grid_columnconfigure ( 1 , weight = 3 )
self . grid_columnconfigure ( 2 , weight = 3 )
self . name = device_dict [ " name " ]
2023-01-26 12:10:49 +02:00
self . title = ttk . Label ( self , text = self . name , font = ( " SunValleyBodyStrongFont " , 12 , " bold " ) , justify = LEFT , width = self . widget_width )
2023-01-25 17:23:18 +02:00
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 " )
2023-01-26 12:10:49 +02:00
self . description = ttk . Label ( self , text = f ' OS: { device_dict [ " os " ] } \n Client: { device_dict [ " client " ] } \n Last upload: { last_upload } ' , width = self . widget_width )
2023-01-25 17:23:18 +02:00
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 \n Server 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 ( )
2023-01-26 12:10:49 +02:00
device_title = ttk . Label ( self , text = self . name , font = ( " SunValleyBodyStrongFont " , 12 , " bold " ) , justify = LEFT , width = self . widget_width )
2023-01-25 17:23:18 +02:00
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 ( )
2023-01-26 12:10:49 +02:00
device_title = ttk . Label ( self , text = self . name , font = ( " SunValleyBodyStrongFont " , 12 , " bold " ) , justify = LEFT , width = self . widget_width )
2023-01-25 17:23:18 +02:00
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 ( )