Rename to slixmpp

This commit is contained in:
Florent Le Coz
2014-07-17 14:19:04 +02:00
parent e5582694c0
commit 5ab77c7452
514 changed files with 3473 additions and 3530 deletions

View File

@@ -0,0 +1,22 @@
"""
Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
from slixmpp.plugins.base import register_plugin
from slixmpp.plugins.xep_0004.stanza import Form
from slixmpp.plugins.xep_0004.stanza import FormField, FieldOption
from slixmpp.plugins.xep_0004.dataforms import XEP_0004
register_plugin(XEP_0004)
# Retain some backwards compatibility
xep_0004 = XEP_0004
xep_0004.makeForm = xep_0004.make_form
xep_0004.buildForm = xep_0004.build_form

View File

@@ -0,0 +1,57 @@
"""
Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
from slixmpp import Message
from slixmpp.xmlstream import register_stanza_plugin
from slixmpp.xmlstream.handler import Callback
from slixmpp.xmlstream.matcher import StanzaPath
from slixmpp.plugins import BasePlugin
from slixmpp.plugins.xep_0004 import stanza
from slixmpp.plugins.xep_0004.stanza import Form, FormField, FieldOption
class XEP_0004(BasePlugin):
"""
XEP-0004: Data Forms
"""
name = 'xep_0004'
description = 'XEP-0004: Data Forms'
dependencies = set(['xep_0030'])
stanza = stanza
def plugin_init(self):
self.xmpp.register_handler(
Callback('Data Form',
StanzaPath('message/form'),
self.handle_form))
register_stanza_plugin(FormField, FieldOption, iterable=True)
register_stanza_plugin(Form, FormField, iterable=True)
register_stanza_plugin(Message, Form)
def plugin_end(self):
self.xmpp.remove_handler('Data Form')
self.xmpp['xep_0030'].del_feature(feature='jabber:x:data')
def session_bind(self, jid):
self.xmpp['xep_0030'].add_feature('jabber:x:data')
def make_form(self, ftype='form', title='', instructions=''):
f = Form()
f['type'] = ftype
f['title'] = title
f['instructions'] = instructions
return f
def handle_form(self, message):
self.xmpp.event("message_xform", message)
def build_form(self, xml):
return Form(xml=xml)

View File

