-
Notifications
You must be signed in to change notification settings - Fork 0
/
client.py
executable file
·163 lines (116 loc) · 4.67 KB
/
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
# -*- coding: utf-8 -*-
import sys
if sys.version_info[0] != 3:
print("You need to run this with Python 3!")
sys.exit(1)
'''
KTN-project 2013 / 2014
'''
import socket
from Message import *
from MessageWorker import MessageWorker
import threading
import re
import time
from _io import StringIO
class Client(object):
def __init__(self, host, port):
self.connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.connection.connect((host, port))
self.login_response_event = threading.Event()
# Start the message worker (which listens on the connection and notifies us if it has received a message)
self.message_worker = MessageWorker(self.connection, self)
self.message_worker.start()
self.run = True
# Main loop
def start(self):
self.username = None
# Log in
while self.username is None:
self.login_response_event.clear()
new_username = self.input("Enter username: ")
if self.valid_username(new_username):
loginRequestMessage = LoginRequestMessage()
loginRequestMessage.set_login_info(new_username)
self.send(loginRequestMessage)
self.login_response_event.wait() # Blocks until message_received receives a LoginResponseMessage
else:
self.output("Client: Invalid username!")
self.output("Logged in as " + self.username)
while self.run:
new_message = self.input("> ")
# Parse as cmd
cmd = self.get_cmd(new_message)
if not cmd:
now_string = time.strftime("%H:%M:%S")
self.output(self.username + " " + now_string + ": " + new_message)
chatRequestMessage = ChatRequestMessage()
chatRequestMessage.set_chat_message(new_message)
self.send(chatRequestMessage)
else:
if cmd == "logout":
logoutRequestMessage = LogoutRequestMessage()
self.send(logoutRequestMessage)
self.run = False
elif cmd == "listusers":
listUsersRequestMessage = ListUsersRequestMessage()
self.send(listUsersRequestMessage)
else:
self.output("Unknown command: /" + cmd)
self.output("Logged out, good bye!")
def get_cmd(self, text):
if len(text) > 1 and text[0] == '/':
return text[1:].lower()
else:
return False
# Message is already decoded from JSON
def message_received(self, data):
#print "Message received from server: " + str(data)
if "response" in data:
if data["response"] == "login":
# Success
if "error" not in data:
self.username = data["username"]
for message in data["messages"]:
self.output(message, True)
elif data["error"] == "Invalid username!":
self.output("Invalid username!")
elif data["error"] == "Name already taken!":
self.output("Name already taken!")
# Notify main thread
self.login_response_event.set()
elif data["response"] == "message":
if not "error" in data:
self.output(data["message"], True)
# Error: not logged in
else:
self.output(data["error"])
elif data["response"] == "listUsers":
users_online_string = "Online users: " + ", ".join(data["users"])
self.output(users_online_string)
else:
self.output("Server makes no sense, me don't understand!")
def valid_username(self, username):
match_obj = re.search(u'[A-zæøåÆØÅ_0-9]+', username)
return match_obj is not None and match_obj.group(0) == username
# Server closed connection
def connection_closed(self):
self.message_worker.join() # Wait for listener to exit
# data should be a Message object
def send(self, data):
self.connection.sendall(data.get_JSON().encode("UTF-8"))
def force_disconnect(self):
self.connection.close()
# Output this to console
def output(self, line, newline=False):
if newline:
print("\r" + line)
else:
print("\r" + line, end="")
# Get input
def input(self, prompt):
print("\r" + prompt)
return sys.stdin.readline().strip()
if __name__ == "__main__":
client = Client('www.furic.pw', 9999)
client.start()