def issueResolved(self, issue): if issue != self.currentIssue: #got resolved by someone else return log("Agent %s resolved issue \"%s\" resolution=%s" % (self.name, issue.description, issue.resolution), type='issues') self.currentIssue = None self.sop = None if self.available and any(self.issues): self.engage( self.issues.next() ) return issue
def issueResolved(self, issue): if issue != self.currentIssue: #got resolved by someone else return log("Agent %s resolved issue \"%s\" resolution=%s" % (self.name, issue.description, issue.resolution), type='issues') self.currentIssue = None self.sop = None if self.available and any(self.issues): self.engage(self.issues.next()) return issue
def postOptions(self): """used to decide what we need to do now. i am called by parseOptions. """ if self.running: return #if we are given external configuration use it overrides commandline if self.CONFIGFILE and os.path.exists(self.CONFIGFILE): from ConfigParser import ConfigParser as _cf _config = _cf() _config.read(self.CONFIGFILE) for key in self.keys(): if any([ i for i in self.optFlags if key in i]): continue #things like stop and nodaemon are not meant for config try: #attempt to update the keys t = type(self[key]) self[key] = t(_config.get('droned', key)) except: pass self.sanitize_droned(kill=self['stop']) if self['stop']: sys.exit(0)
def postOptions(self): """used to decide what we need to do now. i am called by parseOptions. """ if self.running: return #if we are given external configuration use it overrides commandline if self.CONFIGFILE and os.path.exists(self.CONFIGFILE): from ConfigParser import ConfigParser as _cf _config = _cf() _config.read(self.CONFIGFILE) for key in self.keys(): if any([i for i in self.optFlags if key in i]): continue #things like stop and nodaemon are not meant for config try: #attempt to update the keys t = type(self[key]) self[key] = t(_config.get('droned', key)) except: pass self.sanitize_droned(kill=self['stop']) if self['stop']: sys.exit(0)
def build_plugin(self, name): """build or lookup plugins @param name C{str} name of the application @return L{IDroneDApplication} provider """ if name in self._instanceMap: return self._instanceMap[name] #create a logging router logging = logWithContext( type="%s,plugin" % (name,), route='application' ) logging('dynamically building new plugin class') pluginConfig = self._config.get(name, {}) #look up the application class by name className = pluginConfig.get('CLASS') if isinstance(className, bool) and not className: return None #this is explicitly disabled in config #get the positional constructor args from configuration classArgs = tuple(pluginConfig.get('CLASSARGS', ())) #get the constructor keyword args from configuration classKwargs = pluginConfig.get('CLASSKWARGS', {}) #try to get your application plugin, defaults to builtin bases = (self._classMap.get(className, self._default),) MRO = set() for x in bases: MRO.add(x) for i in x.__bases__: MRO.add(i) #check if mro is ok MRO = any([b for b in MRO if ApplicationPlugin is b or \ issubclass(b, ApplicationPlugin)]) if not MRO: i = 'adding %s to %s for MRO safety' % \ (ApplicationPlugin, bases[0]) logging(i) #log what we are doing to take the mystory out of it. bases += (ApplicationPlugin,) else: logging('Method Resolution Order looks good') logging('Adding Storage API to the Plugin.') bases = (StorageMixin,) + bases ####################################################################### # new class defaults!!!! ####################################################################### #setup the plugin by dynamically building a new class based #off of the provided reference design. newClassName = "Plugin(app=%s, class=%s)" % (name, bases[1].__name__) logging('creating plugin %s' % (newClassName,)) plugin = self.makeAdaptable(type(newClassName, bases, { 'name': property(lambda s: name), 'service': property(lambda s: IDroneModelAppManager(s)), 'configuration': property(lambda s: pluginConfig), 'reactor': property(lambda s: reactor), 'STARTUP_INFO': { 'START_USEPTY' : 0, 'START_CHILDFD' : {0:'w',1:'r',2:'r'}, 'START_ENV' : {}, 'START_PATH' : None, 'START_CMD' : '/bin/true', 'START_ARGS' : (), }, 'SHUTDOWN_INFO': { 'STOP_USEPTY' : 0, 'STOP_CHILDFD' : {0:'w',1:'r',2:'r'}, 'STOP_ENV' : {}, 'STOP_PATH' : None, 'STOP_CMD' : '/bin/true', 'STOP_ARGS' : (), }, 'startProtocol': ApplicationProtocol, 'startProtoArgs': tuple(), 'startProtoKwargs': dict(), 'stopProtocol': ApplicationProtocol, 'stopProtoArgs': tuple(), 'stopProtoKwargs': dict(), })) #this guarentees we have a known API to work against #instantiate the plugin object with it's parameters self._instanceMap[name] = plugin(*classArgs, **classKwargs) self._instanceMap[name].log('application plugin interface initialized') self._pluginSetup(self._instanceMap[name]) return self._instanceMap[name]
def workNextIssue(self): while any(self.availableAgents) and any(self.pendingIssues): issue = self.pendingIssues.next() agent = self.availableAgents.next() agent.engage(issue) issue.whenResolved(lambda result: self.workNextIssue() or result)
def build_plugin(self, name): """build or lookup plugins @param name C{str} name of the application @return L{IDroneDApplication} provider """ if name in self._instanceMap: return self._instanceMap[name] #create a logging router logging = logWithContext(type="%s,plugin" % (name, ), route='application') logging('dynamically building new plugin class') pluginConfig = self._config.get(name, {}) #look up the application class by name className = pluginConfig.get('CLASS') if isinstance(className, bool) and not className: return None #this is explicitly disabled in config #get the positional constructor args from configuration classArgs = tuple(pluginConfig.get('CLASSARGS', ())) #get the constructor keyword args from configuration classKwargs = pluginConfig.get('CLASSKWARGS', {}) #try to get your application plugin, defaults to builtin bases = (self._classMap.get(className, self._default), ) MRO = set() for x in bases: MRO.add(x) for i in x.__bases__: MRO.add(i) #check if mro is ok MRO = any([b for b in MRO if ApplicationPlugin is b or \ issubclass(b, ApplicationPlugin)]) if not MRO: i = 'adding %s to %s for MRO safety' % \ (ApplicationPlugin, bases[0]) logging(i) #log what we are doing to take the mystory out of it. bases += (ApplicationPlugin, ) else: logging('Method Resolution Order looks good') logging('Adding Storage API to the Plugin.') bases = (StorageMixin, ) + bases ####################################################################### # new class defaults!!!! ####################################################################### #setup the plugin by dynamically building a new class based #off of the provided reference design. newClassName = "Plugin(app=%s, class=%s)" % (name, bases[1].__name__) logging('creating plugin %s' % (newClassName, )) plugin = self.makeAdaptable( type( newClassName, bases, { 'name': property(lambda s: name), 'service': property(lambda s: IDroneModelAppManager(s)), 'configuration': property(lambda s: pluginConfig), 'reactor': property(lambda s: config.reactor), 'STARTUP_INFO': { 'START_USEPTY': 0, 'START_CHILDFD': { 0: 'w', 1: 'r', 2: 'r' }, 'START_ENV': {}, 'START_PATH': None, 'START_CMD': '/bin/true', 'START_ARGS': (), }, 'SHUTDOWN_INFO': { 'STOP_USEPTY': 0, 'STOP_CHILDFD': { 0: 'w', 1: 'r', 2: 'r' }, 'STOP_ENV': {}, 'STOP_PATH': None, 'STOP_CMD': '/bin/true', 'STOP_ARGS': (), }, 'startProtocol': ApplicationProtocol, 'startProtoArgs': tuple(), 'startProtoKwargs': dict(), 'stopProtocol': ApplicationProtocol, 'stopProtoArgs': tuple(), 'stopProtoKwargs': dict(), })) #this guarentees we have a known API to work against #instantiate the plugin object with it's parameters self._instanceMap[name] = plugin(*classArgs, **classKwargs) self._instanceMap[name].log('application plugin interface initialized') self._pluginSetup(self._instanceMap[name]) return self._instanceMap[name]
class Team(Entity): jabber_service = property(lambda s: services.getService('jabber')) jabber_config = property(lambda s: s.jabber_service.SERVICECONFIG) availableAgents = property( lambda s: (agent for agent in s.agents if agent.available)) available = property(lambda self: any(self.availableAgents)) busy = property(lambda s: not s.available) rosterPath = property(lambda s: '%s/%s' % (s.jabber_config.JABBER_TEAM_ROSTER, s.name)) pendingIssues = property(lambda s: \ (i for i in Issue.objects if not i.resolved and i.assignedTo == s)) def __init__(self, name): self.name = name self.agents = set() self.worker = LoopingCall(self.workNextIssue) self.worker.start(5) self.loadRoster() def __getstate__(self): return { 'name': self.name, 'members': set(agent.jid for agent in self.agents), } @staticmethod def construct(state): team = Team(state['name']) team.agents = set(SupportAgent(jid) for jid in state['members']) return team def loadRoster(self): if not os.path.exists(self.rosterPath): log('no roster exists for the %s team, so it has no members!' % self.name, warning=True) return for line in open(self.rosterPath): line = line.strip() if not line or line.startswith('#'): continue jid = line agent = SupportAgent(jid) self.agents.add(agent) def saveRoster(self): jids = [agent.jid for agent in self.agents] content = '\n'.join(jids) + '\n' def blockingWrite(): roster = open(self.rosterPath, 'w') roster.write(content) roster.close() config.reactor.callInThread(blockingWrite) def addMember(self, jid): self.agents.add(SupportAgent(jid)) self.saveRoster() def removeMember(self, jid): self.agents.discard(SupportAgent(jid)) self.saveRoster() def workNextIssue(self): while any(self.availableAgents) and any(self.pendingIssues): issue = self.pendingIssues.next() agent = self.availableAgents.next() agent.engage(issue) issue.whenResolved(lambda result: self.workNextIssue() or result) def notify(self, message): for agent in self.agents: agent.tell("<b>%s team notification:</b> %s" % (self.name, message))