Moved some code to ease maintenance.
This commit is contained in:
		
							parent
							
								
									477f33b6b9
								
							
						
					
					
						commit
						de23ba2a15
					
				
					 3 changed files with 241 additions and 113 deletions
				
			
		
							
								
								
									
										232
									
								
								src/common/commands.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								src/common/commands.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,232 @@
 | 
				
			||||||
 | 
					##
 | 
				
			||||||
 | 
					## Copyright (C) 2006 Gajim Team
 | 
				
			||||||
 | 
					##
 | 
				
			||||||
 | 
					## This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					## it under the terms of the GNU General Public License as published
 | 
				
			||||||
 | 
					## by the Free Software Foundation; version 2 only.
 | 
				
			||||||
 | 
					##
 | 
				
			||||||
 | 
					## This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					## but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					## GNU General Public License for more details.
 | 
				
			||||||
 | 
					##
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import xmpp
 | 
				
			||||||
 | 
					import helpers
 | 
				
			||||||
 | 
					import dataforms
 | 
				
			||||||
 | 
					import gajim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AdHocCommand:
 | 
				
			||||||
 | 
						commandnode = 'command'
 | 
				
			||||||
 | 
						commandname = 'The Command'
 | 
				
			||||||
 | 
						commandfeatures = (xmpp.NS_DATA,)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@staticmethod
 | 
				
			||||||
 | 
						def isVisibleFor(jid): return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def __init__(self, conn, jid, sessionid):
 | 
				
			||||||
 | 
							self.connection = conn
 | 
				
			||||||
 | 
							self.jid = jid
 | 
				
			||||||
 | 
							self.sessionid = sessionid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def buildResponse(self, request, status='executing', defaultaction=None, actions=None):
 | 
				
			||||||
 | 
							assert status in ('executing', 'completed', 'canceled')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							response = request.buildReply('result')
 | 
				
			||||||
 | 
							cmd = response.addChild('command', {
 | 
				
			||||||
 | 
								'xmlns': xmpp.NS_COMMANDS,
 | 
				
			||||||
 | 
								'sessionid': self.sessionid,
 | 
				
			||||||
 | 
								'node': self.commandnode,
 | 
				
			||||||
 | 
								'status': status})
 | 
				
			||||||
 | 
							if defaultaction is not None or actions is not None:
 | 
				
			||||||
 | 
								if defaultaction is not None:
 | 
				
			||||||
 | 
									assert defaultaction in ('cancel', 'execute', 'prev', 'next', 'complete')
 | 
				
			||||||
 | 
									attrs = {'action': defaultaction}
 | 
				
			||||||
 | 
								else:
 | 
				
			||||||
 | 
									attrs = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								cmd.addChild('actions', attrs, actions)
 | 
				
			||||||
 | 
							return response, cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def cancel(self, request):
 | 
				
			||||||
 | 
							response, cmd = self.buildResponse(request, status='canceled')
 | 
				
			||||||
 | 
							self.connection.send(response)
 | 
				
			||||||
 | 
							return False	# finish the session
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ChangeStatusCommand(AdHocCommand):
 | 
				
			||||||
 | 
						commandnode = 'change-status'
 | 
				
			||||||
 | 
						commandname = 'Change status information'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def execute(self, request):
 | 
				
			||||||
 | 
							# first query...
 | 
				
			||||||
 | 
							response, cmd = self.buildResponse(request, defaultaction='execute', actions=['execute'])
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							cmd.addChild(node=dataforms.DataForm(
 | 
				
			||||||
 | 
								title='Change status',
 | 
				
			||||||
 | 
								instructions='Set the presence type and description',
 | 
				
			||||||
 | 
								fields=[
 | 
				
			||||||
 | 
									dataforms.DataField('list-single', 'presence-type',
 | 
				
			||||||
 | 
										label='Type of presence:',
 | 
				
			||||||
 | 
										options=[
 | 
				
			||||||
 | 
											(u'free-for-chat', u'Free for chat'),
 | 
				
			||||||
 | 
											(u'online', u'Online'),
 | 
				
			||||||
 | 
											(u'away', u'Away'),
 | 
				
			||||||
 | 
											(u'xa', u'Extended away'),
 | 
				
			||||||
 | 
											(u'dnd', u'Do not disturb'),
 | 
				
			||||||
 | 
											(u'offline', u'Offline - disconnect')],
 | 
				
			||||||
 | 
										value='online',
 | 
				
			||||||
 | 
										required=True),
 | 
				
			||||||
 | 
									dataforms.DataField('text-multi', 'presence-desc',
 | 
				
			||||||
 | 
										label='Presence description:')]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							self.connection.send(response)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							# for next invocation
 | 
				
			||||||
 | 
							self.execute = self.changestatus
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							return True	# keep the session
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def changestatus(self, request):
 | 
				
			||||||
 | 
							# check if the data is correct
 | 
				
			||||||
 | 
							try:
 | 
				
			||||||
 | 
								form=dataforms.DataForm(node=request.getTag('command').getTag('x'))
 | 
				
			||||||
 | 
							except TypeError:
 | 
				
			||||||
 | 
								return False
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							try:
 | 
				
			||||||
 | 
								presencetype = form['presence-type']
 | 
				
			||||||
 | 
								if not presencetype in ('free-for-chat', 'online', 'away', 'xa', 'dnd', 'offline'):
 | 
				
			||||||
 | 
									#raise BadSomething
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
							except KeyError:
 | 
				
			||||||
 | 
					#			raise BadSomething
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							try:
 | 
				
			||||||
 | 
								presencedesc = form['presence-desc']
 | 
				
			||||||
 | 
							except KeyError:
 | 
				
			||||||
 | 
								presencedesc = u''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							response, cmd = self.buildResponse(request, status='completed')
 | 
				
			||||||
 | 
							cmd.addChild('note', {}, 'The status has been changed.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							self.connection.send(response)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							# looking for account name...
 | 
				
			||||||
 | 
							accname = None
 | 
				
			||||||
 | 
							for acc in gajim.connections.iterkeys():
 | 
				
			||||||
 | 
								if self.connection is gajim.connections[acc]:
 | 
				
			||||||
 | 
									accname=acc
 | 
				
			||||||
 | 
							assert accname is not None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							gajim.interface.roster.send_status(accname, presencetype, presencedesc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return False	# finish the session
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ConnectionCommands:
 | 
				
			||||||
 | 
						''' This class depends on that it is a part of Connection() class. '''
 | 
				
			||||||
 | 
						def __init__(self):
 | 
				
			||||||
 | 
							# a list of all commands exposed: node -> command class
 | 
				
			||||||
 | 
							self.__commands = {}
 | 
				
			||||||
 | 
							for cmdobj in (ChangeStatusCommand,):
 | 
				
			||||||
 | 
								self.__commands[cmdobj.commandnode] = cmdobj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							# a list of sessions; keys are tuples (jid, sessionid, node)
 | 
				
			||||||
 | 
							self.__sessions = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def commandListQuery(self, con, iq_obj):
 | 
				
			||||||
 | 
							iq = iq_obj.buildReply('result')
 | 
				
			||||||
 | 
							jid = helpers.get_full_jid_from_iq(iq_obj)
 | 
				
			||||||
 | 
							q = iq.getTag('query')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for node, cmd in self.__commands.iteritems():
 | 
				
			||||||
 | 
								if cmd.isVisibleFor(jid):
 | 
				
			||||||
 | 
									q.addChild('item', {
 | 
				
			||||||
 | 
										# TODO: find the jid
 | 
				
			||||||
 | 
										'jid': 'our-jid',
 | 
				
			||||||
 | 
										'node': node,
 | 
				
			||||||
 | 
										'name': cmd.commandname})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							self.connection.send(iq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def commandQuery(self, con, iq_obj):
 | 
				
			||||||
 | 
							''' Send disco result for query for command (JEP-0050, example 6.).
 | 
				
			||||||
 | 
							Return True if the result was sent, False if not. '''
 | 
				
			||||||
 | 
							jid = helpers.get_full_jid_from_iq(iq_obj)
 | 
				
			||||||
 | 
							node = iq_obj.getTagAttr('query', 'node')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if node not in self.__commands: return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cmd = self.__commands[node]
 | 
				
			||||||
 | 
							if cmd.isVisibleFor(jid):
 | 
				
			||||||
 | 
								iq = iq_obj.buildReply('result')
 | 
				
			||||||
 | 
								q = iq.getTag('query')
 | 
				
			||||||
 | 
								q.addChild('identity', attrs = {'type': 'command-node',
 | 
				
			||||||
 | 
								                                'category': 'automation',
 | 
				
			||||||
 | 
								                                'name': cmd.commandname})
 | 
				
			||||||
 | 
								q.addChild('feature', attrs = {'var': xmpp.NS_COMMANDS})
 | 
				
			||||||
 | 
								for feature in cmd.commandfeatures:
 | 
				
			||||||
 | 
									q.addChild('feature', attrs = {'var': feature})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								self.connection.send(iq)
 | 
				
			||||||
 | 
								return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def _CommandExecuteCB(self, con, iq_obj):
 | 
				
			||||||
 | 
							jid = helpers.get_full_jid_from_iq(iq_obj)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cmd = iq_obj.getTag('command')
 | 
				
			||||||
 | 
							if cmd is None: return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							node = cmd.getAttr('node')
 | 
				
			||||||
 | 
							if node is None: return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							sessionid = cmd.getAttr('sessionid')
 | 
				
			||||||
 | 
							if sessionid is None:
 | 
				
			||||||
 | 
								# we start a new command session... only if we are visible for the jid
 | 
				
			||||||
 | 
								newcmd = self.__commands[node]
 | 
				
			||||||
 | 
								if not newcmd.isVisibleFor(jid):
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								# generate new sessionid
 | 
				
			||||||
 | 
								sessionid = self.connection.getAnID()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								# create new instance and run it
 | 
				
			||||||
 | 
								obj = newcmd(conn=self.connection, jid=jid, sessionid=sessionid)
 | 
				
			||||||
 | 
								rc = obj.execute(iq_obj)
 | 
				
			||||||
 | 
								if rc:
 | 
				
			||||||
 | 
									self.__sessions[(jid, sessionid, node)] = obj
 | 
				
			||||||
 | 
								raise NodeProcessed
 | 
				
			||||||
 | 
							else:
 | 
				
			||||||
 | 
								# the command is already running, check for it
 | 
				
			||||||
 | 
								magictuple = (jid, sessionid, node)
 | 
				
			||||||
 | 
								if magictuple not in self.__sessions:
 | 
				
			||||||
 | 
									# we don't have this session... ha!
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								action = cmd.getAttr('action')
 | 
				
			||||||
 | 
								obj = self.__sessions[magictuple]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								try:
 | 
				
			||||||
 | 
									if action == 'cancel': rc = obj.cancel(iq_obj)
 | 
				
			||||||
 | 
									elif action == 'prev': rc = obj.prev(iq_obj)
 | 
				
			||||||
 | 
									elif action == 'next': rc = obj.next(iq_obj)
 | 
				
			||||||
 | 
									elif action == 'execute': rc = obj.execute(iq_obj)
 | 
				
			||||||
 | 
									elif action == 'complete': rc = obj.complete(iq_obj)
 | 
				
			||||||
 | 
									else:
 | 
				
			||||||
 | 
										# action is wrong. stop the session, send error
 | 
				
			||||||
 | 
										del self.__sessions[magictuple]
 | 
				
			||||||
 | 
										return
 | 
				
			||||||
 | 
								except AttributeError:
 | 
				
			||||||
 | 
									# the command probably doesn't handle invoked action...
 | 
				
			||||||
 | 
									# stop the session, return error
 | 
				
			||||||
 | 
									del self.__sessions[magictuple]
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								# delete the session if rc is False
 | 
				
			||||||
 | 
								if not rc:
 | 
				
			||||||
 | 
									del self.__sessions[magictuple]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								raise xmpp.NodeProcessed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,8 @@ import common.xmpp
 | 
				
			||||||
from common import GnuPG
 | 
					from common import GnuPG
 | 
				
			||||||
from common import helpers
 | 
					from common import helpers
 | 
				
			||||||
from common import gajim
 | 
					from common import gajim
 | 
				
			||||||
 | 
					from common import dataforms
 | 
				
			||||||
 | 
					from common.commands import ConnectionCommands
 | 
				
			||||||
 | 
					
 | 
				
			||||||
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
 | 
					STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
 | 
				
			||||||
	'invisible']
 | 
						'invisible']
 | 
				
			||||||
| 
						 | 
					@ -1054,119 +1056,6 @@ class ConnectionVcard:
 | 
				
			||||||
			else:
 | 
								else:
 | 
				
			||||||
				self.dispatch('VCARD', vcard)
 | 
									self.dispatch('VCARD', vcard)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AdHocCommand:
 | 
					 | 
				
			||||||
	commandnode = 'command'
 | 
					 | 
				
			||||||
	commandname = 'The Command'
 | 
					 | 
				
			||||||
	commandfeatures = (common.xmpp.NS_DATA,)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	@staticmethod
 | 
					 | 
				
			||||||
	def isVisibleFor(jid): return True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ChangeStatusCommand(AdHocCommand):
 | 
					 | 
				
			||||||
	commandnode = 'change-status'
 | 
					 | 
				
			||||||
	commandname = 'Change status information'
 | 
					 | 
				
			||||||
	def __init__(self, sessiondata):
 | 
					 | 
				
			||||||
		pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ConnectionCommands:
 | 
					 | 
				
			||||||
	def __init__(self):
 | 
					 | 
				
			||||||
		# a list of all commands exposed
 | 
					 | 
				
			||||||
		self.__commands = {}
 | 
					 | 
				
			||||||
		for cmdobj in (ChangeStatusCommand,):
 | 
					 | 
				
			||||||
			self.__commands[cmdobj.commandnode] = cmdobj
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		# a list of sessions; keys are tuples (jid, sessionid, node)
 | 
					 | 
				
			||||||
		self.__sessions = {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	def commandListQuery(self, con, iq_obj):
 | 
					 | 
				
			||||||
		iq = iq_obj.buildReply('result')
 | 
					 | 
				
			||||||
		jid = helpers.get_full_jid_from_iq(iq_obj)
 | 
					 | 
				
			||||||
		q = iq.getTag('query')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for node, cmd in self.__commands.iter_items():
 | 
					 | 
				
			||||||
			if cmd.isVisibleFor(jid):
 | 
					 | 
				
			||||||
				q.addChild('item', {
 | 
					 | 
				
			||||||
					'jid': 'our-jid',
 | 
					 | 
				
			||||||
					'node': node,
 | 
					 | 
				
			||||||
					'name': cmd.commandname})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		self.connection.send(iq)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	def commandQuery(self, con, iq_obj):
 | 
					 | 
				
			||||||
		''' Send disco result for query for command (JEP-0050, example 6.).
 | 
					 | 
				
			||||||
		Return True if the result was sent, False if not. '''
 | 
					 | 
				
			||||||
		jid = helpers.get_full_jid_from_iq(iq_obj)
 | 
					 | 
				
			||||||
		node = iq_obj.getTagAttr('query', 'node')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if node not in self.__commands: return False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		cmd = self.__commands[node]
 | 
					 | 
				
			||||||
		if cmd.isVisibleFor(jid):
 | 
					 | 
				
			||||||
			iq = iq_obj.buildReply('result')
 | 
					 | 
				
			||||||
			q = iq.getTag('query')
 | 
					 | 
				
			||||||
			q.addChild('identity', attrs = {'type': 'command-node',
 | 
					 | 
				
			||||||
			                                 'category': 'automation',
 | 
					 | 
				
			||||||
			                                 'name': cmd.commandname})
 | 
					 | 
				
			||||||
			q.addChild('feature', attrs = {'var': common.xmpp.NS_COMMANDS})
 | 
					 | 
				
			||||||
			for feature in cmd.commandfeatures:
 | 
					 | 
				
			||||||
				q.addChild('feature', attrs = {'var': feature})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			self.connection.send(iq)
 | 
					 | 
				
			||||||
			return True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	def _CommandExecuteCB(self, con, iq_obj):
 | 
					 | 
				
			||||||
		jid = helpers.get_full_jid_from_iq(iq_obj)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		cmd = iq_obj.getTag('command')
 | 
					 | 
				
			||||||
		if cmd is None: return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		node = cmd.getAttr('node')
 | 
					 | 
				
			||||||
		if node is None: return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		sessionid = cmd.getAttr('sessionid')
 | 
					 | 
				
			||||||
		if sessionid is None:
 | 
					 | 
				
			||||||
			# we start a new command session... only if we are visible for the jid
 | 
					 | 
				
			||||||
			newcmd = self.__commands[node]
 | 
					 | 
				
			||||||
			if not newcmd.isVisibleFor(jid):
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			# generate new sessionid
 | 
					 | 
				
			||||||
			sessionid = self.connection.getAnID()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			# create new instance and run it
 | 
					 | 
				
			||||||
			obj = newcmd(jid=jid, sessionid=sessionid)
 | 
					 | 
				
			||||||
			rc = obj.execute()
 | 
					 | 
				
			||||||
			if rc:
 | 
					 | 
				
			||||||
				self.__sessions[(jid, sessionid, node)] = obj
 | 
					 | 
				
			||||||
			raise NodeProcessed
 | 
					 | 
				
			||||||
		else:
 | 
					 | 
				
			||||||
			# the command is already running, check for it
 | 
					 | 
				
			||||||
			magictuple = (jid, sessionid, node)
 | 
					 | 
				
			||||||
			if magictuple not in self.__sessions:
 | 
					 | 
				
			||||||
				# we don't have this session... ha!
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			action = cmd.getAttr('action')
 | 
					 | 
				
			||||||
			obj = self.__sessions[magictuple]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if action == 'cancel': rc = obj.cancel(iq_obj)
 | 
					 | 
				
			||||||
			elif action == 'prev': rc = obj.prev(iq_obj)
 | 
					 | 
				
			||||||
			elif action == 'next': rc = obj.next(iq_obj)
 | 
					 | 
				
			||||||
			elif action == 'execute': rc = obj.execute(iq_obj)
 | 
					 | 
				
			||||||
			elif action == 'complete': rc = obj.complete(iq_obj)
 | 
					 | 
				
			||||||
			else:
 | 
					 | 
				
			||||||
				# action is wrong. stop the session, send error
 | 
					 | 
				
			||||||
				del self.__sessions[magictuple]
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			# delete the session if rc is False
 | 
					 | 
				
			||||||
			if not rc:
 | 
					 | 
				
			||||||
				del self.__sessions[magictuple]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			raise NodeProcessed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco, ConnectionCommands):
 | 
					class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco, ConnectionCommands):
 | 
				
			||||||
	def __init__(self):
 | 
						def __init__(self):
 | 
				
			||||||
		ConnectionVcard.__init__(self)
 | 
							ConnectionVcard.__init__(self)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -287,6 +287,13 @@ class DataForm(xmpp.Node, object):
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
		raise KeyError, "This form does not contain %r field." % var
 | 
							raise KeyError, "This form does not contain %r field." % var
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def __contains__(self, name):
 | 
				
			||||||
 | 
							for field in self.iter_fields():
 | 
				
			||||||
 | 
								if field.var==name:
 | 
				
			||||||
 | 
									return True
 | 
				
			||||||
 | 
							else:
 | 
				
			||||||
 | 
								return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DataField(xmpp.Node, object):
 | 
					class DataField(xmpp.Node, object):
 | 
				
			||||||
	def __init__(self, typ=None,var=None, value=None, label=None, desc=None,
 | 
						def __init__(self, typ=None,var=None, value=None, label=None, desc=None,
 | 
				
			||||||
		required=None, options=None, node=None):
 | 
							required=None, options=None, node=None):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue