commandhandler.py

Wed, 05 Nov 2014 01:38:08 +0200

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Wed, 05 Nov 2014 01:38:08 +0200
changeset 64
384167adad2b
parent 62
052a8a1e3d7d
permissions
-rw-r--r--

- restart correctly after updating

import os
import re

CommandModules = {}
Commands = {}

class CommandError (Exception):
	def __init__ (self, value):
		self.value = value
	def __str__ (self):
		return self.value

#
# init_data()
#
# Initializes command module data
#
def init_data():
	global Commands
	global CommandModules
	files = os.listdir ('.')

	for fn in files:
		if fn[0:4] != 'cmd_' or fn[-3:] != '.py':
			continue

		fn = fn[0:-3]
		globals = {}
		module = __import__ (fn)
		CommandModules[fn] = module

		for cmd in module.ModuleData['commands']:
			if cmd['args'] == None:
				cmd['args'] = ''

			cmd['module'] = module
			cmd['regex'] = make_regex (cmd['args'])
			cmd['argnames'] = []
			Commands[cmd['name']] = cmd

			for argname in cmd['args'].split (' '):
				argname = argname[1:-1]

				if argname[-3:] == '...':
					argname = argname[0:-3]

				if argname == '':
					continue

				cmd['argnames'].append (argname)
			#done
		#done

		print "Loaded command module %s" % fn
	#done

	print 'Loaded %d commands in %d modules' % (len (Commands), len (CommandModules))
#enddef

#
# command_error (message)
#
# Raises a command error
#
def command_error (message):
	raise CommandError (message)

#
# call_command (bot, message, cmdname, **kvargs)
#
# Calls a cobalt command
#
def call_command (bot, message, cmdname, **kvargs):
	try:
		cmd = Commands[cmdname]
	except KeyError:
		return False

	if cmd['level'] == 'admin' and not bot.is_admin (kvargs['ident'], kvargs['host']):
		command_error ("%s requires admin access" % cmdname)

	match = re.compile (cmd['regex']).match (message)

	if match == None:
		# didn't match
		command_error ('invalid arguments\nusage: %s %s' % (cmd['name'], cmd['args']))
	#fi

	i = 1
	args = {}

	for argname in cmd['argnames']:
		args[argname] = match.group (i)
		i += 1
	#done

	getattr (cmd['module'], "cmd_%s" % cmdname) (bot=bot, cmdname=cmdname, args=args, **kvargs)
	return True

#
# make_regex
#
# Takes the argument list and returns a corresponding regular expression
#
def make_regex (arglist):
	if arglist == None:
		return '^.+$'

	gotoptional = False
	gotvariadic = False
	regex = ''

	for arg in arglist.split (' '):
		if gotvariadic:
			raise CommandError ('variadic argument is not last')

		if arg == '':
			continue

		if arg[0] == '[' and arg[-1] == ']':
			arg = arg[1:-1]
			gotoptional = True
		elif arg[0] == '<' and arg[-1] == '>':
			if gotoptional:
				raise CommandError ('mandatory argument after optional one')

			arg = arg[1:-1]
		else:
			raise CommandError ('badly formed argument list')
		#fi

		if arg[-3:] == '...':
			gotvariadic = True
			arg = arg[0:-3]
		#fi

		if gotoptional == False:
			regex += '\s+'
		else:
			regex += '\s*'

		if gotoptional:
			if gotvariadic:
				regex += r'(.*)'
			else:
				regex += r'([^ ]*)'
		else:
			if gotvariadic:
				regex += r'(.+)'
			else:
				regex += r'([^ ]+)'
		#fi
	#done

	return '^[^ ]+%s$' % regex
#enddef

mercurial