]> jfr.im git - erebus.git/blob - modules/sockets.py
start work on sockets module, not ready to use yet
[erebus.git] / modules / sockets.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/
4
5 # Note: this module doesn't do any kind of authentication, so anyone who can connect to the bound port can spam you.
6
7 # module info
8 modinfo = {
9 'author': 'Erebus Team',
10 'license': 'public domain',
11 'compatible': [0],
12 'depends': [],
13 'softdeps': [],
14 }
15
16 # preamble
17 import modlib
18 lib = modlib.modlib(__name__)
19 def modstart(parent, *args, **kwargs):
20 gotParent(parent)
21 return lib.modstart(parent, *args, **kwargs)
22 modstop = lib.modstop
23
24 # module code
25
26 def gotParent(parent):
27 for bindto, channel in parent.cfg.items('sockets'):
28 @lib.bind(bindto, data=channel)
29 class BasicServer(object):
30 def __init__(self, sock, data):
31 # The lambda bit is needed to make this copy the value-at-definition instead of using the closure value-at-runtime
32 self.chan = data
33 print(repr(self.chan))
34 self.buffer = b''
35 self.sock = sock
36
37 def getdata(self):
38 recvd = self.sock.recv(8192)
39 if recvd == b"": # EOF
40 if len(self.buffer) != 0:
41 # Process what's left in the buffer. We'll get called again after.
42 remaining_buf = self.buffer.decode('utf-8', 'backslashreplace')
43 self.buffer = b""
44 return [remaining_buf]
45 else:
46 # Nothing left in the buffer. Return None to signal the core to close this socket.
47 return None
48 self.buffer += recvd
49 lines = []
50
51 while b"\n" in self.buffer:
52 pieces = self.buffer.split(b"\n", 1)
53 s = pieces[0].decode('utf-8', 'backslashreplace').rstrip("\r")
54 lines.append(pieces[0].decode('utf-8', 'backslashreplace'))
55 self.buffer = pieces[1]
56
57 return lines
58
59 def parse(self, line):
60 bot = lib.parent.randbot()
61 maxlen = bot.maxmsglen() - len("PRIVMSG :") - len(self.chan)
62 while len(line) > maxlen:
63 cutat = line.rfind(' ', 0, maxlen)
64 if cutat == -1:
65 cutat = maxlen
66 bot.msg(self.chan, line[0:cutat])
67 line = line[cutat:].strip()
68 bot.msg(self.chan, line)
69
70 def send(self, line):
71 if lib.parent.parent.cfg.getboolean('debug', 'io'):
72 lib.parent.log(str(self), 'O', line)
73 self.sock.sendall(line.encode('utf-8', 'backslashreplace')+b"\r\n")
74
75 def _getsockerr(self):
76 try: # SO_ERROR might not exist on all platforms
77 return self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
78 except:
79 return None
80
81 def __str__(self):
82 return '%s#%d' % (__name__, self.sock.fileno())
83 def __repr__(self):
84 return '<%s #%d %s:%d>' % ((__name__, self.sock.fileno())+self.sock.getpeername())