@@ -0,0 +1,10 @@
"""
Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
from slixmpp.plugins.xep_0004.stanza.field import FormField, FieldOption
from slixmpp.plugins.xep_0004.stanza.form import Form

View File

@@ -0,0 +1,183 @@
"""
Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
from slixmpp.xmlstream import ElementBase, ET
class FormField(ElementBase):
namespace = 'jabber:x:data'
name = 'field'
plugin_attrib = 'field'
interfaces = set(('answer', 'desc', 'required', 'value',
'options', 'label', 'type', 'var'))
sub_interfaces = set(('desc',))
plugin_tag_map = {}
plugin_attrib_map = {}
field_types = set(('boolean', 'fixed', 'hidden', 'jid-multi',
'jid-single', 'list-multi', 'list-single',
'text-multi', 'text-private', 'text-single'))
true_values = set((True, '1', 'true'))
option_types = set(('list-multi', 'list-single'))
multi_line_types = set(('hidden', 'text-multi'))
multi_value_types = set(('hidden', 'jid-multi',
'list-multi', 'text-multi'))
def setup(self, xml=None):
if ElementBase.setup(self, xml):
self._type = None
else:
self._type = self['type']
def set_type(self, value):
self._set_attr('type', value)
if value:
self._type = value
def add_option(self, label='', value=''):
if self._type is None or self._type in self.option_types:
opt = FieldOption()
opt['label'] = label
opt['value'] = value
self.append(opt)
else:
raise ValueError("Cannot add options to " + \
"a %s field." % self['type'])
def del_options(self):
optsXML = self.xml.findall('{%s}option' % self.namespace)
for optXML in optsXML:
self.xml.remove(optXML)
def del_required(self):
reqXML = self.xml.find('{%s}required' % self.namespace)
if reqXML is not None:
self.xml.remove(reqXML)
def del_value(self):
valsXML = self.xml.findall('{%s}value' % self.namespace)
for valXML in valsXML:
self.xml.remove(valXML)
def get_answer(self):
return self['value']
def get_options(self):
options = []
optsXML = self.xml.findall('{%s}option' % self.namespace)
for optXML in optsXML:
opt = FieldOption(xml=optXML)
options.append({'label': opt['label'], 'value': opt['value']})
return options
def get_required(self):
reqXML = self.xml.find('{%s}required' % self.namespace)
return reqXML is not None
def get_value(self, convert=True):
valsXML = self.xml.findall('{%s}value' % self.namespace)
if len(valsXML) == 0:
return None
elif self._type == 'boolean':
if convert:
return valsXML[0].text in self.true_values
return valsXML[0].text
elif self._type in self.multi_value_types or len(valsXML) > 1:
values = []
for valXML in valsXML:
if valXML.text is None:
valXML.text = ''
values.append(valXML.text)
if self._type == 'text-multi' and convert:
values = "\n".join(values)
return values
else:
if valsXML[0].text is None:
return ''
return valsXML[0].text
def set_answer(self, answer):
self['value'] = answer
def set_false(self):
self['value'] = False
def set_options(self, options):
for value in options:
if isinstance(value, dict):
self.add_option(**value)
else:
self.add_option(value=value)
def set_required(self, required):
exists = self['required']
if not exists and required:
self.xml.append(ET.Element('{%s}required' % self.namespace))
elif exists and not required:
del self['required']
def set_true(self):
self['value'] = True
def set_value(self, value):
del self['value']
valXMLName = '{%s}value' % self.namespace
if self._type == 'boolean':
if value in self.true_values:
valXML = ET.Element(valXMLName)
valXML.text = '1'
self.xml.append(valXML)
else:
valXML = ET.Element(valXMLName)
valXML.text = '0'
self.xml.append(valXML)
elif self._type in self.multi_value_types or self._type in ('', None):
if isinstance(value, bool):
value = [value]
if not isinstance(value, list):
value = value.replace('\r', '')
value = value.split('\n')
for val in value:
if self._type in ('', None) and val in self.true_values:
val = '1'
valXML = ET.Element(valXMLName)
valXML.text = val
self.xml.append(valXML)
else:
if isinstance(value, list):
raise ValueError("Cannot add multiple values " + \
"to a %s field." % self._type)
valXML = ET.Element(valXMLName)
valXML.text = value
self.xml.append(valXML)
class FieldOption(ElementBase):
namespace = 'jabber:x:data'
name = 'option'
plugin_attrib = 'option'
interfaces = set(('label', 'value'))
sub_interfaces = set(('value',))
FormField.addOption = FormField.add_option
FormField.delOptions = FormField.del_options
FormField.delRequired = FormField.del_required
FormField.delValue = FormField.del_value
FormField.getAnswer = FormField.get_answer
FormField.getOptions = FormField.get_options
FormField.getRequired = FormField.get_required
FormField.getValue = FormField.get_value
FormField.setAnswer = FormField.set_answer
FormField.setFalse = FormField.set_false
FormField.setOptions = FormField.set_options
FormField.setRequired = FormField.set_required
FormField.setTrue = FormField.set_true
FormField.setValue = FormField.set_value

View File

