commandhandler.py

changeset 62
052a8a1e3d7d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commandhandler.py	Wed Nov 05 00:19:15 2014 +0200
@@ -0,0 +1,156 @@
+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
\ No newline at end of file

mercurial