|
1 import os |
|
2 import re |
|
3 |
|
4 Modules = {} |
|
5 Commands = {} |
|
6 |
|
7 class CommandError (Exception): |
|
8 def __init__ (self, value): |
|
9 self.value = value |
|
10 def __str__ (self): |
|
11 return self.value |
|
12 |
|
13 # |
|
14 # init_data() |
|
15 # |
|
16 # Initializes command module data |
|
17 # |
|
18 def init_data(): |
|
19 global Commands |
|
20 global Modules |
|
21 files = os.listdir ('.') |
|
22 |
|
23 for fn in files: |
|
24 if fn[0:4] != 'mod_' or fn[-3:] != '.py': |
|
25 continue |
|
26 |
|
27 fn = fn[0:-3] |
|
28 globals = {} |
|
29 module = __import__ (fn) |
|
30 Modules[fn] = module |
|
31 |
|
32 for cmd in module.ModuleData['commands']: |
|
33 if cmd['args'] == None: |
|
34 cmd['args'] = '' |
|
35 |
|
36 cmd['module'] = module |
|
37 cmd['regex'] = make_regex (cmd['args']) |
|
38 cmd['argnames'] = [] |
|
39 Commands[cmd['name']] = cmd |
|
40 |
|
41 for argname in cmd['args'].split (' '): |
|
42 argname = argname[1:-1] |
|
43 |
|
44 if argname[-3:] == '...': |
|
45 argname = argname[0:-3] |
|
46 |
|
47 if argname == '': |
|
48 continue |
|
49 |
|
50 cmd['argnames'].append (argname) |
|
51 #done |
|
52 #done |
|
53 |
|
54 print "Loaded module %s" % fn |
|
55 #done |
|
56 |
|
57 print 'Loaded %d commands in %d modules' % (len (Commands), len (Modules)) |
|
58 #enddef |
|
59 |
|
60 # |
|
61 # command_error (message) |
|
62 # |
|
63 # Raises a command error |
|
64 # |
|
65 def command_error (message): |
|
66 raise CommandError (message) |
|
67 |
|
68 # |
|
69 # call_command (bot, message, cmdname, **kvargs) |
|
70 # |
|
71 # Calls a cobalt command |
|
72 # |
|
73 def call_command (bot, message, cmdname, **kvargs): |
|
74 try: |
|
75 cmd = Commands[cmdname] |
|
76 except KeyError: |
|
77 return False |
|
78 |
|
79 if cmd['level'] == 'admin' and not bot.is_admin (kvargs['ident'], kvargs['host']): |
|
80 command_error ("%s requires admin access" % cmdname) |
|
81 |
|
82 match = re.compile (cmd['regex']).match (message) |
|
83 |
|
84 if match == None: |
|
85 # didn't match |
|
86 command_error ('invalid arguments\nusage: %s %s' % (cmd['name'], cmd['args'])) |
|
87 #fi |
|
88 |
|
89 i = 1 |
|
90 args = {} |
|
91 |
|
92 for argname in cmd['argnames']: |
|
93 args[argname] = match.group (i) |
|
94 i += 1 |
|
95 #done |
|
96 |
|
97 getattr (cmd['module'], "cmd_%s" % cmdname) (bot=bot, cmdname=cmdname, args=args, **kvargs) |
|
98 return True |
|
99 |
|
100 # |
|
101 # make_regex |
|
102 # |
|
103 # Takes the argument list and returns a corresponding regular expression |
|
104 # |
|
105 def make_regex (arglist): |
|
106 if arglist == None: |
|
107 return '^.+$' |
|
108 |
|
109 gotoptional = False |
|
110 gotvariadic = False |
|
111 regex = '' |
|
112 |
|
113 for arg in arglist.split (' '): |
|
114 if gotvariadic: |
|
115 raise CommandError ('variadic argument is not last') |
|
116 |
|
117 if arg == '': |
|
118 continue |
|
119 |
|
120 if arg[0] == '[' and arg[-1] == ']': |
|
121 arg = arg[1:-1] |
|
122 gotoptional = True |
|
123 elif arg[0] == '<' and arg[-1] == '>': |
|
124 if gotoptional: |
|
125 raise CommandError ('mandatory argument after optional one') |
|
126 |
|
127 arg = arg[1:-1] |
|
128 else: |
|
129 raise CommandError ('badly formed argument list') |
|
130 #fi |
|
131 |
|
132 if arg[-3:] == '...': |
|
133 gotvariadic = True |
|
134 arg = arg[0:-3] |
|
135 #fi |
|
136 |
|
137 if gotoptional == False: |
|
138 regex += '\s+' |
|
139 else: |
|
140 regex += '\s*' |
|
141 |
|
142 if gotoptional: |
|
143 if gotvariadic: |
|
144 regex += r'(.*)' |
|
145 else: |
|
146 regex += r'([^ ]*)' |
|
147 else: |
|
148 if gotvariadic: |
|
149 regex += r'(.+)' |
|
150 else: |
|
151 regex += r'([^ ]+)' |
|
152 #fi |
|
153 #done |
|
154 |
|
155 return '^[^ ]+%s$' % regex |
|
156 #enddef |