Question: The following are my files for a python chat server project Main.py ---------------------------------------------------------- import tkinter as tk from tkinter import messagebox import ChatClient as client

The following are my files for a python chat server project

Main.py

----------------------------------------------------------

import tkinter as tk from tkinter import messagebox import ChatClient as client import BaseDialog as dialog import BaseEntry as entry import threading class SocketThreadedTask(threading.Thread): def __init__(self, socket, callback): threading.Thread.__init__(self) self.socket = socket self.callback = callback def run(self): while True: try: message = self.socket.receive() if message == '/quit': self.callback(' > You have been disconnected from the server. ') self.socket.disconnect() break  else: self.callback(message) except OSError: break  class ChatDialog(dialog.BaseDialog): def body(self, master): tk.Label(master, text="Enter host:").grid(row=0, sticky="w") tk.Label(master, text="Enter port:").grid(row=1, sticky="w") self.hostEntryField = tk.Entry(master) self.portEntryField = tk.Entry(master) self.hostEntryField.grid(row=0, column=1) self.portEntryField.grid(row=1, column=1) return self.hostEntryField def validate(self): host = str(self.hostEntryField.get()) try: port = int(self.portEntryField.get()) if(port >= 0 and port < 65536): self.result = (host, port) return True  else: tk.messagebox.showwarning("Error", "The port number has to be between 0 and 65535. Both values are inclusive.") return False  except ValueError: tk.messagebox.showwarning("Error", "The port number has to be an integer.") return False  class ChatWindow(tk.Frame): def __init__(self, parent): tk.Frame.__init__(self, parent) self.initUI(parent) def initUI(self, parent): self.messageTextArea = tk.Text(parent, bg="white", state=tk.DISABLED, wrap=tk.WORD) self.messageTextArea.grid(row=0, column=0, columnspan=2, sticky="nsew") self.messageScrollbar = tk.Scrollbar(parent, orient=tk.VERTICAL, command=self.messageTextArea.yview) self.messageScrollbar.grid(row=0, column=3, sticky="ns") self.messageTextArea['yscrollcommand'] = self.messageScrollbar.set self.usersListBox = tk.Listbox(parent, bg="white") self.usersListBox.grid(row=0, column=4, padx=5, sticky="nsew") self.entryField = entry.BaseEntry(parent, placeholder="Enter message.", width=80) self.entryField.grid(row=1, column=0, padx=5, pady=10, sticky="we") self.send_message_button = tk.Button(parent, text="Send", width=10, bg="#CACACA", activebackground="#CACACA") self.send_message_button.grid(row=1, column=1, padx=5, sticky="we") def update_chat_window(self, message): self.messageTextArea.configure(state='normal') self.messageTextArea.insert(tk.END, message) self.messageTextArea.configure(state='disabled') def send_message(self, **callbacks): message = self.entryField.get() self.set_message("") callbacks['send_message_to_server'](message) def set_message(self, message): self.entryField.delete(0, tk.END) self.entryField.insert(0, message) def bind_widgets(self, callback): self.send_message_button['command'] = lambda sendCallback = callback : self.send_message(send_message_to_server=sendCallback) self.entryField.bind("", lambda event, sendCallback = callback : self.send_message(send_message_to_server=sendCallback)) self.messageTextArea.bind("<1>", lambda event: self.messageTextArea.focus_set()) class ChatGUI(tk.Frame): def __init__(self, parent): tk.Frame.__init__(self, parent) self.initUI(parent) self.ChatWindow = ChatWindow(self.parent) self.clientSocket = client.Client() self.ChatWindow.bind_widgets(self.clientSocket.send) self.parent.protocol("WM_DELETE_WINDOW", self.on_closing) def initUI(self, parent): self.parent = parent self.parent.title("ChatApp") screenSizeX = self.parent.winfo_screenwidth() screenSizeY = self.parent.winfo_screenheight() frameSizeX = 800 frameSizeY = 600 framePosX = (screenSizeX - frameSizeX) / 2 framePosY = (screenSizeY - frameSizeY) / 2 self.parent.geometry('%dx%d+%d+%d' % (frameSizeX, frameSizeY, framePosX, framePosY)) self.parent.resizable(True, True) self.parent.columnconfigure(0, weight=1) self.parent.rowconfigure(0, weight=1) self.mainMenu = tk.Menu(self.parent) self.parent.config(menu=self.mainMenu) self.subMenu = tk.Menu(self.mainMenu, tearoff=0) self.mainMenu.add_cascade(label='File', menu=self.subMenu) self.subMenu.add_command(label='Connect', command=self.connect_to_server) self.subMenu.add_command(label='Exit', command=self.on_closing) def connect_to_server(self): if self.clientSocket.isClientConnected: tk.messagebox.showwarning("Info", "Already connected to the server.") return   dialogResult = ChatDialog(self.parent).result if dialogResult: self.clientSocket.connect(dialogResult[0], dialogResult[1]) if self.clientSocket.isClientConnected: SocketThreadedTask(self.clientSocket, self.ChatWindow.update_chat_window).start() else: tk.messagebox.showwarning("Error", "Unable to connect to the server.") def on_closing(self): if self.clientSocket.isClientConnected: self.clientSocket.send('/quit') self.parent.quit() self.parent.destroy() if __name__ == "__main__": root = tk.Tk() chatGUI = ChatGUI(root) root.mainloop() 

