From: Christian Heller <c.heller@plomlompom.de>
Date: Sat, 7 Jun 2025 18:08:06 +0000 (+0200)
Subject: Allow reconnecting.
X-Git-Url: https://plomlompom.com/repos/%22https:/validator.w3.org/static/tasks?a=commitdiff_plain;h=1d410763aa0987f8fa5aba5c34e9a24782ab9f31;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: