|
1 import re |
|
2 from configfile import Config |
|
3 import irc as Irc |
|
4 |
|
5 ModuleData = { |
|
6 'commands': |
|
7 [ |
|
8 { |
|
9 'name': 'bridge', |
|
10 'description': 'Creates a bridge between two channels', |
|
11 'args': '<destination>', |
|
12 'level': 'admin', |
|
13 }, |
|
14 |
|
15 { |
|
16 'name': 'unbridge', |
|
17 'description': 'Removes a bridge between two channels', |
|
18 'args': '<destination>', |
|
19 'level': 'admin', |
|
20 }, |
|
21 ], |
|
22 |
|
23 'hooks': |
|
24 { |
|
25 'chanmsg': ['hook_chanmsg'], |
|
26 } |
|
27 } |
|
28 |
|
29 def get_destination (bot, target, destination, error): |
|
30 match = re.match (r'^([A-Za-z0-9_]+)/(#[#A-Za-z0-9_]*)$', destination) |
|
31 if not match: |
|
32 error ('malformed destination') |
|
33 |
|
34 destHost, destChannel = match.group (1, 2) |
|
35 dest = None |
|
36 |
|
37 # ensure we know this target |
|
38 for conndata in Config.get_nodelist ('connections'): |
|
39 if conndata.get_value('name') == destHost: |
|
40 break |
|
41 else: |
|
42 error ('unknown connection %s' % destHost) |
|
43 |
|
44 for channel in conndata.get_value('channels'): |
|
45 if channel['name'] == destChannel: |
|
46 break |
|
47 else: |
|
48 error ('unknown channel %s' % destChannel) |
|
49 |
|
50 if destHost == bot.name and destChannel == target: |
|
51 error ('cannot establish a bridge to self!') |
|
52 |
|
53 return (destHost, destChannel) |
|
54 |
|
55 def cmd_bridge (bot, target, args, reply, error, **rest): |
|
56 source = (bot.name, target) |
|
57 dest = get_destination (bot, target, args['destination'], error) |
|
58 sourceName = '%s/%s' % source |
|
59 destName = '%s/%s' % dest |
|
60 bridges = Config.get_node('bridges') |
|
61 |
|
62 if destName in bridges.get_value (sourceName, []) \ |
|
63 or sourceName in bridges.get_value (destName, []): |
|
64 error ('bridge to %s already established' % destName) |
|
65 |
|
66 bridges.append_value ('%s/%s' % source, '%s/%s' % dest) |
|
67 bridges.append_value ('%s/%s' % dest, '%s/%s' % source) |
|
68 reply ('bridge to %s established' % destName) |
|
69 |
|
70 def cmd_unbridge (bot, target, args, reply, error, **rest): |
|
71 source = (bot.name, target) |
|
72 dest = get_destination (bot, target, args['destination'], error) |
|
73 sourceName = '%s/%s' % source |
|
74 destName = '%s/%s' % dest |
|
75 bridges = Config.get_node('bridges') |
|
76 |
|
77 if destName in bridges.get_value (sourceName, []) \ |
|
78 or sourceName in bridges.get_value (destName, []): |
|
79 try: |
|
80 bridges.get_value (sourceName, []).remove (destName) |
|
81 bridges.get_value (destName, []).remove (sourceName) |
|
82 except ValueError: |
|
83 pass |
|
84 reply ('bridge to %s dropped' % destName) |
|
85 else: |
|
86 error ('no bridge to %s established' % destName) |
|
87 |
|
88 def hook_chanmsg (bot, channel, sender, message, **rest): |
|
89 sourceName = '%s/%s' % (bot.name, channel) |
|
90 |
|
91 for dest in Config.get_node('bridges').get_value (sourceName, []): |
|
92 try: |
|
93 clientName, channelName = dest.split ('/') |
|
94 Irc.get_client (clientName).privmsg (channelName, |
|
95 '[%s/%s] <%s> %s' % (bot.name, channel, sender, message)) |
|
96 except Exception as e: |
|
97 Irc.broadcast ('Error while bridging from %s to %s: %s' % |
|
98 (sourceName, dest, e)) |
|
99 pass |