]> jfr.im git - erebus.git/commitdiff
sockets - now working
authorJohn Runyon <redacted>
Wed, 20 Dec 2023 03:52:44 +0000 (20:52 -0700)
committerJohn Runyon <redacted>
Wed, 20 Dec 2023 03:52:44 +0000 (20:52 -0700)
modlib.py
modules/example_socket.py
modules/sockets.py

index 06276184ef27876a3c338adb94a0d3e2f473db8f..cc1c47c7a6ac179391c6bc268da0c161fb6814bc 100644 (file)
--- a/modlib.py
+++ b/modlib.py
@@ -170,7 +170,7 @@ class modlib(object):
                        return func
                return realhook
 
-       def bind(self, bindto):
+       def bind(self, bindto, data=None):
                """Used as a decorator on a class which implements getdata and parse methods.
                        See modules/sockets.py for an example.
                        Takes an arg like:
@@ -191,39 +191,36 @@ class modlib(object):
                        bindto = bindto[4:]
                if len(bindto) > 4 and bindto[0:4] == 'tcp:':
                        bindto = bindto[4:]
-               print(repr(bindto), ':' in bindto)
                if ':' in bindto:
-                       print(bindto)
                        pieces = bindto.rsplit(':', 1)
                        host = pieces[0]
                        bindto = pieces[1]
-                       print(pieces,host,bindto)
                port = int(bindto)
-               return self._hooksocket(af, ty, (host, port))
+               return self._hooksocket(af, ty, (host, port), data)
 
-       def bind_tcp(self, host, port):
-               return self._hooksocket(socket.AF_INET, socket.SOCK_STREAM, (host, port))
-       def bind_udp(self, host, port):
-               return self._hooksocket(socket.AF_INET, socket.SOCK_DGRAM, (host, port))
-       def bind_unix(self, path):
-               return self._hooksocket(socket.AF_UNIX, socket.SOCK_STREAM, path)
-       def _hooksocket(self, af, ty, address):
+       def bind_tcp(self, host, port, data=None):
+               return self._hooksocket(socket.AF_INET, socket.SOCK_STREAM, (host, port), data)
+       def bind_udp(self, host, port, data=None):
+               return self._hooksocket(socket.AF_INET, socket.SOCK_DGRAM, (host, port), data)
+       def bind_unix(self, path, data=None):
+               return self._hooksocket(socket.AF_UNIX, socket.SOCK_STREAM, path, data)
+       def _hooksocket(self, af, ty, address, data):
                def realhook(cls):
                        if not (hasattr(cls, 'getdata') and callable(cls.getdata)):
                                # Check early that the object implements getdata.
                                # If getdata ever returns a non-empty list, then a parse method must also exist, but we don't check that.
                                raise Exception('Attempted to hook a socket without a class to process data')
-                       self.sockhooks.append((af, ty, address, cls))
+                       self.sockhooks.append((af, ty, address, cls, data))
                        if self.parent is not None:
-                               self._create_socket(af, ty, address, cls)
+                               self._create_socket(af, ty, address, cls, data)
                        return cls
                return realhook
-       def _create_socket(self, af, ty, address, cls):
+       def _create_socket(self, af, ty, address, cls, data):
                ty = ty | socket.SOCK_NONBLOCK
                sock = socket.socket(af, ty)
                sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                sock.bind(address)
-               obj = _ListenSocket(self, sock, cls)
+               obj = _ListenSocket(self, sock, cls, data)
                self.sockets.append((sock,obj))
                sock.listen(5)
                self.parent.newfd(obj, sock.fileno())
@@ -281,11 +278,12 @@ class modlib(object):
                return realhook
 
 class _ListenSocket(object):
-       def __init__(self, lib, sock, cls):
+       def __init__(self, lib, sock, cls, data):
                self.clients = []
                self.lib = lib
                self.sock = sock
                self.cls = cls
+               self.data = data
 
        def _make_closer(self, obj, client):
                def close():
@@ -302,7 +300,7 @@ class _ListenSocket(object):
 
        def getdata(self):
                client, addr = self.sock.accept()
-               obj = self.cls(client)
+               obj = self.cls(client, self.data)
                obj.close = self._make_closer(obj, client)
                self.lib.parent.log(repr(self), '?', 'New connection #%d from %s' % (client.fileno(), addr))
                self.clients.append((client,obj))
index 1f6563d5c293f6c4653402d1ebd483dc542b87d9..dc9076787ba4398367e9da6317582ce82458059a 100644 (file)
@@ -25,7 +25,7 @@ modstop = lib.modstop
 # - listen on the socket `sock.listen()`
 # - accept `sock.accept()`
 #
-# Once a connection is accepted, your class is instantiated with the client socket.
+# Once a connection is accepted, your class is instantiated with the client socket. (And the optional third argument you passed to bind_*, or None)
 # - When data comes in on the client socket, your `getdata` method will be called. It should return a list of strings.
 # - For each element in the list returned by `getdata`, `parse` will be called.
 # - When the socket is being closed by the bot (f.e. your module is unloaded), the optional method `closing` will be called.
@@ -36,7 +36,7 @@ modstop = lib.modstop
 
 @lib.bind_tcp('0.0.0.0', 12543)
 class BasicServer(object):
-       def __init__(self, sock):
+       def __init__(self, sock, data):
                self.chan = lib.parent.cfg.get('basic_socket', 'channel', '#')
                self.buffer = b''
                self.sock = sock
index 0e96e0455889335d7a14dedac84a7c8866ebf95b..060057b5f182829b9a351964144443416cf3b998 100644 (file)
@@ -28,9 +28,9 @@ def gotParent(parent):
                @lib.bind(bindto, data=channel)
                class BasicServer(object):
                        def __init__(self, sock, data):
-                               # The lambda bit is needed to make this copy the value-at-definition instead of using the closure value-at-runtime
+                               # NB neither directly referencing `channel`, nor trying to pass it through a default-arg-to-a-lambda like the python docs suggest, works here.
+                               # Yay python. At least passing it via bind works.
                                self.chan = data
-                               print(repr(self.chan))
                                self.buffer = b''
                                self.sock = sock