Update main.py/client.py
This commit is contained in:
@@ -1,11 +1,3 @@
|
|||||||
# ==========================================================
|
|
||||||
# terminal chat standaard user = test passwd = test
|
|
||||||
# edit port at the comment with a arrow
|
|
||||||
# you have to ask the port of the srver at ben@de-roo.org or
|
|
||||||
# directly to me.
|
|
||||||
# have fun! (I guess)
|
|
||||||
# ==========================================================
|
|
||||||
|
|
||||||
import socket
|
import socket
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
@@ -13,18 +5,46 @@ import hashlib
|
|||||||
import json
|
import json
|
||||||
import getpass
|
import getpass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import time
|
|
||||||
import re
|
|
||||||
import threading
|
import threading
|
||||||
|
import readline
|
||||||
|
|
||||||
# kleuren
|
|
||||||
wit = "\x1b[97m"
|
wit = "\x1b[97m"
|
||||||
blauw_bg = "\x1b[44m"
|
blauw_bg = "\x1b[44m"
|
||||||
groen = "\x1b[92m"
|
groen = "\x1b[92m"
|
||||||
rood = "\x1b[91m"
|
rood = "\x1b[91m"
|
||||||
reset = "\x1b[0m"
|
reset = "\x1b[0m"
|
||||||
|
|
||||||
# terminal helpers
|
commands = ["/add", "/quit", "/break", "/users"]
|
||||||
|
chat_users = []
|
||||||
|
chat_messages = []
|
||||||
|
lock = threading.Lock()
|
||||||
|
|
||||||
|
def completer(text, state):
|
||||||
|
buffer = readline.get_line_buffer()
|
||||||
|
parts = buffer.split()
|
||||||
|
|
||||||
|
if not buffer.startswith("/"):
|
||||||
|
return None
|
||||||
|
|
||||||
|
if len(parts) == 1:
|
||||||
|
matches = [cmd for cmd in commands if cmd.startswith(parts[0])]
|
||||||
|
if state < len(matches):
|
||||||
|
return matches[state]
|
||||||
|
return None
|
||||||
|
|
||||||
|
if parts[0] == "/add" and len(parts) >= 2:
|
||||||
|
current_input = parts[-1]
|
||||||
|
matches = [user for user in chat_users if user.startswith(current_input)]
|
||||||
|
if state < len(matches):
|
||||||
|
return matches[state]
|
||||||
|
return None
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
readline.set_completer_delims(" \t\n")
|
||||||
|
readline.set_completer(completer)
|
||||||
|
readline.parse_and_bind("tab: complete")
|
||||||
|
|
||||||
def clear():
|
def clear():
|
||||||
os.system("cls" if os.name == "nt" else "clear")
|
os.system("cls" if os.name == "nt" else "clear")
|
||||||
|
|
||||||
@@ -35,13 +55,10 @@ def term_size():
|
|||||||
def print_white(text=""):
|
def print_white(text=""):
|
||||||
print(wit + text + reset)
|
print(wit + text + reset)
|
||||||
|
|
||||||
# login
|
|
||||||
def login():
|
def login():
|
||||||
base_dir = Path(__file__).parent
|
base_dir = Path(__file__).parent
|
||||||
passwd_file = base_dir / "passwd.json"
|
passwd_file = base_dir / "passwd.json"
|
||||||
if not passwd_file.exists():
|
if not passwd_file.exists():
|
||||||
print_white("Geen gebruikers.")
|
|
||||||
input(wit + "druk op een knop..." + reset)
|
|
||||||
return None
|
return None
|
||||||
try:
|
try:
|
||||||
with passwd_file.open("r", encoding="utf-8") as f:
|
with passwd_file.open("r", encoding="utf-8") as f:
|
||||||
@@ -52,13 +69,9 @@ def login():
|
|||||||
password = getpass.getpass(wit + "Wachtwoord: " + reset)
|
password = getpass.getpass(wit + "Wachtwoord: " + reset)
|
||||||
password_hash = hashlib.sha256(password.encode("utf-8")).hexdigest()
|
password_hash = hashlib.sha256(password.encode("utf-8")).hexdigest()
|
||||||
if user in data and data[user] == password_hash:
|
if user in data and data[user] == password_hash:
|
||||||
print(groen + "Login succesvol!" + reset)
|
|
||||||
return user
|
return user
|
||||||
print(rood + "Ongeldige gebruikersnaam of wachtwoord." + reset)
|
|
||||||
input(wit + "druk op een knop..." + reset)
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# signup
|
|
||||||
def signup():
|
def signup():
|
||||||
base_dir = Path(__file__).parent
|
base_dir = Path(__file__).parent
|
||||||
passwd_file = base_dir / "passwd.json"
|
passwd_file = base_dir / "passwd.json"
|
||||||
@@ -70,30 +83,20 @@ def signup():
|
|||||||
data = {}
|
data = {}
|
||||||
else:
|
else:
|
||||||
data = {}
|
data = {}
|
||||||
print_white("Nieuwe gebruiker")
|
|
||||||
user = input(wit + "Gebruiker: " + reset)
|
user = input(wit + "Gebruiker: " + reset)
|
||||||
if user in data:
|
if user in data:
|
||||||
print(rood + "Bestaat al." + reset)
|
|
||||||
input(wit + "druk op een knop..." + reset)
|
|
||||||
return
|
return
|
||||||
password = getpass.getpass(wit + "Wachtwoord: " + reset)
|
password = getpass.getpass(wit + "Wachtwoord: " + reset)
|
||||||
data[user] = hashlib.sha256(password.encode("utf-8")).hexdigest()
|
data[user] = hashlib.sha256(password.encode("utf-8")).hexdigest()
|
||||||
with passwd_file.open("w", encoding="utf-8") as f:
|
with passwd_file.open("w", encoding="utf-8") as f:
|
||||||
json.dump(data, f, indent=4)
|
json.dump(data, f, indent=4)
|
||||||
print(groen + "Succes!" + reset)
|
|
||||||
input(wit + "druk op een knop..." + reset)
|
|
||||||
|
|
||||||
# strip kleuren
|
|
||||||
def strip_ansi(s):
|
|
||||||
return re.sub(r'\x1b\[.*?m', '', s)
|
|
||||||
|
|
||||||
# login/signup loop
|
|
||||||
current_user = None
|
current_user = None
|
||||||
|
|
||||||
while not current_user:
|
while not current_user:
|
||||||
clear()
|
clear()
|
||||||
w, _ = term_size()
|
w, _ = term_size()
|
||||||
print(blauw_bg + wit + " Terminal Chat ".center(w) + reset)
|
print(blauw_bg + wit + "Terminal Chat ".center(w) + reset)
|
||||||
print_white("Welkom bij Python Terminal Chat!")
|
|
||||||
print_white("1. inloggen")
|
print_white("1. inloggen")
|
||||||
print_white("2. nieuw account")
|
print_white("2. nieuw account")
|
||||||
keuze = input(wit + " > " + reset)
|
keuze = input(wit + " > " + reset)
|
||||||
@@ -102,41 +105,24 @@ while not current_user:
|
|||||||
elif keuze == "2":
|
elif keuze == "2":
|
||||||
signup()
|
signup()
|
||||||
|
|
||||||
# connect
|
host = "192.168.254.36"
|
||||||
host = "192.168.254.138"
|
port = 44703
|
||||||
port = 44703 # <---- edit port
|
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
try:
|
try:
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
s.connect((host, port))
|
s.connect((host, port))
|
||||||
except:
|
|
||||||
print(rood + "Connectie mislukt" + reset)
|
|
||||||
exit()
|
|
||||||
|
|
||||||
# stuur username
|
|
||||||
try:
|
|
||||||
s.sendall(current_user.encode("utf-8"))
|
s.sendall(current_user.encode("utf-8"))
|
||||||
except:
|
except Exception as e:
|
||||||
print(rood + "Verbinding verloren" + reset)
|
print("Connection failed:", e)
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
# ontvang chatlijst
|
data = s.recv(4096)
|
||||||
try:
|
chat_data = json.loads(data.decode("utf-8"))
|
||||||
while True:
|
chat_names = list(chat_data.keys())
|
||||||
data = s.recv(4096)
|
|
||||||
if data:
|
|
||||||
chat_names = json.loads(data.decode("utf-8"))
|
|
||||||
break
|
|
||||||
except:
|
|
||||||
print(rood + "Verbinding verloren" + reset)
|
|
||||||
exit()
|
|
||||||
|
|
||||||
chat_messages = []
|
|
||||||
|
|
||||||
# teken chatwindow
|
|
||||||
def draw_chat_window(messages, chatname):
|
def draw_chat_window(messages, chatname):
|
||||||
clear()
|
clear()
|
||||||
w, h = term_size()
|
w, h = term_size()
|
||||||
print(blauw_bg + wit + chatname.center(w) + reset) # chat header
|
print(blauw_bg + wit + chatname.center(w) + reset)
|
||||||
available_lines = h - 3
|
available_lines = h - 3
|
||||||
to_display = messages[-available_lines:]
|
to_display = messages[-available_lines:]
|
||||||
for msg in to_display:
|
for msg in to_display:
|
||||||
@@ -148,49 +134,65 @@ def draw_chat_window(messages, chatname):
|
|||||||
print_white(f"[{user}] {text}")
|
print_white(f"[{user}] {text}")
|
||||||
print("-" * w)
|
print("-" * w)
|
||||||
|
|
||||||
# chat session
|
|
||||||
def chat_session(chatkeuze):
|
def chat_session(chatkeuze):
|
||||||
global chat_messages
|
global chat_messages
|
||||||
|
global chat_users
|
||||||
|
|
||||||
# open chat
|
|
||||||
s.sendall(json.dumps({"action": "openchat", "chat_name": chatkeuze}).encode("utf-8"))
|
s.sendall(json.dumps({"action": "openchat", "chat_name": chatkeuze}).encode("utf-8"))
|
||||||
data = s.recv(4096)
|
data = s.recv(4096)
|
||||||
try:
|
|
||||||
chat_data = json.loads(data.decode("utf-8"))
|
chat_data = json.loads(data.decode("utf-8"))
|
||||||
if chat_data:
|
|
||||||
chat_messages = list(chat_data[chatkeuze]["messages"])
|
|
||||||
except:
|
|
||||||
chat_messages = []
|
|
||||||
|
|
||||||
# ontvang berichten
|
if chatkeuze in chat_data:
|
||||||
|
chat_messages = chat_data[chatkeuze].get("messages", [])
|
||||||
|
chat_users = chat_data[chatkeuze].get("users", [])
|
||||||
|
|
||||||
def receive_messages(sock):
|
def receive_messages(sock):
|
||||||
global chat_messages
|
global chat_messages
|
||||||
|
global chat_users
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
data = sock.recv(4096)
|
data = sock.recv(4096)
|
||||||
if not data:
|
if not data:
|
||||||
|
break
|
||||||
|
|
||||||
|
decoded = json.loads(data.decode("utf-8"))
|
||||||
|
|
||||||
|
# /users response
|
||||||
|
if isinstance(decoded, dict) and decoded.get("type") == "users_list":
|
||||||
|
users = decoded.get("users", [])
|
||||||
|
print("\nUsers:", ", ".join(users))
|
||||||
|
print(wit + "Typ je bericht: " + reset, end="", flush=True)
|
||||||
continue
|
continue
|
||||||
try:
|
|
||||||
messages = json.loads(data.decode("utf-8"))
|
# normale chat update
|
||||||
chat_messages.extend(messages)
|
if isinstance(decoded, dict) and chatkeuze in decoded:
|
||||||
|
with lock:
|
||||||
|
chat_messages = decoded[chatkeuze].get("messages", [])
|
||||||
|
chat_users = decoded[chatkeuze].get("users", [])
|
||||||
|
|
||||||
draw_chat_window(chat_messages, chatkeuze)
|
draw_chat_window(chat_messages, chatkeuze)
|
||||||
print(wit + "Typ je bericht (/break om terug te gaan): " + reset, end="", flush=True)
|
print(wit + "Typ je bericht: " + reset, end="", flush=True)
|
||||||
except:
|
|
||||||
continue
|
except Exception:
|
||||||
except:
|
|
||||||
break
|
break
|
||||||
|
|
||||||
threading.Thread(target=receive_messages, args=(s,), daemon=True).start()
|
threading.Thread(target=receive_messages, args=(s,), daemon=True).start()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
draw_chat_window(chat_messages, chatkeuze)
|
draw_chat_window(chat_messages, chatkeuze)
|
||||||
bericht = input(wit + "Typ je bericht (/break om terug te gaan): " + reset)
|
bericht = input(wit + "Typ je bericht: " + reset)
|
||||||
|
|
||||||
if bericht.lower() == "/quit": # sluit
|
if bericht.lower() == "/quit":
|
||||||
exit()
|
exit()
|
||||||
elif bericht.lower() == "/break": # terug
|
elif bericht.lower() == "/break":
|
||||||
break
|
break
|
||||||
elif bericht.lower().startswith("/add "): # add user
|
elif bericht.lower() == "/users":
|
||||||
|
s.sendall(json.dumps({
|
||||||
|
"action": "get_users",
|
||||||
|
"chat": chatkeuze
|
||||||
|
}).encode("utf-8"))
|
||||||
|
elif bericht.lower().startswith("/add "):
|
||||||
target_user = bericht.split(" ", 1)[1]
|
target_user = bericht.split(" ", 1)[1]
|
||||||
s.sendall(json.dumps({
|
s.sendall(json.dumps({
|
||||||
"action": "add_user",
|
"action": "add_user",
|
||||||
@@ -198,15 +200,19 @@ def chat_session(chatkeuze):
|
|||||||
"user": target_user,
|
"user": target_user,
|
||||||
"by": current_user
|
"by": current_user
|
||||||
}).encode("utf-8"))
|
}).encode("utf-8"))
|
||||||
else: # verstuur
|
else:
|
||||||
|
with lock:
|
||||||
|
chat_messages.append({
|
||||||
|
"user": current_user,
|
||||||
|
"message": bericht
|
||||||
|
})
|
||||||
|
draw_chat_window(chat_messages, chatkeuze)
|
||||||
s.sendall(json.dumps({
|
s.sendall(json.dumps({
|
||||||
"action": "message",
|
"action": "message",
|
||||||
"chat_name": chatkeuze,
|
"chat_name": chatkeuze,
|
||||||
"message": bericht
|
"message": bericht
|
||||||
}).encode("utf-8"))
|
}).encode("utf-8"))
|
||||||
# chat_messages.append({"user": current_user, "message": bericht})
|
|
||||||
|
|
||||||
# main loop
|
|
||||||
while True:
|
while True:
|
||||||
print_white("Beschikbare chats:")
|
print_white("Beschikbare chats:")
|
||||||
for i, chat in enumerate(chat_names, start=1):
|
for i, chat in enumerate(chat_names, start=1):
|
||||||
@@ -214,13 +220,12 @@ while True:
|
|||||||
print_white(f"{len(chat_names)+1}. Nieuwe chat aanmaken")
|
print_white(f"{len(chat_names)+1}. Nieuwe chat aanmaken")
|
||||||
keuze = input(wit + " > " + reset)
|
keuze = input(wit + " > " + reset)
|
||||||
|
|
||||||
if keuze.isdigit() and int(keuze) == len(chat_names)+1: # #chataanmaken
|
if keuze.isdigit() and int(keuze) == len(chat_names)+1:
|
||||||
nieuwe_chat = input("Naam van nieuwe chat: ")
|
nieuwe_chat = input("Naam van nieuwe chat: ")
|
||||||
s.sendall(json.dumps({"action": "new_chat", "chat_name": nieuwe_chat}).encode("utf-8"))
|
s.sendall(json.dumps({"action": "new_chat", "chat_name": nieuwe_chat}).encode("utf-8"))
|
||||||
data = s.recv(4096)
|
data = s.recv(4096)
|
||||||
if data:
|
chat_data = json.loads(data.decode("utf-8"))
|
||||||
chat_names = json.loads(data.decode("utf-8"))
|
chat_names = list(chat_data.keys())
|
||||||
|
elif keuze.isdigit() and 1 <= int(keuze) <= len(chat_names):
|
||||||
elif keuze.isdigit() and 1 <= int(keuze) <= len(chat_names): # #chat openen
|
|
||||||
chatkeuze = chat_names[int(keuze)-1]
|
chatkeuze = chat_names[int(keuze)-1]
|
||||||
chat_session(chatkeuze)
|
chat_session(chatkeuze)
|
||||||
|
|||||||
Reference in New Issue
Block a user