mod_bridge.py

Sat, 11 Apr 2015 21:02:09 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sat, 11 Apr 2015 21:02:09 +0300
changeset 121
ac07779f788d
parent 120
9880bb697149
child 124
7b2cd8b1ba86
permissions
-rw-r--r--

- reworked mercurial repository handling, removed hardcoded values

import re
from configfile import Config
import irc as Irc

ModuleData = {
	'commands':
	[
		{
			'name': 'bridge',
			'description': 'Creates a bridge between two channels',
			'args': '<destination>',
			'level': 'admin',
		},

		{
			'name': 'unbridge',
			'description': 'Removes a bridge between two channels',
			'args': '<destination>',
			'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:
			# Stuff some control characters into the name so that this doesn't cause people who
			# are on both ends of the bridge to highlight themselves
			# sender = sender[0:len(sender)/2] + (Irc.BoldChar * 2)
			# sender += '_'
			sender = sender[:len(sender)/2] + '`' + sender[len(sender)/2:]

			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

mercurial