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 )