--------------------------------------------------------------------------------

ChatServer.py

-----------------------------------------------------------------------------------

import socket import sys import threading import Channel class Server: SERVER_CONFIG = {"MAX_CONNECTIONS": 15} HELP_MESSAGE = """ > The list of commands available are:  /help - Show the instructions /join [channel_name] - To create or switch to a channel. /quit - Exits the program. /list - Lists all available channels. """.encode('utf8') def __init__(self, host=socket.gethostbyname('localhost'), port=50000, allowReuseAddress=True): self.address = (host, port) self.channels = {} # Channel Name -> Channel  self.channels_client_map = {} # Client Name -> Channel Name   try: self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) except socket.error as errorMessage: sys.stderr.write("Failed to initialize the server. Error - %s ", str(errorMessage)) raise   if allowReuseAddress: self.serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: self.serverSocket.bind(self.address) except socket.error as errorMessage: sys.stderr.write('Failed to bind to ' + self.address + '. Error - %s ', str(errorMessage)) raise   def listen_thread(self, defaultGreeting=" > Welcome to our chat app!!! What is your name? "): while True: print("Waiting for a client to establish a connection ") clientSocket, clientAddress = self.serverSocket.accept() print("Connection established with IP address {0} and port {1} ".format(clientAddress[0], clientAddress[1])) self.welcome_client(clientSocket) clientThread = threading.Thread(target=self.client_thread, args=(clientSocket,)) clientThread.start() def start_listening(self): self.serverSocket.listen(Server.SERVER_CONFIG["MAX_CONNECTIONS"]) listenerThread = threading.Thread(target=self.listen_thread) listenerThread.start() listenerThread.join() def welcome_client(self, clientSocket): clientSocket.sendall(" > Welcome to our chat app!!! What is your name? ".encode('utf8')) def client_thread(self, clientSocket, size=4096): clientName = clientSocket.recv(size).decode('utf8') welcomeMessage = '> Welcome %s, type /help for a list of helpful commands. ' % clientName clientSocket.send(welcomeMessage.encode('utf8')) while True: chatMessage = clientSocket.recv(size).decode('utf8').lower() if not chatMessage: break   if '/quit' in chatMessage: self.quit(clientSocket, clientName) break  elif '/list' in chatMessage: self.list_all_channels(clientSocket) elif '/help' in chatMessage: self.help(clientSocket) elif '/join' in chatMessage: self.join(clientSocket, chatMessage, clientName) else: self.send_message(clientSocket, chatMessage + ' ' , clientName) clientSocket.close() def quit(self, clientSocket, clientName): clientSocket.sendall('/quit'.encode('utf8')) self.remove_client(clientName) def list_all_channels(self, clientSocket): if len(self.channels) == 0: chatMessage = " > No rooms available. Create your own by typing /join [channel_name] "  clientSocket.sendall(chatMessage.encode('utf8')) else: chatMessage = ' > Current channels available are:  '  for channel in self.channels: chatMessage += "  " + channel + ": " + str(len(self.channels[channel].clients)) + " user(s)"  chatMessage += " "  clientSocket.sendall(chatMessage.encode('utf8')) def help(self, clientSocket): clientSocket.sendall(Server.HELP_MESSAGE) def join(self, clientSocket, chatMessage, clientName): isInSameRoom = False   if len(chatMessage.split()) >= 2: channelName = chatMessage.split()[1] if clientName in self.channels_client_map: # Here we are switching to a new channel.  if self.channels_client_map[clientName] == channelName: clientSocket.sendall((" > You are already in channel: " + channelName).encode('utf8')) isInSameRoom = True  else: # switch to a new channel  oldChannelName = self.channels_client_map[clientName] self.channels[oldChannelName].remove_client_from_channel(clientName) # remove them from the previous channel   if not isInSameRoom: if not channelName in self.channels: newChannel = Channel.Channel(channelName) self.channels[channelName] = newChannel self.channels[channelName].clients[clientName] = clientSocket self.channels[channelName].welcome_client(clientName) self.channels_client_map[clientName] = channelName else: self.help(clientSocket) def send_message(self, clientSocket, chatMessage, clientName): if clientName in self.channels_client_map: self.channels[self.channels_client_map[clientName]].broadcast_message(chatMessage, clientName + ": ") else: chatMessage = """ > You are currently not in any channels:  Use /list to see a list of available channels. Use /join [channel name] to join a channels. """.encode('utf8') clientSocket.sendall(chatMessage) def remove_client(self, clientName): if clientName in self.channels_client_map: self.channels[self.channels_client_map[clientName]].remove_client_from_channel(clientName) del self.channels_client_map[clientName] print("Client: " + clientName + " has left ") def server_shutdown(self): print("Shutting down chat server. ") self.serverSocket.shutdown(socket.SHUT_RDWR) self.serverSocket.close() def main(): chatServer = Server() print(" Listening on port " + str(chatServer.address[1])) print("Waiting for connections... ") chatServer.start_listening() chatServer.server_shutdown() if __name__ == "__main__": main() 

