11from PyQt6 .QtCore import QObject , pyqtSignal , pyqtSlot
2- from PyQt6 .QtNetwork import QTcpSocket
3- from PyQt6 .QtWidgets import QApplication , QVBoxLayout , QLineEdit , QDialogButtonBox , QDialog , QLabel
4-
2+ from PyQt6 .QtNetwork import QSslSocket
3+ from src .irc .logger import Logger
4+ import datetime
5+
56class IRCClient (QObject ):
67 received_message = pyqtSignal (str )
78
8- def __init__ (self , server , port , nickname , realname , channel ):
9+ def __init__ (self , server , port , nickname , realname , channel , use_ssl = False ):
910 super ().__init__ ()
1011
11- self .socket = QTcpSocket ()
12+ self .socket = QSslSocket ()
1213 self .socket .readyRead .connect (self .on_ready_read )
1314 self .socket .errorOccurred .connect (self .on_error_occurred )
15+ self .socket .connected .connect (self .start_encryption )
1416
1517 self .server = server
1618 self .port = port
1719 self .nickname = nickname
1820 self .realname = realname
1921 self .channel = channel
22+ self .use_ssl = use_ssl
23+
24+ self .logger = Logger ('logs/irc_client.log' ) # Create an instance of Logger
25+ self .logger .info (f'Initialized IRCClient with server={ server } , port={ port } , nickname={ nickname } , realname={ realname } , channel={ channel } , use_ssl={ use_ssl } ' )
26+
27+ @pyqtSlot ()
28+ def start_encryption (self ):
29+ pass
2030
2131 def connect_to_host (self ):
22- self .socket .connectToHost (self .server , self .port )
32+ if self .use_ssl and not QSslSocket .supportsSsl ():
33+ self .logger .error ("This system does not support SSL." )
34+ return
35+
36+ self .logger .info (f'Connecting to host { self .server } :{ self .port } ' )
37+ if self .use_ssl :
38+ self .socket .connectToHostEncrypted (self .server , self .port )
39+ else :
40+ self .socket .connectToHost (self .server , self .port )
2341 self .send_command (f'NICK { self .nickname } ' )
2442 self .send_command (f'USER { self .nickname } 0 * :{ self .realname } ' )
43+ self .logger .info (f'Connected to host { self .server } :{ self .port } with SSL={ self .use_ssl } ' )
2544
2645 def decode (self , bytes ):
2746 encodings = ['utf-8' , 'latin1' , 'iso-8859-1' , 'cp1252' ]
@@ -30,12 +49,22 @@ def decode(self, bytes):
3049 return bytes .decode (encoding )
3150 except UnicodeDecodeError :
3251 continue
52+ self .logger .error ('None of the encodings could decode the bytes.' )
3353 raise UnicodeDecodeError ("None of the encodings could decode the bytes." )
3454
3555 def parse_message (self , message ):
56+
57+ tags = {}
58+ server_time = None
59+ if message .startswith ('@' ):
60+ tags_str , message = message [1 :].split (' ' , 1 )
61+ tags = dict (tag .split ('=' ) for tag in tags_str .split (';' ))
62+ if 'time' in tags :
63+ server_time = datetime .datetime .fromisoformat (tags ['time' ].replace ('Z' , '+00:00' ))
64+
3665 parts = message .split ()
3766 if len (parts ) < 2 :
38- return None , None , []
67+ return None , None , [], tags , server_time
3968 source = parts [0 ][1 :] if parts [0 ].startswith (':' ) else None
4069 command = parts [1 ] if source else parts [0 ]
4170 args_start = 2 if source else 1
@@ -49,16 +78,17 @@ def parse_message(self, message):
4978 args .append (part )
5079 if trailing_arg_start is not None :
5180 args .append (' ' .join (parts [trailing_arg_start :])[1 :])
52- return source , command , args
81+ return source , command , args , tags , server_time
5382
5483 @pyqtSlot ()
5584 def on_ready_read (self ):
5685 while self .socket .canReadLine ():
5786 line = self .socket .readLine ().data ()
5887 line = self .decode (line ).strip ()
5988 self .received_message .emit (line )
89+ self .logger .debug (f'Received line: { line } ' )
6090
61- source , command , args = self .parse_message (line )
91+ source , command , args , _ , _ = self .parse_message (line )
6292
6393 if command == 'NICK' and source .split ('!' )[0 ] == self .nickname :
6494 self .nickname = args [0 ]
@@ -70,15 +100,18 @@ def on_ready_read(self):
70100 elif 'End of /MOTD command.' in line :
71101 self .send_command (f'JOIN { self .channel } ' )
72102
73- @pyqtSlot (QTcpSocket .SocketError )
103+ @pyqtSlot (QSslSocket .SocketError )
74104 def on_error_occurred (self , socket_error ):
75- print (f'Error occurred: { self .socket .errorString ()} ' )
105+ self . logger . error (f'Error occurred on the socket : { self .socket .errorString ()} ' )
76106
77107 def send_command (self , command ):
108+ self .logger .info (f'Sending command: { command } ' )
78109 if ' ' in command :
79110 cmd , args = command .split (' ' , 1 )
80111 if cmd in ['JOIN' , 'PART' ]:
81112 args = args .split (' ' , 1 )[0 ]
82113 self .socket .write (f'{ cmd } { args } \r \n ' .encode ())
114+ self .logger .info (f'Sent command: { cmd } { args } ' ) # Log the command sent
83115 else :
84- self .socket .write (f'{ command } \r \n ' .encode ())
116+ self .socket .write (f'{ command } \r \n ' .encode ())
117+ self .logger .info (f'Sent command: { command } ' ) # Log the command sent
0 commit comments