Mercurial > libervia-backend
comparison src/plugins/plugin_xep_0234.py @ 1556:cbfbe028d099
plugin XEP-0166, XEP-0234, XEP-0261:
- transport and application data are now managed in separate dictionaries
- new client.IQ method is used
- new buildAction helper method for applications and transports
- "role" is now stored in session_data
- "senders" is now stored in content_data
- plugin XEP-0166: "transport-info" action is now managed
- plugin XEP-0166: application namespace and handler are now managed in a namedtuple
- plugin XEP-0234: <range/> element is added by responder if not already present
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 02 Nov 2015 22:02:41 +0100 |
parents | a151f3a5a2d0 |
children | 22f0307864b4 |
comparison
equal
deleted
inserted
replaced
1555:eb8aae35085b | 1556:cbfbe028d099 |
---|---|
91 @param session(dict): jingle session data | 91 @param session(dict): jingle session data |
92 @param content_data(dict): content informations | 92 @param content_data(dict): content informations |
93 @param profile: %(doc_profile)s | 93 @param profile: %(doc_profile)s |
94 return (defer.Deferred): True if transfer is accepted | 94 return (defer.Deferred): True if transfer is accepted |
95 """ | 95 """ |
96 file_data = content_data['file_data'] | 96 application_data = content_data['application_data'] |
97 file_data = application_data['file_data'] | |
97 d = xml_tools.deferDialog(self.host, | 98 d = xml_tools.deferDialog(self.host, |
98 _(CONFIRM).format(entity=session['to_jid'].full(), **file_data), | 99 _(CONFIRM).format(entity=session['to_jid'].full(), **file_data), |
99 _(CONFIRM_TITLE), | 100 _(CONFIRM_TITLE), |
100 type_=C.XMLUI_DIALOG_FILE, | 101 type_=C.XMLUI_DIALOG_FILE, |
101 options={C.XMLUI_DATA_FILETYPE: C.XMLUI_DATA_FILETYPE_DIR}, | 102 options={C.XMLUI_DATA_FILETYPE: C.XMLUI_DATA_FILETYPE_DIR}, |
102 profile=profile) | 103 profile=profile) |
103 d.addCallback(self._gotConfirmation, session, content_data, profile) | 104 d.addCallback(self._gotConfirmation, session, content_data, application_data, profile) |
104 return d | 105 return d |
105 | 106 |
106 def _gotConfirmation(self, data, session, content_data, profile): | 107 def _gotConfirmation(self, data, session, content_data, application_data, profile): |
107 """Called when the permission and dest path have been received | 108 """Called when the permission and dest path have been received |
108 | 109 |
109 @param data(dict): xmlui data received from file dialog | 110 @param data(dict): xmlui data received from file dialog |
110 return (bool): True if copy is wanted and OK | 111 return (bool): True if copy is wanted and OK |
111 False if user wants to cancel | 112 False if user wants to cancel |
112 if fill exists ask confirmation and call again self._getDestDir if needed | 113 if fill exists ask confirmation and call again self._getDestDir if needed |
113 """ | 114 """ |
114 if data.get('cancelled', False): | 115 if data.get('cancelled', False): |
115 return False | 116 return False |
116 file_data = content_data['file_data'] | 117 file_data = application_data['file_data'] |
117 path = data['path'] | 118 path = data['path'] |
118 file_data['file_path'] = file_path = os.path.join(path, file_data['name']) | 119 file_data['file_path'] = file_path = os.path.join(path, file_data['name']) |
119 log.debug(u'destination file path set to {}'.format(file_path)) | 120 log.debug(u'destination file path set to {}'.format(file_path)) |
120 | 121 |
121 # we manage case where file already exists | 122 # we manage case where file already exists |
142 | 143 |
143 # jingle callbacks | 144 # jingle callbacks |
144 | 145 |
145 def jingleSessionInit(self, session, content_name, filepath, name=None, file_desc=None, profile=C.PROF_KEY_NONE): | 146 def jingleSessionInit(self, session, content_name, filepath, name=None, file_desc=None, profile=C.PROF_KEY_NONE): |
146 content_data = session['contents'][content_name] | 147 content_data = session['contents'][content_name] |
147 assert 'file_path' not in content_data | 148 application_data = content_data['application_data'] |
148 content_data['file_path'] = filepath | 149 assert 'file_path' not in application_data |
149 file_data = content_data['file_data'] = {} | 150 application_data['file_path'] = filepath |
151 file_data = application_data['file_data'] = {} | |
150 file_data['date'] = utils.xmpp_date() | 152 file_data['date'] = utils.xmpp_date() |
151 file_data['desc'] = file_desc or '' | 153 file_data['desc'] = file_desc or '' |
152 file_data['media-type'] = "application/octet-stream" # TODO | 154 file_data['media-type'] = "application/octet-stream" # TODO |
153 file_data['name'] = os.path.basename(filepath) if name is None else name | 155 file_data['name'] = os.path.basename(filepath) if name is None else name |
154 file_data['size'] = os.path.getsize(filepath) | 156 file_data['size'] = os.path.getsize(filepath) |
188 log.warning(u"File name contain path characters, we replace them: {}".format(name)) | 190 log.warning(u"File name contain path characters, we replace them: {}".format(name)) |
189 file_data['name'] = name.replace('/', '_').replace('\\', '_') | 191 file_data['name'] = name.replace('/', '_').replace('\\', '_') |
190 | 192 |
191 # TODO: parse hash using plugin XEP-0300 | 193 # TODO: parse hash using plugin XEP-0300 |
192 | 194 |
193 content_data['file_data'] = file_data | 195 content_data['application_data']['file_data'] = file_data |
194 | 196 |
195 # now we actualy request permission to user | 197 # now we actualy request permission to user |
196 return self._getDestDir(session, content_data, profile) | 198 return self._getDestDir(session, content_data, profile) |
197 | 199 |
198 | 200 |
199 def jingleHandler(self, action, session, content_name, desc_elt, profile): | 201 def jingleHandler(self, action, session, content_name, desc_elt, profile): |
200 content_data = session['contents'][content_name] | 202 content_data = session['contents'][content_name] |
201 if action in (self._j.A_SESSION_INITIATE, self._j.A_ACCEPTED_ACK): | 203 application_data = content_data['application_data'] |
204 if action in (self._j.A_ACCEPTED_ACK,): | |
202 pass | 205 pass |
206 elif action == self._j.A_SESSION_INITIATE: | |
207 file_elt = desc_elt.elements(NS_JINGLE_FT, 'file').next() | |
208 try: | |
209 file_elt.elements(NS_JINGLE_FT, 'range').next() | |
210 except StopIteration: | |
211 # initiator doesn't manage <range>, but we do so we advertise it | |
212 log.debug("adding <range> element") | |
213 file_elt.addElement('range') | |
203 elif action == self._j.A_SESSION_ACCEPT: | 214 elif action == self._j.A_SESSION_ACCEPT: |
204 assert not 'file_obj' in content_data | 215 assert not 'file_obj' in content_data |
205 file_path = content_data['file_path'] | 216 file_path = application_data['file_path'] |
206 size = content_data['file_data']['size'] | 217 size = application_data['file_data']['size'] |
207 file_obj = content_data['file_obj'] = self._f.File(self.host, | 218 file_obj = content_data['file_obj'] = self._f.File(self.host, |
208 file_path, | 219 file_path, |
209 size=size, | 220 size=size, |
210 profile=profile | 221 profile=profile |
211 ) | 222 ) |