def test_handle_disconnect(self): room = Chatroom("../config/test_config/chat.yaml") fake_websocket = Mwsc() self.assertEqual(len(room.connected), 0) self.connect_fake_client(fake_websocket, room) self.assertEqual(len(room.connected), 1) asyncio.get_event_loop().run_until_complete( room.handle_disconnect(fake_websocket)) self.assertEqual(len(room.connected), 0)
def test_handle_message(self): room = Chatroom("../config/test_config/chat.yaml") fake_websocket = Mwsc() fake_websocket2 = Mwsc() self.connect_fake_client(fake_websocket, room) self.connect_fake_client(fake_websocket2, room) asyncio.get_event_loop().run_until_complete( room.handle_message(fake_websocket, "Fake message")) self.assertIn(fake_websocket, room.connected) self.assertEqual(room.connected[fake_websocket].websocket, fake_websocket) self.assertTrue( len(room.connected[fake_websocket2].websocket.incoming) > 1)
def new_activity(): # 客户端提供name, info, durations,frequency # TODO Activity.new_activity(.....) try: name = flask.request.args['name'] info = flask.request.args['info'] duration = flask.request.args['duration'] frequency = flask.request.args['frequency'] act = Activity.new_activity(name, info, duration, frequency, '{}'.format(datetime.datetime.now())) Chatroom.new_chat(act.get_id()) return json.dumps({ 'status': 'ok', }) except Exception as e: return json.dumps({'status': 'error', 'message': str(e)})
def test_help(self): handler = CommandHandler() room = Chatroom("../config/test_config/chat.yaml") socket = Mwsc() user = User(socket, "Test") test_helper.sync(handler.handle_command("!help", user, room)) self.assertTrue("!help" in user.websocket.incoming[-1])
def test_send_to_all(self): room = Chatroom("../config/test_config/chat.yaml") fake_websocket = Mwsc() fake_websocket2 = Mwsc() self.connect_fake_client(fake_websocket, room) self.connect_fake_client(fake_websocket2, room) resp = Response("TO ALL") asyncio.get_event_loop().run_until_complete( room.send_to_all(resp, fake_websocket2)) self.assertEqual(resp.json(), room.connected[fake_websocket].websocket.incoming[-1]) self.assertNotEqual( resp.json(), room.connected[fake_websocket2].websocket.incoming[-1])
def test_pm(self): room = Chatroom("../config/test_config/chat.yaml") sender = Mwsc() reciever = Mwsc() bystander = Mwsc() test_helper.sync(room.handle_connection(sender, "sender")) test_helper.sync(room.handle_connection(reciever, "reciever")) test_helper.sync(room.handle_connection(bystander, "bystander")) test_helper.sync( room.command_handler.handle_command("!pm reciever MESSAGE BODY", room.connected[sender], room) ) expected_reciver = room.get_outgoing_pm("MESSAGE BODY", "sender") expected_sender = room.get_pm_receipt("MESSAGE BODY", "reciever") self.assertIn(expected_reciver, reciever.incoming[-1]) self.assertIn("PRIVATE", reciever.incoming[-1]) self.assertIn(expected_sender, sender.incoming[-1]) self.assertIn("PRIVATE", sender.incoming[-1]) self.assertNotIn(expected_sender, bystander.incoming[-1]) self.assertNotIn("PRIVATE", bystander.incoming[-1])
def __init__(self, browser=None): super().__init__(browser) self.session = Session(browser=self.browser) self.chatroom = Chatroom(browser=self.browser) self.group = Group(browser=self.browser) # def __del__(self): # self.browser.quit()
def post_chat(): try: user = flask_login.current_user.get_id() content = flask.request.form['content'] act_id = flask.request.form['id'] chat = Chatroom.load_from_db(act_id) chat.add_chat(user, content) return json.dumps({'status': 'ok'}) except Exception as e: return json.dumps({'status': 'error', 'message': str(e)})
def test_handle_shutdown(self): room = Chatroom("../config/test_config/chat.yaml") fake_websocket = Mwsc() fake_websocket2 = Mwsc() self.connect_fake_client(fake_websocket, room) self.connect_fake_client(fake_websocket2, room) asyncio.get_event_loop().run_until_complete(room.handle_shutdown()) expected = Response(room.get_shutdown_notification(), Origin.SERVER) self.assertIn( str(expected), str(room.connected[fake_websocket].websocket.incoming[-1])) self.assertIn( str(expected), str(room.connected[fake_websocket2].websocket.incoming[-1])) self.assertFalse(room.connected[fake_websocket].websocket.open) self.assertFalse(room.connected[fake_websocket2].websocket.open)
def test_name_change(self): room = Chatroom("../config/test_config/chat.yaml") fake_websocket = Mwsc() fake_websocket2 = Mwsc() self.connect_fake_client(fake_websocket, room, "old_name") self.connect_fake_client(fake_websocket2, room) asyncio.get_event_loop().run_until_complete( room.change_name(fake_websocket, "new_name")) expected = Response( room.get_name_change_notification("old_name", "new_name"), Origin.SERVER) self.assertEqual(expected.json(), room.connected[fake_websocket].websocket.incoming[-1]) self.assertEqual( expected.json(), room.connected[fake_websocket2].websocket.incoming[-1]) self.assertEqual(room.connected[fake_websocket].name, "new_name")
def test_create_server(self): server_config = ConfigManager("../config/test_config/server.yaml") chat = Chatroom("../config/test_config/chat.yaml") server = Server("../config/test_config/server.yaml", chat) self.assertEqual(server.port, server_config["port"]) self.assertEqual(server.host, server_config["host"]) self.assertFalse(server.running) self.assertIsNotNone(server.handler) self.assertEqual(server.handler, chat)
def test_handle_connection(self): room = Chatroom("../config/test_config/chat.yaml") fake_websocket = Mwsc() self.connect_fake_client(fake_websocket, room) self.assertIn(fake_websocket, room.connected) self.assertEqual(room.connected[fake_websocket].websocket, fake_websocket) self.assertTrue( len(room.connected[fake_websocket].websocket.incoming) > 0) self.assertEqual(len(room.connected), 1)
def __init__(self): """ The class that contains server related functionality. """ self.listener = socket() self.address = (gethostname(), 8585) self.tcp_backlog = 5 self.users = {} self.userlist = [] self.chatrooms = {"General": Chatroom("General", None, True)}
def test_bad_pm(self): room = Chatroom("../config/test_config/chat.yaml") sender = Mwsc() reciever = Mwsc() test_helper.sync(room.handle_connection(sender, "sender")) test_helper.sync(room.handle_connection(reciever, "reciever")) test_helper.sync( room.command_handler.handle_command("!pm", room.connected[sender], room) ) test_helper.sync( room.command_handler.handle_command("!pm test", room.connected[sender], room) ) test_helper.sync( room.command_handler.handle_command("!pm test ", room.connected[sender], room) )
def create_new_chatroom(self, room_name, conn): # Check if there's already a room of that name if room_name in self.rooms: error_msg = f"A room with name {room_name} already exists!" send_packet(ErrorMessagePacket(error_msg), conn) else: # Create new room self.rooms[room_name] = Chatroom(room_name) # Send success message to user send_packet(CreateRoomResponsePacket(room_name), conn)
def _create_chatroom(self, name): self.chatrooms_lock.acquire() chatroom = self._get_chatroom_by_name(name) if chatroom is None: room_ref = str(len(self.chatrooms) + 1) chatroom = Chatroom(name, room_ref) self.chatrooms[room_ref] = chatroom self.chatrooms_lock.release() return chatroom
def get_chat(): try: act_id = flask.request.args['id'] starttime = flask.request.args['starttime'] return json.dumps({ 'status': 'ok', 'message': str(Chatroom.load_from_db(act_id).get_chat(starttime)) }) except Exception as e: return json.dumps({'status': 'error', 'message': str(e)})
def create_chatroom(self, name, client): try: temp = self.chatroom_dict[name] except KeyError: new_room = self.chatroom_dict[name] = Chatroom(name) new_room.set_moderator(client) client.add_created_room(name) old_room = self.chatroom_dict[client.get_chatroom_name()] self.__switch_chatroom(old_room, new_room, client) else: msg = Message(client.get_cid(), self.server_alias, MessageType.chat_message, 'Chatroom ' + name + ' already exists') self.outgoing_queue.put(msg)
def process_join_req(client, message): room_name, _ = parse_join(message) room_id = hash(room_name) % 255 with CHATROOMS_MAP_MUTEX: if room_id not in CHATROOMS_MAP.keys(): CHATROOMS_MAP[room_id] = Chatroom(room_id, room_name) if CHATROOMS_MAP[room_id].add_client(client): client.socket.sendall( respond_to_join(room_name, room_id, client.join_id, HOST, JOIN_PORT)) CHATROOMS_MAP[room_id].broadcast_message( client.handle, "{} Joined {}".format(client.handle, CHATROOMS_MAP[room_id].room_name)) else: client.socket.sendall(respond_with_error(1))
def start(self): self.socket.bind(self.get_adrs()) self.socket.listen(5) self.connected_client_socket.append(self.socket) chatroom = Chatroom("main_chatroom") self.chatroom[chatroom.get_name()] = chatroom
import socket import sys,os from threading import Thread from SocketServer import ThreadingMixIn from chatroom import Chatroom data="" kill=0 leave=0 chat_room1=Chatroom("room1",1) chat_room2=Chatroom("room2",2) rooms = [] rooms.append(chat_room1) rooms.append(chat_room2) TCP_IP = '0.0.0.0' TCP_PORT = 8000 BUFFER_SIZE = 1024 # Usually 1024, but we need quick response tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcpServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) tcpServer.bind((TCP_IP, TCP_PORT)) tcpServer.listen(10) alive = True t_lim = 150 num_threads=0 threads=[] #class ClientThread(Thread): def communication(conn):
level=logging.INFO, format='%(asctime)s : %(levelname)s : %(name)s : %(message)s') logger = logging.getLogger(__name__) class App: """ Main entrypoint for chatroom server, instantiates and runs server """ def __init__(self, server): """Create a new app to run a given server Args: server (Server): app server """ self.server = server @log(logger, logging.INFO) def start(self): """ Start the server """ self.server.start() if __name__ == "__main__": chatroom_handler = Chatroom("../config/chat.yaml") server = Server("../config/server.yaml", chatroom_handler) app = App(server) app.start()
def execute_command(self, cmd: Command, origin_address: (str, int), sock: socket): """ Executes a given command and performs an action depending on the command type. """ currUser = self.users.get(sock, None) if cmd.type == 'message': # Adds a tag that says who authored the command cmd.creator = currUser.alias # Notifies user if chatroom doesnt exist if cmd.specificChatroom not in self.chatrooms: errorResponse = Command() errorResponse.init_error("Chatroom {} doesnt exist.".format( cmd.specificChatroom)) errorResponse.send(sock) return # Notifies user if their message is too long if len(cmd.body) > 200: errorResponse = Command() errorResponse.init_error( "Your message exceeds the 200 character limit.") errorResponse.send(sock) return print('{}/{}: {}'.format(cmd.creator, cmd.specificChatroom, cmd.body)) # Relays the message to all the other clients in the same chatroom that the message was sent from self.chatrooms[cmd.specificChatroom].send_all(cmd) elif cmd.type == 'alias': # Some thoughts about https://github.com/sterlinglaird/SENG-299/issues/53: # to remove old user in user list, we'd have to search by sock (because that is unique to user, even if alias changes) # also have to edit cliengui.py, as every time set_alias is executed, a new user is added to GUI user list # Get the chosen alias and address alias = cmd.body # Check that the alias isn't already in use if alias in self.userlist: # Send warning back to client errorResponse = Command() errorResponse.init_error( "Alias '{}' already exist.".format(alias)) errorResponse.send(sock) return # Update the server data and the command newUser = User(alias, sock) self.users[sock] = newUser self.chatrooms[util.defaultChatroom].add_user(newUser) cmd.creator = newUser.alias self.userlist.append(newUser.alias) cmd.specificChatroom = util.defaultChatroom print("Alias '{}' accepted".format(alias)) # let all users in default chatroom know about the connection self.chatrooms[cmd.specificChatroom].send_all(cmd) elif cmd.type == 'connect': # Get the chosen alias and address address = "{}:{}".format(origin_address[0], origin_address[1]) alias = address print("Connected with address '{}'".format(address)) # let users know about connection cmd.send(sock) elif cmd.type == 'disconnect': # Close the socket sock.close() connectedChatrooms = [] # Remove the user self.users.pop(sock) for chatroom in self.chatrooms.values(): chatroom.rem_user(currUser.alias) connectedChatrooms.append(chatroom.name) # Adds a tag that says who authored the command cmd.creator = currUser.alias print("{} disconnected".format(currUser.alias)) # Relays the message to all the other clients in the same chatrooms as the user who disconnected for chatroom in connectedChatrooms: chatroom.send_all(cmd) elif cmd.type == 'join_chatroom': userOccupies = self.get_all_chatrooms(currUser) newChatroom = self.chatrooms.get(cmd.body, None) if newChatroom in userOccupies: errorResponse = Command() errorResponse.init_error( "You are already in chatroom '{}'.".format(cmd.body)) errorResponse.send(sock) return if newChatroom is None: errorResponse = Command() errorResponse.init_error("Chatroom '{}' doesn't exist.".format( cmd.body)) errorResponse.send(sock) return # Check if user is blocked from the room they are trying to join if currUser.alias in self.chatrooms[cmd.body].blocked: errorResponse = Command() errorResponse.init_error( "You are blocked from joining chatroom '{}'.".format( cmd.body)) errorResponse.send(sock) return # Remove user from previous chatrooms for chatroom in self.chatrooms.values(): chatroom.rem_user(currUser) # Add user to chatroom newChatroom.add_user(currUser) print("{} joined chatroom {}".format(currUser.alias, newChatroom.name)) # Adds a tag that says who authored the command cmd.creator = currUser.alias # Notify users in chatroom that user has joined self.chatrooms[newChatroom.name].send_all(cmd) # Notify users in old chatrooms that user joined a different one for chatroom in userOccupies: chatroom.send_all(cmd) elif cmd.type == 'create_chatroom': # Create chatroom if it doesnt already exist, if it does then let user know if cmd.body in self.chatrooms: errorResponse = Command() errorResponse.init_error( "Chatroom \"{}\" already exists.".format(cmd.body)) errorResponse.send(sock) return else: self.chatrooms[cmd.body] = Chatroom(cmd.body, currUser) print("{} created chatroom {}".format(currUser.alias, cmd.body)) # Adds a tag that says who authored the command cmd.creator = currUser.alias # Let all users know about the new chatroom self.send_all(cmd) elif cmd.type == 'delete_chatroom': chatroom = self.chatrooms.get(cmd.body, None) if chatroom is None: # Send error if chatroom doesnt exist errorResponse = Command() errorResponse.init_error( "Chatroom \"{}\" doesn't exist.".format(cmd.body)) errorResponse.send(sock) return elif chatroom.owner is not currUser: # Send error if user doesnt own the chatroom errorResponse = Command() errorResponse.init_error( "Chatroom \"{}\" is not owned by you so you cannot delete it." .format(chatroom.name)) errorResponse.send(sock) return # Move all current users in chatroom to default room userList = list(chatroom.users.values()) for user in userList: chatroom.rem_user(user) self.chatrooms[util.defaultChatroom].add_user(user) self.chatrooms.pop(cmd.body, None) # Adds a tag that says who authored the command cmd.creator = currUser.alias # Let all users know about the deleted chatroom self.send_all(cmd) # Let all users know about the joins to default chatroom for deletedUser in userList: joinCmd = Command() joinCmd.init_join_chatroom(util.defaultChatroom) joinCmd.creator = deletedUser.alias for user_socket in self.chatrooms[ util.defaultChatroom].users.values(): joinCmd.send(user_socket.socket) print("{} deleted chatroom {}".format(currUser.alias, cmd.body)) elif cmd.type == 'block_user': # Find location of blocker for blocker_chatroom in self.chatrooms: # When the blocker is found if currUser.alias in self.chatrooms[blocker_chatroom].users: user_location = self.chatrooms[blocker_chatroom] # Check if they are the owner of the room they're in if user_location.owner is not currUser: errorResponse = Command() errorResponse.init_error( "You don't own chatroom {}, so you can't block users from joining it." .format(user_location.name)) errorResponse.send(sock) return # If they are the owner else: # Find the location of the user being blocked for chatroom in self.chatrooms: if cmd.body in self.chatrooms[chatroom].users: blocked_user_location = self.chatrooms[ chatroom] blocked_user = blocked_user_location.users[ cmd.body] # Check if the user is trying to block themselves (it should have been a feature, but sterlinglaird is lame) if currUser == blocked_user: errorResponse = Command() errorResponse.init_error( "Why are you trying to block yourself? Stop that." ) errorResponse.send(sock) return # Block the user user_location.block_user(blocked_user) # Add a tag that says who authored the command cmd.creator = currUser.alias # Add a tag that says which room the user is blocked from cmd.specificChatroom = user_location.name # Let all users in the blocker's room know about the block user_location.send_all(cmd) # If the blocker and the user being blocked are in the same room if user_location == blocked_user_location: # Remove the blocked user from the room, and return them to Default user_location.rem_user(blocked_user) self.chatrooms[ util.defaultChatroom].add_user( blocked_user) else: # Let the blocked user's room know about the block (console logging only) blocked_user_location.send_all(cmd) # Let user know they've been forced into default chatroom join_cmd = Command() join_cmd.init_join_chatroom( util.defaultChatroom) join_cmd.creator = blocked_user.alias # Let all users in new chatroom know that user has joined self.chatrooms[util.defaultChatroom].send_all( join_cmd) # Let all users in old chatroom know that user has left, as long as we havent already sent the message in the line above if blocked_user_location is not self.chatrooms[ util.defaultChatroom]: blocked_user_location.send_all(join_cmd) print("{} blocked {} from chatroom {}".format( currUser.alias, cmd.body, user_location.name)) return # If the user can't be found errorResponse = Command() errorResponse.init_error("User \"{}\" does not exist.".format( cmd.body)) errorResponse.send(sock) return elif cmd.type == 'unblock_user': # Find location of unblocker for unblocker_chatroom in self.chatrooms: # When the unblocker is found if currUser.alias in self.chatrooms[unblocker_chatroom].users: user_location = self.chatrooms[unblocker_chatroom] # Check if they are the owner of the room they're in if user_location.owner is not currUser: errorResponse = Command() errorResponse.init_error( "You are not the owner of chatroom {}, so you cannot unblock blocked users." .format(user_location.name)) errorResponse.send(sock) return # If they are the owner else: # Find the location of the user being unblocked for chatroom in self.chatrooms: if cmd.body in self.chatrooms[chatroom].users: blocked_user_location = self.chatrooms[ chatroom] blocked_user = blocked_user_location.users[ cmd.body] # unlock the user user_location.unblock_user(blocked_user) print( "{} unblocked {} from chatroom {}".format( currUser.alias, cmd.body, user_location.name)) # Add a tag that says who authored the command cmd.creator = currUser.alias # Add a tag that says which room the user is unblocked from cmd.specificChatroom = user_location.name # Let all users in the room know about the unblock user_location.send_all(cmd) if user_location != blocked_user_location: # Let the blocked user's room know about the block blocked_user_location.send_all(cmd) return # If the user can't be found errorResponse = Command() errorResponse.init_error("User \"{}\" does not exist.".format( cmd.body)) errorResponse.send(sock) return elif cmd.type == 'get_chatrooms': get_chatrooms_cmd = Command() get_chatrooms_cmd.init_get_chatrooms(list(self.chatrooms.keys())) get_chatrooms_cmd.send(sock) elif cmd.type == 'list_users': newChatroom = self.chatrooms.get(cmd.body, None) # send a join command for every user in the chatroom, except the current user for user in newChatroom.users: if user == currUser.alias: continue responseCmd = Command() responseCmd.init_join_chatroom(newChatroom.name) responseCmd.creator = user responseCmd.suppress = True responseCmd.send(sock) print("Listing user '{}' for '{}'".format( user, currUser.alias))
def __init__(self, browser=None): super().__init__(browser) self.session = Session(self.browser) self.chatroom = Chatroom(self.browser) self.group = Group(self.browser)
def login_account(self): self.chatroom = Chatroom(self.name, self.ADDR)
def Worker(self): print("Started worker. There are now {0} workers".format(self.no_of_workers)) while len(self.tasks) > 0: (client, (host, port)) = self.tasks.pop(0) size = 1024 while True: try: data = client.recv(size) data = data.decode("utf-8") if data: print("Received message: {0}".format(data)) # Set the response to echo back the recieved data if "HELO" in data: print("Handling HELO message.") print("Adding student id.") response = "{3}IP:{0}\nPort:{1}\nStudentID:{2}\n".format(self.ip, self.port, std_ID, data) client.send(response.encode("utf-8")) elif data == "KILL_SERVICE\n": print("Calling Stop()") self.Stop() elif "JOIN_CHATROOM:" in data: #handle a request to join a chatroom print("Handling JOIN_CHATROOM message.") #parse chatroom_name = parameter(data.split("\n")[0]).strip() client_name = parameter(data.split("\n")[3]).strip() #check if chatroom exists exists = False for k, v in self.rooms.items(): #join if v.chatroom_name == chatroom_name: v.join(client_name, client, self.ip, self.port) exists = True if not exists: #get room ref self.roomsLock.acquire() room_ref = self.room_ref_seed self.room_ref_seed += 1 self.roomsLock.release() #create new chatroom cr = Chatroom(chatroom_name, room_ref) self.rooms[room_ref] = cr #join the aforesaid chatroom cr.join(client_name, client, self.ip, self.port) print("Joined chatroom.") elif "LEAVE_CHATROOM:" in data: print("Handling LEAVE_CHATROOM message.") #handle a request to leave a chatroom #parse room_ref = int(parameter(data.split('\n')[0])) join_id = int(parameter(data.split('\n')[1])) client_name = parameter(data.split('\n')[2]).strip() #leave chatroom chatroom = self.rooms[room_ref] chatroom.leave(join_id, client, client_name) if chatroom.isEmpty(): self.rooms.pop(room_ref, None) elif "DISCONNECT:" in data: print("Handling DISCONNECT message.") #handle a request to disconnect from server ie. kill socket connection and worker thread #parse client_name = parameter(data.split('\n')[2]).strip() for k in list(self.rooms): v = self.rooms[k] #leave the chatroom if it is in it join_id = v.getJoinId(client_name, client) v.disconnect(join_id, client_name) if v.isEmpty(): self.rooms.pop(room_ref, None) client.close() elif "CHAT:" in data: print("Handling CHAT message.") #send chat message to all members of the chat #parse room_ref = int(parameter(data.split('\n')[0])) join_id = int(parameter(data.split('\n')[1])) client_name = parameter(data.split('\n')[2]).strip() message = parameter(data.split('\n')[3]).strip() #spread message self.rooms[room_ref].spread_message(client_name, message) print("Handled packet") else: raise error('Client disconnected') except: client.close() print("Got to break") break print("Worker dying")
def handle_join_room(self, room_name, client_name, client_ip=0, client_port=0): if room_name not in self.chatrooms: room = Chatroom(room_name) self.chatrooms[room_name] = room self.chatroom_ids[room.get_id()] = room_name room.subscribe(client_name, client_ip) else: # create and join room room = self.chatrooms[room_name] room.subscribe(client_name, client_ip) room.subscribe(client_name, client_ip, client_port) l = room.get_publish_list() client_ip.send( self.success_response(room_name, self.host, self.port, room.get_id(), id(client_name)).encode()) self.client_ids[id(client_name)] = client_name for i in l: # print("i in l loop: " + str(i) + "\n\n") i[1].sendall((str(client_name) + " has joined the room").encode()) print("sent")
from chatroom import Chatroom application = Chatroom().build_app()
def test_create_chatroom(self): room = Chatroom("../config/test_config/chat.yaml") self.assertIsNotNone(room.connected)