]>
jfr.im git - erebus.git/blob - modules/basic_socket.py
1 # Erebus IRC bot - Author: Erebus Team
2 # vim: fileencoding=utf-8
3 # This file is released into the public domain; see http://unlicense.org/
7 'author': 'Erebus Team',
8 'license': 'public domain',
16 lib
= modlib
.modlib(__name__
)
17 modstart
= lib
.modstart
22 # Note: bind_* does all of the following:
23 # - create a socket `sock = socket.socket()`
24 # - bind the socket `sock.bind()`
25 # - listen on the socket `sock.listen()`
26 # - accept `sock.accept()`
28 # Once a connection is accepted, your class is instantiated with the client socket.
29 # - When data comes in on the client socket, your `getdata` method will be called. It should return a list of strings.
30 # - For each element in the list returned by `getdata`, `parse` will be called.
31 # - When the socket is being closed by the bot (f.e. your module is unloaded), the optional method `closing` will be called.
32 # Then the bot will call `sock.shutdown()` and `sock.close()` for you.
33 # XXX error handling? what happens when the other side closes the socket?
35 # You can interact with the rest of the bot through `lib.parent`.
36 @lib.bind_tcp('0.0.0.0', 12543)
37 class BasicServer(object):
38 def __init__(self
, sock
):
43 recvd
= self
.sock
.recv(8192)
45 if len(self
.buffer) != 0:
46 # Process what's left in the buffer. We'll get called again after.
47 remaining_buf
= self
.buffer.decode('utf-8', 'backslashreplace')
49 return [remaining_buf
]
51 # Nothing left in the buffer. Return None to signal the core to close this socket.
56 while b
"\n" in self
.buffer:
57 pieces
= self
.buffer.split(b
"\n", 1)
58 s
= pieces
[0].decode('utf-8', 'backslashreplace').rstrip("\r")
59 lines
.append(pieces
[0].decode('utf-8', 'backslashreplace'))
60 self
.buffer = pieces
[1]
64 def parse(self
, line
):
65 peer
= self
.sock
.getpeername()
66 lib
.parent
.randbot().msg('#', "%s:%d says: %s" % (peer
[0], peer
[1], line
))
69 self
.socket
.sendall(line
.encode('utf-8', 'backslashreplace')+b
"\r\n")
71 def _getsockerr(self
):
72 try: # SO_ERROR might not exist on all platforms
73 return self
.socket
.getsockopt(socket
.SOL_SOCKET
, socket
.SO_ERROR
)