Add GUI
This commit is contained in:
parent
23b4628804
commit
c421933780
16
controller/AppController.py
Normal file
16
controller/AppController.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
from controller.IAppController import *
|
||||||
|
|
||||||
|
class AppController(IAppController):
|
||||||
|
def __init__(self, parser):
|
||||||
|
self.parser = parser
|
||||||
|
self.window_controller = None
|
||||||
|
|
||||||
|
def set_window_controller(self, window_controller):
|
||||||
|
self.window_controller = window_controller
|
||||||
|
|
||||||
|
def on_quit(self):
|
||||||
|
pass
|
||||||
|
# if self.connection.is_connected:
|
||||||
|
# self.connection.send_message(self.parser.buildEXIT())
|
||||||
|
# if self.client_thread != None:
|
||||||
|
# self.client_thread.stop_loop()
|
2
controller/IAppController.py
Normal file
2
controller/IAppController.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
class IAppController:
|
||||||
|
pass
|
2
controller/IMainWindowController.py
Normal file
2
controller/IMainWindowController.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
class IEventHandler:
|
||||||
|
pass
|
10
controller/MainWindowController.py
Normal file
10
controller/MainWindowController.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from controller.IMainWindowController import *
|
||||||
|
|
||||||
|
class MainWindowController(IEventHandler):
|
||||||
|
def __init__(self, parser, app_controller):
|
||||||
|
self.parser = parser
|
||||||
|
self.app_controller = app_controller
|
||||||
|
|
||||||
|
def on_quit(self):
|
||||||
|
self.app_controller.on_quit()
|
||||||
|
pass
|
2
gui/IMainWindow.py
Normal file
2
gui/IMainWindow.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
class IMainWindow:
|
||||||
|
pass
|
144
gui/MainWindow.py
Normal file
144
gui/MainWindow.py
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
import tkinter as tk
|
||||||
|
from tkinter import ttk
|
||||||
|
from tkinter import messagebox
|
||||||
|
from gui.IMainWindow import *
|
||||||
|
|
||||||
|
class MainWindow(IMainWindow):
|
||||||
|
def __init__(self, controller):
|
||||||
|
self.controller = controller
|
||||||
|
self.root = tk.Tk()
|
||||||
|
self.root.title("SecCon - © Louis SWINNEN 2022")
|
||||||
|
self.root.config(bd=5)
|
||||||
|
self.host = tk.StringVar()
|
||||||
|
self.passw = tk.StringVar()
|
||||||
|
self.login = tk.StringVar()
|
||||||
|
self.tls = tk.BooleanVar()
|
||||||
|
self.port = tk.IntVar()
|
||||||
|
self.draw_window()
|
||||||
|
|
||||||
|
def start_main_loop(self):
|
||||||
|
self.tf_host.focus()
|
||||||
|
self.root.mainloop()
|
||||||
|
|
||||||
|
def draw_window(self):
|
||||||
|
self.draw_top_pane()
|
||||||
|
self.draw_center_pane()
|
||||||
|
self.draw_footer_pane()
|
||||||
|
self.not_connected_mode()
|
||||||
|
|
||||||
|
def draw_top_pane(self):
|
||||||
|
top_pane = ttk.LabelFrame(self.root, padding=(3, 3, 12, 12), text=" Connection to FileFrontEnd ")
|
||||||
|
top_pane.pack(fill=tk.X)
|
||||||
|
top_pane.columnconfigure(1, weight=1)
|
||||||
|
|
||||||
|
ttk.Label(top_pane, text="Host:").grid(row=0, column=0, sticky=tk.E)
|
||||||
|
self.tf_host = ttk.Entry(top_pane, textvariable=self.host)
|
||||||
|
self.tf_host.grid(row=0, column=1, sticky=tk.EW, padx=5, pady=5)
|
||||||
|
|
||||||
|
ttk.Label(top_pane, text="Port:").grid(row=0, column=2, sticky=tk.E)
|
||||||
|
self.tf_port = ttk.Entry(top_pane, textvariable=self.port)
|
||||||
|
self.tf_port.grid(row=0, column=3, sticky=tk.EW, padx=5, pady=2)
|
||||||
|
|
||||||
|
ttk.Label(top_pane, text="Login:").grid(row=1, column=0, sticky=tk.E)
|
||||||
|
self.tf_login = ttk.Entry(top_pane, textvariable=self.login)
|
||||||
|
self.tf_login.grid(row=1,column=1, sticky=tk.EW, padx=5, pady=5)
|
||||||
|
|
||||||
|
ttk.Label(top_pane, text="Password:").grid(row=1, column=2, sticky=tk.E)
|
||||||
|
self.tf_password = ttk.Entry(top_pane, show="*", textvariable=self.passw)
|
||||||
|
self.tf_password.grid(row=1,column=3, sticky=tk.EW, padx=5, pady=2)
|
||||||
|
|
||||||
|
inner_frame = ttk.Frame(top_pane)
|
||||||
|
inner_frame.grid(row=2, column=0, columnspan=4, sticky=tk.NSEW)
|
||||||
|
inner_frame.columnconfigure(1,weight=1)
|
||||||
|
|
||||||
|
ttk.Label(inner_frame, text="Security:").grid(row=0, column=0, sticky=tk.E)
|
||||||
|
self.cb_tls = ttk.Checkbutton(inner_frame, text="with SSL/TLS", variable=self.tls)
|
||||||
|
self.cb_tls.grid(row=0, column=1, padx=5, pady=2, sticky=tk.W)
|
||||||
|
self.bt_signup = ttk.Button(inner_frame, text="Sign up", command=self.sign_up)
|
||||||
|
self.bt_signup.grid(row=0, column=2, padx=5, pady=2,sticky=tk.E)
|
||||||
|
self.bt_signin = ttk.Button(inner_frame, text="Sign in", command=self.sign_in)
|
||||||
|
self.bt_signin.grid(row=0, column=3, padx=5, pady=2, sticky=tk.E)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def draw_center_pane(self):
|
||||||
|
title_pane = ttk.Frame(self.root, padding=(5, 0, 5, 0))
|
||||||
|
ttk.Label(title_pane, text="My files:").grid(row=0, column=0, sticky=tk.E)
|
||||||
|
title_pane.pack(fill=tk.X)
|
||||||
|
center_pane = ttk.Frame(self.root, padding=(5, 0, 5, 0))
|
||||||
|
center_pane.pack(fill=tk.BOTH, expand=True)
|
||||||
|
center_pane.columnconfigure(1, weight=1)
|
||||||
|
|
||||||
|
self.scroll = ttk.Scrollbar(center_pane)
|
||||||
|
self.tv_files = ttk.Treeview(center_pane, yscrollcommand=self.scroll.set, height=6)
|
||||||
|
self.tv_files["columns"] = ["Filename", "Size"]
|
||||||
|
self.tv_files["show"] = "headings"
|
||||||
|
self.tv_files.heading("Filename", text="Filename")
|
||||||
|
self.tv_files.heading("Size", text="Filesize")
|
||||||
|
self.tv_files.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, pady=5)
|
||||||
|
self.scroll.config(command=self.tv_files.yview)
|
||||||
|
self.scroll.pack(side=tk.RIGHT, fill=tk.Y, pady=5)
|
||||||
|
|
||||||
|
bottom_pane = ttk.Frame(self.root, padding=(5, 0, 5, 0))
|
||||||
|
bottom_pane.columnconfigure(1, weight=1)
|
||||||
|
self.bt_filelist = ttk.Button(bottom_pane, text="Refresh list", command=self.file_list)
|
||||||
|
self.bt_filelist.grid(row=0, column=0, padx=10, pady=2,sticky=tk.E)
|
||||||
|
self.bt_savefile = ttk.Button(bottom_pane, text="Upload file", command=self.save_file)
|
||||||
|
self.bt_savefile.grid(row=0, column=1, padx=10, pady=2,sticky=tk.E)
|
||||||
|
self.bt_getfile = ttk.Button(bottom_pane, text="Download file", command=self.get_file)
|
||||||
|
self.bt_getfile.grid(row=0, column=2, padx=10, pady=2,sticky=tk.E)
|
||||||
|
self.bt_removefile = ttk.Button(bottom_pane, text="Remove file", command=self.remove_file)
|
||||||
|
self.bt_removefile.grid(row=0, column=3, padx=10, pady=2,sticky=tk.E)
|
||||||
|
bottom_pane.pack(fill=tk.X)
|
||||||
|
|
||||||
|
def draw_footer_pane(self):
|
||||||
|
footer_pane = ttk.Frame(self.root, padding=(5,10,5,0))
|
||||||
|
footer_pane.pack(fill=tk.X)
|
||||||
|
footer_pane.columnconfigure(1, weight=1)
|
||||||
|
self.bt_about = ttk.Button(footer_pane, text="About", command=self.about)
|
||||||
|
self.bt_about.grid(row=0, column=0, pady=3, sticky=tk.E)
|
||||||
|
self.bt_quit = ttk.Button(footer_pane, text="Quit", command=self.quit)
|
||||||
|
self.bt_quit.grid(row=0, column=1, pady=3, sticky=tk.E)
|
||||||
|
|
||||||
|
def not_connected_mode(self):
|
||||||
|
self.bt_filelist.state(["disabled"])
|
||||||
|
self.bt_savefile.state(["disabled"])
|
||||||
|
self.bt_getfile.state(["disabled"])
|
||||||
|
self.bt_removefile.state(["disabled"])
|
||||||
|
|
||||||
|
def connected_mode(self):
|
||||||
|
self.tf_host.state(["disabled"])
|
||||||
|
self.tf_port.state(["disabled"])
|
||||||
|
self.tf_login.state(["disabled"])
|
||||||
|
self.tf_password.state(["disabled"])
|
||||||
|
self.bt_signin.state(["disabled"])
|
||||||
|
self.bt_signup.state(["disabled"])
|
||||||
|
self.cb_tls.state(["disabled"])
|
||||||
|
self.bt_filelist.state(["!disabled"])
|
||||||
|
self.bt_savefile.state(["!disabled"])
|
||||||
|
self.bt_getfile.state(["!disabled"])
|
||||||
|
self.bt_removefile.state(["!disabled"])
|
||||||
|
|
||||||
|
def sign_in(self):
|
||||||
|
pass
|
||||||
|
def sign_up(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def save_file(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_file(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def remove_file(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def file_list(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def about(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def quit(self):
|
||||||
|
self.root.destroy()
|
||||||
|
self.controller.on_quit()
|
11
main.py
11
main.py
@ -1,2 +1,11 @@
|
|||||||
|
from gui.MainWindow import *
|
||||||
|
from controller.MainWindowController import *
|
||||||
|
from controller.AppController import *
|
||||||
|
from model.Protocol import *
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print("Hello World")
|
parser = Protocol()
|
||||||
|
app_controller = AppController(parser)
|
||||||
|
event_handler = MainWindowController(parser, app_controller)
|
||||||
|
window = MainWindow(event_handler)
|
||||||
|
window.start_main_loop()
|
||||||
|
30
model/IProtocol.py
Normal file
30
model/IProtocol.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
class IProtocol:
|
||||||
|
def build_SIGNIN(self, login, password):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def build_SIGNUP(self, login, password):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def build_FILELIST(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def build_SAVEFILE(self, filename, size):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def build_GETFILE(self, filename):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def build_REMOVEFILE(self, filename):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def build_SIGNOUT(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def parse(self, line, debug_enabled):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def parse_FILES(self, line):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def parse_GETFILEOK(self, line):
|
||||||
|
pass
|
90
model/Protocol.py
Normal file
90
model/Protocol.py
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
from model.IProtocol import *
|
||||||
|
import re
|
||||||
|
|
||||||
|
class Protocol(IProtocol):
|
||||||
|
RX_DIGIT = r"[0-9]"
|
||||||
|
RX_SIZE = r"(" + RX_DIGIT + "{1,10})"
|
||||||
|
RX_LINE = r"(\\x0d\\x0a){0,1}"
|
||||||
|
RX_PASSCHAR = r"[\x22-\xff]"
|
||||||
|
RX_BL = r" "
|
||||||
|
RX_FILENAME = r"(" + RX_PASSCHAR + "{1,20})"
|
||||||
|
RX_SIGNOK = r"SIGN_OK" + RX_LINE
|
||||||
|
RX_SIGNERROR = r"SIGN_ERROR" + RX_LINE
|
||||||
|
RX_FILES = r"FILES((" + RX_BL + RX_FILENAME + "!" + RX_SIZE + "){0,50})" + RX_LINE
|
||||||
|
RX_SAVEFILEOK = r"SAVEFILE_OK" + RX_LINE
|
||||||
|
RX_SAVEFILEERROR = r"SAVEFILE_ERROR" + RX_LINE
|
||||||
|
RX_GETFILEOK = r"GETFILE_OK" + RX_BL + RX_FILENAME + RX_BL + RX_SIZE + RX_LINE
|
||||||
|
RX_GETFILEERROR = r"GETFILE_ERROR" + RX_LINE
|
||||||
|
RX_REMOVEFILEOK = r"REMOVEFILE_OK" + RX_LINE
|
||||||
|
RX_REMOVEFILEERROR = r"REMOVEFILE_ERROR" + RX_LINE
|
||||||
|
ALL_MESSAGES = [RX_SIGNOK, RX_SIGNERROR, RX_FILES, RX_SAVEFILEOK, RX_SAVEFILEERROR, RX_GETFILEOK, RX_GETFILEERROR, RX_REMOVEFILEOK, RX_REMOVEFILEERROR]
|
||||||
|
PARSE_UNKNOWN = -1
|
||||||
|
PARSE_SIGNOK = 0
|
||||||
|
PARSE_SIGNERROR = 1
|
||||||
|
PARSE_FILES = 2
|
||||||
|
PARSE_SAVEFILEOK = 3
|
||||||
|
PARSE_SAVEFILEERROR = 4
|
||||||
|
PARSE_GETFILEOK = 5
|
||||||
|
PARSE_GETFILEERROR = 6
|
||||||
|
PARSE_REMOVEFILEOK = 7
|
||||||
|
PARSE_REMOVEFILEERROR = 8
|
||||||
|
|
||||||
|
MSG_CLIENT_SIGNIN = "SIGNIN <login> <password>\r\n"
|
||||||
|
MSG_CLIENT_SIGNUP = "SIGNUP <login> <password>\r\n"
|
||||||
|
MSG_CLIENT_FILELIST = "FILELIST\r\n"
|
||||||
|
MSG_CLIENT_SAVEFILE = "SAVEFILE <filename> <size>\r\n"
|
||||||
|
MSG_CLIENT_GETFILE = "GETFILE <filename>\r\n"
|
||||||
|
MSG_CLIENT_REMOVEFILE = "REMOVEFILE <filename>\r\n"
|
||||||
|
MSG_CLIENT_SIGNOUT = "SIGNOUT\r\n"
|
||||||
|
|
||||||
|
def build_SIGNIN(self, login, password):
|
||||||
|
return Protocol.MSG_CLIENT_SIGNIN.replace("<login>", login).replace("<password>", password)
|
||||||
|
|
||||||
|
def build_SIGNUP(self, login, password):
|
||||||
|
return Protocol.MSG_CLIENT_SIGNUP.replace("<login>", login).replace("<password>", password)
|
||||||
|
|
||||||
|
def build_FILELIST(self):
|
||||||
|
return Protocol.MSG_CLIENT_FILELIST
|
||||||
|
|
||||||
|
def build_SAVEFILE(self, filename, size):
|
||||||
|
return Protocol.MSG_CLIENT_SAVEFILE.replace("<filename>", filename).replace("<size>", str(size))
|
||||||
|
|
||||||
|
def build_GETFILE(self, filename):
|
||||||
|
return Protocol.MSG_CLIENT_GETFILE.replace("<filename>", filename)
|
||||||
|
|
||||||
|
def build_REMOVEFILE(self, filename):
|
||||||
|
return Protocol.MSG_CLIENT_REMOVEFILE.replace("<filename>", filename)
|
||||||
|
|
||||||
|
def build_SIGNOUT(self):
|
||||||
|
return Protocol.MSG_CLIENT_SIGNOUT
|
||||||
|
|
||||||
|
def parse(self, line, debug_enabled):
|
||||||
|
for i in range(len(Protocol.ALL_MESSAGES)):
|
||||||
|
if(re.match(Protocol.ALL_MESSAGES[i], line) != None):
|
||||||
|
if(debug_enabled):
|
||||||
|
print("OK REGEXP:" + Protocol.ALL_MESSAGES[i])
|
||||||
|
return i
|
||||||
|
else:
|
||||||
|
if(debug_enabled):
|
||||||
|
print("KO REGEXP:" + Protocol.ALL_MESSAGES[i])
|
||||||
|
return Protocol.PARSE_UNKNOWN
|
||||||
|
|
||||||
|
def parse_FILES(self, line):
|
||||||
|
if(self.parse(line, False) == Protocol.PARSE_FILES):
|
||||||
|
tokens = re.match(Protocol.RX_FILES, line)
|
||||||
|
return [tokens[1]]
|
||||||
|
return None
|
||||||
|
|
||||||
|
def parse_GETFILEOK(self, line):
|
||||||
|
if(self.parse(line, False) == Protocol.PARSE_GETFILEOK):
|
||||||
|
tokens = re.match(Protocol.RX_GETFILEOK, line)
|
||||||
|
return [tokens[1], tokens[2]]
|
||||||
|
return None
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
protocol = Protocol()
|
||||||
|
line = input("> ")
|
||||||
|
while(line != ""):
|
||||||
|
val = protocol.parse(line, True)
|
||||||
|
print("Val =" + str(val))
|
||||||
|
line = input("> ")
|
Loading…
Reference in New Issue
Block a user