def quit(connection, args): # @ReservedAssignment abort_if(lambda: connection.status == ConnectionStatus.NOT_CONNECTED, "201 ERR_NOTCONNECTED") connection.write_all(":" + connection.client.pseudo + " QUIT " + " ".join(args)) connection.close(); # no reply will be sent return None
def reply_file(connection, args): abort_if(lambda: connection.status == ConnectionStatus.NOT_CONNECTED, "201 ERR_NOTCONNECTED") abort_if(lambda: len(args) < 2, "203 ERR_NOTENOUGHARGS") file_id, answer = args[0], args[1].lower() abort_if(lambda: file_id not in connection._protocol.sender_per_file_request, "209 ERR_FILEIDNOTEXIST") file_sender = connection._protocol.sender_per_file_request[file_id] if answer != "no" and answer != "yes": return "208 ERR_BADARGUMENT" if answer == "no": response = f":{connection.client.pseudo} REPLY_FILE {file_id} NO" else: abort_if(lambda: len(args) < 3, "203 ERR_NOTENOUGHARGS") port = args[2] ip = file_sender.ip() response = f":{connection.client.pseudo} REPLY_FILE {file_id} {answer} {port} {ip}" try: file_sender.write(response) except OSError: return "204 ERR_NICKNAMENOTEXIST" finally: del connection._protocol.sender_per_file_request[file_id] return "100 RPL_DONE"
def mute(connection, args): abort_if(lambda: connection.status == ConnectionStatus.NOT_CONNECTED, "201 ERR_NOTCONNECTED") abort_if(lambda: len(args) < 1, "203 ERR_NOTENOUGHARGS") in_error = [] for pseudo in args: try: to_mute = connection._protocol.clients[pseudo] except KeyError: in_error.append(pseudo) else: connection.ignored.add(to_mute.connection) return "100 RPL_DONE" if not in_error else "204 ERR_NICKNAMENOTEXIST " + " ".join(in_error)
def ask_file(connection, args): abort_if(lambda: connection.status == ConnectionStatus.NOT_CONNECTED, "201 ERR_NOTCONNECTED") abort_if(lambda: len(args) < 3, "203 ERR_NOTENOUGHARGS") dest, size, file = args[0], args[1], args[2] file_id = connection._protocol.generate_file_id(file) try: connection.write_to(dest, f":{connection.client.pseudo} ASK_FILE {file_id} {size} {file}") except KeyError: return "204 ERR_NICKNAMENOTEXIST" connection._protocol.sender_per_file_request[file_id] = connection return f"102 RPL_FILE {file_id}"
def whisper(connection, args): abort_if(lambda: connection.status == ConnectionStatus.NOT_CONNECTED, "201 ERR_NOTCONNECTED") abort_if(lambda: connection.status == ConnectionStatus.AWAY, "202 ERR_BADSTATUS") abort_if(lambda: len(args) < 2, "203 ERR_NOTENOUGHARGS") dest = args[0] try: abort_if(lambda: not connection in connection._protocol[dest].connection.private, "207 ERR_WHISPERNOTALLOWED") message = " ".join(args[1:]) connection.write_to(dest, ":" + connection.client.pseudo + " WHISPER " + message) except KeyError: return "204 ERR_NICKNAMENOTEXIST" return "100 RPL_DONE"
def message(connection, args): abort_if(lambda: connection.status == ConnectionStatus.NOT_CONNECTED, "201 ERR_NOTCONNECTED") abort_if(lambda: connection.status == ConnectionStatus.AWAY, "202 ERR_BADSTATUS") abort_if(lambda: len(args) < 1, "203 ERR_NOTENOUGHARGS") if args[0].startswith('!'): return connection._protocol.chat_bot.react(*args) connection.write_all(":" + connection.client.pseudo + " MESSAGE " + " ".join(args)) return "100 RPL_DONE"
def ask_whisper(connection, args): abort_if(lambda: connection.status == ConnectionStatus.NOT_CONNECTED, "201 ERR_NOTCONNECTED") abort_if(lambda: connection.status == ConnectionStatus.AWAY, "202 ERR_BADSTATUS") abort_if(lambda: len(args) < 1, "203 ERR_NOTENOUGHARGS") dest = args[0] try: connection.write_to(dest, ":" + connection.client.pseudo + " ASK_WHISPER") except KeyError: return "204 ERR_NICKNAMENOTEXIST" return "100 RPL_DONE"
def nick(connection, args): abort_if(lambda: connection.status == ConnectionStatus.NOT_CONNECTED, "201 ERR_NOTCONNECTED") abort_if(lambda: len(args) < 1, "203 ERR_NOTENOUGHARGS") abort_if(lambda: args[0] in connection._protocol.clients, "205 ERR_NICKNAMEINUSE") new_nick = args[0] if len(new_nick) > 10 or new_nick.startswith('@') or ',' in new_nick: return "206 ERR_INVALIDNICKNAME" connection.write_all(":" + connection.client.pseudo + " NICK " + " " + new_nick) connection._protocol.clients.rename(connection.client, args[0]) return "100 RPL_DONE"
def connect(connection, args): abort_if(lambda: connection.status == ConnectionStatus.CONNECTED, "200 ERR_ALREADYCONNECTED") abort_if(lambda: len(args) < 1, "203 ERR_NOTENOUGHARGS") abort_if(lambda: args[0] in connection._protocol.clients, "205 ERR_NICKNAMEINUSE") pseudo = args[0] if len(pseudo) > 10 or pseudo.startswith('@') or ',' in pseudo: return "206 ERR_INVALIDNICKNAME" connection.status = ConnectionStatus.CONNECTED connection.client = Client(pseudo, connection) connection._protocol.clients[pseudo] = connection.client connection.write_all(f":{pseudo} CONNECT") return "100 RPL_DONE"
def stop_whisper(connection, args): abort_if(lambda: connection.status == ConnectionStatus.NOT_CONNECTED, "201 ERR_NOTCONNECTED") abort_if(lambda: connection.status == ConnectionStatus.AWAY, "202 ERR_BADSTATUS") abort_if(lambda: len(args) < 1, "203 ERR_NOTENOUGHARGS") dest = args[0] try: dest_connection = connection._protocol[dest].connection dest_connection.private.remove(connection) connection.private.remove(dest_connection) dest_connection.write(":" + connection.client.pseudo + " STOP_WHISPER") except KeyError: return "204 ERR_NICKNAMENOTEXIST" return "100 RPL_DONE"
def reply_whisper(connection, args): abort_if(lambda: connection.status == ConnectionStatus.NOT_CONNECTED, "201 ERR_NOTCONNECTED") abort_if(lambda: connection.status == ConnectionStatus.AWAY, "202 ERR_BADSTATUS") abort_if(lambda: len(args) < 2, "203 ERR_NOTENOUGHARGS") dest = args[0] answer = str(args[1]).strip() try: connection.write_to(dest, ":" + connection.client.pseudo + " REPLY_WHISPER " + str(answer)) except KeyError: return "204 ERR_NICKNAMENOTEXIST" else: if answer.lower() == "yes": dest_connection = connection._protocol[dest].connection connection.private.add(dest_connection) dest_connection.private.add(connection) return "100 RPL_DONE"
def __iadd__(self, client): abort_if(lambda: not isinstance(client, Client), "cannot add a non Client instance") self[client.pseudo] = client return self
def re(connection, args): abort_if(lambda: connection.status == ConnectionStatus.NOT_CONNECTED, "201 ERR_NOTCONNECTED") connection.status = ConnectionStatus.CONNECTED return "100 RPL_DONE"
def names(connection, args): abort_if(lambda: connection.status == ConnectionStatus.NOT_CONNECTED, "201 ERR_NOTCONNECTED") return "101 RPL_NAMES " + " ".join(client for client in connection._protocol.clients)