]> jfr.im git - erebus.git/blob - modules/sockets.py
admin_config - add !getconfig, remove some unused functions
[erebus.git] / modules / sockets.py
1 # Erebus IRC bot - Author: Erebus Team
2 # vim: fileencoding=utf-8
3 # Configurable sockets module. DO NOT USE without understanding the risks
4 # This file is released into the public domain; see http://unlicense.org/
5
6 # Note: this module doesn't do any kind of authentication, so anyone who can connect to the bound port can spam you.
7
8 """
9 To use - add in bot.config something like:
10
11 [sockets]
12 127.0.0.1:1337 = #example
13
14 The left side is the address to listen on and the right side is the channel to send to.
15 The exmaple will send incoming lines/packets on localhost, port 1337 to channel #example
16
17 The full syntax for the address is:
18 [unix:]</path/to/socket>
19 [udp|tcp:][<ip>:]<port>
20
21
22 Address examples:
23
24 Unix domain socket: /path
25 Unix domain socket: unix:/path
26 TCP socket (all interfaces): 1337
27 TCP socket (one interface): 127.0.0.1:1337
28 UDP socket (all interfaces): udp:1337
29 UDP socket (one interface): udp:127.0.0.1:1337
30 """
31
32 # module info
33 modinfo = {
34 'author': 'Erebus Team',
35 'license': 'public domain',
36 'compatible': [0],
37 'depends': [],
38 'softdeps': [],
39 }
40
41 # preamble
42 import modlib
43 lib = modlib.modlib(__name__)
44 def modstart(parent, *args, **kwargs):
45 gotParent(parent)
46 return lib.modstart(parent, *args, **kwargs)
47 modstop = lib.modstop
48
49 # module code
50 class BasicServer(lib.Socketlike):
51 def __init__(self, sock, data):
52 super(BasicServer, self).__init__(sock, data)
53 # NB neither directly referencing `channel`, nor trying to pass it through a default-arg-to-a-lambda like the python docs suggest, works here.
54 # Yay python. At least passing it via bind works.
55 self.chan = data
56
57 # default getdata() and send() methods are defined by lib.Socketlike
58 # suitable for line-based protocols like IRC
59
60 def parse(self, line):
61 try:
62 bot = lib.parent.channel(self.chan).bot
63 except AttributeError: # <class 'AttributeError'> 'NoneType' object has no attribute 'bot'
64 bot = lib.parent.randbot()
65 maxlen = bot.maxmsglen() - len("PRIVMSG :") - len(self.chan)
66 while len(line) > maxlen:
67 cutat = line.rfind(' ', 0, maxlen)
68 if cutat == -1:
69 cutat = maxlen
70 bot.msg(self.chan, line[0:cutat])
71 line = line[cutat:].strip()
72 bot.msg(self.chan, line)
73
74 # default __str__() and __repr__() methods are defined by lib.Socketlike
75
76 def gotParent(parent):
77 for bindto, channel in parent.cfg.items('sockets'):
78 lib.bind(bindto, data=channel)(BasicServer)