---------------------------------------------------------------------------

ChatClient.py

--------------------------------------------------------------------------

import socket import sys class Client: def __init__(self, name='client user'): self.socket = None  self.isClientConnected = False   def connect(self, host, port): try: self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.socket.connect((host, port)) self.isClientConnected = True  except socket.error as errorMessage: if errorMessage.errno == socket.errno.ECONNREFUSED: sys.stderr.write('Connection refused to ' + str(host) + ' on port ' + str(port)) else: sys.stderr.write('Error, unable to connect: ' + str(errorMessage)) def disconnect(self): if self.isClientConnected: self.socket.close() self.isClientConnected = False   def send(self, data): if self.isClientConnected: self.socket.send(data.encode('utf8')) def receive(self, size=4096): if not self.isClientConnected: return ""   return self.socket.recv(size).decode('utf8') 

-----------------------------------------------------------------------------------------

Channel.py

------------------------------------------------------------------------------------------

class Channel: def __init__(self, name): self.clients = {} # Client Name -> Socket  self.channel_name = name def welcome_client(self, clientName): for name, socket in self.clients.items(): if name is clientName: chatMessage = ' > {0} have joined the channel {1}! '.format("You", self.channel_name) socket.sendall(chatMessage.encode('utf8')) else: chatMessage = ' > {0} has joined the channel {1}! '.format(clientName, self.channel_name) socket.sendall(chatMessage.encode('utf8')) def broadcast_message(self, chatMessage, clientName=''): for name, socket in self.clients.items(): if name is clientName: socket.sendall(("You: " + chatMessage).encode('utf8')) else: socket.sendall((clientName + chatMessage).encode('utf8')) def remove_client_from_channel(self, clientName): del self.clients[clientName] leave_message = " " + clientName + " has left the channel " + self.channel_name + " "  self.broadcast_message(leave_message) 

