summaryrefslogtreecommitdiff
path: root/sleekxmpp
diff options
context:
space:
mode:
Diffstat (limited to 'sleekxmpp')
-rw-r--r--sleekxmpp/plugins/old_0004.py421
-rw-r--r--sleekxmpp/plugins/old_0009.py277
-rw-r--r--sleekxmpp/plugins/xep_0045.py23
3 files changed, 1 insertions, 720 deletions
diff --git a/sleekxmpp/plugins/old_0004.py b/sleekxmpp/plugins/old_0004.py
deleted file mode 100644
index 7f086866..00000000
--- a/sleekxmpp/plugins/old_0004.py
+++ /dev/null
@@ -1,421 +0,0 @@
-"""
- SleekXMPP: The Sleek XMPP Library
- Copyright (C) 2010 Nathanael C. Fritz
- This file is part of SleekXMPP.
-
- See the file LICENSE for copying permission.
-"""
-from . import base
-import logging
-from xml.etree import cElementTree as ET
-import copy
-import logging
-#TODO support item groups and results
-
-
-log = logging.getLogger(__name__)
-
-
-class old_0004(base.base_plugin):
-
- def plugin_init(self):
- self.xep = '0004'
- self.description = '*Deprecated Data Forms'
- self.xmpp.add_handler("<message><x xmlns='jabber:x:data' /></message>", self.handler_message_xform, name='Old Message Form')
-
- def post_init(self):
- base.base_plugin.post_init(self)
- self.xmpp.plugin['xep_0030'].add_feature('jabber:x:data')
- log.warning("This implementation of XEP-0004 is deprecated.")
-
- def handler_message_xform(self, xml):
- object = self.handle_form(xml)
- self.xmpp.event("message_form", object)
-
- def handler_presence_xform(self, xml):
- object = self.handle_form(xml)
- self.xmpp.event("presence_form", object)
-
- def handle_form(self, xml):
- xmlform = xml.find('{jabber:x:data}x')
- object = self.buildForm(xmlform)
- self.xmpp.event("message_xform", object)
- return object
-
- def buildForm(self, xml):
- form = Form(ftype=xml.attrib['type'])
- form.fromXML(xml)
- return form
-
- def makeForm(self, ftype='form', title='', instructions=''):
- return Form(self.xmpp, ftype, title, instructions)
-
-class FieldContainer(object):
- def __init__(self, stanza = 'form'):
- self.fields = []
- self.field = {}
- self.stanza = stanza
-
- def addField(self, var, ftype='text-single', label='', desc='', required=False, value=None):
- self.field[var] = FormField(var, ftype, label, desc, required, value)
- self.fields.append(self.field[var])
- return self.field[var]
-
- def buildField(self, xml):
- self.field[xml.get('var', '__unnamed__')] = FormField(xml.get('var', '__unnamed__'), xml.get('type', 'text-single'))
- self.fields.append(self.field[xml.get('var', '__unnamed__')])
- self.field[xml.get('var', '__unnamed__')].buildField(xml)
-
- def buildContainer(self, xml):
- self.stanza = xml.tag
- for field in xml.findall('{jabber:x:data}field'):
- self.buildField(field)
-
- def getXML(self, ftype):
- container = ET.Element(self.stanza)
- for field in self.fields:
- container.append(field.getXML(ftype))
- return container
-
-class Form(FieldContainer):
- types = ('form', 'submit', 'cancel', 'result')
- def __init__(self, xmpp=None, ftype='form', title='', instructions=''):
- if not ftype in self.types:
- raise ValueError("Invalid Form Type")
- FieldContainer.__init__(self)
- self.xmpp = xmpp
- self.type = ftype
- self.title = title
- self.instructions = instructions
- self.reported = []
- self.items = []
-
- def merge(self, form2):
- form1 = Form(ftype=self.type)
- form1.fromXML(self.getXML(self.type))
- for field in form2.fields:
- if not field.var in form1.field:
- form1.addField(field.var, field.type, field.label, field.desc, field.required, field.value)
- else:
- form1.field[field.var].value = field.value
- for option, label in field.options:
- if (option, label) not in form1.field[field.var].options:
- form1.fields[field.var].addOption(option, label)
- return form1
-
- def copy(self):
- newform = Form(ftype=self.type)
- newform.fromXML(self.getXML(self.type))
- return newform
-
- def update(self, form):
- values = form.getValues()
- for var in values:
- if var in self.fields:
- self.fields[var].setValue(self.fields[var])
-
- def getValues(self):
- result = {}
- for field in self.fields:
- value = field.value
- if len(value) == 1:
- value = value[0]
- result[field.var] = value
- return result
-
- def setValues(self, values={}):
- for field in values:
- if field in self.field:
- if isinstance(values[field], list) or isinstance(values[field], tuple):
- for value in values[field]:
- self.field[field].setValue(value)
- else:
- self.field[field].setValue(values[field])
-
- def fromXML(self, xml):
- self.buildForm(xml)
-
- def addItem(self):
- newitem = FieldContainer('item')
- self.items.append(newitem)
- return newitem
-
- def buildItem(self, xml):
- newitem = self.addItem()
- newitem.buildContainer(xml)
-
- def addReported(self):
- reported = FieldContainer('reported')
- self.reported.append(reported)
- return reported
-
- def buildReported(self, xml):
- reported = self.addReported()
- reported.buildContainer(xml)
-
- def setTitle(self, title):
- self.title = title
-
- def setInstructions(self, instructions):
- self.instructions = instructions
-
- def setType(self, ftype):
- self.type = ftype
-
- def getXMLMessage(self, to):
- msg = self.xmpp.makeMessage(to)
- msg.append(self.getXML())
- return msg
-
- def buildForm(self, xml):
- self.type = xml.get('type', 'form')
- if xml.find('{jabber:x:data}title') is not None:
- self.setTitle(xml.find('{jabber:x:data}title').text)
- if xml.find('{jabber:x:data}instructions') is not None:
- self.setInstructions(xml.find('{jabber:x:data}instructions').text)
- for field in xml.findall('{jabber:x:data}field'):
- self.buildField(field)
- for reported in xml.findall('{jabber:x:data}reported'):
- self.buildReported(reported)
- for item in xml.findall('{jabber:x:data}item'):
- self.buildItem(item)
-
- #def getXML(self, tostring = False):
- def getXML(self, ftype=None):
- if ftype:
- self.type = ftype
- form = ET.Element('{jabber:x:data}x')
- form.attrib['type'] = self.type
- if self.title and self.type in ('form', 'result'):
- title = ET.Element('{jabber:x:data}title')
- title.text = self.title
- form.append(title)
- if self.instructions and self.type == 'form':
- instructions = ET.Element('{jabber:x:data}instructions')
- instructions.text = self.instructions
- form.append(instructions)
- for field in self.fields:
- form.append(field.getXML(self.type))
- for reported in self.reported:
- form.append(reported.getXML('{jabber:x:data}reported'))
- for item in self.items:
- form.append(item.getXML(self.type))
- #if tostring:
- # form = self.xmpp.tostring(form)
- return form
-
- def getXHTML(self):
- form = ET.Element('{http://www.w3.org/1999/xhtml}form')
- if self.title:
- title = ET.Element('h2')
- title.text = self.title
- form.append(title)
- if self.instructions:
- instructions = ET.Element('p')
- instructions.text = self.instructions
- form.append(instructions)
- for field in self.fields:
- form.append(field.getXHTML())
- for field in self.reported:
- form.append(field.getXHTML())
- for field in self.items:
- form.append(field.getXHTML())
- return form
-
-
- def makeSubmit(self):
- self.setType('submit')
-
-class FormField(object):
- types = ('boolean', 'fixed', 'hidden', 'jid-multi', 'jid-single', 'list-multi', 'list-single', 'text-multi', 'text-private', 'text-single')
- listtypes = ('jid-multi', 'jid-single', 'list-multi', 'list-single')
- lbtypes = ('fixed', 'text-multi')
- def __init__(self, var, ftype='text-single', label='', desc='', required=False, value=None):
- if not ftype in self.types:
- raise ValueError("Invalid Field Type")
- self.type = ftype
- self.var = var
- self.label = label
- self.desc = desc
- self.options = []
- self.required = False
- self.value = []
- if self.type in self.listtypes:
- self.islist = True
- else:
- self.islist = False
- if self.type in self.lbtypes:
- self.islinebreak = True
- else:
- self.islinebreak = False
- if value:
- self.setValue(value)
-
- def addOption(self, value, label):
- if self.islist:
- self.options.append((value, label))
- else:
- raise ValueError("Cannot add options to non-list type field.")
-
- def setTrue(self):
- if self.type == 'boolean':
- self.value = [True]
-
- def setFalse(self):
- if self.type == 'boolean':
- self.value = [False]
-
- def require(self):
- self.required = True
-
- def setDescription(self, desc):
- self.desc = desc
-
- def setValue(self, value):
- if self.type == 'boolean':
- if value in ('1', 1, True, 'true', 'True', 'yes'):
- value = True
- else:
- value = False
- if self.islinebreak and value is not None:
- self.value += value.split('\n')
- else:
- if len(self.value) and (not self.islist or self.type == 'list-single'):
- self.value = [value]
- else:
- self.value.append(value)
-
- def delValue(self, value):
- if type(self.value) == type([]):
- try:
- idx = self.value.index(value)
- if idx != -1:
- self.value.pop(idx)
- except ValueError:
- pass
- else:
- self.value = ''
-
- def setAnswer(self, value):
- self.setValue(value)
-
- def buildField(self, xml):
- self.type = xml.get('type', 'text-single')
- self.label = xml.get('label', '')
- for option in xml.findall('{jabber:x:data}option'):
- self.addOption(option.find('{jabber:x:data}value').text, option.get('label', ''))
- for value in xml.findall('{jabber:x:data}value'):
- self.setValue(value.text)
- if xml.find('{jabber:x:data}required') is not None:
- self.require()
- if xml.find('{jabber:x:data}desc') is not None:
- self.setDescription(xml.find('{jabber:x:data}desc').text)
-
- def getXML(self, ftype):
- field = ET.Element('{jabber:x:data}field')
- if ftype != 'result':
- field.attrib['type'] = self.type
- if self.type != 'fixed':
- if self.var:
- field.attrib['var'] = self.var
- if self.label:
- field.attrib['label'] = self.label
- if ftype == 'form':
- for option in self.options:
- optionxml = ET.Element('{jabber:x:data}option')
- optionxml.attrib['label'] = option[1]
- optionval = ET.Element('{jabber:x:data}value')
- optionval.text = option[0]
- optionxml.append(optionval)
- field.append(optionxml)
- if self.required:
- required = ET.Element('{jabber:x:data}required')
- field.append(required)
- if self.desc:
- desc = ET.Element('{jabber:x:data}desc')
- desc.text = self.desc
- field.append(desc)
- for value in self.value:
- valuexml = ET.Element('{jabber:x:data}value')
- if value is True or value is False:
- if value:
- valuexml.text = '1'
- else:
- valuexml.text = '0'
- else:
- valuexml.text = value
- field.append(valuexml)
- return field
-
- def getXHTML(self):
- field = ET.Element('div', {'class': 'xmpp-xforms-%s' % self.type})
- if self.label:
- label = ET.Element('p')
- label.text = "%s: " % self.label
- else:
- label = ET.Element('p')
- label.text = "%s: " % self.var
- field.append(label)
- if self.type == 'boolean':
- formf = ET.Element('input', {'type': 'checkbox', 'name': self.var})
- if len(self.value) and self.value[0] in (True, 'true', '1'):
- formf.attrib['checked'] = 'checked'
- elif self.type == 'fixed':
- formf = ET.Element('p')
- try:
- formf.text = ', '.join(self.value)
- except:
- pass
- field.append(formf)
- formf = ET.Element('input', {'type': 'hidden', 'name': self.var})
- try:
- formf.text = ', '.join(self.value)
- except:
- pass
- elif self.type == 'hidden':
- formf = ET.Element('input', {'type': 'hidden', 'name': self.var})
- try:
- formf.text = ', '.join(self.value)
- except:
- pass
- elif self.type in ('jid-multi', 'list-multi'):
- formf = ET.Element('select', {'name': self.var})
- for option in self.options:
- optf = ET.Element('option', {'value': option[0], 'multiple': 'multiple'})
- optf.text = option[1]
- if option[1] in self.value:
- optf.attrib['selected'] = 'selected'
- formf.append(option)
- elif self.type in ('jid-single', 'text-single'):
- formf = ET.Element('input', {'type': 'text', 'name': self.var})
- try:
- formf.attrib['value'] = ', '.join(self.value)
- except:
- pass
- elif self.type == 'list-single':
- formf = ET.Element('select', {'name': self.var})
- for option in self.options:
- optf = ET.Element('option', {'value': option[0]})
- optf.text = option[1]
- if not optf.text:
- optf.text = option[0]
- if option[1] in self.value:
- optf.attrib['selected'] = 'selected'
- formf.append(optf)
- elif self.type == 'text-multi':
- formf = ET.Element('textarea', {'name': self.var})
- try:
- formf.text = ', '.join(self.value)
- except:
- pass
- if not formf.text:
- formf.text = ' '
- elif self.type == 'text-private':
- formf = ET.Element('input', {'type': 'password', 'name': self.var})
- try:
- formf.attrib['value'] = ', '.join(self.value)
- except:
- pass
- label.append(formf)
- return field
-
diff --git a/sleekxmpp/plugins/old_0009.py b/sleekxmpp/plugins/old_0009.py
deleted file mode 100644
index 625b03fb..00000000
--- a/sleekxmpp/plugins/old_0009.py
+++ /dev/null
@@ -1,277 +0,0 @@
-"""
-XEP-0009 XMPP Remote Procedure Calls
-"""
-from __future__ import with_statement
-from . import base
-import logging
-from xml.etree import cElementTree as ET
-import copy
-import time
-import base64
-
-def py2xml(*args):
- params = ET.Element("params")
- for x in args:
- param = ET.Element("param")
- param.append(_py2xml(x))
- params.append(param) #<params><param>...
- return params
-
-def _py2xml(*args):
- for x in args:
- val = ET.Element("value")
- if type(x) is int:
- i4 = ET.Element("i4")
- i4.text = str(x)
- val.append(i4)
- if type(x) is bool:
- boolean = ET.Element("boolean")
- boolean.text = str(int(x))
- val.append(boolean)
- elif type(x) is str:
- string = ET.Element("string")
- string.text = x
- val.append(string)
- elif type(x) is float:
- double = ET.Element("double")
- double.text = str(x)
- val.append(double)
- elif type(x) is rpcbase64:
- b64 = ET.Element("Base64")
- b64.text = x.encoded()
- val.append(b64)
- elif type(x) is rpctime:
- iso = ET.Element("dateTime.iso8601")
- iso.text = str(x)
- val.append(iso)
- elif type(x) is list:
- array = ET.Element("array")
- data = ET.Element("data")
- for y in x:
- data.append(_py2xml(y))
- array.append(data)
- val.append(array)
- elif type(x) is dict:
- struct = ET.Element("struct")
- for y in x.keys():
- member = ET.Element("member")
- name = ET.Element("name")
- name.text = y
- member.append(name)
- member.append(_py2xml(x[y]))
- struct.append(member)
- val.append(struct)
- return val
-
-def xml2py(params):
- vals = []
- for param in params.findall('param'):
- vals.append(_xml2py(param.find('value')))
- return vals
-
-def _xml2py(value):
- if value.find('i4') is not None:
- return int(value.find('i4').text)
- if value.find('int') is not None:
- return int(value.find('int').text)
- if value.find('boolean') is not None:
- return bool(value.find('boolean').text)
- if value.find('string') is not None:
- return value.find('string').text
- if value.find('double') is not None:
- return float(value.find('double').text)
- if value.find('Base64') is not None:
- return rpcbase64(value.find('Base64').text)
- if value.find('dateTime.iso8601') is not None:
- return rpctime(value.find('dateTime.iso8601'))
- if value.find('struct') is not None:
- struct = {}
- for member in value.find('struct').findall('member'):
- struct[member.find('name').text] = _xml2py(member.find('value'))
- return struct
- if value.find('array') is not None:
- array = []
- for val in value.find('array').find('data').findall('value'):
- array.append(_xml2py(val))
- return array
- raise ValueError()
-
-class rpcbase64(object):
- def __init__(self, data):
- #base 64 encoded string
- self.data = data
-
- def decode(self):
- return base64.decodestring(data)
-
- def __str__(self):
- return self.decode()
-
- def encoded(self):
- return self.data
-
-class rpctime(object):
- def __init__(self,data=None):
- #assume string data is in iso format YYYYMMDDTHH:MM:SS
- if type(data) is str:
- self.timestamp = time.strptime(data,"%Y%m%dT%H:%M:%S")
- elif type(data) is time.struct_time:
- self.timestamp = data
- elif data is None:
- self.timestamp = time.gmtime()
- else:
- raise ValueError()
-
- def iso8601(self):
- #return a iso8601 string
- return time.strftime("%Y%m%dT%H:%M:%S",self.timestamp)
-
- def __str__(self):
- return self.iso8601()
-
-class JabberRPCEntry(object):
- def __init__(self,call):
- self.call = call
- self.result = None
- self.error = None
- self.allow = {} #{'<jid>':['<resource1>',...],...}
- self.deny = {}
-
- def check_acl(self, jid, resource):
- #Check for deny
- if jid in self.deny.keys():
- if self.deny[jid] == None or resource in self.deny[jid]:
- return False
- #Check for allow
- if allow == None:
- return True
- if jid in self.allow.keys():
- if self.allow[jid] == None or resource in self.allow[jid]:
- return True
- return False
-
- def acl_allow(self, jid, resource):
- if jid == None:
- self.allow = None
- elif resource == None:
- self.allow[jid] = None
- elif jid in self.allow.keys():
- self.allow[jid].append(resource)
- else:
- self.allow[jid] = [resource]
-
- def acl_deny(self, jid, resource):
- if jid == None:
- self.deny = None
- elif resource == None:
- self.deny[jid] = None
- elif jid in self.deny.keys():
- self.deny[jid].append(resource)
- else:
- self.deny[jid] = [resource]
-
- def call_method(self, args):
- ret = self.call(*args)
-
-class xep_0009(base.base_plugin):
-
- def plugin_init(self):
- self.xep = '0009'
- self.description = 'Jabber-RPC'
- self.xmpp.add_handler("<iq type='set'><query xmlns='jabber:iq:rpc' /></iq>",
- self._callMethod, name='Jabber RPC Call')
- self.xmpp.add_handler("<iq type='result'><query xmlns='jabber:iq:rpc' /></iq>",
- self._callResult, name='Jabber RPC Result')
- self.xmpp.add_handler("<iq type='error'><query xmlns='jabber:iq:rpc' /></iq>",
- self._callError, name='Jabber RPC Error')
- self.entries = {}
- self.activeCalls = []
-
- def post_init(self):
- base.base_plugin.post_init(self)
- self.xmpp.plugin['xep_0030'].add_feature('jabber:iq:rpc')
- self.xmpp.plugin['xep_0030'].add_identity('automatition','rpc')
-
- def register_call(self, method, name=None):
- #@returns an string that can be used in acl commands.
- with self.lock:
- if name is None:
- self.entries[method.__name__] = JabberRPCEntry(method)
- return method.__name__
- else:
- self.entries[name] = JabberRPCEntry(method)
- return name
-
- def acl_allow(self, entry, jid=None, resource=None):
- #allow the method entry to be called by the given jid and resource.
- #if jid is None it will allow any jid/resource.
- #if resource is None it will allow any resource belonging to the jid.
- with self.lock:
- if self.entries[entry]:
- self.entries[entry].acl_allow(jid,resource)
- else:
- raise ValueError()
-
- def acl_deny(self, entry, jid=None, resource=None):
- #Note: by default all requests are denied unless allowed with acl_allow.
- #If you deny an entry it will not be allowed regardless of acl_allow
- with self.lock:
- if self.entries[entry]:
- self.entries[entry].acl_deny(jid,resource)
- else:
- raise ValueError()
-
- def unregister_call(self, entry):
- #removes the registered call
- with self.lock:
- if self.entries[entry]:
- del self.entries[entry]
- else:
- raise ValueError()
-
- def makeMethodCallQuery(self,pmethod,params):
- query = self.xmpp.makeIqQuery(iq,"jabber:iq:rpc")
- methodCall = ET.Element('methodCall')
- methodName = ET.Element('methodName')
- methodName.text = pmethod
- methodCall.append(methodName)
- methodCall.append(params)
- query.append(methodCall)
- return query
-
- def makeIqMethodCall(self,pto,pmethod,params):
- iq = self.xmpp.makeIqSet()
- iq.set('to',pto)
- iq.append(self.makeMethodCallQuery(pmethod,params))
- return iq
-
- def makeIqMethodResponse(self,pto,pid,params):
- iq = self.xmpp.makeIqResult(pid)
- iq.set('to',pto)
- query = self.xmpp.makeIqQuery(iq,"jabber:iq:rpc")
- methodResponse = ET.Element('methodResponse')
- methodResponse.append(params)
- query.append(methodResponse)
- return iq
-
- def makeIqMethodError(self,pto,id,pmethod,params,condition):
- iq = self.xmpp.makeIqError(id)
- iq.set('to',pto)
- iq.append(self.makeMethodCallQuery(pmethod,params))
- iq.append(self.xmpp['xep_0086'].makeError(condition))
- return iq
-
-
-
- def call_remote(self, pto, pmethod, *args):
- #calls a remote method. Returns the id of the Iq.
- pass
-
- def _callMethod(self,xml):
- pass
-
- def _callResult(self,xml):
- pass
-
- def _callError(self,xml):
- pass
diff --git a/sleekxmpp/plugins/xep_0045.py b/sleekxmpp/plugins/xep_0045.py
index cba07702..b823e76d 100644
--- a/sleekxmpp/plugins/xep_0045.py
+++ b/sleekxmpp/plugins/xep_0045.py
@@ -198,30 +198,9 @@ class XEP_0045(BasePlugin):
if entry is not None and entry['jid'].full == jid:
return nick
- def getRoomForm(self, room, ifrom=None):
- iq = self.xmpp.makeIqGet()
- iq['to'] = room
- if ifrom is not None:
- iq['from'] = ifrom
- query = ET.Element('{http://jabber.org/protocol/muc#owner}query')
- iq.append(query)
- # For now, swallow errors to preserve existing API
- try:
- result = iq.send()
- except IqError:
- return False
- except IqTimeout:
- return False
- xform = result.xml.find('{http://jabber.org/protocol/muc#owner}query/{jabber:x:data}x')
- if xform is None: return False
- form = self.xmpp.plugin['old_0004'].buildForm(xform)
- return form
-
def configureRoom(self, room, form=None, ifrom=None):
if form is None:
- form = self.getRoomForm(room, ifrom=ifrom)
- #form = self.xmpp.plugin['old_0004'].makeForm(ftype='submit')
- #form.addField('FORM_TYPE', value='http://jabber.org/protocol/muc#roomconfig')
+ form = self.getRoomConfig(room, ifrom=ifrom)
iq = self.xmpp.makeIqSet()
iq['to'] = room
if ifrom is not None: