Tchatapp 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- client.py +88 -0
- server.py +114 -0
- tchatapp-1.0.0.dist-info/METADATA +13 -0
- tchatapp-1.0.0.dist-info/RECORD +6 -0
- tchatapp-1.0.0.dist-info/WHEEL +5 -0
- tchatapp-1.0.0.dist-info/top_level.txt +2 -0
client.py
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import socket
|
|
2
|
+
import threading
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
# Color codes
|
|
6
|
+
RED = "\x1b[38;5;196m"
|
|
7
|
+
GREEN = "\033[38;5;156m"
|
|
8
|
+
BLUE = "\033[38;5;75m"
|
|
9
|
+
WHITE = "\033[38;5;231m"
|
|
10
|
+
ORANGE = "\033[38;5;208m"
|
|
11
|
+
CYAN = "\033[1;36m"
|
|
12
|
+
RESET = "\033[0m"
|
|
13
|
+
|
|
14
|
+
class ChatClient:
|
|
15
|
+
def __init__(self, host='localhost', port=5000):
|
|
16
|
+
self.host = host
|
|
17
|
+
self.port = port
|
|
18
|
+
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
19
|
+
|
|
20
|
+
def connect(self):
|
|
21
|
+
"""Connect to the server"""
|
|
22
|
+
try:
|
|
23
|
+
self.socket.connect((self.host, self.port))
|
|
24
|
+
print(f"{GREEN}[✓] Connected to server{RESET}")
|
|
25
|
+
|
|
26
|
+
name_prompt = self.socket.recv(1024).decode()
|
|
27
|
+
print(f"{CYAN}{name_prompt}{RESET}", end='')
|
|
28
|
+
name = input()
|
|
29
|
+
self.socket.send(name.encode())
|
|
30
|
+
|
|
31
|
+
receive_thread = threading.Thread(target=self.receive_messages)
|
|
32
|
+
receive_thread.daemon = True
|
|
33
|
+
receive_thread.start()
|
|
34
|
+
|
|
35
|
+
self.send_messages()
|
|
36
|
+
|
|
37
|
+
except Exception as e:
|
|
38
|
+
print(f"{RED}[✗] Connection error: {e}{RESET}")
|
|
39
|
+
finally:
|
|
40
|
+
self.socket.close()
|
|
41
|
+
|
|
42
|
+
def receive_messages(self):
|
|
43
|
+
"""Receive messages from server"""
|
|
44
|
+
while True:
|
|
45
|
+
try:
|
|
46
|
+
message = self.socket.recv(1024).decode()
|
|
47
|
+
if message:
|
|
48
|
+
print(f"\n{message}")
|
|
49
|
+
print(f"{WHITE}You: {RESET}", end='', flush=True)
|
|
50
|
+
except:
|
|
51
|
+
break
|
|
52
|
+
|
|
53
|
+
def send_messages(self):
|
|
54
|
+
"""Send messages to server"""
|
|
55
|
+
print(f"\n{CYAN}[Tip: type /quit to exit]{RESET}\n")
|
|
56
|
+
|
|
57
|
+
while True:
|
|
58
|
+
try:
|
|
59
|
+
message = input(f"{WHITE}You: {RESET}")
|
|
60
|
+
if message:
|
|
61
|
+
self.socket.send(message.encode())
|
|
62
|
+
if message.lower() == '/quit':
|
|
63
|
+
print(f"{ORANGE}Leaving chat...{RESET}")
|
|
64
|
+
break
|
|
65
|
+
except Exception as e:
|
|
66
|
+
print(f"{RED}[✗] Send error: {e}{RESET}")
|
|
67
|
+
break
|
|
68
|
+
|
|
69
|
+
def main():
|
|
70
|
+
"""Entry point for CLI"""
|
|
71
|
+
import argparse
|
|
72
|
+
|
|
73
|
+
parser = argparse.ArgumentParser(description='PyChat Client')
|
|
74
|
+
parser.add_argument('--host', default='localhost', help='Server host (default: localhost)')
|
|
75
|
+
parser.add_argument('--port', type=int, default=5000, help='Server port (default: 5000)')
|
|
76
|
+
|
|
77
|
+
args = parser.parse_args()
|
|
78
|
+
|
|
79
|
+
print(f"{CYAN}{'='*50}{RESET}")
|
|
80
|
+
print(f"{CYAN} Chat Client {RESET}")
|
|
81
|
+
print(f"{CYAN}{'='*50}{RESET}\n")
|
|
82
|
+
print(f"{GREEN}[*] Connecting to {args.host}:{args.port}{RESET}")
|
|
83
|
+
|
|
84
|
+
client = ChatClient(host=args.host, port=args.port)
|
|
85
|
+
client.connect()
|
|
86
|
+
|
|
87
|
+
if __name__ == "__main__":
|
|
88
|
+
main()
|
server.py
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import socket
|
|
2
|
+
import threading
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
# Color codes
|
|
6
|
+
RED = "\x1b[38;5;196m"
|
|
7
|
+
GREEN = "\033[38;5;156m"
|
|
8
|
+
BLUE = "\033[38;5;75m"
|
|
9
|
+
WHITE = "\033[38;5;231m"
|
|
10
|
+
ORANGE = "\033[38;5;208m"
|
|
11
|
+
CYAN = "\033[1;36m"
|
|
12
|
+
RESET = "\033[0m"
|
|
13
|
+
|
|
14
|
+
class ChatServer:
|
|
15
|
+
def __init__(self, host='0.0.0.0', port=5000):
|
|
16
|
+
self.host = host
|
|
17
|
+
self.port = port
|
|
18
|
+
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
19
|
+
self.clients = []
|
|
20
|
+
self.client_names = {}
|
|
21
|
+
|
|
22
|
+
def start(self):
|
|
23
|
+
"""Start the server"""
|
|
24
|
+
try:
|
|
25
|
+
self.server_socket.bind((self.host, self.port))
|
|
26
|
+
self.server_socket.listen(5)
|
|
27
|
+
print(f"{GREEN}[✓] Server started at {self.host}:{self.port}{RESET}")
|
|
28
|
+
print(f"{CYAN}[*] Waiting for clients...{RESET}\n")
|
|
29
|
+
|
|
30
|
+
while True:
|
|
31
|
+
client_socket, client_address = self.server_socket.accept()
|
|
32
|
+
print(f"{ORANGE}[+] New connection: {client_address}{RESET}")
|
|
33
|
+
|
|
34
|
+
client_thread = threading.Thread(
|
|
35
|
+
target=self.handle_client,
|
|
36
|
+
args=(client_socket, client_address)
|
|
37
|
+
)
|
|
38
|
+
client_thread.daemon = True
|
|
39
|
+
client_thread.start()
|
|
40
|
+
|
|
41
|
+
except Exception as e:
|
|
42
|
+
print(f"{RED}[✗] Server error: {e}{RESET}")
|
|
43
|
+
finally:
|
|
44
|
+
self.server_socket.close()
|
|
45
|
+
|
|
46
|
+
def handle_client(self, client_socket, client_address):
|
|
47
|
+
"""Handle individual client connections"""
|
|
48
|
+
client_name = None
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
client_socket.send("Enter your name: ".encode())
|
|
52
|
+
client_name = client_socket.recv(1024).decode().strip()
|
|
53
|
+
|
|
54
|
+
if not client_name:
|
|
55
|
+
client_name = f"User_{len(self.clients)+1}"
|
|
56
|
+
|
|
57
|
+
self.clients.append(client_socket)
|
|
58
|
+
self.client_names[client_socket] = client_name
|
|
59
|
+
|
|
60
|
+
print(f"{GREEN}[+] {client_name} joined{RESET}")
|
|
61
|
+
|
|
62
|
+
self.broadcast(f"{CYAN}[!] {client_name} joined the chat{RESET}", client_socket)
|
|
63
|
+
|
|
64
|
+
while True:
|
|
65
|
+
message = client_socket.recv(1024).decode()
|
|
66
|
+
|
|
67
|
+
if not message:
|
|
68
|
+
break
|
|
69
|
+
|
|
70
|
+
if message.lower() == '/quit':
|
|
71
|
+
break
|
|
72
|
+
|
|
73
|
+
print(f"{BLUE}[{client_name}]: {message}{RESET}")
|
|
74
|
+
self.broadcast(f"{BLUE}[{client_name}]: {WHITE}{message}{RESET}", client_socket)
|
|
75
|
+
|
|
76
|
+
except Exception as e:
|
|
77
|
+
print(f"{RED}[✗] Client error ({client_name}): {e}{RESET}")
|
|
78
|
+
|
|
79
|
+
finally:
|
|
80
|
+
if client_socket in self.clients:
|
|
81
|
+
self.clients.remove(client_socket)
|
|
82
|
+
|
|
83
|
+
if client_socket in self.client_names:
|
|
84
|
+
name = self.client_names[client_socket]
|
|
85
|
+
del self.client_names[client_socket]
|
|
86
|
+
print(f"{RED}[-] {name} left{RESET}")
|
|
87
|
+
self.broadcast(f"{ORANGE}[!] {name} left the chat{RESET}")
|
|
88
|
+
|
|
89
|
+
client_socket.close()
|
|
90
|
+
|
|
91
|
+
def broadcast(self, message, sender_socket=None):
|
|
92
|
+
"""Send message to all clients except sender"""
|
|
93
|
+
for client in self.clients:
|
|
94
|
+
if client != sender_socket:
|
|
95
|
+
try:
|
|
96
|
+
client.send(message.encode())
|
|
97
|
+
except:
|
|
98
|
+
pass
|
|
99
|
+
|
|
100
|
+
def main():
|
|
101
|
+
"""Entry point for CLI"""
|
|
102
|
+
import argparse
|
|
103
|
+
|
|
104
|
+
parser = argparse.ArgumentParser(description='PyChat Server')
|
|
105
|
+
parser.add_argument('--host', default='0.0.0.0', help='Server host (default: 0.0.0.0)')
|
|
106
|
+
parser.add_argument('--port', type=int, default=5000, help='Server port (default: 5000)')
|
|
107
|
+
|
|
108
|
+
args = parser.parse_args()
|
|
109
|
+
|
|
110
|
+
server = ChatServer(host=args.host, port=args.port)
|
|
111
|
+
server.start()
|
|
112
|
+
|
|
113
|
+
if __name__ == "__main__":
|
|
114
|
+
main()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: Tchatapp
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A simple chat application
|
|
5
|
+
Author-email: Mr Tan <mrtanvai@gmail.com>
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Requires-Python: >=3.7
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
# pychatapp
|
|
13
|
+
secure chat
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
client.py,sha256=8iL0oO-WnDQGq8MvedXcqy_imxVxhjMB3BdhAFeQ0aE,2790
|
|
2
|
+
server.py,sha256=up94aM4P1VO8xiGdS8fF-WBCddNRA1YFsIVnp49GYhQ,3940
|
|
3
|
+
tchatapp-1.0.0.dist-info/METADATA,sha256=ilfD2BDHvBdx8bslDfW-pmjATWXErdybnfrA5HaKnx8,363
|
|
4
|
+
tchatapp-1.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
5
|
+
tchatapp-1.0.0.dist-info/top_level.txt,sha256=KwhQx6Np9abTSEPy-jGTR0d0L38g9ZW1Io1VGoS9ejE,14
|
|
6
|
+
tchatapp-1.0.0.dist-info/RECORD,,
|