update commands.py from xmpppy cvs
This commit is contained in:
parent
7ee643c02e
commit
6e50f0bbc0
1 changed files with 73 additions and 55 deletions
|
@ -1,4 +1,4 @@
|
||||||
## $Id: commands.py,v 1.4 2005/04/30 07:33:11 snakeru Exp $
|
## $Id: commands.py,v 1.9 2005/09/23 18:32:21 normanr Exp $
|
||||||
|
|
||||||
## Ad-Hoc Command manager
|
## Ad-Hoc Command manager
|
||||||
## Mike Albon (c) 5th January 2005
|
## Mike Albon (c) 5th January 2005
|
||||||
|
@ -35,7 +35,7 @@ from xmpp.protocol import *
|
||||||
from xmpp.client import PlugIn
|
from xmpp.client import PlugIn
|
||||||
|
|
||||||
class Commands(PlugIn):
|
class Commands(PlugIn):
|
||||||
"""Commands is an ancestor of Plugin and can be attached to any session.
|
"""Commands is an ancestor of PlugIn and can be attached to any session.
|
||||||
|
|
||||||
The commands class provides a lookup and browse mechnism. It follows the same priciple of the Browser class, for Service Discovery to provide the list of commands, it adds the 'list' disco type to your existing disco handler function.
|
The commands class provides a lookup and browse mechnism. It follows the same priciple of the Browser class, for Service Discovery to provide the list of commands, it adds the 'list' disco type to your existing disco handler function.
|
||||||
|
|
||||||
|
@ -43,27 +43,28 @@ class Commands(PlugIn):
|
||||||
The commands are added into the existing Browser on the correct nodes. When the command list is built the supplied discovery handler function needs to have a 'list' option in type. This then gets enumerated, all results returned as None are ignored.
|
The commands are added into the existing Browser on the correct nodes. When the command list is built the supplied discovery handler function needs to have a 'list' option in type. This then gets enumerated, all results returned as None are ignored.
|
||||||
The command executed is then called using it's Execute method. All session management is handled by the command itself.
|
The command executed is then called using it's Execute method. All session management is handled by the command itself.
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self, browser):
|
||||||
"""Initialises class and sets up local variables"""
|
"""Initialises class and sets up local variables"""
|
||||||
PlugIn.__init__(self)
|
PlugIn.__init__(self)
|
||||||
DBG_LINE='commands'
|
DBG_LINE='commands'
|
||||||
self._exported_methods=[]
|
self._exported_methods=[]
|
||||||
self._handlers={'':{}}
|
self._handlers={'':{}}
|
||||||
|
self._browser = browser
|
||||||
|
|
||||||
def plugin(self, owner, browser):
|
def plugin(self, owner):
|
||||||
"""Makes handlers within the session"""
|
"""Makes handlers within the session"""
|
||||||
# Plug into the session and the disco manager
|
# Plug into the session and the disco manager
|
||||||
# We only need get and set, results are not needed by a service provider, only a service user.
|
# We only need get and set, results are not needed by a service provider, only a service user.
|
||||||
owner.RegisterHandler('iq',self._CommandHandler,typ='set',ns=NS_COMMANDS)
|
owner.RegisterHandler('iq',self._CommandHandler,typ='set',ns=NS_COMMANDS)
|
||||||
owner.RegisterHandler('iq',self._CommandHandler,typ='get',ns=NS_COMMANDS)
|
owner.RegisterHandler('iq',self._CommandHandler,typ='get',ns=NS_COMMANDS)
|
||||||
browser.setDiscoHandler(self._DiscoHandler,node=NS_COMMANDS,jid='')
|
self._browser.setDiscoHandler(self._DiscoHandler,node=NS_COMMANDS,jid='')
|
||||||
self._browser = browser
|
|
||||||
|
|
||||||
def plugout(self):
|
def plugout(self):
|
||||||
"""Removes handlers from the session"""
|
"""Removes handlers from the session"""
|
||||||
# unPlug from the session and the disco manager
|
# unPlug from the session and the disco manager
|
||||||
self._owner.UnregisterHandler('iq',self_CommandHandler,ns=NS_COMMANDS)
|
self._owner.UnregisterHandler('iq',self_CommandHandler,ns=NS_COMMANDS)
|
||||||
self._browser.delDiscoHandler(self._DiscoHandler,node=NS_COMMANDS)
|
for jid in self._handlers:
|
||||||
|
self._browser.delDiscoHandler(self._DiscoHandler,node=NS_COMMANDS)
|
||||||
|
|
||||||
def _CommandHandler(self,conn,request):
|
def _CommandHandler(self,conn,request):
|
||||||
"""The internal method to process the routing of command execution requests"""
|
"""The internal method to process the routing of command execution requests"""
|
||||||
|
@ -81,45 +82,49 @@ class Commands(PlugIn):
|
||||||
if self._handlers[jid].has_key(node):
|
if self._handlers[jid].has_key(node):
|
||||||
self._handlers[jid][node]['execute'](conn,request)
|
self._handlers[jid][node]['execute'](conn,request)
|
||||||
else:
|
else:
|
||||||
conn.send(Error(request,ERR_NOT_FOUND))
|
conn.send(Error(request,ERR_ITEM_NOT_FOUND))
|
||||||
raise NodeProcessed
|
raise NodeProcessed
|
||||||
elif self._handlers[''].has_key(node):
|
elif self._handlers[''].has_key(node):
|
||||||
self._handlers[jid][node]['execute'](conn,request)
|
self._handlers[''][node]['execute'](conn,request)
|
||||||
else:
|
else:
|
||||||
conn.send(Error(requet,ERR_NOT_FOUND))
|
conn.send(Error(requet,ERR_ITEM_NOT_FOUND))
|
||||||
raise NodeProcessed
|
raise NodeProcessed
|
||||||
|
|
||||||
def _DiscoHandler(self,conn,request,typ):
|
def _DiscoHandler(self,conn,request,typ):
|
||||||
"""The internal method to process service discovery requests"""
|
"""The internal method to process service discovery requests"""
|
||||||
# This is the disco manager handler.
|
# This is the disco manager handler.
|
||||||
# We must:
|
if typ == 'items':
|
||||||
# Generate a list of commands and return the list
|
# We must:
|
||||||
# * This handler does not handle individual commands disco requests.
|
# Generate a list of commands and return the list
|
||||||
# Pseudo:
|
# * This handler does not handle individual commands disco requests.
|
||||||
# Enumerate the 'item' disco of each command for the specified jid
|
# Pseudo:
|
||||||
# Build responce and send
|
# Enumerate the 'item' disco of each command for the specified jid
|
||||||
# To make this code easy to write we add an 'list' disco type, it returns a tuple or 'none' if not advertised
|
# Build responce and send
|
||||||
list = []
|
# To make this code easy to write we add an 'list' disco type, it returns a tuple or 'none' if not advertised
|
||||||
items = []
|
list = []
|
||||||
jid = str(request.getTo())
|
items = []
|
||||||
# Get specific jid based results
|
jid = str(request.getTo())
|
||||||
if self._handlers.has_key(jid):
|
# Get specific jid based results
|
||||||
for each in self._handlers[jid].keys():
|
if self._handlers.has_key(jid):
|
||||||
items.append((jid,each))
|
for each in self._handlers[jid].keys():
|
||||||
# Get generic results
|
items.append((jid,each))
|
||||||
for each in self._handlers[''].keys():
|
else:
|
||||||
items.append(('',each))
|
# Get generic results
|
||||||
if items != []:
|
for each in self._handlers[''].keys():
|
||||||
for each in items:
|
items.append(('',each))
|
||||||
i = self._handlers[each[0]][each[1]]['disco'](conn,request,'list')
|
if items != []:
|
||||||
if i != None:
|
for each in items:
|
||||||
list.append(Node(tag='item',attrs={'jid':i[0],'node':i[1],'name':i[2]}))
|
i = self._handlers[each[0]][each[1]]['disco'](conn,request,'list')
|
||||||
iq = request.buildReply('result')
|
if i != None:
|
||||||
iq.setQueryPayload(list)
|
list.append(Node(tag='item',attrs={'jid':i[0],'node':i[1],'name':i[2]}))
|
||||||
conn.send(iq)
|
iq = request.buildReply('result')
|
||||||
else:
|
iq.setQueryPayload(list)
|
||||||
conn.send(Error(request,ERR_NOT_FOUND))
|
conn.send(iq)
|
||||||
raise NodeProcessed
|
else:
|
||||||
|
conn.send(Error(request,ERR_ITEM_NOT_FOUND))
|
||||||
|
raise NodeProcessed
|
||||||
|
elif typ == 'info':
|
||||||
|
return {'ids':[],'features':[]}
|
||||||
|
|
||||||
def addCommand(self,name,cmddisco,cmdexecute,jid=''):
|
def addCommand(self,name,cmddisco,cmdexecute,jid=''):
|
||||||
"""The method to call if adding a new command to the session, the requred parameters of cmddisco and cmdexecute are the methods to enable that command to be executed"""
|
"""The method to call if adding a new command to the session, the requred parameters of cmddisco and cmdexecute are the methods to enable that command to be executed"""
|
||||||
|
@ -129,6 +134,7 @@ class Commands(PlugIn):
|
||||||
# Add item into command list
|
# Add item into command list
|
||||||
if not self._handlers.has_key(jid):
|
if not self._handlers.has_key(jid):
|
||||||
self._handlers[jid]={}
|
self._handlers[jid]={}
|
||||||
|
self._browser.setDiscoHandler(self._DiscoHandler,node=NS_COMMANDS,jid=jid)
|
||||||
if self._handlers[jid].has_key(name):
|
if self._handlers[jid].has_key(name):
|
||||||
raise NameError,'Command Exists'
|
raise NameError,'Command Exists'
|
||||||
else:
|
else:
|
||||||
|
@ -179,10 +185,11 @@ class Command_Handler_Prototype(PlugIn):
|
||||||
All stages set the 'actions' dictionary for each session to represent the possible options available.
|
All stages set the 'actions' dictionary for each session to represent the possible options available.
|
||||||
"""
|
"""
|
||||||
name = 'examplecommand'
|
name = 'examplecommand'
|
||||||
|
count = 0
|
||||||
description = 'an example command'
|
description = 'an example command'
|
||||||
discofeatures = [NS_COMMANDS,NS_DATA]
|
discofeatures = [NS_COMMANDS,NS_DATA]
|
||||||
# This is the command template
|
# This is the command template
|
||||||
def __init__(self):
|
def __init__(self,jid=''):
|
||||||
"""Set up the class"""
|
"""Set up the class"""
|
||||||
PlugIn.__init__(self)
|
PlugIn.__init__(self)
|
||||||
DBG_LINE='command'
|
DBG_LINE='command'
|
||||||
|
@ -190,19 +197,22 @@ class Command_Handler_Prototype(PlugIn):
|
||||||
self.sessions = {}
|
self.sessions = {}
|
||||||
# Disco information for command list pre-formatted as a tuple
|
# Disco information for command list pre-formatted as a tuple
|
||||||
self.discoinfo = {'ids':[{'category':'automation','type':'command','name':self.description}],'features': self.discofeatures}
|
self.discoinfo = {'ids':[{'category':'automation','type':'command','name':self.description}],'features': self.discofeatures}
|
||||||
|
self._jid = jid
|
||||||
|
|
||||||
def plugin(self,owner,jid=''):
|
def plugin(self,owner):
|
||||||
"""Plug command into the commands class"""
|
"""Plug command into the commands class"""
|
||||||
# The owner in this instance is the Command Processor
|
# The owner in this instance is the Command Processor
|
||||||
owner.addCommand(self.name,self._DiscoHandler,self.Execute,jid=jid)
|
self._commands = owner
|
||||||
|
self._owner = owner._owner
|
||||||
|
self._commands.addCommand(self.name,self._DiscoHandler,self.Execute,jid=self._jid)
|
||||||
|
|
||||||
def plugout(self,jid):
|
def plugout(self):
|
||||||
"""Remove command from the commands class"""
|
"""Remove command from the commands class"""
|
||||||
self._owner.delCommand(name,jid)
|
self._commands.delCommand(name,self._jid)
|
||||||
|
|
||||||
def getSessionID(self):
|
def getSessionID(self):
|
||||||
"""Returns an id for the command session"""
|
"""Returns an id for the command session"""
|
||||||
self.count = self.count+1
|
self.count = self.count+1
|
||||||
return 'cmd-%s-%d'%(self.name,self.count)
|
return 'cmd-%s-%d'%(self.name,self.count)
|
||||||
|
|
||||||
def Execute(self,conn,request):
|
def Execute(self,conn,request):
|
||||||
|
@ -212,25 +222,33 @@ class Command_Handler_Prototype(PlugIn):
|
||||||
session = request.getTagAttr('command','sessionid')
|
session = request.getTagAttr('command','sessionid')
|
||||||
except:
|
except:
|
||||||
session = None
|
session = None
|
||||||
|
try:
|
||||||
|
action = request.getTagAttr('command','action')
|
||||||
|
except:
|
||||||
|
action = None
|
||||||
|
if action == None: action = 'execute'
|
||||||
# Check session is in session list
|
# Check session is in session list
|
||||||
if self.sessions.has_key(session):
|
if self.sessions.has_key(session):
|
||||||
if self.sessions[session]['jid']==request.getFrom():
|
if self.sessions[session]['jid']==request.getFrom():
|
||||||
# Check status is vaild
|
# Check action is vaild
|
||||||
if self.sessions[session]['actions'].has_key(request.getTagAttr('command','status')):
|
if self.sessions[session]['actions'].has_key(action):
|
||||||
# Execute next action
|
# Execute next action
|
||||||
self.sessions[session]['actions'][request.getTagAttr('command','status')](conn,request)
|
self.sessions[session]['actions'][action](conn,request)
|
||||||
else:
|
else:
|
||||||
# Stage not presented as an option
|
# Stage not presented as an option
|
||||||
self._owner.send(Error(request,BAD_REQUEST))
|
self._owner.send(Error(request,ERR_BAD_REQUEST))
|
||||||
|
raise NodeProcessed
|
||||||
else:
|
else:
|
||||||
# Jid and session don't match. Go away imposter
|
# Jid and session don't match. Go away imposter
|
||||||
self._owner.send(Error(request,BAD_REQUEST))
|
self._owner.send(Error(request,ERR_BAD_REQUEST))
|
||||||
|
raise NodeProcessed
|
||||||
elif session != None:
|
elif session != None:
|
||||||
# Not on this sessionid you won't.
|
# Not on this sessionid you won't.
|
||||||
self._owner.send(Error(request,BAD_REQUEST))
|
self._owner.send(Error(request,ERR_BAD_REQUEST))
|
||||||
|
raise NodeProcessed
|
||||||
else:
|
else:
|
||||||
# New session
|
# New session
|
||||||
self.initial[request.getTagAttr('command','status')](conn,request)
|
self.initial[action](conn,request)
|
||||||
|
|
||||||
def _DiscoHandler(self,conn,request,type):
|
def _DiscoHandler(self,conn,request,type):
|
||||||
"""The handler for discovery events"""
|
"""The handler for discovery events"""
|
||||||
|
@ -247,9 +265,9 @@ class TestCommand(Command_Handler_Prototype):
|
||||||
"""
|
"""
|
||||||
name = 'testcommand'
|
name = 'testcommand'
|
||||||
description = 'a noddy example command'
|
description = 'a noddy example command'
|
||||||
def __init__(self):
|
def __init__(self,jid=''):
|
||||||
""" Init internal constants. """
|
""" Init internal constants. """
|
||||||
Command_Handler_Prototype.__init__(self)
|
Command_Handler_Prototype.__init__(self,jid)
|
||||||
self.pi = 3.14
|
self.pi = 3.14
|
||||||
self.initial = {'execute':self.cmdFirstStage}
|
self.initial = {'execute':self.cmdFirstStage}
|
||||||
|
|
||||||
|
@ -272,7 +290,7 @@ class TestCommand(Command_Handler_Prototype):
|
||||||
raise NodeProcessed
|
raise NodeProcessed
|
||||||
|
|
||||||
def cmdSecondStage(self,conn,request):
|
def cmdSecondStage(self,conn,request):
|
||||||
form = DataForm(node = result.getTag(name='command').getTag(namespace=NS_DATA))
|
form = DataForm(node = result.getTag(name='command').getTag(name='x',namespace=NS_DATA))
|
||||||
sessions[request.getTagAttr('command','sessionid')]['data']['type']=form.getField('calctype')
|
sessions[request.getTagAttr('command','sessionid')]['data']['type']=form.getField('calctype')
|
||||||
sessions[request.getTagAttr('command','sessionid')]['actions']={'cancel':self.cmdCancel,None:self.cmdThirdStage,'previous':cmdFirstStage}
|
sessions[request.getTagAttr('command','sessionid')]['actions']={'cancel':self.cmdCancel,None:self.cmdThirdStage,'previous':cmdFirstStage}
|
||||||
# The form generation is split out to another method as it may be called by cmdThirdStage
|
# The form generation is split out to another method as it may be called by cmdThirdStage
|
||||||
|
@ -287,7 +305,7 @@ class TestCommand(Command_Handler_Prototype):
|
||||||
raise NodeProcessed
|
raise NodeProcessed
|
||||||
|
|
||||||
def cmdThirdStage(self,conn,request):
|
def cmdThirdStage(self,conn,request):
|
||||||
form = DataForm(node = result.getTag(name='command').getTag(namespace=NS_DATA))
|
form = DataForm(node = result.getTag(name='command').getTag(name='x',namespace=NS_DATA))
|
||||||
try:
|
try:
|
||||||
num = float(form.getField('radius'))
|
num = float(form.getField('radius'))
|
||||||
except:
|
except:
|
||||||
|
|
Loading…
Add table
Reference in a new issue