comparison src/plugins/plugin_xep_0020.py @ 383:98e1d44d5cd4

plugins: feature negociation (XEP-0020) implementation
author Goffi <goffi@goffi.org>
date Thu, 29 Sep 2011 12:05:25 +0200
parents
children cf005701624b
comparison
equal deleted inserted replaced
382:f6deca4e328e 383:98e1d44d5cd4
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 """
5 SAT plugin for managing xep-0020
6 Copyright (C) 2009, 2010, 2011 Jérôme Poisson (goffi@goffi.org)
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 """
21
22 from logging import debug, info, warning, error
23 from twisted.words.protocols.jabber import client, jid
24 from twisted.words.xish import domish
25
26 from zope.interface import implements
27
28 try:
29 from twisted.words.protocols.xmlstream import XMPPHandler
30 except ImportError:
31 from wokkel.subprotocols import XMPPHandler
32
33 from wokkel import disco, iwokkel, data_form
34
35 NS_FEATURE_NEG = 'http://jabber.org/protocol/feature-neg'
36
37 PLUGIN_INFO = {
38 "name": "XEP 0020 Plugin",
39 "import_name": "XEP-0020",
40 "type": "XEP",
41 "protocols": ["XEP-0020"],
42 "main": "XEP_0020",
43 "handler": "yes",
44 "description": _("""Implementation of Feature Negotiation""")
45 }
46
47 class XEP_0020():
48
49 def __init__(self, host):
50 info(_("Plugin XEP_0020 initialization"))
51
52 def getHandler(self, profile):
53 return XEP_0020_handler()
54
55 def getFeatureElt(self, elt):
56 """Check element's children to find feature elements
57 @param elt: domish.Element
58 @return: feature elements"""
59 return filter(lambda elt: elt.name == 'feature', elt.elements())
60
61 def getChoosedOptions(self, elt):
62 """Return choosed feature for feature element
63 @param elt: feature domish element
64 @return: dict with feature name as key, and choosed option as value"""
65 form = data_form.Form.fromElement(elt.firstChildElement())
66 result = {}
67 for field in form.fields:
68 values = form.fields[field].values
69 result[field] = values[0] if values else None
70 if len(values)>1:
71 warning(_("More than one value choosed for %s, keeping the first one") % field)
72 return result
73
74 def negociate(self, feature_elt, form_type, negociable_values):
75 """Negociate the feature options
76 @param feature_elt: feature domish element
77 @param form_type: the option to negociate
78 @param negociable_values: acceptable values for this negociation"""
79 form = data_form.Form.fromElement(feature_elt.firstChildElement())
80 options = [option.value for option in form.fields[form_type].options]
81 for value in negociable_values:
82 if value in options:
83 return value
84 return None
85
86 def chooseOption(self, options_dict):
87 """Build a feature element with choosed options
88 @param options_dict: dict with feature as key and choosed option as value"""
89 feature_elt = domish.Element((NS_FEATURE_NEG, 'feature'))
90 x_form = data_form.Form('submit')
91 x_form.makeFields(options_dict)
92 feature_elt.addChild(x_form.toElement())
93 return feature_elt
94
95 def proposeFeatures(self, options_dict, namespace = None):
96 """Build a feature element with options to propose
97 @param options_dict: dict with feature as key and list of acceptable options as value
98 @param namespace: feature namespace"""
99 feature_elt = domish.Element((NS_FEATURE_NEG, 'feature'))
100 x_form = data_form.Form('form', formNamespace=namespace)
101 for field in options_dict:
102 x_form.addField(data_form.Field('list-single', field,
103 options=[data_form.Option(_option) for _option in options_dict[field]]))
104 feature_elt.addChild(x_form.toElement())
105 return feature_elt
106
107 class XEP_0020_handler(XMPPHandler):
108 implements(iwokkel.IDisco)
109
110 def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
111 return [disco.DiscoFeature(NS_FEATURE_NEG)]
112
113 def getDiscoItems(self, requestor, target, nodeIdentifier=''):
114 return []
115