From: Christian Heller Date: Sat, 7 Jun 2025 18:08:06 +0000 (+0200) Subject: Allow reconnecting. X-Git-Url: https://plomlompom.com/repos/%7B%7Bdb.prefix%7D%7D/%22https:/validator.w3.org/tasks?a=commitdiff_plain;h=HEAD;p=ircplom Allow reconnecting. --- diff --git a/ircplom.py b/ircplom.py index 186bd75..5b18324 100755 --- a/ircplom.py +++ b/ircplom.py @@ -147,7 +147,6 @@ class Terminal: class IrcConnection: 'Abstracts socket connection, loop over it, and handling messages from it.' - _socket: socket def __init__(self, q_to_main: EventQueue, @@ -157,17 +156,23 @@ class IrcConnection: ) -> None: self._idx = idx self._q_to_main = q_to_main + self._hostname = hostname self._login = login + self._socket: Optional[socket] = None self._assumed_open = False self._recv_loop: Optional[SocketRecvLoop] = None - self._socket = socket() - self._socket.settimeout(TIMEOUT_CONNECT) self._broadcast('CONNECTION_WINDOW', self._idx) + self._start_connecting() + + def _start_connecting(self) -> None: def connect(self): - self._broadcast('CONN_ALERT', f'Connecting to {hostname} …') + self._socket = socket() + self._broadcast('CONN_ALERT', + f'Connecting to {self._hostname} …') + self._socket.settimeout(TIMEOUT_CONNECT) try: - self._socket.connect((hostname, PORT)) + self._socket.connect((self._hostname, PORT)) except (TimeoutError, socket_gaierror) as e: self._broadcast('CONN_ALERT', str(e)) return @@ -184,7 +189,10 @@ class IrcConnection: self._assumed_open = False if self._recv_loop: self._recv_loop.stop() - self._socket.close() + self._recv_loop = None + if self._socket: + self._socket.close() + self._socket = None def _broadcast(self, type_: str, payload: Any = None) -> None: 'Send event to main loop via queue, with connection index as 1st arg.' @@ -192,6 +200,7 @@ class IrcConnection: def _read_lines(self) -> Iterator[Optional[str]]: 'Receive line-separator-delimited messages from socket.' + assert self._socket is not None bytes_total = b'' buffer_linesep = b'' while True: @@ -222,7 +231,7 @@ class IrcConnection: def _write_line(self, line: str) -> None: 'Send line-separator-delimited message over socket.' - if not self._assumed_open: + if not (self._socket and self._assumed_open): self._broadcast('CONN_ALERT', 'cannot send, assuming connection closed') return @@ -235,6 +244,13 @@ class IrcConnection: '*', self._login[2]])) self._broadcast('SEND', IrcMessage('NICK', [self._login[1]])) return + if event.type_ == 'INIT_RECONNECTION': + if self._assumed_open: + self._broadcast('CONN_ALERT', 'Reconnect called, but still ' + 'seem connected, so nothing to do.') + else: + self._start_connecting() + return msg: IrcMessage = event.payload[1] if event.type_ == 'SEND': self._write_line(msg.raw) @@ -689,6 +705,14 @@ class TuiLoop(Loop): self._window_idx = idx self.window.draw() + def cmd__reconnect(self) -> Optional[str]: + 'Send INIT_RECONNECTION to server if in connection window.' + if self.window not in self._conn_windows: + return 'can only reconnect from inside connection window.' + conn_idx = self._conn_windows.index(self.window) + self.broadcast('INIT_RECONNECTION', (conn_idx,)) + return None + def cmd__connect(self, hostname: str, username: str, @@ -804,7 +828,8 @@ def run() -> None: if event.type_ == 'INIT_CONNECTION': connections += [IrcConnection(q_to_main, len(connections), *event.payload)] - elif event.type_ in {'CONNECTED', 'RECV', 'SEND'}: + elif event.type_ in { + 'CONNECTED', 'INIT_RECONNECTION', 'RECV', 'SEND'}: connections[event.payload[0]].handle(event) finally: for conn in connections: