]>
jfr.im git - erebus.git/blob - modules/example_socket.py
dc9076787ba4398367e9da6317582ce82458059a
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. (And the optional third argument you passed to bind_*, or None)
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`.
37 @lib.bind_tcp('0.0.0.0', 12543)
38 class BasicServer(object):
39 def __init__(self
, sock
, data
):
40 self
.chan
= lib
.parent
.cfg
.get('basic_socket', 'channel', '#')
45 recvd
= self
.sock
.recv(8192)
46 if recvd
== b
"": # EOF
47 if len(self
.buffer) != 0:
48 # Process what's left in the buffer. We'll get called again after.
49 remaining_buf
= self
.buffer.decode('utf-8', 'backslashreplace')
51 return [remaining_buf
]
53 # Nothing left in the buffer. Return None to signal the core to close this socket.
58 while b
"\n" in self
.buffer:
59 pieces
= self
.buffer.split(b
"\n", 1)
60 s
= pieces
[0].decode('utf-8', 'backslashreplace').rstrip("\r")
61 lines
.append(pieces
[0].decode('utf-8', 'backslashreplace'))
62 self
.buffer = pieces
[1]
66 def parse(self
, line
):
67 bot
= lib
.parent
.randbot()
68 maxlen
= bot
.maxmsglen() - len("PRIVMSG :") - len(self
.chan
)
69 while len(line
) > maxlen
:
70 cutat
= line
.rfind(' ', 0, maxlen
)
73 bot
.msg(self
.chan
, line
[0:cutat
])
74 line
= line
[cutat
:].strip()
75 bot
.msg(self
.chan
, line
)
78 if lib
.parent
.parent
.cfg
.getboolean('debug', 'io'):
79 lib
.parent
.log(str(self
), 'O', line
)
80 self
.sock
.sendall(line
.encode('utf-8', 'backslashreplace')+b
"\r\n")
82 def _getsockerr(self
):
83 try: # SO_ERROR might not exist on all platforms
84 return self
.socket
.getsockopt(socket
.SOL_SOCKET
, socket
.SO_ERROR
)
89 return '%s#%d' % (__name__
, self
.sock
.fileno())
91 return '<%s #%d %s:%d>' % ((__name__
, self
.sock
.fileno())+self
.sock
.getpeername())