home
·
contact
·
privacy
projects
/
ircplom
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
bfa9adc
)
Move more server interaction logic into former SocketRecvLoop, now ConnectionLoop.
master
author
Christian Heller
<c.heller@plomlompom.de>
Tue, 10 Jun 2025 06:29:29 +0000
(08:29 +0200)
committer
Christian Heller
<c.heller@plomlompom.de>
Tue, 10 Jun 2025 06:29:29 +0000
(08:29 +0200)
ircplom.py
patch
|
blob
|
history
diff --git
a/ircplom.py
b/ircplom.py
index f85b62be1dbc2ae80f8e6226b2219a0edc6ab4a8..930b8874f7f1852f57f1dc10be6f1e7b466d9b1e 100755
(executable)
--- a/
ircplom.py
+++ b/
ircplom.py
@@
-61,6
+61,7
@@
class EventType(Enum):
CONN_ALERT = auto()
CONNECTED = auto()
CONN_WINDOW = auto()
CONN_ALERT = auto()
CONNECTED = auto()
CONN_WINDOW = auto()
+ DISCONNECTED = auto()
EXCEPTION = auto()
INIT_CONNECT = auto()
INIT_RECONNECT = auto()
EXCEPTION = auto()
INIT_CONNECT = auto()
INIT_RECONNECT = auto()
@@
-227,7
+228,7
@@
class IrcConnection:
self._login = login
self._socket: Optional[socket] = None
self._assumed_open = False
self._login = login
self._socket: Optional[socket] = None
self._assumed_open = False
- self._
recv_loop: Optional[SocketRecv
Loop] = None
+ self._
loop: Optional[Connection
Loop] = None
self._broadcast(EventType.CONN_WINDOW, self._idx)
self._start_connecting()
self._broadcast(EventType.CONN_WINDOW, self._idx)
self._start_connecting()
@@
-245,18
+246,18
@@
class IrcConnection:
return
self._socket.settimeout(TIMEOUT_LOOP)
self._assumed_open = True
return
self._socket.settimeout(TIMEOUT_LOOP)
self._assumed_open = True
- self._
broadcast(EventType.CONNECTED)
- self._recv_loop = SocketRecvLoop(self._idx, self._q_to_main,
-
self._read_lines()
)
+ self._
loop = ConnectionLoop(self._idx, self._q_to_main,
+ self._read_lines())
+
self._broadcast(EventType.CONNECTED, self._login
)
Thread(target=connect, daemon=True, args=(self,)).start()
def close(self):
Thread(target=connect, daemon=True, args=(self,)).start()
def close(self):
- 'Close both
SocketRecv
Loop and socket.'
+ 'Close both
Connection
Loop and socket.'
self._assumed_open = False
self._assumed_open = False
- if self._
recv_
loop:
- self._
recv_
loop.stop()
- self._
recv_
loop = None
+ if self._loop:
+ self._loop.stop()
+ self._loop = None
if self._socket:
self._socket.close()
self._socket = None
if self._socket:
self._socket.close()
self._socket = None
@@
-306,13
+307,6
@@
class IrcConnection:
def handle(self, event: Event) -> None:
'Process connection-directed Event into further steps.'
def handle(self, event: Event) -> None:
'Process connection-directed Event into further steps.'
- if event.type_ == EventType.CONNECTED:
- self._broadcast(EventType.SEND,
- IrcMessage('USER', [self._login[0], '0', '*',
- self._login[2]]))
- self._broadcast(EventType.SEND,
- IrcMessage('NICK', [self._login[1]]))
- return
if event.type_ == EventType.INIT_RECONNECT:
if self._assumed_open:
self._broadcast(EventType.CONN_ALERT,
if event.type_ == EventType.INIT_RECONNECT:
if self._assumed_open:
self._broadcast(EventType.CONN_ALERT,
@@
-320,17
+314,14
@@
class IrcConnection:
'so nothing to do.')
else:
self._start_connecting()
'so nothing to do.')
else:
self._start_connecting()
- return
- msg: IrcMessage = event.payload[1]
- if event.type_ == EventType.SEND:
+ elif event.type_ == EventType.CONNECTED:
+ assert self._loop is not None
+ self._loop.put(event)
+ elif event.type_ == EventType.DISCONNECTED:
+ self.close()
+ elif event.type_ == EventType.SEND:
+ msg: IrcMessage = event.payload[1]
self._write_line(msg.raw)
self._write_line(msg.raw)
- elif event.type_ == EventType.RECV:
- if msg.verb == 'PING':
- self._broadcast(EventType.SEND,
- IrcMessage('PONG', [msg.parameters[0]]))
- elif msg.verb == 'ERROR'\
- and msg.parameters[0].startswith('Closing link:'):
- self._assumed_open = False
class IrcMessage:
class IrcMessage:
@@
-339,12
+330,12
@@
class IrcMessage:
def __init__(self,
verb: str,
def __init__(self,
verb: str,
- parameters: Optional[
list[str
]] = None,
+ parameters: Optional[
tuple[str, ...
]] = None,
source: str = '',
tags: Optional[dict[str, str]] = None
) -> None:
self.verb: str = verb
source: str = '',
tags: Optional[dict[str, str]] = None
) -> None:
self.verb: str = verb
- self.parameters:
list[str] = parameters or []
+ self.parameters:
tuple[str, ...] = parameters or tuple()
self.source: str = source
self.tags: dict[str, str] = tags or {}
self.source: str = source
self.tags: dict[str, str] = tags or {}
@@
-372,7
+363,7
@@
class IrcMessage:
tags[key] = val
return tags
tags[key] = val
return tags
- def _split_params(str_params: str) ->
list[str
]:
+ def _split_params(str_params: str) ->
tuple[str, ...
]:
params = []
params_stage = 0 # 0: gap, 1: non-trailing, 2: trailing
for char in str_params:
params = []
params_stage = 0 # 0: gap, 1: non-trailing, 2: trailing
for char in str_params:
@@
-386,7
+377,7
@@
class IrcMessage:
params_stage += 1
continue
params[-1] += char
params_stage += 1
continue
params[-1] += char
- return
params
+ return
tuple(p for p in params)
stages = [_Stage('tags', '@', _parse_tags),
_Stage('source', ':'),
stages = [_Stage('tags', '@', _parse_tags),
_Stage('source', ':'),
@@
-744,7
+735,7
@@
class ConnectionWindow(Window):
def cmd__disconnect(self, quit_msg: str = 'ircplom says bye') -> None:
'Send QUIT command to server.'
self._broadcast(EventType.SEND,
def cmd__disconnect(self, quit_msg: str = 'ircplom says bye') -> None:
'Send QUIT command to server.'
self._broadcast(EventType.SEND,
- (self._conn_idx, IrcMessage('QUIT',
[quit_msg]
)))
+ (self._conn_idx, IrcMessage('QUIT',
(quit_msg, )
)))
def cmd__reconnect(self) -> None:
'Attempt reconnection.'
def cmd__reconnect(self) -> None:
'Attempt reconnection.'
@@
-898,16
+889,34
@@
class TuiLoop(Loop):
return None
return None
-class
SocketRecv
Loop(Loop):
+class
Connection
Loop(Loop):
'Loop receiving and translating socket messages towards main loop.'
def __init__(self, connection_idx: int, *args, **kwargs) -> None:
self._conn_idx = connection_idx
super().__init__(*args, **kwargs)
'Loop receiving and translating socket messages towards main loop.'
def __init__(self, connection_idx: int, *args, **kwargs) -> None:
self._conn_idx = connection_idx
super().__init__(*args, **kwargs)
+ def _send(self, verb: str, parameters: tuple[str, ...]) -> None:
+ self.broadcast(EventType.SEND, (self._conn_idx,
+ IrcMessage(verb, parameters)))
+
+ def process_main(self, event: Event) -> bool:
+ if not super().process_main(event):
+ return False
+ if event.type_ == EventType.CONNECTED:
+ login = event.payload[1]
+ self._send('USER', (login[0], '0', '*', login[2]))
+ self._send('NICK', (login[1],))
+ return True
+
def process_bonus(self, yielded: str) -> None:
def process_bonus(self, yielded: str) -> None:
- self.broadcast(EventType.RECV, (self._conn_idx,
- IrcMessage.from_raw(yielded)))
+ msg = IrcMessage.from_raw(yielded)
+ self.broadcast(EventType.RECV, (self._conn_idx, msg))
+ if msg.verb == 'PING':
+ self._send('PONG', (msg.parameters[0],))
+ if msg.verb == 'ERROR'\
+ and msg.parameters[0].startswith('Closing link:'):
+ self.broadcast(EventType.DISCONNECTED, (self._conn_idx,))
class KeyboardLoop(Loop):
class KeyboardLoop(Loop):
@@
-953,8
+962,12
@@
def run() -> None:
connections += [IrcConnection(q_to_main, len(connections),
*event.payload)]
elif event.type_ in {
connections += [IrcConnection(q_to_main, len(connections),
*event.payload)]
elif event.type_ in {
- EventType.CONNECTED, EventType.INIT_RECONNECT,
- EventType.RECV, EventType.SEND}:
+ EventType.CONNECTED,
+ EventType.DISCONNECTED,
+ EventType.INIT_RECONNECT,
+ EventType.RECV,
+ EventType.SEND,
+ }:
connections[event.payload[0]].handle(event)
finally:
for conn in connections:
connections[event.payload[0]].handle(event)
finally:
for conn in connections: