-
Notifications
You must be signed in to change notification settings - Fork 14
/
autonomic.py
290 lines (205 loc) · 6.67 KB
/
autonomic.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
import inspect
import sys
from config import load_config
from id import Id
from pprint import pprint
# The core of the library methodology used
# by MongoBot. All brainmeats are Dendrites,
# inheriting the state of the cortex as the
# cortex monitors the chatroom. It also adds
# some shortcuts to cortex functions.
# future experiment
def router(self):
destination = self.values.pop(0)
if not self[destination].create_command: return
return self[destination]()
def autocommand(fn_name):
def add(object):
object.routed = True
object[fn_name] = router
return object
return add
class Dendrite(object):
config = None
secrets = None
def __init__(self, cortex):
self.cx = cortex
name = type(self).__name__.lower()
# Load in brainmeats specific secrets and only make those available as first
# class secrets to the brainmeats
if name in self.cx.secrets:
self.secrets = self.cx.secrets[name]
# Load in config file by the same name as the brainmeats, if available
try:
self.config = load_config('config/%s.yaml' % name)
except Exception as e:
print e
pass
def chat(self, what, target=False, error=False):
self.cx.chat(what, target, error)
def debug(self, what, target=False):
self.cx.debug(what, target)
def announce(self, what, channel=None):
self.cx.announce(what, channel)
def _act(self, what, public=False, target=False):
self.cx.act(what, public, target)
def validate(self):
return self.cx.validate()
@property
def botname(self):
return self.cx.thalamus.name
@property
def values(self):
return self.cx.values
@property
def flags(self):
return self.cx.flags
@property
def butler(self):
return self.cx.butler
@property
def lastsender(self):
return self.cx.lastsender
@property
def lastid(self):
return self.cx.lastid
@property
def lastip(self):
return self.cx.lastip
@property
def context(self):
return self.cx.context
@property
def context_is_channel(self):
return self.cx.context.startswith('#')
@property
def members(self):
return self.cx.members
@property
def settings(self):
return self.cx.settings
@property
def ego(self):
return self.cx.personality
# @property
# def mysender(self):
# return Id(self.cx.lastsender)
# This is what the cortex uses to setup the brainmeat
# libs, according to the decorators on the classes and
# functions in the lib.
def serotonin(cortex, meatname, electroshock):
brainmeat = cortex.brainmeats[meatname]
methods = inspect.getmembers(brainmeat)
helps = []
if hasattr(brainmeat, 'routed'):
cortex.commands[meatname] = brainmeat[meatname]
return
for name, method in methods:
if not hasattr(method, 'create_command'):
continue
if hasattr(method, 'help') and method.help:
me = cortex.amnesia()
help_text = method.help.replace('%NICK%', me.nick)
helps.append('%s%s %s' % (cortex.settings.bot.command_prefix, name, help_text))
else:
helps.append('%s%s (undocumented)' % (cortex.settings.bot.command_prefix, name))
if hasattr(method, 'public_command'):
cortex.public_commands.append(name)
if name in cortex.commands and not electroshock:
print "Warning: overwriting %s command" % name
cortex.commands[name] = method
if hasattr(method, 'aliases') and method.aliases:
for item in method.aliases:
cortex.commands[item] = method
cortex.helpmenu[meatname] = ['No commands for this meat.']
if len(helps):
cortex.helpmenu[meatname] = sorted(helps)
helpfile = open('helpfiles/%s' % meatname, 'w')
for item in sorted(helps):
helpfile.write("%s\n" % item)
# Neurons hold some vesicles. Vesicles are cool.
class Neurons(object):
cortex = None
vesicles = {}
# Cerebellum is needed on any class that has
# methods that will be used as receptors - this is
# due to pythons way of handling decorators and
# not binding them until the class is defined,
# which is not how receptors should be utilized.
#
# aka, this be a hack
def Cerebellum(object):
for name, method in object.__dict__.iteritems():
if hasattr(method, 'is_receptor'):
receptors = Neurons.vesicles.get(method.name, [])
receptors.append({object.__name__.lower(): method.neuron})
Neurons.vesicles.update({method.name: receptors})
return object
# Synapse is an event emitting decorator that will
# fire off a neuron to all receptors that are
# listening for the passed keyword.
#
# Usage:
#
# @Synapse('my_keyword')
# def some_method():
# ...
class Synapse(Neurons):
def __init__(self, neuron):
self.neuron = neuron
def __call__(self, neuron):
def glutamate(*args, **kwargs):
neurotransmission = neuron(*args, **kwargs)
vesicles = self.vesicles.get(self.neuron, [])
for vesicle in vesicles:
for name in vesicle:
if name and name in self.cortex.brainmeats:
vesicle[name](self.cortex.brainmeats[name], *(neurotransmission or []))
return neurotransmission
return glutamate
# Receptor is an observer decorator that will
# auto trigger when a neuron is fired using
# a keyword the receptor is listening for.
#
# Usage:
#
# @Receptor('my_keyword')
# def do_something():
# ....
def Receptor(name, *args, **kwargs):
class AutoReceptor(Neurons):
def __init__(self, neuron, name=False):
self.neuron = neuron
self.name = name
self.is_receptor = True
def glutamate(function, *args, **kwargs):
return AutoReceptor(function, name)
return glutamate
# Decorators, yo
# Proposed:
# @requires(vars, connections, installs)
# Makes the function available as
# a chat command, using the function
# name.
def axon(fn):
fn.create_command = True
return fn
# Makes the function available
# to non-registered users.
def public(fn):
fn.public_command = True
return fn
# Tell people your function is
# there and how to use it.
def help(text):
def add(fn):
fn.help = text
return fn
return add
# Don't want to type out findfreechildpornwithukmirrors?
# @alias(['perv', 'seriouslydude', 'gethelp'])
def alias(*args):
def add(fn):
fn.aliases = args
return fn
return add