mirror of
https://github.com/Xevion/tcp-chat.git
synced 2025-12-06 03:16:44 -06:00
fix help command without argument, change from default DEBUG level to individually configured, comments/docs/formatting, improved imports, remove REFRESH CLIENT LIST request
This commit is contained in:
@@ -29,7 +29,6 @@ class Requests:
|
||||
The Requests class provides a universal naming for the types of requests that can be made and received.
|
||||
"""
|
||||
REQUEST_NICK = 'REQUEST_NICK' # Send the server the client's nickname
|
||||
REFRESH_CONNECTIONS_LIST = 'REFRESH_CLIENT_LIST' # Send the client all connections to the server and their information
|
||||
GET_MESSAGE_HISTORY = 'GET_MESSAGE_HISTORY' # Send the client a detailed list of all messages sent up to a certain point.
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import logging
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG,
|
||||
format='[%(asctime)s] [%(levelname)s] [%(threadName)s] %(message)s')
|
||||
logging.basicConfig(format='[%(asctime)s] [%(levelname)s] [%(threadName)s] %(message)s')
|
||||
|
||||
@@ -11,6 +11,7 @@ if TYPE_CHECKING:
|
||||
from server.handler import Client
|
||||
|
||||
logger = logging.getLogger('commands')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
class CommandHandler:
|
||||
@@ -24,10 +25,13 @@ class CommandHandler:
|
||||
self.client = client
|
||||
self.aliases = {}
|
||||
self.commands = {}
|
||||
self.__install_command(self.reroll, 'Reroll', 'reroll', 'Change your color to a random color.', aliases=['newcolor'])
|
||||
self.__install_command(self.help, 'Help', 'help', 'Get info on a given commands functionality and more.', aliases=['about', 'doc'])
|
||||
self.__install_command(self.reroll, 'Reroll', 'reroll', 'Change your color to a random color.',
|
||||
aliases=['newcolor'])
|
||||
self.__install_command(self.help, 'Help', 'help', 'Get info on a given commands functionality and more.',
|
||||
aliases=['about', 'doc'])
|
||||
|
||||
def __install_command(self, func: Callable, name: str = None, command_name: str = None, description: str = '', aliases: List[str] = None):
|
||||
def __install_command(self, func: Callable, name: str = None, command_name: str = None, description: str = '',
|
||||
aliases: List[str] = None):
|
||||
if aliases is None:
|
||||
aliases = []
|
||||
|
||||
@@ -75,21 +79,24 @@ class CommandHandler:
|
||||
Randomly change the client's color to a different color.
|
||||
"""
|
||||
i = 0
|
||||
newColor = self.client.color
|
||||
new_color = self.client.color
|
||||
choices = constants.Colors.has_contrast(float(minimum_contrast))
|
||||
|
||||
while i < 50 and newColor == self.client.color:
|
||||
newColor = random.choice(choices)
|
||||
while i < 50 and new_color == self.client.color:
|
||||
new_color = random.choice(choices)
|
||||
|
||||
self.client.color = newColor
|
||||
contrast = round(constants.Colors.WHITE.contrast_ratio(newColor), 1)
|
||||
return f'Changed your color to {newColor.name} ({newColor.hex}/{contrast})'
|
||||
self.client.color = new_color
|
||||
contrast = round(constants.Colors.WHITE.contrast_ratio(new_color), 1)
|
||||
return f'Changed your color to {new_color.name} ({new_color.hex}/{contrast})'
|
||||
|
||||
def help(self, command: str) -> Optional[str]:
|
||||
def help(self, command: str = None) -> Optional[str]:
|
||||
"""
|
||||
Print information about a given command
|
||||
:return:
|
||||
"""
|
||||
if command is None:
|
||||
return f"'help' requires 1 argument (command: str)."
|
||||
|
||||
if command in self.aliases.keys():
|
||||
command = self.aliases[command]
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ from typing import List
|
||||
import constants
|
||||
|
||||
logger = logging.getLogger('database')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
lock = threading.Lock()
|
||||
|
||||
|
||||
@@ -20,6 +22,9 @@ class Database(object):
|
||||
return self.__isClosed
|
||||
|
||||
def close(self) -> None:
|
||||
"""
|
||||
Closes the database connection and record it's connection status.
|
||||
"""
|
||||
if self.__isClosed:
|
||||
logger.warning(f'Database connection is already closed.', exc_info=True)
|
||||
else:
|
||||
@@ -30,7 +35,9 @@ class Database(object):
|
||||
with lock:
|
||||
cur = self.conn.cursor()
|
||||
try:
|
||||
# check if the table exists
|
||||
cur.execute('''SELECT name FROM sqlite_master WHERE type='table' AND name='?';''', 'message')
|
||||
# if it doesn't exist, create the table and report it
|
||||
if cur.fetchone() is None:
|
||||
self.conn.execute('''CREATE TABLE message
|
||||
(id INTEGER PRIMARY KEY,
|
||||
@@ -55,6 +62,7 @@ class Database(object):
|
||||
:return: The unique integer primary key chosen for the message, i.e. it's ID.
|
||||
"""
|
||||
with lock:
|
||||
with self.conn:
|
||||
cur = self.conn.cursor()
|
||||
try:
|
||||
cur.execute('''INSERT INTO message (nickname, connection_hash, color, message, timestamp)
|
||||
|
||||
@@ -13,9 +13,9 @@ import helpers
|
||||
from exceptions import DataReceptionException
|
||||
from server import db
|
||||
from server.commands import CommandHandler
|
||||
from server.db import Database
|
||||
|
||||
logger = logging.getLogger('handler')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
class BaseClient(object):
|
||||
@@ -23,12 +23,12 @@ class BaseClient(object):
|
||||
|
||||
def __init__(self, conn: socket.socket, all_clients: List['Client'], address) -> None:
|
||||
self.conn, self.all_clients, self.address = conn, all_clients, address
|
||||
self.db: Optional[Database] = None
|
||||
self.db: Optional[db.Database] = None
|
||||
|
||||
def connect_database(self):
|
||||
if self.db is None:
|
||||
logger.debug('Connecting client to database.')
|
||||
self.db = Database()
|
||||
self.db = db.Database()
|
||||
|
||||
def send(self, message: bytes) -> None:
|
||||
"""Sends a pre-encoded message to this client."""
|
||||
@@ -89,7 +89,7 @@ class Client(BaseClient):
|
||||
def connect_database(self) -> None:
|
||||
if self.db is None:
|
||||
logger.debug(f'Connecting Client({self.id[:8]}) to the database.')
|
||||
self.db = Database()
|
||||
self.db = db.Database()
|
||||
|
||||
def request_nickname(self) -> None:
|
||||
"""Send a request for the client's nickname information."""
|
||||
@@ -149,13 +149,19 @@ class Client(BaseClient):
|
||||
else:
|
||||
logger.info(f'{self.nickname} changed their name to {nickname}')
|
||||
self.nickname = nickname
|
||||
# New nickname has to be sent to all clients
|
||||
for client in self.all_clients:
|
||||
client.send_connections_list()
|
||||
|
||||
def close(self) -> None:
|
||||
logger.info(f'Client {self.id} closed. ({self.nickname})')
|
||||
self.conn.close() # Close socket connection
|
||||
self.all_clients.remove(self) # Remove the user from the global client list
|
||||
self.broadcast_message(f'{self.nickname} left!') # Now we can broadcast it's exit message
|
||||
self.db.conn.close() # Close database connection
|
||||
# Inform all clients of the disconnected client
|
||||
for client in self.all_clients:
|
||||
client.send_connections_list()
|
||||
self.db.close() # Close database connection
|
||||
|
||||
def handle(self) -> None:
|
||||
self.connect_database()
|
||||
@@ -164,8 +170,6 @@ class Client(BaseClient):
|
||||
data = self.receive()
|
||||
|
||||
if data['type'] == constants.Types.REQUEST:
|
||||
if data['request'] == constants.Requests.REFRESH_CONNECTIONS_LIST:
|
||||
self.send_connections_list()
|
||||
if data['request'] == constants.Requests.GET_MESSAGE_HISTORY:
|
||||
self.send_message_history(
|
||||
limit=data.get('limit', 50), time_limit=data.get('time_limit', 60 * 30)
|
||||
|
||||
@@ -12,6 +12,7 @@ server.bind((host, port))
|
||||
server.listen()
|
||||
|
||||
logger = logging.getLogger('server')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
clients = []
|
||||
|
||||
@@ -28,6 +29,10 @@ def receive():
|
||||
clients.append(client)
|
||||
client.request_nickname()
|
||||
|
||||
# Inform all clients of new client, give new client connections list
|
||||
for client in clients:
|
||||
client.send_connections_list()
|
||||
|
||||
# Start Handling Thread For Client
|
||||
thread = threading.Thread(target=client.handle, name=client.id[:8])
|
||||
thread.start()
|
||||
|
||||
Reference in New Issue
Block a user