-
Notifications
You must be signed in to change notification settings - Fork 0
/
gui_client.py
174 lines (140 loc) · 6.4 KB
/
gui_client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import socket
import threading
import tkinter
from tkinter.constants import S
import tkinter.scrolledtext
from tkinter import Text, simpledialog
from tkinter import filedialog
import time
import os
import json
from cryptography.fernet import Fernet
def write_key():
key = Fernet.generate_key()
with open("key.text", "wb") as key_file:
key_file.write(key)
def load_key():
#Loads the key from the current directory named `key.key`
return open("key.text", "rb").read()
write_key()
key = load_key()
print(key)
fernet = Fernet(key)
HOST = '127.0.0.1'
PORT = 9090
class Client :
def __init__(self,host,port):#parametrized constructor
#AF_INET (address from the internet) refers to the address family ipv4. The SOCK_STREAM means connection oriented TCP protocol.
self.sock = socket.socket(socket.AF_INET , socket.SOCK_STREAM)#Create a socket object
self.sock.connect((host , port))#initiates TCP server connection
msg = tkinter.Tk()
msg.withdraw()
self.nickname = simpledialog.askstring("Nickname","Please choose a nickname", parent =msg)
if self.nickname == 'admin':
self.password = simpledialog.askstring("Password","Please enter a password", parent =msg)
self.gui_done = False
self.running = True
self.stop_thread = False
#creating threads by creating objects of Thread class
gui_thread = threading.Thread(target=self.gui_loop)
receive_thread = threading.Thread(target=self.receive)
#starting threads
gui_thread.start()
receive_thread.start()
def gui_loop(self):
self.win = tkinter.Tk()
self.frame=tkinter.Frame(self.win)
self.frame.pack()
self.win.configure(bg='gray60')
self.frame.configure(bg='gray60')
self.win.title(f'Client Window: {self.nickname}')
self.chat_label =tkinter.Label(self.win , text="Chat:" , bg="gray60")
self.chat_label.config(font=("Arial",12))#used for performing an overwriting over label widget
self.chat_label.pack(padx=20,pady=5)
self.text_area = tkinter.scrolledtext.ScrolledText(self.win , bg="gray80")
self.text_area.pack(padx=20,pady=15)
self.text_area.config(state='disabled')
self.upload_button = tkinter.Button(self.frame , text='Upload',command=self.write , bg="gray95")
self.upload_button.config(font=("Arial",12))
self.upload_button.pack(side=tkinter.LEFT,padx=0,pady=5)
self.download_button = tkinter.Button(self.frame , text='Download',command=self.write , bg="gray95")
self.download_button.config(font=("Arial",12))
self.download_button.pack(side=tkinter.RIGHT, padx=90,pady=5)
self.msg_label =tkinter.Label(self.win , text="Message:" , bg="gray60")
self.msg_label.config(font=("Arial",12))
self.msg_label.pack(padx=20,pady=5)
self.input_area =tkinter.Text(self.win,height=3 , bg="gray80")
self.input_area.pack(padx=2,pady=5)
self.send_button = tkinter.Button(self.win , text='send',command=self.write , bg="gray95")
self.send_button.config(font=("Arial",12))
self.send_button.pack(padx=20,pady=5)
self.gui_done=True
self.win.protocol("WM_DELETE_WINDOW",self.stop)
self.win.mainloop()
def write(self):
if self.stop_thread == False:
message = f"{self.nickname}:{self.input_area.get('1.0','end')}"
if message[len(self.nickname)+1:].startswith('/'):
#username: /action
if self.nickname == 'admin':
if message[len(self.nickname)+1:].startswith('/kick'):
msg = f'KICK {message[len(self.nickname)+1+6:]}'.encode('utf-8')#transmits TCP message
encMessage= fernet.encrypt(msg)
self.sock.send(encMessage)
elif message[len(self.nickname)+1:].startswith('/ban'):
msg = f'BAN {message[len(self.nickname)+1+5:]}'.encode('utf-8')
encMessage= fernet.encrypt(msg)
self.sock.send(encMessage)
else:
msg = 'actions only done by admin'.encode('utf-8')
encMessage= fernet.encrypt(msg)
self.sock.send(encMessage)
else:
msg = message.encode('utf-8')
encMessage= fernet.encrypt(msg)
print(encMessage)
self.sock.send(encMessage)#transmits TCP message
self.input_area.delete('1.0','end')
def stop(self):
self.running = False
self.win.destroy()
self.sock.close()
exit(0)
def UploadFun(self):
self.filename = filedialog.askopenfilename()
print('Selected:', filename)
def receive(self):
while self.running:
if self.stop_thread:
break
try:
# Receive Message From Server
# If 'NICK' Send Nickname
message = self.sock.recv(1024).decode('utf-8')
if message == "Key":
print(key)
self.sock.send(key)
elif message == 'NICK':
self.sock.send(self.nickname.encode('utf-8'))
next_message = self.sock.recv(1024).decode('utf-8')
if next_message == 'PASS':
self.sock.send(self.password.encode('utf-8'))
if self.sock.recv(1024).decode('utf-8') == 'REFUSE':
self.sock.send("Connection refused! Wrong Password!".encode('utf-8'))
self.stop_thread = True
elif next_message == 'BAN':
self.sock.send('connection refused because you were ban!'.encode('utf-8'))
self.sock.close()
self.stop_thread = True
else:
if self.gui_done:
self.text_area.config(state='normal')
self.text_area.insert('end',message)
self.text_area.yview('end')
self.text_area.config(state='disabled')
except:
# Close Connection When Error
print("An error occured!")
self.sock.close()
break
cliet = Client(HOST,PORT)