------------------------------------------------------------------------------------------------------------------------------------------------------------------

BaseEntry.py

---------------------------------------------------------------------------------------------------------------------------------------------------------------

import tkinter as tk class BaseEntry(tk.Entry): def __init__(self, root=None, placeholder="PlaceHolder", color="grey", **options): super().__init__(root, options) self.placeholder = placeholder self.placeholder_color = color self.default_fg_color = self['fg'] self.bind("", self.focus_in) self.bind("", self.focus_out) self.put_placeholder() def put_placeholder(self): self.insert(0, self.placeholder) self['fg'] = self.placeholder_color def focus_in(self, *args): if self['fg'] == self.placeholder_color: self.delete('0', 'end') self['fg'] = self.default_fg_color def focus_out(self, *args): if not self.get(): self.put_placeholder() 

------------------------------------------------------------------------------------------------------------------

BaseDiolog.py

----------------------------------------------------------------------------------------------------------------

import tkinter as tk class BaseDialog(tk.Toplevel): def __init__(self, parent, title = None): tk.Toplevel.__init__(self, parent) self.transient(parent) # associate this dialog with parent window   if title: self.title(title) self.parent = parent self.result = None   body = tk.Frame(self) self.initial_focus = self.body(body) body.pack(padx=5, pady=5) """  createa an ok and cancel button and also binds the return and escape key.  """  self.buttonbox() self.grab_set() # makes the dialog modal.   if not self.initial_focus: self.initial_focus = self self.protocol("WM_DELETE_WINDOW", self.cancel) # position the dialog relative to the parent window  self.geometry("+%d+%d" % (parent.winfo_rootx()+50, parent.winfo_rooty()+50)) # move the keyboard focus to the appropriate widget.  self.initial_focus.focus_set() self.wait_window(self) def body(self, master): # create dialog body. return widget that should have initial focus.  # This method is meant to be overriden.  pass   def buttonbox(self): # add standard button box. override if you don't want the standard buttons.   box = tk.Frame(self) button = tk.Button(box, text="OK", width=10, bg="#CACACA", activebackground="#CACACA", command=self.ok, default=tk.ACTIVE) button.pack(side=tk.LEFT, padx=5, pady=5) button = tk.Button(box, text="Cancel", width=10, bg="#CACACA", activebackground="#CACACA", command=self.cancel) button.pack(side=tk.LEFT, padx=5, pady=5) self.bind("", self.ok) self.bind("", self.cancel) box.pack() def ok(self, event=None): if not self.validate(): self.initial_focus.focus_set() # put focus back  return   self.withdraw() self.update_idletasks() self.apply() self.cancel() def cancel(self, event=None): self.parent.focus_set() # puts focus back to the parent window.  self.destroy() def validate(self): return True # override if necessary   def apply(self): pass # override if necessary ------------------------------------------------------------------------ 

right now im using pycharm and when I run main I am supposed to get a list of commands, which I have but Im having trouble adding a few.

can someone help me add the following commands to the server

AWAY

CONNECT

DIE

INFO

The definitions of the commands can be found below

----------------------------------------------------------------------------------------------------------------------------------------------------------

AWAY[edit]

Syntax:

AWAY []

Provides the server with a message to automatically send in reply to a PRIVMSG directed at the user, but not to a channel they are on.[2] If is omitted, the away status is removed. Defined in RFC 1459.

CONNECT[edit]

Syntax:

CONNECT [ []] (RFC 1459)

CONNECT [] (RFC 2812)

Instructs the server (or the current server, if is omitted) to connect to on port .[3][4] This command should only be available to IRC operators. Defined in RFC 1459; the parameter became mandatory in RFC 2812.

DIE[edit]

Syntax:

DIE

Instructs the server to shut down.[5] This command may only be issued by IRC server operators. Defined in RFC 2812.

INFO[edit]

Syntax:

INFO []

Returns information about the server, or the current server if is omitted.[8] Information returned includes the servers version, when it was compiled, the patch level, when it was started, and any other information which may be considered to be relevant. Defined in RFC 1459.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

please help

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!