comparison src/plugins/plugin_xep_0020.py @ 1577:d04d7402b8e9

plugins XEP-0020, XEP-0065, XEP-0095, XEP-0096: fixed file copy with Stream Initiation: /!\ range is not working yet /!\ pipe plugin is broken for now
author Goffi <goffi@goffi.org>
date Wed, 11 Nov 2015 18:19:49 +0100
parents 3265a2639182
children 14fcbaa82fd4
comparison
equal deleted inserted replaced
1576:d5f59ba166fe 1577:d04d7402b8e9
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20 from sat.core.i18n import _ 20 from sat.core.i18n import _
21 from sat.core.log import getLogger 21 from sat.core.log import getLogger
22 log = getLogger(__name__) 22 log = getLogger(__name__)
23 from twisted.words.protocols.jabber import client, jid 23 from core import exceptions
24 from twisted.words.xish import domish 24 from twisted.words.xish import domish
25 25
26 from zope.interface import implements 26 from zope.interface import implements
27 27
28 try: 28 try:
53 def getHandler(self, profile): 53 def getHandler(self, profile):
54 return XEP_0020_handler() 54 return XEP_0020_handler()
55 55
56 def getFeatureElt(self, elt): 56 def getFeatureElt(self, elt):
57 """Check element's children to find feature elements 57 """Check element's children to find feature elements
58 @param elt: domish.Element
59 @return: feature elements"""
60 return [child for child in elt.elements() if child.name == 'feature']
61 58
62 def getChoosedOptions(self, elt): 59 @param elt(domish.Element): parent element of the feature element
60 @return: feature elements
61 @raise exceptions.NotFound: no feature element found
62 """
63 try:
64 feature_elt = elt.elements(NS_FEATURE_NEG, 'feature').next()
65 except StopIteration:
66 raise exceptions.NotFound
67 return feature_elt
68
69 def _getForm(self, elt, namespace):
70 """Return the first child data form
71
72 @param elt(domish.Element): parent of the data form
73 @param namespace (None, unicode): form namespace or None to ignore
74 @return (None, data_form.Form): data form or None is nothing is found
75 """
76 if namespace is None:
77 try:
78 form_elt = elt.elements(data_form.NS_X_DATA).next()
79 except StopIteration:
80 return None
81 else:
82 return data_form.Form.fromElement(form_elt)
83 else:
84 return data_form.findForm(elt, namespace)
85
86 def getChoosedOptions(self, feature_elt, namespace):
63 """Return choosed feature for feature element 87 """Return choosed feature for feature element
64 @param elt: feature domish element 88
65 @return: dict with feature name as key, and choosed option as value""" 89 @param feature_elt(domish.Element): feature domish element
66 form = data_form.Form.fromElement(elt.firstChildElement()) 90 @param namespace (None, unicode): form namespace or None to ignore
91 @return (dict): feature name as key, and choosed option as value
92 @raise exceptions.NotFound: not data form is found
93 """
94 form = self._getForm(feature_elt, namespace)
95 if form is None:
96 raise exceptions.NotFound
67 result = {} 97 result = {}
68 for field in form.fields: 98 for field in form.fields:
69 values = form.fields[field].values 99 values = form.fields[field].values
70 result[field] = values[0] if values else None 100 result[field] = values[0] if values else None
71 if len(values) > 1: 101 if len(values) > 1:
72 log.warning(_(u"More than one value choosed for %s, keeping the first one") % field) 102 log.warning(_(u"More than one value choosed for {}, keeping the first one").format(field))
73 return result 103 return result
74 104
75 def negociate(self, feature_elt, form_type, negociable_values): 105 def negotiate(self, feature_elt, name, negotiable_values, namespace):
76 """Negociate the feature options 106 """Negotiate the feature options
77 @param feature_elt: feature domish element 107
78 @param form_type: the option to negociate 108 @param feature_elt(domish.Element): feature element
79 @param negociable_values: acceptable values for this negociation""" 109 @param name: the option name (i.e. field's var attribute) to negotiate
80 form = data_form.Form.fromElement(feature_elt.firstChildElement()) 110 @param negotiable_values(iterable): acceptable values for this negotiation
81 options = [option.value for option in form.fields[form_type].options] 111 first corresponding value will be returned
82 for value in negociable_values: 112 @param namespace (None, unicode): form namespace or None to ignore
113 @raise KeyError: name is not found in data form fields
114 """
115 form = self._getForm(feature_elt, namespace)
116 options = [option.value for option in form.fields[name].options]
117 for value in negotiable_values:
83 if value in options: 118 if value in options:
84 return value 119 return value
85 return None 120 return None
86 121
87 def chooseOption(self, options_dict): 122 def chooseOption(self, options, namespace):
88 """Build a feature element with choosed options 123 """Build a feature element with choosed options
89 @param options_dict: dict with feature as key and choosed option as value""" 124
125 @param options(dict): dict with feature as key and choosed option as value
126 @param namespace (None, unicode): form namespace or None to ignore
127 """
90 feature_elt = domish.Element((NS_FEATURE_NEG, 'feature')) 128 feature_elt = domish.Element((NS_FEATURE_NEG, 'feature'))
91 x_form = data_form.Form('submit') 129 x_form = data_form.Form('submit', formNamespace=namespace)
92 x_form.makeFields(options_dict) 130 x_form.makeFields(options)
93 feature_elt.addChild(x_form.toElement()) 131 feature_elt.addChild(x_form.toElement())
94 return feature_elt 132 return feature_elt
95 133
96 def proposeFeatures(self, options_dict, namespace=None): 134 def proposeFeatures(self, options_dict, namespace):
97 """Build a feature element with options to propose 135 """Build a feature element with options to propose
98 @param options_dict: dict with feature as key and list of acceptable options as value 136
99 @param namespace: feature namespace""" 137 @param options_dict(dict): dict with feature as key and iterable of acceptable options as value
138 @param namespace(None, unicode): feature namespace
139 """
100 feature_elt = domish.Element((NS_FEATURE_NEG, 'feature')) 140 feature_elt = domish.Element((NS_FEATURE_NEG, 'feature'))
101 x_form = data_form.Form('form', formNamespace=namespace) 141 x_form = data_form.Form('form', formNamespace=namespace)
102 for field in options_dict: 142 for field in options_dict:
103 x_form.addField(data_form.Field('list-single', field, 143 x_form.addField(data_form.Field('list-single', field,
104 options=[data_form.Option(_option) for _option in options_dict[field]])) 144 options=[data_form.Option(option) for option in options_dict[field]]))
105 feature_elt.addChild(x_form.toElement()) 145 feature_elt.addChild(x_form.toElement())
106 return feature_elt 146 return feature_elt
107 147
108 148
109 class XEP_0020_handler(XMPPHandler): 149 class XEP_0020_handler(XMPPHandler):