diff -r 6c0609395889 -r dbf49689af0d mod_bridge.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_bridge.py Thu Jan 15 19:06:14 2015 +0200 @@ -0,0 +1,99 @@ +import re +from configfile import Config +import irc as Irc + +ModuleData = { + 'commands': + [ + { + 'name': 'bridge', + 'description': 'Creates a bridge between two channels', + 'args': '', + 'level': 'admin', + }, + + { + 'name': 'unbridge', + 'description': 'Removes a bridge between two channels', + 'args': '', + 'level': 'admin', + }, + ], + + 'hooks': + { + 'chanmsg': ['hook_chanmsg'], + } +} + +def get_destination (bot, target, destination, error): + match = re.match (r'^([A-Za-z0-9_]+)/(#[#A-Za-z0-9_]*)$', destination) + if not match: + error ('malformed destination') + + destHost, destChannel = match.group (1, 2) + dest = None + + # ensure we know this target + for conndata in Config.get_nodelist ('connections'): + if conndata.get_value('name') == destHost: + break + else: + error ('unknown connection %s' % destHost) + + for channel in conndata.get_value('channels'): + if channel['name'] == destChannel: + break + else: + error ('unknown channel %s' % destChannel) + + if destHost == bot.name and destChannel == target: + error ('cannot establish a bridge to self!') + + return (destHost, destChannel) + +def cmd_bridge (bot, target, args, reply, error, **rest): + source = (bot.name, target) + dest = get_destination (bot, target, args['destination'], error) + sourceName = '%s/%s' % source + destName = '%s/%s' % dest + bridges = Config.get_node('bridges') + + if destName in bridges.get_value (sourceName, []) \ + or sourceName in bridges.get_value (destName, []): + error ('bridge to %s already established' % destName) + + bridges.append_value ('%s/%s' % source, '%s/%s' % dest) + bridges.append_value ('%s/%s' % dest, '%s/%s' % source) + reply ('bridge to %s established' % destName) + +def cmd_unbridge (bot, target, args, reply, error, **rest): + source = (bot.name, target) + dest = get_destination (bot, target, args['destination'], error) + sourceName = '%s/%s' % source + destName = '%s/%s' % dest + bridges = Config.get_node('bridges') + + if destName in bridges.get_value (sourceName, []) \ + or sourceName in bridges.get_value (destName, []): + try: + bridges.get_value (sourceName, []).remove (destName) + bridges.get_value (destName, []).remove (sourceName) + except ValueError: + pass + reply ('bridge to %s dropped' % destName) + else: + error ('no bridge to %s established' % destName) + +def hook_chanmsg (bot, channel, sender, message, **rest): + sourceName = '%s/%s' % (bot.name, channel) + + for dest in Config.get_node('bridges').get_value (sourceName, []): + try: + clientName, channelName = dest.split ('/') + Irc.get_client (clientName).privmsg (channelName, + '[%s/%s] <%s> %s' % (bot.name, channel, sender, message)) + except Exception as e: + Irc.broadcast ('Error while bridging from %s to %s: %s' % + (sourceName, dest, e)) + pass