comparison src/plugins/plugin_xep_0055.py @ 799:7f2082b192ed

plugin XEP-0055, Primitivus: Directory search dialogs are now entirely done in plugin XEP-0055, specific code in frontend is not needed anymore
author Goffi <goffi@goffi.org>
date Tue, 04 Feb 2014 18:03:53 +0100
parents bfabeedbf32e
children 9007bb133009
comparison
equal deleted inserted replaced
798:8f5479f8709a 799:7f2082b192ed
15 # GNU Affero General Public License for more details. 15 # GNU Affero General Public License for more details.
16 16
17 # You should have received a copy of the GNU Affero General Public License 17 # You should have received a copy of the GNU Affero General Public License
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 _, D_
21 from logging import debug, info, warning, error 21 from logging import debug, info, warning, error
22 from twisted.words.protocols.jabber.xmlstream import IQ 22 from twisted.words.protocols.jabber.xmlstream import IQ
23 from twisted.words.protocols.jabber import jid 23 from twisted.words.protocols.jabber import jid
24 from wokkel import data_form 24 from wokkel import data_form
25 from sat.core.exceptions import DataError 25 from sat.core.exceptions import DataError
26 from sat.tools.xml_tools import dataForm2XMLUI, dataFormResult2XMLUI 26 from sat.memory.memory import Sessions
27 from sat.tools import xml_tools
27 28
28 NS_SEARCH = 'jabber:iq:search' 29 NS_SEARCH = 'jabber:iq:search'
29 30
30 PLUGIN_INFO = { 31 PLUGIN_INFO = {
31 "name": "Jabber Search", 32 "name": "Jabber Search",
47 method=self._getSearchUI, 48 method=self._getSearchUI,
48 async=True) 49 async=True)
49 host.bridge.addMethod("searchRequest", ".plugin", in_sign='sa{ss}s', out_sign='s', 50 host.bridge.addMethod("searchRequest", ".plugin", in_sign='sa{ss}s', out_sign='s',
50 method=self._searchRequest, 51 method=self._searchRequest,
51 async=True) 52 async=True)
53 self._sessions = Sessions()
54 self.__menu_cb_id = host.registerCallback(self._menuCb, with_data=True)
55 self.__search_request_id = host.registerCallback(self._xmluiSearchRequest, with_data=True)
56 host.importMenu((D_("Communication"), D_("Search directory")), self._searchMenu, help_string=D_("Search use directory"))
57
58 def _menuCb(self, data, profile):
59 entity = jid.JID(data[xml_tools.SAT_FORM_PREFIX+'jid'])
60 d = self.getSearchUI(entity, profile)
61 def gotXMLUI(xmlui):
62 session_id, session_data = self._sessions.newSession(profile=profile)
63 session_data['jid'] = entity
64 xmlui.session_id = session_id # we need to keep track of the session
65 xmlui.submit_id = self.__search_request_id
66 return {'xmlui': xmlui.toXml()}
67 d.addCallback(gotXMLUI)
68 return d
69
70
71 def _searchMenu(self, menu_data, profile):
72 """ First XMLUI activated by menu: ask for target jid
73 @param profile: %(doc_profile)s
74
75 """
76 form_ui = xml_tools.XMLUI("form", title=_("Search directory"), submit_id=self.__menu_cb_id)
77 form_ui.addText(_("Please enter the search jid"), 'instructions')
78 form_ui.changeLayout("pairs")
79 form_ui.addLabel("jid")
80 form_ui.addString("jid", value="users.jabberfr.org") # TODO: replace users.jabberfr.org by any XEP-0055 compatible service discovered on current server
81 return {'xmlui': form_ui.toXml()}
52 82
53 def _getSearchUI(self, to_jid_s, profile_key): 83 def _getSearchUI(self, to_jid_s, profile_key):
54 return self.getSearchUI(jid.JID(to_jid_s), profile_key) 84 d = self.getSearchUI(jid.JID(to_jid_s), profile_key)
85 d.addCallback(lambda xmlui: xmlui.toXml())
86 return d
55 87
56 def getSearchUI(self, to_jid, profile_key): 88 def getSearchUI(self, to_jid, profile_key):
57 """ Ask for a search interface 89 """ Ask for a search interface
58 @param to_jid: XEP-0055 compliant search entity 90 @param to_jid: XEP-0055 compliant search entity
59 @param profile_key: %(doc_profile_key)s 91 @param profile_key: %(doc_profile_key)s
78 form_elt = query_elts.elements(data_form.NS_X_DATA, 'x').next() 110 form_elt = query_elts.elements(data_form.NS_X_DATA, 'x').next()
79 except StopIteration: 111 except StopIteration:
80 info(_("No data form found")) 112 info(_("No data form found"))
81 raise NotImplementedError("Only search through data form is implemented so far") 113 raise NotImplementedError("Only search through data form is implemented so far")
82 parsed_form = data_form.Form.fromElement(form_elt) 114 parsed_form = data_form.Form.fromElement(form_elt)
83 return dataForm2XMLUI(parsed_form, "").toXml() 115 return xml_tools.dataForm2XMLUI(parsed_form, "")
84 116
85 def _fieldsErr(self, failure, profile): 117 def _fieldsErr(self, failure, profile):
86 """ Called when something is wrong with fields request """ 118 """ Called when something is wrong with fields request """
87 info(_("Fields request failure: %s") % str(failure.value)) 119 info(_("Fields request failure: %s") % str(failure.value))
88 return failure 120 return failure
89 121
122 def _xmluiSearchRequest(self, raw_data, profile):
123 try:
124 session_data = self._sessions.profileGet(raw_data["session_id"], profile)
125 except KeyError:
126 warning ("session id doesn't exist, session has probably expired")
127 # TODO: send error dialog
128 return defer.succeed({})
129
130 data = xml_tools.XMLUIResult2DataFormResult(raw_data)
131 entity =session_data['jid']
132 d = self.searchRequest(entity, data, profile)
133 d.addCallback(lambda xmlui: {'xmlui':xmlui.toXml()})
134 del self._sessions[raw_data["session_id"]]
135 return d
136
90 def _searchRequest(self, to_jid_s, search_dict, profile_key): 137 def _searchRequest(self, to_jid_s, search_dict, profile_key):
91 return self.searchRequest(jid.JID(to_jid_s), search_dict, profile_key) 138 d = self.searchRequest(jid.JID(to_jid_s), search_dict, profile_key)
139 d.addCallback(lambda xmlui: xmlui.toXml())
140 return d
92 141
93 def searchRequest(self, to_jid, search_dict, profile_key): 142 def searchRequest(self, to_jid, search_dict, profile_key):
94 """ Actually do a search, according to filled data 143 """ Actually do a search, according to filled data
95 @param to_jid: XEP-0055 compliant search entity 144 @param to_jid: XEP-0055 compliant search entity
96 @param search_dict: filled data, corresponding to the form obtained in getSearchUI 145 @param search_dict: filled data, corresponding to the form obtained in getSearchUI
118 try: 167 try:
119 form_elt = query_elts.elements(data_form.NS_X_DATA, 'x').next() 168 form_elt = query_elts.elements(data_form.NS_X_DATA, 'x').next()
120 except StopIteration: 169 except StopIteration:
121 info(_("No data form found")) 170 info(_("No data form found"))
122 raise NotImplementedError("Only search through data form is implemented so far") 171 raise NotImplementedError("Only search through data form is implemented so far")
123 xmlui = dataFormResult2XMLUI(form_elt).toXml() 172 return xml_tools.dataFormResult2XMLUI(form_elt)
124 print "=== XMLUI ===\n%s\n\n" % xmlui
125 return xmlui
126
127 173
128 def _searchErr(self, failure, profile): 174 def _searchErr(self, failure, profile):
129 """ Called when something is wrong with search request """ 175 """ Called when something is wrong with search request """
130 info(_("Search request failure: %s") % str(failure.value)) 176 info(_("Search request failure: %s") % str(failure.value))
131 return failure 177 return failure