@@ -0,0 +1,257 @@
"""
Slixmpp: The Slick XMPP Library
Copyright (C) 2011 Nathanael C. Fritz, Lance J.T. Stout
This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import copy
import logging
from slixmpp.thirdparty import OrderedDict
from slixmpp.xmlstream import ElementBase, ET
from slixmpp.plugins.xep_0004.stanza import FormField
log = logging.getLogger(__name__)
class Form(ElementBase):
namespace = 'jabber:x:data'
name = 'x'
plugin_attrib = 'form'
interfaces = set(('fields', 'instructions', 'items',
'reported', 'title', 'type', 'values'))
sub_interfaces = set(('title',))
form_types = set(('cancel', 'form', 'result', 'submit'))
def __init__(self, *args, **kwargs):
title = None
if 'title' in kwargs:
title = kwargs['title']
del kwargs['title']
ElementBase.__init__(self, *args, **kwargs)
if title is not None:
self['title'] = title
def setup(self, xml=None):
if ElementBase.setup(self, xml):
# If we had to generate xml
self['type'] = 'form'
@property
def field(self):
return self['fields']
def set_type(self, ftype):
self._set_attr('type', ftype)
if ftype == 'submit':
fields = self['fields']
for var in fields:
field = fields[var]
del field['type']
del field['label']
del field['desc']
del field['required']
del field['options']
elif ftype == 'cancel':
del self['fields']
def add_field(self, var='', ftype=None, label='', desc='',
required=False, value=None, options=None, **kwargs):
kwtype = kwargs.get('type', None)
if kwtype is None:
kwtype = ftype
field = FormField()
field['var'] = var
field['type'] = kwtype
field['value'] = value
if self['type'] in ('form', 'result'):
field['label'] = label
field['desc'] = desc
field['required'] = required
if options is not None:
field['options'] = options
else:
del field['type']
self.append(field)
return field
def getXML(self, type='submit'):
self['type'] = type
log.warning("Form.getXML() is deprecated API compatibility " + \
"with plugins/old_0004.py")
return self.xml
def fromXML(self, xml):
log.warning("Form.fromXML() is deprecated API compatibility " + \
"with plugins/old_0004.py")
n = Form(xml=xml)
return n
def add_item(self, values):
itemXML = ET.Element('{%s}item' % self.namespace)
self.xml.append(itemXML)
reported_vars = self['reported'].keys()
for var in reported_vars:
field = FormField()
field._type = self['reported'][var]['type']
field['var'] = var
field['value'] = values.get(var, None)
itemXML.append(field.xml)
def add_reported(self, var, ftype=None, label='', desc='', **kwargs):
kwtype = kwargs.get('type', None)
if kwtype is None:
kwtype = ftype
reported = self.xml.find('{%s}reported' % self.namespace)
if reported is None:
reported = ET.Element('{%s}reported' % self.namespace)
self.xml.append(reported)
fieldXML = ET.Element('{%s}field' % FormField.namespace)
reported.append(fieldXML)
field = FormField(xml=fieldXML)
field['var'] = var
field['type'] = kwtype
field['label'] = label
field['desc'] = desc
return field
def cancel(self):
self['type'] = 'cancel'
def del_fields(self):
fieldsXML = self.xml.findall('{%s}field' % FormField.namespace)
for fieldXML in fieldsXML:
self.xml.remove(fieldXML)
def del_instructions(self):
instsXML = self.xml.findall('{%s}instructions')
for instXML in instsXML:
self.xml.remove(instXML)
def del_items(self):
itemsXML = self.xml.find('{%s}item' % self.namespace)
for itemXML in itemsXML:
self.xml.remove(itemXML)
def del_reported(self):
reportedXML = self.xml.find('{%s}reported' % self.namespace)
if reportedXML is not None:
self.xml.remove(reportedXML)
def get_fields(self, use_dict=False):
fields = OrderedDict()
for stanza in self['substanzas']:
if isinstance(stanza, FormField):
fields[stanza['var']] = stanza
return fields
def get_instructions(self):
instructions = ''
instsXML = self.xml.findall('{%s}instructions' % self.namespace)
return "\n".join([instXML.text for instXML in instsXML])
def get_items(self):
items = []
itemsXML = self.xml.findall('{%s}item' % self.namespace)
for itemXML in itemsXML:
item = OrderedDict()
fieldsXML = itemXML.findall('{%s}field' % FormField.namespace)
for fieldXML in fieldsXML:
field = FormField(xml=fieldXML)
item[field['var']] = field['value']
items.append(item)
return items
def get_reported(self):
fields = OrderedDict()
xml = self.xml.findall('{%s}reported/{%s}field' % (self.namespace,
FormField.namespace))
for field in xml:
field = FormField(xml=field)
fields[field['var']] = field
return fields
def get_values(self):
values = OrderedDict()
fields = self['fields']
for var in fields:
values[var] = fields[var]['value']
return values
def reply(self):
if self['type'] == 'form':
self['type'] = 'submit'
elif self['type'] == 'submit':
self['type'] = 'result'
def set_fields(self, fields):
del self['fields']
if not isinstance(fields, list):
fields = fields.items()
for var, field in fields:
field['var'] = var
self.add_field(**field)
def set_instructions(self, instructions):
del self['instructions']
if instructions in [None, '']:
return
if not isinstance(instructions, list):
instructions = instructions.split('\n')
for instruction in instructions:
inst = ET.Element('{%s}instructions' % self.namespace)
inst.text = instruction
self.xml.append(inst)
def set_items(self, items):
for item in items:
self.add_item(item)
def set_reported(self, reported):
for var in reported:
field = reported[var]
field['var'] = var
self.add_reported(var, **field)
def set_values(self, values):
fields = self['fields']
for field in values:
if field not in fields:
fields[field] = self.add_field(var=field)
fields[field]['value'] = values[field]
def merge(self, other):
new = copy.copy(self)
if type(other) == dict:
new['values'] = other
return new
nfields = new['fields']
ofields = other['fields']
nfields.update(ofields)
new['fields'] = nfields
return new
Form.setType = Form.set_type
Form.addField = Form.add_field
Form.addItem = Form.add_item
Form.addReported = Form.add_reported
Form.delFields = Form.del_fields
Form.delInstructions = Form.del_instructions
Form.delItems = Form.del_items
Form.delReported = Form.del_reported
Form.getFields = Form.get_fields
Form.getInstructions = Form.get_instructions
Form.getItems = Form.get_items
Form.getReported = Form.get_reported
Form.getValues = Form.get_values
Form.setFields = Form.set_fields
Form.setInstructions = Form.set_instructions
Form.setItems = Form.set_items
Form.setReported = Form.set_reported
Form.setValues = Form.set_values