comparison sat/plugins/plugin_xep_0166.py @ 4037:524856bd7b19

massive refactoring to switch from camelCase to snake_case: historically, Libervia (SàT before) was using camelCase as allowed by PEP8 when using a pre-PEP8 code, to use the same coding style as in Twisted. However, snake_case is more readable and it's better to follow PEP8 best practices, so it has been decided to move on full snake_case. Because Libervia has a huge codebase, this ended with a ugly mix of camelCase and snake_case. To fix that, this patch does a big refactoring by renaming every function and method (including bridge) that are not coming from Twisted or Wokkel, to use fully snake_case. This is a massive change, and may result in some bugs.
author Goffi <goffi@goffi.org>
date Sat, 08 Apr 2023 13:54:42 +0200
parents 8e7d5796fb23
children
comparison
equal deleted inserted replaced
4036:c4464d7ae97b 4037:524856bd7b19
108 self._type_transports = { 108 self._type_transports = {
109 XEP_0166.TRANSPORT_DATAGRAM: [], 109 XEP_0166.TRANSPORT_DATAGRAM: [],
110 XEP_0166.TRANSPORT_STREAMING: [], 110 XEP_0166.TRANSPORT_STREAMING: [],
111 } 111 }
112 112
113 def profileConnected(self, client): 113 def profile_connected(self, client):
114 client.jingle_sessions = {} # key = sid, value = session_data 114 client.jingle_sessions = {} # key = sid, value = session_data
115 115
116 def getHandler(self, client): 116 def get_handler(self, client):
117 return XEP_0166_handler(self) 117 return XEP_0166_handler(self)
118 118
119 def _delSession(self, client, sid): 119 def _del_session(self, client, sid):
120 try: 120 try:
121 del client.jingle_sessions[sid] 121 del client.jingle_sessions[sid]
122 except KeyError: 122 except KeyError:
123 log.debug( 123 log.debug(
124 f"Jingle session id {sid!r} is unknown, nothing to delete " 124 f"Jingle session id {sid!r} is unknown, nothing to delete "
126 else: 126 else:
127 log.debug(f"Jingle session id {sid!r} deleted [{client.profile}]") 127 log.debug(f"Jingle session id {sid!r} deleted [{client.profile}]")
128 128
129 ## helpers methods to build stanzas ## 129 ## helpers methods to build stanzas ##
130 130
131 def _buildJingleElt(self, client, session, action): 131 def _build_jingle_elt(self, client, session, action):
132 iq_elt = client.IQ("set") 132 iq_elt = client.IQ("set")
133 iq_elt["from"] = session['local_jid'].full() 133 iq_elt["from"] = session['local_jid'].full()
134 iq_elt["to"] = session["peer_jid"].full() 134 iq_elt["to"] = session["peer_jid"].full()
135 jingle_elt = iq_elt.addElement("jingle", NS_JINGLE) 135 jingle_elt = iq_elt.addElement("jingle", NS_JINGLE)
136 jingle_elt["sid"] = session["id"] 136 jingle_elt["sid"] = session["id"]
147 """ 147 """
148 iq_elt = error.StanzaError(error_condition).toResponse(request) 148 iq_elt = error.StanzaError(error_condition).toResponse(request)
149 if jingle_condition is not None: 149 if jingle_condition is not None:
150 iq_elt.error.addElement((NS_JINGLE_ERROR, jingle_condition)) 150 iq_elt.error.addElement((NS_JINGLE_ERROR, jingle_condition))
151 if error.STANZA_CONDITIONS[error_condition]["type"] == "cancel" and sid: 151 if error.STANZA_CONDITIONS[error_condition]["type"] == "cancel" and sid:
152 self._delSession(client, sid) 152 self._del_session(client, sid)
153 log.warning( 153 log.warning(
154 "Error while managing jingle session, cancelling: {condition}".format( 154 "Error while managing jingle session, cancelling: {condition}".format(
155 condition=error_condition 155 condition=error_condition
156 ) 156 )
157 ) 157 )
158 return client.send(iq_elt) 158 return client.send(iq_elt)
159 159
160 def _terminateEb(self, failure_): 160 def _terminate_eb(self, failure_):
161 log.warning(_("Error while terminating session: {msg}").format(msg=failure_)) 161 log.warning(_("Error while terminating session: {msg}").format(msg=failure_))
162 162
163 def terminate(self, client, reason, session, text=None): 163 def terminate(self, client, reason, session, text=None):
164 """Terminate the session 164 """Terminate the session
165 165
166 send the session-terminate action, and delete the session data 166 send the session-terminate action, and delete the session data
167 @param reason(unicode, list[domish.Element]): if unicode, will be transformed to an element 167 @param reason(unicode, list[domish.Element]): if unicode, will be transformed to an element
168 if a list of element, add them as children of the <reason/> element 168 if a list of element, add them as children of the <reason/> element
169 @param session(dict): data of the session 169 @param session(dict): data of the session
170 """ 170 """
171 iq_elt, jingle_elt = self._buildJingleElt( 171 iq_elt, jingle_elt = self._build_jingle_elt(
172 client, session, XEP_0166.A_SESSION_TERMINATE 172 client, session, XEP_0166.A_SESSION_TERMINATE
173 ) 173 )
174 reason_elt = jingle_elt.addElement("reason") 174 reason_elt = jingle_elt.addElement("reason")
175 if isinstance(reason, str): 175 if isinstance(reason, str):
176 reason_elt.addElement(reason) 176 reason_elt.addElement(reason)
177 else: 177 else:
178 for elt in reason: 178 for elt in reason:
179 reason_elt.addChild(elt) 179 reason_elt.addChild(elt)
180 if text is not None: 180 if text is not None:
181 reason_elt.addElement("text", content=text) 181 reason_elt.addElement("text", content=text)
182 self._delSession(client, session["id"]) 182 self._del_session(client, session["id"])
183 d = iq_elt.send() 183 d = iq_elt.send()
184 d.addErrback(self._terminateEb) 184 d.addErrback(self._terminate_eb)
185 return d 185 return d
186 186
187 ## errors which doesn't imply a stanza sending ## 187 ## errors which doesn't imply a stanza sending ##
188 188
189 def _iqError(self, failure_, sid, client): 189 def _iq_error(self, failure_, sid, client):
190 """Called when we got an <iq/> error 190 """Called when we got an <iq/> error
191 191
192 @param failure_(failure.Failure): the exceptions raised 192 @param failure_(failure.Failure): the exceptions raised
193 @param sid(unicode): jingle session id 193 @param sid(unicode): jingle session id
194 """ 194 """
195 log.warning( 195 log.warning(
196 "Error while sending jingle <iq/> stanza: {failure_}".format( 196 "Error while sending jingle <iq/> stanza: {failure_}".format(
197 failure_=failure_.value 197 failure_=failure_.value
198 ) 198 )
199 ) 199 )
200 self._delSession(client, sid) 200 self._del_session(client, sid)
201 201
202 def _jingleErrorCb(self, failure_, session, request, client): 202 def _jingle_error_cb(self, failure_, session, request, client):
203 """Called when something is going wrong while parsing jingle request 203 """Called when something is going wrong while parsing jingle request
204 204
205 The error condition depend of the exceptions raised: 205 The error condition depend of the exceptions raised:
206 exceptions.DataError raise a bad-request condition 206 exceptions.DataError raise a bad-request condition
207 @param fail(failure.Failure): the exceptions raised 207 @param fail(failure.Failure): the exceptions raised
222 return self.terminate(client, self.REASON_FAILED_APPLICATION, session, 222 return self.terminate(client, self.REASON_FAILED_APPLICATION, session,
223 text=str(failure_)) 223 text=str(failure_))
224 224
225 ## methods used by other plugins ## 225 ## methods used by other plugins ##
226 226
227 def registerApplication(self, namespace, handler): 227 def register_application(self, namespace, handler):
228 """Register an application plugin 228 """Register an application plugin
229 229
230 @param namespace(unicode): application namespace managed by the plugin 230 @param namespace(unicode): application namespace managed by the plugin
231 @param handler(object): instance of a class which manage the application. 231 @param handler(object): instance of a class which manage the application.
232 May have the following methods: 232 May have the following methods:
233 - requestConfirmation(session, desc_elt, client): 233 - requestConfirmation(session, desc_elt, client):
234 - if present, it is called on when session must be accepted. 234 - if present, it is called on when session must be accepted.
235 - if it return True the session is accepted, else rejected. 235 - if it return True the session is accepted, else rejected.
236 A Deferred can be returned 236 A Deferred can be returned
237 - if not present, a generic accept dialog will be used 237 - if not present, a generic accept dialog will be used
238 - jingleSessionInit(client, self, session, content_name[, *args, **kwargs]): must return the domish.Element used for initial content 238 - jingle_session_init(client, self, session, content_name[, *args, **kwargs]): must return the domish.Element used for initial content
239 - jingleHandler(client, self, action, session, content_name, transport_elt): 239 - jingle_handler(client, self, action, session, content_name, transport_elt):
240 called on several action to negociate the application or transport 240 called on several action to negociate the application or transport
241 - jingleTerminate: called on session terminate, with reason_elt 241 - jingle_terminate: called on session terminate, with reason_elt
242 May be used to clean session 242 May be used to clean session
243 """ 243 """
244 if namespace in self._applications: 244 if namespace in self._applications:
245 raise exceptions.ConflictError( 245 raise exceptions.ConflictError(
246 "Trying to register already registered namespace {}".format(namespace) 246 "Trying to register already registered namespace {}".format(namespace)
248 self._applications[namespace] = ApplicationData( 248 self._applications[namespace] = ApplicationData(
249 namespace=namespace, handler=handler 249 namespace=namespace, handler=handler
250 ) 250 )
251 log.debug("new jingle application registered") 251 log.debug("new jingle application registered")
252 252
253 def registerTransport(self, namespace, transport_type, handler, priority=0): 253 def register_transport(self, namespace, transport_type, handler, priority=0):
254 """Register a transport plugin 254 """Register a transport plugin
255 255
256 @param namespace(unicode): the XML namespace used for this transport 256 @param namespace(unicode): the XML namespace used for this transport
257 @param transport_type(unicode): type of transport to use (see XEP-0166 §8) 257 @param transport_type(unicode): type of transport to use (see XEP-0166 §8)
258 @param handler(object): instance of a class which manage the application. 258 @param handler(object): instance of a class which manage the application.
259 Must have the following methods: 259 Must have the following methods:
260 - jingleSessionInit(client, self, session, content_name[, *args, **kwargs]): must return the domish.Element used for initial content 260 - jingle_session_init(client, self, session, content_name[, *args, **kwargs]): must return the domish.Element used for initial content
261 - jingleHandler(client, self, action, session, content_name, transport_elt): 261 - jingle_handler(client, self, action, session, content_name, transport_elt):
262 called on several action to negociate the application or transport 262 called on several action to negociate the application or transport
263 @param priority(int): priority of this transport 263 @param priority(int): priority of this transport
264 """ 264 """
265 assert transport_type in ( 265 assert transport_type in (
266 XEP_0166.TRANSPORT_DATAGRAM, 266 XEP_0166.TRANSPORT_DATAGRAM,
279 ) 279 )
280 self._transports[namespace] = transport_data 280 self._transports[namespace] = transport_data
281 log.debug("new jingle transport registered") 281 log.debug("new jingle transport registered")
282 282
283 @defer.inlineCallbacks 283 @defer.inlineCallbacks
284 def transportReplace(self, client, transport_ns, session, content_name): 284 def transport_replace(self, client, transport_ns, session, content_name):
285 """Replace a transport 285 """Replace a transport
286 286
287 @param transport_ns(unicode): namespace of the new transport to use 287 @param transport_ns(unicode): namespace of the new transport to use
288 @param session(dict): jingle session data 288 @param session(dict): jingle session data
289 @param content_name(unicode): name of the content 289 @param content_name(unicode): name of the content
295 transport_data = content_data["transport_data"] 295 transport_data = content_data["transport_data"]
296 try: 296 try:
297 transport = self._transports[transport_ns] 297 transport = self._transports[transport_ns]
298 except KeyError: 298 except KeyError:
299 raise exceptions.InternalError("Unkown transport") 299 raise exceptions.InternalError("Unkown transport")
300 yield content_data["transport"].handler.jingleHandler( 300 yield content_data["transport"].handler.jingle_handler(
301 client, XEP_0166.A_DESTROY, session, content_name, None 301 client, XEP_0166.A_DESTROY, session, content_name, None
302 ) 302 )
303 content_data["transport"] = transport 303 content_data["transport"] = transport
304 transport_data.clear() 304 transport_data.clear()
305 305
306 iq_elt, jingle_elt = self._buildJingleElt( 306 iq_elt, jingle_elt = self._build_jingle_elt(
307 client, session, XEP_0166.A_TRANSPORT_REPLACE 307 client, session, XEP_0166.A_TRANSPORT_REPLACE
308 ) 308 )
309 content_elt = jingle_elt.addElement("content") 309 content_elt = jingle_elt.addElement("content")
310 content_elt["name"] = content_name 310 content_elt["name"] = content_name
311 content_elt["creator"] = content_data["creator"] 311 content_elt["creator"] = content_data["creator"]
312 312
313 transport_elt = transport.handler.jingleSessionInit(client, session, content_name) 313 transport_elt = transport.handler.jingle_session_init(client, session, content_name)
314 content_elt.addChild(transport_elt) 314 content_elt.addChild(transport_elt)
315 iq_elt.send() 315 iq_elt.send()
316 316
317 def buildAction(self, client, action, session, content_name): 317 def build_action(self, client, action, session, content_name):
318 """Build an element according to requested action 318 """Build an element according to requested action
319 319
320 @param action(unicode): a jingle action (see XEP-0166 §7.2), 320 @param action(unicode): a jingle action (see XEP-0166 §7.2),
321 session-* actions are not managed here 321 session-* actions are not managed here
322 transport-replace is managed in the dedicated [transportReplace] method 322 transport-replace is managed in the dedicated [transport_replace] method
323 @param session(dict): jingle session data 323 @param session(dict): jingle session data
324 @param content_name(unicode): name of the content 324 @param content_name(unicode): name of the content
325 @return (tuple[domish.Element, domish.Element]): parent <iq> element, <transport> or <description> element, according to action 325 @return (tuple[domish.Element, domish.Element]): parent <iq> element, <transport> or <description> element, according to action
326 """ 326 """
327 # we first build iq, jingle and content element which are the same in every cases 327 # we first build iq, jingle and content element which are the same in every cases
328 iq_elt, jingle_elt = self._buildJingleElt(client, session, action) 328 iq_elt, jingle_elt = self._build_jingle_elt(client, session, action)
329 # FIXME: XEP-0260 § 2.3 Ex 5 has an initiator attribute, but it should not according to XEP-0166 §7.1 table 1, must be checked 329 # FIXME: XEP-0260 § 2.3 Ex 5 has an initiator attribute, but it should not according to XEP-0166 §7.1 table 1, must be checked
330 content_data = session["contents"][content_name] 330 content_data = session["contents"][content_name]
331 content_elt = jingle_elt.addElement("content") 331 content_elt = jingle_elt.addElement("content")
332 content_elt["name"] = content_name 332 content_elt["name"] = content_name
333 content_elt["creator"] = content_data["creator"] 333 content_elt["creator"] = content_data["creator"]
340 else: 340 else:
341 raise exceptions.InternalError("unmanaged action {}".format(action)) 341 raise exceptions.InternalError("unmanaged action {}".format(action))
342 342
343 return iq_elt, context_elt 343 return iq_elt, context_elt
344 344
345 def buildSessionInfo(self, client, session): 345 def build_session_info(self, client, session):
346 """Build a session-info action 346 """Build a session-info action
347 347
348 @param session(dict): jingle session data 348 @param session(dict): jingle session data
349 @return (tuple[domish.Element, domish.Element]): parent <iq> element, <jingle> element 349 @return (tuple[domish.Element, domish.Element]): parent <iq> element, <jingle> element
350 """ 350 """
351 return self._buildJingleElt(client, session, XEP_0166.A_SESSION_INFO) 351 return self._build_jingle_elt(client, session, XEP_0166.A_SESSION_INFO)
352 352
353 def getApplication(self, namespace: str) -> object: 353 def getApplication(self, namespace: str) -> object:
354 """Retreive application corresponding to a namespace 354 """Retreive application corresponding to a namespace
355 355
356 @raise exceptions.NotFound if application can't be found 356 @raise exceptions.NotFound if application can't be found
360 except KeyError: 360 except KeyError:
361 raise exceptions.NotFound( 361 raise exceptions.NotFound(
362 f"No application registered for {namespace}" 362 f"No application registered for {namespace}"
363 ) 363 )
364 364
365 def getContentData(self, content: dict) -> Tuple[object, list, dict, str]: 365 def get_content_data(self, content: dict) -> Tuple[object, list, dict, str]:
366 """"Retrieve application and its argument from content""" 366 """"Retrieve application and its argument from content"""
367 app_ns = content["app_ns"] 367 app_ns = content["app_ns"]
368 try: 368 try:
369 application = self.getApplication(app_ns) 369 application = self.getApplication(app_ns)
370 except exceptions.NotFound as e: 370 except exceptions.NotFound as e:
412 "peer_jid": peer_jid, 412 "peer_jid": peer_jid,
413 "started": time.time(), 413 "started": time.time(),
414 "contents": {}, 414 "contents": {},
415 } 415 }
416 416
417 if not await self.host.trigger.asyncPoint( 417 if not await self.host.trigger.async_point(
418 "XEP-0166_initiate", 418 "XEP-0166_initiate",
419 client, session, contents 419 client, session, contents
420 ): 420 ):
421 return 421 return
422 422
423 iq_elt, jingle_elt = self._buildJingleElt( 423 iq_elt, jingle_elt = self._build_jingle_elt(
424 client, session, XEP_0166.A_SESSION_INITIATE 424 client, session, XEP_0166.A_SESSION_INITIATE
425 ) 425 )
426 jingle_elt["initiator"] = initiator.full() 426 jingle_elt["initiator"] = initiator.full()
427 427
428 contents_dict = session["contents"] 428 contents_dict = session["contents"]
429 429
430 for content in contents: 430 for content in contents:
431 # we get the application plugin 431 # we get the application plugin
432 application, app_args, app_kwargs, content_name = self.getContentData(content) 432 application, app_args, app_kwargs, content_name = self.get_content_data(content)
433 433
434 # and the transport plugin 434 # and the transport plugin
435 transport_type = content.get("transport_type", XEP_0166.TRANSPORT_STREAMING) 435 transport_type = content.get("transport_type", XEP_0166.TRANSPORT_STREAMING)
436 try: 436 try:
437 transport = self._type_transports[transport_type][0] 437 transport = self._type_transports[transport_type][0]
463 content_elt["senders"] = content["senders"] 463 content_elt["senders"] = content["senders"]
464 except KeyError: 464 except KeyError:
465 pass 465 pass
466 466
467 # then the description element 467 # then the description element
468 desc_elt = await utils.asDeferred( 468 desc_elt = await utils.as_deferred(
469 application.handler.jingleSessionInit, 469 application.handler.jingle_session_init,
470 client, session, content_name, *app_args, **app_kwargs 470 client, session, content_name, *app_args, **app_kwargs
471 ) 471 )
472 content_elt.addChild(desc_elt) 472 content_elt.addChild(desc_elt)
473 473
474 # and the transport one 474 # and the transport one
475 transport_elt = await utils.asDeferred( 475 transport_elt = await utils.as_deferred(
476 transport.handler.jingleSessionInit, 476 transport.handler.jingle_session_init,
477 client, session, content_name 477 client, session, content_name
478 ) 478 )
479 content_elt.addChild(transport_elt) 479 content_elt.addChild(transport_elt)
480 480
481 if not await self.host.trigger.asyncPoint( 481 if not await self.host.trigger.async_point(
482 "XEP-0166_initiate_elt_built", 482 "XEP-0166_initiate_elt_built",
483 client, session, iq_elt, jingle_elt 483 client, session, iq_elt, jingle_elt
484 ): 484 ):
485 return 485 return
486 if encrypted: 486 if encrypted:
492 492
493 try: 493 try:
494 await iq_elt.send() 494 await iq_elt.send()
495 except Exception as e: 495 except Exception as e:
496 failure_ = failure.Failure(e) 496 failure_ = failure.Failure(e)
497 self._iqError(failure_, sid, client) 497 self._iq_error(failure_, sid, client)
498 raise failure_ 498 raise failure_
499 499
500 def delayedContentTerminate(self, *args, **kwargs): 500 def delayed_content_terminate(self, *args, **kwargs):
501 """Put contentTerminate in queue but don't execute immediately 501 """Put content_terminate in queue but don't execute immediately
502 502
503 This is used to terminate a content inside a handler, to avoid modifying contents 503 This is used to terminate a content inside a handler, to avoid modifying contents
504 """ 504 """
505 reactor.callLater(0, self.contentTerminate, *args, **kwargs) 505 reactor.callLater(0, self.content_terminate, *args, **kwargs)
506 506
507 def contentTerminate(self, client, session, content_name, reason=REASON_SUCCESS): 507 def content_terminate(self, client, session, content_name, reason=REASON_SUCCESS):
508 """Terminate and remove a content 508 """Terminate and remove a content
509 509
510 if there is no more content, then session is terminated 510 if there is no more content, then session is terminated
511 @param session(dict): jingle session 511 @param session(dict): jingle session
512 @param content_name(unicode): name of the content terminated 512 @param content_name(unicode): name of the content terminated
517 if not contents: 517 if not contents:
518 self.terminate(client, reason, session) 518 self.terminate(client, reason, session)
519 519
520 ## defaults methods called when plugin doesn't have them ## 520 ## defaults methods called when plugin doesn't have them ##
521 521
522 def jingleRequestConfirmationDefault( 522 def jingle_request_confirmation_default(
523 self, client, action, session, content_name, desc_elt 523 self, client, action, session, content_name, desc_elt
524 ): 524 ):
525 """This method request confirmation for a jingle session""" 525 """This method request confirmation for a jingle session"""
526 log.debug("Using generic jingle confirmation method") 526 log.debug("Using generic jingle confirmation method")
527 return xml_tools.deferConfirm( 527 return xml_tools.defer_confirm(
528 self.host, 528 self.host,
529 _(CONFIRM_TXT).format(entity=session["peer_jid"].full()), 529 _(CONFIRM_TXT).format(entity=session["peer_jid"].full()),
530 _("Confirm Jingle session"), 530 _("Confirm Jingle session"),
531 profile=client.profile, 531 profile=client.profile,
532 ) 532 )
618 log.error("session id doesn't match") 618 log.error("session id doesn't match")
619 self.sendError(client, "service-unavailable", sid, request) 619 self.sendError(client, "service-unavailable", sid, request)
620 raise exceptions.InternalError 620 raise exceptions.InternalError
621 621
622 if action == XEP_0166.A_SESSION_INITIATE: 622 if action == XEP_0166.A_SESSION_INITIATE:
623 await self.onSessionInitiate(client, request, jingle_elt, session) 623 await self.on_session_initiate(client, request, jingle_elt, session)
624 elif action == XEP_0166.A_SESSION_TERMINATE: 624 elif action == XEP_0166.A_SESSION_TERMINATE:
625 self.onSessionTerminate(client, request, jingle_elt, session) 625 self.on_session_terminate(client, request, jingle_elt, session)
626 elif action == XEP_0166.A_SESSION_ACCEPT: 626 elif action == XEP_0166.A_SESSION_ACCEPT:
627 self.onSessionAccept(client, request, jingle_elt, session) 627 self.on_session_accept(client, request, jingle_elt, session)
628 elif action == XEP_0166.A_SESSION_INFO: 628 elif action == XEP_0166.A_SESSION_INFO:
629 self.onSessionInfo(client, request, jingle_elt, session) 629 self.on_session_info(client, request, jingle_elt, session)
630 elif action == XEP_0166.A_TRANSPORT_INFO: 630 elif action == XEP_0166.A_TRANSPORT_INFO:
631 self.onTransportInfo(client, request, jingle_elt, session) 631 self.on_transport_info(client, request, jingle_elt, session)
632 elif action == XEP_0166.A_TRANSPORT_REPLACE: 632 elif action == XEP_0166.A_TRANSPORT_REPLACE:
633 self.onTransportReplace(client, request, jingle_elt, session) 633 self.on_transport_replace(client, request, jingle_elt, session)
634 elif action == XEP_0166.A_TRANSPORT_ACCEPT: 634 elif action == XEP_0166.A_TRANSPORT_ACCEPT:
635 self.onTransportAccept(client, request, jingle_elt, session) 635 self.on_transport_accept(client, request, jingle_elt, session)
636 elif action == XEP_0166.A_TRANSPORT_REJECT: 636 elif action == XEP_0166.A_TRANSPORT_REJECT:
637 self.onTransportReject(client, request, jingle_elt, session) 637 self.on_transport_reject(client, request, jingle_elt, session)
638 else: 638 else:
639 raise exceptions.InternalError("Unknown action {}".format(action)) 639 raise exceptions.InternalError("Unknown action {}".format(action))
640 640
641 ## Actions callbacks ## 641 ## Actions callbacks ##
642 642
643 def _parseElements( 643 def _parse_elements(
644 self, 644 self,
645 jingle_elt, 645 jingle_elt,
646 session, 646 session,
647 request, 647 request,
648 client, 648 client,
757 ) 757 )
758 758
759 content_data["transport_elt"] = transport_elt 759 content_data["transport_elt"] = transport_elt
760 760
761 def _ignore(self, client, action, session, content_name, elt): 761 def _ignore(self, client, action, session, content_name, elt):
762 """Dummy method used when not exception must be raised if a method is not implemented in _callPlugins 762 """Dummy method used when not exception must be raised if a method is not implemented in _call_plugins
763 763
764 must be used as app_default_cb and/or transp_default_cb 764 must be used as app_default_cb and/or transp_default_cb
765 """ 765 """
766 return elt 766 return elt
767 767
768 def _callPlugins(self, client, action, session, app_method_name="jingleHandler", 768 def _call_plugins(self, client, action, session, app_method_name="jingle_handler",
769 transp_method_name="jingleHandler", app_default_cb=None, 769 transp_method_name="jingle_handler", app_default_cb=None,
770 transp_default_cb=None, delete=True, elements=True, 770 transp_default_cb=None, delete=True, elements=True,
771 force_element=None): 771 force_element=None):
772 """Call application and transport plugin methods for all contents 772 """Call application and transport plugin methods for all contents
773 773
774 @param action(unicode): jingle action name 774 @param action(unicode): jingle action name
782 @param transp_default_cb(callable, None): default callback to use if plugin has not transp_method_name 782 @param transp_default_cb(callable, None): default callback to use if plugin has not transp_method_name
783 None to raise an exception instead 783 None to raise an exception instead
784 @param delete(bool): if True, remove desc_elt and transport_elt from session 784 @param delete(bool): if True, remove desc_elt and transport_elt from session
785 ignored if elements is False 785 ignored if elements is False
786 @param elements(bool): True if elements(desc_elt and tranport_elt) must be managed 786 @param elements(bool): True if elements(desc_elt and tranport_elt) must be managed
787 must be True if _callPlugins is used in a request, and False if it used after a request 787 must be True if _call_plugins is used in a request, and False if it used after a request
788 (i.e. on <iq> result or error) 788 (i.e. on <iq> result or error)
789 @param force_element(None, domish.Element, object): if elements is False, it is used as element parameter 789 @param force_element(None, domish.Element, object): if elements is False, it is used as element parameter
790 else it is ignored 790 else it is ignored
791 @return (list[defer.Deferred]): list of launched Deferred 791 @return (list[defer.Deferred]): list of launched Deferred
792 @raise exceptions.NotFound: method is not implemented 792 @raise exceptions.NotFound: method is not implemented
813 method = default_cb 813 method = default_cb
814 if elements: 814 if elements:
815 elt = content_data.pop(elt_name) if delete else content_data[elt_name] 815 elt = content_data.pop(elt_name) if delete else content_data[elt_name]
816 else: 816 else:
817 elt = force_element 817 elt = force_element
818 d = utils.asDeferred( 818 d = utils.as_deferred(
819 method, client, action, session, content_name, elt 819 method, client, action, session, content_name, elt
820 ) 820 )
821 defers_list.append(d) 821 defers_list.append(d)
822 822
823 return defers_list 823 return defers_list
824 824
825 async def onSessionInitiate( 825 async def on_session_initiate(
826 self, 826 self,
827 client: SatXMPPEntity, 827 client: SatXMPPEntity,
828 request: domish.Element, 828 request: domish.Element,
829 jingle_elt: domish.Element, 829 jingle_elt: domish.Element,
830 session: Dict[str, Any] 830 session: Dict[str, Any]
831 ) -> None: 831 ) -> None:
832 """Called on session-initiate action 832 """Called on session-initiate action
833 833
834 The "jingleRequestConfirmation" method of each application will be called 834 The "jingle_request_confirmation" method of each application will be called
835 (or self.jingleRequestConfirmationDefault if the former doesn't exist). 835 (or self.jingle_request_confirmation_default if the former doesn't exist).
836 The session is only accepted if all application are confirmed. 836 The session is only accepted if all application are confirmed.
837 The application must manage itself multiple contents scenari (e.g. audio/video). 837 The application must manage itself multiple contents scenari (e.g. audio/video).
838 @param client: %(doc_client)s 838 @param client: %(doc_client)s
839 @param request(domish.Element): full request 839 @param request(domish.Element): full request
840 @param jingle_elt(domish.Element): <jingle> element 840 @param jingle_elt(domish.Element): <jingle> element
845 "Contents dict should not already exist at this point" 845 "Contents dict should not already exist at this point"
846 ) 846 )
847 session["contents"] = contents_dict = {} 847 session["contents"] = contents_dict = {}
848 848
849 try: 849 try:
850 self._parseElements( 850 self._parse_elements(
851 jingle_elt, session, request, client, True, XEP_0166.ROLE_INITIATOR 851 jingle_elt, session, request, client, True, XEP_0166.ROLE_INITIATOR
852 ) 852 )
853 except exceptions.CancelError: 853 except exceptions.CancelError:
854 return 854 return
855 855
860 860
861 # at this point we can send the <iq/> result to confirm reception of the request 861 # at this point we can send the <iq/> result to confirm reception of the request
862 client.send(xmlstream.toResponse(request, "result")) 862 client.send(xmlstream.toResponse(request, "result"))
863 863
864 864
865 if not await self.host.trigger.asyncPoint( 865 if not await self.host.trigger.async_point(
866 "XEP-0166_on_session_initiate", 866 "XEP-0166_on_session_initiate",
867 client, session, request, jingle_elt 867 client, session, request, jingle_elt
868 ): 868 ):
869 return 869 return
870 870
871 # we now request each application plugin confirmation 871 # we now request each application plugin confirmation
872 # and if all are accepted, we can accept the session 872 # and if all are accepted, we can accept the session
873 confirm_defers = self._callPlugins( 873 confirm_defers = self._call_plugins(
874 client, 874 client,
875 XEP_0166.A_SESSION_INITIATE, 875 XEP_0166.A_SESSION_INITIATE,
876 session, 876 session,
877 "jingleRequestConfirmation", 877 "jingle_request_confirmation",
878 None, 878 None,
879 self.jingleRequestConfirmationDefault, 879 self.jingle_request_confirmation_default,
880 delete=False, 880 delete=False,
881 ) 881 )
882 882
883 confirm_dlist = defer.gatherResults(confirm_defers) 883 confirm_dlist = defer.gatherResults(confirm_defers)
884 confirm_dlist.addCallback(self._confirmationCb, session, jingle_elt, client) 884 confirm_dlist.addCallback(self._confirmation_cb, session, jingle_elt, client)
885 confirm_dlist.addErrback(self._jingleErrorCb, session, request, client) 885 confirm_dlist.addErrback(self._jingle_error_cb, session, request, client)
886 886
887 def _confirmationCb(self, confirm_results, session, jingle_elt, client): 887 def _confirmation_cb(self, confirm_results, session, jingle_elt, client):
888 """Method called when confirmation from user has been received 888 """Method called when confirmation from user has been received
889 889
890 This method is only called for the responder 890 This method is only called for the responder
891 @param confirm_results(list[bool]): all True if session is accepted 891 @param confirm_results(list[bool]): all True if session is accepted
892 @param session(dict): session data 892 @param session(dict): session data
895 """ 895 """
896 confirmed = all(confirm_results) 896 confirmed = all(confirm_results)
897 if not confirmed: 897 if not confirmed:
898 return self.terminate(client, XEP_0166.REASON_DECLINE, session) 898 return self.terminate(client, XEP_0166.REASON_DECLINE, session)
899 899
900 iq_elt, jingle_elt = self._buildJingleElt( 900 iq_elt, jingle_elt = self._build_jingle_elt(
901 client, session, XEP_0166.A_SESSION_ACCEPT 901 client, session, XEP_0166.A_SESSION_ACCEPT
902 ) 902 )
903 jingle_elt["responder"] = session['local_jid'].full() 903 jingle_elt["responder"] = session['local_jid'].full()
904 904
905 # contents 905 # contents
913 content_elt = jingle_elt.addElement("content") 913 content_elt = jingle_elt.addElement("content")
914 content_elt["creator"] = XEP_0166.ROLE_INITIATOR 914 content_elt["creator"] = XEP_0166.ROLE_INITIATOR
915 content_elt["name"] = content_name 915 content_elt["name"] = content_name
916 916
917 application = content_data["application"] 917 application = content_data["application"]
918 app_session_accept_cb = application.handler.jingleHandler 918 app_session_accept_cb = application.handler.jingle_handler
919 919
920 app_d = utils.asDeferred( 920 app_d = utils.as_deferred(
921 app_session_accept_cb, 921 app_session_accept_cb,
922 client, 922 client,
923 XEP_0166.A_SESSION_INITIATE, 923 XEP_0166.A_SESSION_INITIATE,
924 session, 924 session,
925 content_name, 925 content_name,
927 ) 927 )
928 app_d.addCallback(addElement, content_elt) 928 app_d.addCallback(addElement, content_elt)
929 defers_list.append(app_d) 929 defers_list.append(app_d)
930 930
931 transport = content_data["transport"] 931 transport = content_data["transport"]
932 transport_session_accept_cb = transport.handler.jingleHandler 932 transport_session_accept_cb = transport.handler.jingle_handler
933 933
934 transport_d = utils.asDeferred( 934 transport_d = utils.as_deferred(
935 transport_session_accept_cb, 935 transport_session_accept_cb,
936 client, 936 client,
937 XEP_0166.A_SESSION_INITIATE, 937 XEP_0166.A_SESSION_INITIATE,
938 session, 938 session,
939 content_name, 939 content_name,
942 transport_d.addCallback(addElement, content_elt) 942 transport_d.addCallback(addElement, content_elt)
943 defers_list.append(transport_d) 943 defers_list.append(transport_d)
944 944
945 d_list = defer.DeferredList(defers_list) 945 d_list = defer.DeferredList(defers_list)
946 d_list.addCallback( 946 d_list.addCallback(
947 lambda __: self._callPlugins( 947 lambda __: self._call_plugins(
948 client, 948 client,
949 XEP_0166.A_PREPARE_RESPONDER, 949 XEP_0166.A_PREPARE_RESPONDER,
950 session, 950 session,
951 app_method_name=None, 951 app_method_name=None,
952 elements=False, 952 elements=False,
953 ) 953 )
954 ) 954 )
955 d_list.addCallback(lambda __: iq_elt.send()) 955 d_list.addCallback(lambda __: iq_elt.send())
956 956
957 def changeState(__, session): 957 def change_state(__, session):
958 session["state"] = STATE_ACTIVE 958 session["state"] = STATE_ACTIVE
959 959
960 d_list.addCallback(changeState, session) 960 d_list.addCallback(change_state, session)
961 d_list.addCallback( 961 d_list.addCallback(
962 lambda __: self._callPlugins( 962 lambda __: self._call_plugins(
963 client, XEP_0166.A_ACCEPTED_ACK, session, elements=False 963 client, XEP_0166.A_ACCEPTED_ACK, session, elements=False
964 ) 964 )
965 ) 965 )
966 d_list.addErrback(self._iqError, session["id"], client) 966 d_list.addErrback(self._iq_error, session["id"], client)
967 return d_list 967 return d_list
968 968
969 def onSessionTerminate(self, client, request, jingle_elt, session): 969 def on_session_terminate(self, client, request, jingle_elt, session):
970 # TODO: check reason, display a message to user if needed 970 # TODO: check reason, display a message to user if needed
971 log.debug("Jingle Session {} terminated".format(session["id"])) 971 log.debug("Jingle Session {} terminated".format(session["id"]))
972 try: 972 try:
973 reason_elt = next(jingle_elt.elements(NS_JINGLE, "reason")) 973 reason_elt = next(jingle_elt.elements(NS_JINGLE, "reason"))
974 except StopIteration: 974 except StopIteration:
975 log.warning("No reason given for session termination") 975 log.warning("No reason given for session termination")
976 reason_elt = jingle_elt.addElement("reason") 976 reason_elt = jingle_elt.addElement("reason")
977 977
978 terminate_defers = self._callPlugins( 978 terminate_defers = self._call_plugins(
979 client, 979 client,
980 XEP_0166.A_SESSION_TERMINATE, 980 XEP_0166.A_SESSION_TERMINATE,
981 session, 981 session,
982 "jingleTerminate", 982 "jingle_terminate",
983 "jingleTerminate", 983 "jingle_terminate",
984 self._ignore, 984 self._ignore,
985 self._ignore, 985 self._ignore,
986 elements=False, 986 elements=False,
987 force_element=reason_elt, 987 force_element=reason_elt,
988 ) 988 )
989 terminate_dlist = defer.DeferredList(terminate_defers) 989 terminate_dlist = defer.DeferredList(terminate_defers)
990 990
991 terminate_dlist.addCallback(lambda __: self._delSession(client, session["id"])) 991 terminate_dlist.addCallback(lambda __: self._del_session(client, session["id"]))
992 client.send(xmlstream.toResponse(request, "result")) 992 client.send(xmlstream.toResponse(request, "result"))
993 993
994 def onSessionAccept(self, client, request, jingle_elt, session): 994 def on_session_accept(self, client, request, jingle_elt, session):
995 """Method called once session is accepted 995 """Method called once session is accepted
996 996
997 This method is only called for initiator 997 This method is only called for initiator
998 @param client: %(doc_client)s 998 @param client: %(doc_client)s
999 @param request(domish.Element): full <iq> request 999 @param request(domish.Element): full <iq> request
1001 @param session(dict): session data 1001 @param session(dict): session data
1002 """ 1002 """
1003 log.debug("Jingle session {} has been accepted".format(session["id"])) 1003 log.debug("Jingle session {} has been accepted".format(session["id"]))
1004 1004
1005 try: 1005 try:
1006 self._parseElements(jingle_elt, session, request, client) 1006 self._parse_elements(jingle_elt, session, request, client)
1007 except exceptions.CancelError: 1007 except exceptions.CancelError:
1008 return 1008 return
1009 1009
1010 # at this point we can send the <iq/> result to confirm reception of the request 1010 # at this point we can send the <iq/> result to confirm reception of the request
1011 client.send(xmlstream.toResponse(request, "result")) 1011 client.send(xmlstream.toResponse(request, "result"))
1012 # and change the state 1012 # and change the state
1013 session["state"] = STATE_ACTIVE 1013 session["state"] = STATE_ACTIVE
1014 1014
1015 negociate_defers = [] 1015 negociate_defers = []
1016 negociate_defers = self._callPlugins(client, XEP_0166.A_SESSION_ACCEPT, session) 1016 negociate_defers = self._call_plugins(client, XEP_0166.A_SESSION_ACCEPT, session)
1017 1017
1018 negociate_dlist = defer.gatherResults(negociate_defers) 1018 negociate_dlist = defer.gatherResults(negociate_defers)
1019 1019
1020 # after negociations we start the transfer 1020 # after negociations we start the transfer
1021 negociate_dlist.addCallback( 1021 negociate_dlist.addCallback(
1022 lambda __: self._callPlugins( 1022 lambda __: self._call_plugins(
1023 client, XEP_0166.A_START, session, app_method_name=None, elements=False 1023 client, XEP_0166.A_START, session, app_method_name=None, elements=False
1024 ) 1024 )
1025 ) 1025 )
1026 1026
1027 def _onSessionCb(self, result, client, request, jingle_elt, session): 1027 def _on_session_cb(self, result, client, request, jingle_elt, session):
1028 client.send(xmlstream.toResponse(request, "result")) 1028 client.send(xmlstream.toResponse(request, "result"))
1029 1029
1030 def _onSessionEb(self, failure_, client, request, jingle_elt, session): 1030 def _on_session_eb(self, failure_, client, request, jingle_elt, session):
1031 log.error("Error while handling onSessionInfo: {}".format(failure_.value)) 1031 log.error("Error while handling on_session_info: {}".format(failure_.value))
1032 # XXX: only error managed so far, maybe some applications/transports need more 1032 # XXX: only error managed so far, maybe some applications/transports need more
1033 self.sendError( 1033 self.sendError(
1034 client, "feature-not-implemented", None, request, "unsupported-info" 1034 client, "feature-not-implemented", None, request, "unsupported-info"
1035 ) 1035 )
1036 1036
1037 def onSessionInfo(self, client, request, jingle_elt, session): 1037 def on_session_info(self, client, request, jingle_elt, session):
1038 """Method called when a session-info action is received from other peer 1038 """Method called when a session-info action is received from other peer
1039 1039
1040 This method is only called for initiator 1040 This method is only called for initiator
1041 @param client: %(doc_client)s 1041 @param client: %(doc_client)s
1042 @param request(domish.Element): full <iq> request 1042 @param request(domish.Element): full <iq> request
1049 return 1049 return
1050 1050
1051 try: 1051 try:
1052 # XXX: session-info is most likely only used for application, so we don't call transport plugins 1052 # XXX: session-info is most likely only used for application, so we don't call transport plugins
1053 # if a future transport use it, this behaviour must be adapted 1053 # if a future transport use it, this behaviour must be adapted
1054 defers = self._callPlugins( 1054 defers = self._call_plugins(
1055 client, 1055 client,
1056 XEP_0166.A_SESSION_INFO, 1056 XEP_0166.A_SESSION_INFO,
1057 session, 1057 session,
1058 "jingleSessionInfo", 1058 "jingle_session_info",
1059 None, 1059 None,
1060 elements=False, 1060 elements=False,
1061 force_element=jingle_elt, 1061 force_element=jingle_elt,
1062 ) 1062 )
1063 except exceptions.NotFound as e: 1063 except exceptions.NotFound as e:
1064 self._onSessionEb(failure.Failure(e), client, request, jingle_elt, session) 1064 self._on_session_eb(failure.Failure(e), client, request, jingle_elt, session)
1065 return 1065 return
1066 1066
1067 dlist = defer.DeferredList(defers, fireOnOneErrback=True) 1067 dlist = defer.DeferredList(defers, fireOnOneErrback=True)
1068 dlist.addCallback(self._onSessionCb, client, request, jingle_elt, session) 1068 dlist.addCallback(self._on_session_cb, client, request, jingle_elt, session)
1069 dlist.addErrback(self._onSessionCb, client, request, jingle_elt, session) 1069 dlist.addErrback(self._on_session_cb, client, request, jingle_elt, session)
1070 1070
1071 @defer.inlineCallbacks 1071 @defer.inlineCallbacks
1072 def onTransportReplace(self, client, request, jingle_elt, session): 1072 def on_transport_replace(self, client, request, jingle_elt, session):
1073 """A transport change is requested 1073 """A transport change is requested
1074 1074
1075 The request is parsed, and jingleHandler is called on concerned transport plugin(s) 1075 The request is parsed, and jingle_handler is called on concerned transport plugin(s)
1076 @param client: %(doc_client)s 1076 @param client: %(doc_client)s
1077 @param request(domish.Element): full <iq> request 1077 @param request(domish.Element): full <iq> request
1078 @param jingle_elt(domish.Element): the <jingle> element 1078 @param jingle_elt(domish.Element): the <jingle> element
1079 @param session(dict): session data 1079 @param session(dict): session data
1080 """ 1080 """
1081 log.debug("Other peer wants to replace the transport") 1081 log.debug("Other peer wants to replace the transport")
1082 try: 1082 try:
1083 self._parseElements( 1083 self._parse_elements(
1084 jingle_elt, session, request, client, with_application=False 1084 jingle_elt, session, request, client, with_application=False
1085 ) 1085 )
1086 except exceptions.CancelError: 1086 except exceptions.CancelError:
1087 defer.returnValue(None) 1087 defer.returnValue(None)
1088 1088
1109 break 1109 break
1110 to_replace.append((content_name, content_data, transport, transport_elt)) 1110 to_replace.append((content_name, content_data, transport, transport_elt))
1111 1111
1112 if content_name is None: 1112 if content_name is None:
1113 # wa can't accept the replacement 1113 # wa can't accept the replacement
1114 iq_elt, reject_jingle_elt = self._buildJingleElt( 1114 iq_elt, reject_jingle_elt = self._build_jingle_elt(
1115 client, session, XEP_0166.A_TRANSPORT_REJECT 1115 client, session, XEP_0166.A_TRANSPORT_REJECT
1116 ) 1116 )
1117 for child in jingle_elt.children: 1117 for child in jingle_elt.children:
1118 reject_jingle_elt.addChild(child) 1118 reject_jingle_elt.addChild(child)
1119 1119
1120 iq_elt.send() 1120 iq_elt.send()
1121 defer.returnValue(None) 1121 defer.returnValue(None)
1122 1122
1123 # at this point, everything is alright and we can replace the transport(s) 1123 # at this point, everything is alright and we can replace the transport(s)
1124 # this is similar to an session-accept action, but for transports only 1124 # this is similar to an session-accept action, but for transports only
1125 iq_elt, accept_jingle_elt = self._buildJingleElt( 1125 iq_elt, accept_jingle_elt = self._build_jingle_elt(
1126 client, session, XEP_0166.A_TRANSPORT_ACCEPT 1126 client, session, XEP_0166.A_TRANSPORT_ACCEPT
1127 ) 1127 )
1128 for content_name, content_data, transport, transport_elt in to_replace: 1128 for content_name, content_data, transport, transport_elt in to_replace:
1129 # we can now actually replace the transport 1129 # we can now actually replace the transport
1130 yield content_data["transport"].handler.jingleHandler( 1130 yield content_data["transport"].handler.jingle_handler(
1131 client, XEP_0166.A_DESTROY, session, content_name, None 1131 client, XEP_0166.A_DESTROY, session, content_name, None
1132 ) 1132 )
1133 content_data["transport"] = transport 1133 content_data["transport"] = transport
1134 content_data["transport_data"].clear() 1134 content_data["transport_data"].clear()
1135 # and build the element 1135 # and build the element
1136 content_elt = accept_jingle_elt.addElement("content") 1136 content_elt = accept_jingle_elt.addElement("content")
1137 content_elt["name"] = content_name 1137 content_elt["name"] = content_name
1138 content_elt["creator"] = content_data["creator"] 1138 content_elt["creator"] = content_data["creator"]
1139 # we notify the transport and insert its <transport/> in the answer 1139 # we notify the transport and insert its <transport/> in the answer
1140 accept_transport_elt = yield transport.handler.jingleHandler( 1140 accept_transport_elt = yield transport.handler.jingle_handler(
1141 client, XEP_0166.A_TRANSPORT_REPLACE, session, content_name, transport_elt 1141 client, XEP_0166.A_TRANSPORT_REPLACE, session, content_name, transport_elt
1142 ) 1142 )
1143 content_elt.addChild(accept_transport_elt) 1143 content_elt.addChild(accept_transport_elt)
1144 # there is no confirmation needed here, so we can directly prepare it 1144 # there is no confirmation needed here, so we can directly prepare it
1145 yield transport.handler.jingleHandler( 1145 yield transport.handler.jingle_handler(
1146 client, XEP_0166.A_PREPARE_RESPONDER, session, content_name, None 1146 client, XEP_0166.A_PREPARE_RESPONDER, session, content_name, None
1147 ) 1147 )
1148 1148
1149 iq_elt.send() 1149 iq_elt.send()
1150 1150
1151 def onTransportAccept(self, client, request, jingle_elt, session): 1151 def on_transport_accept(self, client, request, jingle_elt, session):
1152 """Method called once transport replacement is accepted 1152 """Method called once transport replacement is accepted
1153 1153
1154 @param client: %(doc_client)s 1154 @param client: %(doc_client)s
1155 @param request(domish.Element): full <iq> request 1155 @param request(domish.Element): full <iq> request
1156 @param jingle_elt(domish.Element): the <jingle> element 1156 @param jingle_elt(domish.Element): the <jingle> element
1157 @param session(dict): session data 1157 @param session(dict): session data
1158 """ 1158 """
1159 log.debug("new transport has been accepted") 1159 log.debug("new transport has been accepted")
1160 1160
1161 try: 1161 try:
1162 self._parseElements( 1162 self._parse_elements(
1163 jingle_elt, session, request, client, with_application=False 1163 jingle_elt, session, request, client, with_application=False
1164 ) 1164 )
1165 except exceptions.CancelError: 1165 except exceptions.CancelError:
1166 return 1166 return
1167 1167
1168 # at this point we can send the <iq/> result to confirm reception of the request 1168 # at this point we can send the <iq/> result to confirm reception of the request
1169 client.send(xmlstream.toResponse(request, "result")) 1169 client.send(xmlstream.toResponse(request, "result"))
1170 1170
1171 negociate_defers = [] 1171 negociate_defers = []
1172 negociate_defers = self._callPlugins( 1172 negociate_defers = self._call_plugins(
1173 client, XEP_0166.A_TRANSPORT_ACCEPT, session, app_method_name=None 1173 client, XEP_0166.A_TRANSPORT_ACCEPT, session, app_method_name=None
1174 ) 1174 )
1175 1175
1176 negociate_dlist = defer.DeferredList(negociate_defers) 1176 negociate_dlist = defer.DeferredList(negociate_defers)
1177 1177
1178 # after negociations we start the transfer 1178 # after negociations we start the transfer
1179 negociate_dlist.addCallback( 1179 negociate_dlist.addCallback(
1180 lambda __: self._callPlugins( 1180 lambda __: self._call_plugins(
1181 client, XEP_0166.A_START, session, app_method_name=None, elements=False 1181 client, XEP_0166.A_START, session, app_method_name=None, elements=False
1182 ) 1182 )
1183 ) 1183 )
1184 1184
1185 def onTransportReject(self, client, request, jingle_elt, session): 1185 def on_transport_reject(self, client, request, jingle_elt, session):
1186 """Method called when a transport replacement is refused 1186 """Method called when a transport replacement is refused
1187 1187
1188 @param client: %(doc_client)s 1188 @param client: %(doc_client)s
1189 @param request(domish.Element): full <iq> request 1189 @param request(domish.Element): full <iq> request
1190 @param jingle_elt(domish.Element): the <jingle> element 1190 @param jingle_elt(domish.Element): the <jingle> element
1192 """ 1192 """
1193 # XXX: for now, we terminate the session in case of transport-reject 1193 # XXX: for now, we terminate the session in case of transport-reject
1194 # this behaviour may change in the future 1194 # this behaviour may change in the future
1195 self.terminate(client, "failed-transport", session) 1195 self.terminate(client, "failed-transport", session)
1196 1196
1197 def onTransportInfo(self, client, request, jingle_elt, session): 1197 def on_transport_info(self, client, request, jingle_elt, session):
1198 """Method called when a transport-info action is received from other peer 1198 """Method called when a transport-info action is received from other peer
1199 1199
1200 The request is parsed, and jingleHandler is called on concerned transport plugin(s) 1200 The request is parsed, and jingle_handler is called on concerned transport plugin(s)
1201 @param client: %(doc_client)s 1201 @param client: %(doc_client)s
1202 @param request(domish.Element): full <iq> request 1202 @param request(domish.Element): full <iq> request
1203 @param jingle_elt(domish.Element): the <jingle> element 1203 @param jingle_elt(domish.Element): the <jingle> element
1204 @param session(dict): session data 1204 @param session(dict): session data
1205 """ 1205 """
1206 log.debug("Jingle session {} has been accepted".format(session["id"])) 1206 log.debug("Jingle session {} has been accepted".format(session["id"]))
1207 1207
1208 try: 1208 try:
1209 self._parseElements( 1209 self._parse_elements(
1210 jingle_elt, session, request, client, with_application=False 1210 jingle_elt, session, request, client, with_application=False
1211 ) 1211 )
1212 except exceptions.CancelError: 1212 except exceptions.CancelError:
1213 return 1213 return
1214 1214
1219 try: 1219 try:
1220 transport_elt = content_data.pop("transport_elt") 1220 transport_elt = content_data.pop("transport_elt")
1221 except KeyError: 1221 except KeyError:
1222 continue 1222 continue
1223 else: 1223 else:
1224 content_data["transport"].handler.jingleHandler( 1224 content_data["transport"].handler.jingle_handler(
1225 client, 1225 client,
1226 XEP_0166.A_TRANSPORT_INFO, 1226 XEP_0166.A_TRANSPORT_INFO,
1227 session, 1227 session,
1228 content_name, 1228 content_name,
1229 transport_elt, 1229 transport_elt,