diff sat/plugins/plugin_xep_0166.py @ 3028:ab2696e34d29

Python 3 port: /!\ this is a huge commit /!\ starting from this commit, SàT is needs Python 3.6+ /!\ SàT maybe be instable or some feature may not work anymore, this will improve with time This patch port backend, bridge and frontends to Python 3. Roughly this has been done this way: - 2to3 tools has been applied (with python 3.7) - all references to python2 have been replaced with python3 (notably shebangs) - fixed files not handled by 2to3 (notably the shell script) - several manual fixes - fixed issues reported by Python 3 that where not handled in Python 2 - replaced "async" with "async_" when needed (it's a reserved word from Python 3.7) - replaced zope's "implements" with @implementer decorator - temporary hack to handle data pickled in database, as str or bytes may be returned, to be checked later - fixed hash comparison for password - removed some code which is not needed anymore with Python 3 - deactivated some code which needs to be checked (notably certificate validation) - tested with jp, fixed reported issues until some basic commands worked - ported Primitivus (after porting dependencies like urwid satext) - more manual fixes
author Goffi <goffi@goffi.org>
date Tue, 13 Aug 2019 19:08:41 +0200
parents 69e4716d6268
children fee60f17ebac
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0166.py	Wed Jul 31 11:31:22 2019 +0200
+++ b/sat/plugins/plugin_xep_0166.py	Tue Aug 13 19:08:41 2019 +0200
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 
 # SAT plugin for Jingle (XEP-0166)
@@ -35,7 +35,7 @@
 import uuid
 import time
 
-from zope.interface import implements
+from zope.interface import implementer
 
 
 IQ_SET = '/iq[@type="set"]'
@@ -113,9 +113,9 @@
         try:
             del client.jingle_sessions[sid]
         except KeyError:
-            log.debug(u"Jingle session id [{}] is unknown, nothing to delete".format(sid))
+            log.debug("Jingle session id [{}] is unknown, nothing to delete".format(sid))
         else:
-            log.debug(u"Jingle session id [{}] deleted".format(sid))
+            log.debug("Jingle session id [{}] deleted".format(sid))
 
     ## helpers methods to build stanzas ##
 
@@ -142,14 +142,14 @@
         if error.STANZA_CONDITIONS[error_condition]["type"] == "cancel" and sid:
             self._delSession(client, sid)
             log.warning(
-                u"Error while managing jingle session, cancelling: {condition}".format(
+                "Error while managing jingle session, cancelling: {condition}".format(
                     condition=error_condition
                 )
             )
         client.send(iq_elt)
 
     def _terminateEb(self, failure_):
-        log.warning(_(u"Error while terminating session: {msg}").format(msg=failure_))
+        log.warning(_("Error while terminating session: {msg}").format(msg=failure_))
 
     def terminate(self, client, reason, session):
         """Terminate the session
@@ -163,7 +163,7 @@
             client, session, XEP_0166.A_SESSION_TERMINATE
         )
         reason_elt = jingle_elt.addElement("reason")
-        if isinstance(reason, basestring):
+        if isinstance(reason, str):
             reason_elt.addElement(reason)
         else:
             for elt in reason:
@@ -182,7 +182,7 @@
         @param sid(unicode): jingle session id
         """
         log.warning(
-            u"Error while sending jingle <iq/> stanza: {failure_}".format(
+            "Error while sending jingle <iq/> stanza: {failure_}".format(
                 failure_=failure_.value
             )
         )
@@ -227,12 +227,12 @@
         """
         if namespace in self._applications:
             raise exceptions.ConflictError(
-                u"Trying to register already registered namespace {}".format(namespace)
+                "Trying to register already registered namespace {}".format(namespace)
             )
         self._applications[namespace] = ApplicationData(
             namespace=namespace, handler=handler
         )
-        log.debug(u"new jingle application registered")
+        log.debug("new jingle application registered")
 
     def registerTransport(self, namespace, transport_type, handler, priority=0):
         """Register a transport plugin
@@ -252,7 +252,7 @@
         )
         if namespace in self._transports:
             raise exceptions.ConflictError(
-                u"Trying to register already registered namespace {}".format(namespace)
+                "Trying to register already registered namespace {}".format(namespace)
             )
         transport_data = TransportData(
             namespace=namespace, handler=handler, priority=priority
@@ -262,7 +262,7 @@
             key=lambda transport_data: transport_data.priority, reverse=True
         )
         self._transports[namespace] = transport_data
-        log.debug(u"new jingle transport registered")
+        log.debug("new jingle transport registered")
 
     @defer.inlineCallbacks
     def transportReplace(self, client, transport_ns, session, content_name):
@@ -280,7 +280,7 @@
         try:
             transport = self._transports[transport_ns]
         except KeyError:
-            raise exceptions.InternalError(u"Unkown transport")
+            raise exceptions.InternalError("Unkown transport")
         yield content_data["transport"].handler.jingleHandler(
             client, XEP_0166.A_DESTROY, session, content_name, None
         )
@@ -322,7 +322,7 @@
             )
             transport_elt["sid"] = content_data["transport_data"]["sid"]
         else:
-            raise exceptions.InternalError(u"unmanaged action {}".format(action))
+            raise exceptions.InternalError("unmanaged action {}".format(action))
 
         return iq_elt, context_elt
 
@@ -355,9 +355,9 @@
         assert contents  # there must be at least one content
         if (peer_jid == client.jid
             or client.is_component and peer_jid.host == client.jid.host):
-            raise ValueError(_(u"You can't do a jingle session with yourself"))
+            raise ValueError(_("You can't do a jingle session with yourself"))
         initiator = client.jid
-        sid = unicode(uuid.uuid4())
+        sid = str(uuid.uuid4())
         # TODO: session cleaning after timeout ?
         session = client.jingle_sessions[sid] = {
             "id": sid,
@@ -383,7 +383,7 @@
                 application = self._applications[app_ns]
             except KeyError:
                 raise exceptions.InternalError(
-                    u"No application registered for {}".format(app_ns)
+                    "No application registered for {}".format(app_ns)
                 )
 
             # and the transport plugin
@@ -392,7 +392,7 @@
                 transport = self._type_transports[transport_type][0]
             except IndexError:
                 raise exceptions.InternalError(
-                    u"No transport registered for {}".format(transport_type)
+                    "No transport registered for {}".format(transport_type)
                 )
 
             # we build the session data
@@ -407,7 +407,7 @@
             try:
                 content_name = content["name"]
             except KeyError:
-                content_name = unicode(uuid.uuid4())
+                content_name = str(uuid.uuid4())
             else:
                 if content_name in contents_dict:
                     raise exceptions.InternalError(
@@ -471,7 +471,7 @@
         self, client, action, session, content_name, desc_elt
     ):
         """This method request confirmation for a jingle session"""
-        log.debug(u"Using generic jingle confirmation method")
+        log.debug("Using generic jingle confirmation method")
         return xml_tools.deferConfirm(
             self.host,
             _(CONFIRM_TXT).format(entity=session["peer_jid"].full()),
@@ -489,7 +489,7 @@
         @param request(domish.Element): received IQ request
         """
         request.handled = True
-        jingle_elt = request.elements(NS_JINGLE, "jingle").next()
+        jingle_elt = next(request.elements(NS_JINGLE, "jingle"))
 
         # first we need the session id
         try:
@@ -497,7 +497,7 @@
             if not sid:
                 raise KeyError
         except KeyError:
-            log.warning(u"Received jingle request has no sid attribute")
+            log.warning("Received jingle request has no sid attribute")
             self.sendError(client, "bad-request", None, request)
             return
 
@@ -507,7 +507,7 @@
             if not action:
                 raise KeyError
         except KeyError:
-            log.warning(u"Received jingle request has no action")
+            log.warning("Received jingle request has no action")
             self.sendError(client, "bad-request", None, request)
             return
 
@@ -521,14 +521,14 @@
                 pass
             elif action == XEP_0166.A_SESSION_TERMINATE:
                 log.debug(
-                    u"ignoring session terminate action (inexisting session id): {request_id} [{profile}]".format(
+                    "ignoring session terminate action (inexisting session id): {request_id} [{profile}]".format(
                         request_id=sid, profile=client.profile
                     )
                 )
                 return
             else:
                 log.warning(
-                    u"Received request for an unknown session id: {request_id} [{profile}]".format(
+                    "Received request for an unknown session id: {request_id} [{profile}]".format(
                         request_id=sid, profile=client.profile
                     )
                 )
@@ -549,14 +549,14 @@
         else:
             if session["peer_jid"] != peer_jid:
                 log.warning(
-                    u"sid conflict ({}), the jid doesn't match. Can be a collision, a hack attempt, or a bad sid generation".format(
+                    "sid conflict ({}), the jid doesn't match. Can be a collision, a hack attempt, or a bad sid generation".format(
                         sid
                     )
                 )
                 self.sendError(client, "service-unavailable", sid, request)
                 return
             if session["id"] != sid:
-                log.error(u"session id doesn't match")
+                log.error("session id doesn't match")
                 self.sendError(client, "service-unavailable", sid, request)
                 raise exceptions.InternalError
 
@@ -577,7 +577,7 @@
         elif action == XEP_0166.A_TRANSPORT_REJECT:
             self.onTransportReject(client, request, jingle_elt, session)
         else:
-            raise exceptions.InternalError(u"Unknown action {}".format(action))
+            raise exceptions.InternalError("Unknown action {}".format(action))
 
     ## Actions callbacks ##
 
@@ -626,7 +626,7 @@
                 try:
                     content_data = contents_dict[name]
                 except KeyError:
-                    log.warning(u"Other peer try to access an unknown content")
+                    log.warning("Other peer try to access an unknown content")
                     self.sendError(client, "bad-request", session["id"], request)
                     raise exceptions.CancelError
 
@@ -648,7 +648,7 @@
                         application = self._applications[app_ns]
                     except KeyError:
                         log.warning(
-                            u"Unmanaged application namespace [{}]".format(app_ns)
+                            "Unmanaged application namespace [{}]".format(app_ns)
                         )
                         self.sendError(
                             client, "service-unavailable", session["id"], request
@@ -661,7 +661,7 @@
                     # the content exists, we check that we have not a former desc_elt
                     if "desc_elt" in content_data:
                         raise exceptions.InternalError(
-                            u"desc_elt should not exist at this point"
+                            "desc_elt should not exist at this point"
                         )
 
                 content_data["desc_elt"] = desc_elt
@@ -684,7 +684,7 @@
                         transport = self._transports[transport_ns]
                     except KeyError:
                         raise exceptions.InternalError(
-                            u"No transport registered for namespace {}".format(
+                            "No transport registered for namespace {}".format(
                                 transport_ns
                             )
                         )
@@ -694,7 +694,7 @@
                     # the content exists, we check that we have not a former transport_elt
                     if "transport_elt" in content_data:
                         raise exceptions.InternalError(
-                            u"transport_elt should not exist at this point"
+                            "transport_elt should not exist at this point"
                         )
 
                 content_data["transport_elt"] = transport_elt
@@ -743,7 +743,7 @@
         """
         contents_dict = session["contents"]
         defers_list = []
-        for content_name, content_data in contents_dict.iteritems():
+        for content_name, content_data in contents_dict.items():
             for method_name, handler_key, default_cb, elt_name in (
                 (app_method_name, "application", app_default_cb, "desc_elt"),
                 (transp_method_name, "transport", transp_default_cb, "transport_elt"),
@@ -757,7 +757,7 @@
                 except AttributeError:
                     if default_cb is None:
                         raise exceptions.NotFound(
-                            u"{} not implemented !".format(method_name)
+                            "{} not implemented !".format(method_name)
                         )
                     else:
                         method = default_cb
@@ -846,7 +846,7 @@
 
         defers_list = []
 
-        for content_name, content_data in session["contents"].iteritems():
+        for content_name, content_data in session["contents"].items():
             content_elt = jingle_elt.addElement("content")
             content_elt["creator"] = XEP_0166.ROLE_INITIATOR
             content_elt["name"] = content_name
@@ -907,9 +907,9 @@
         # TODO: check reason, display a message to user if needed
         log.debug("Jingle Session {} terminated".format(session["id"]))
         try:
-            reason_elt = jingle_elt.elements(NS_JINGLE, "reason").next()
+            reason_elt = next(jingle_elt.elements(NS_JINGLE, "reason"))
         except StopIteration:
-            log.warning(u"No reason given for session termination")
+            log.warning("No reason given for session termination")
             reason_elt = jingle_elt.addElement("reason")
 
         terminate_defers = self._callPlugins(
@@ -937,7 +937,7 @@
         @param jingle_elt(domish.Element): the <jingle> element
         @param session(dict): session data
         """
-        log.debug(u"Jingle session {} has been accepted".format(session["id"]))
+        log.debug("Jingle session {} has been accepted".format(session["id"]))
 
         try:
             self._parseElements(jingle_elt, session, request, client)
@@ -965,7 +965,7 @@
         client.send(xmlstream.toResponse(request, "result"))
 
     def _onSessionEb(self, failure_, client, request, jingle_elt, session):
-        log.error(u"Error while handling onSessionInfo: {}".format(failure_.value))
+        log.error("Error while handling onSessionInfo: {}".format(failure_.value))
         # XXX: only error managed so far, maybe some applications/transports need more
         self.sendError(
             client, "feature-not-implemented", None, request, "unsupported-info"
@@ -1015,7 +1015,7 @@
         @param jingle_elt(domish.Element): the <jingle> element
         @param session(dict): session data
         """
-        log.debug(u"Other peer wants to replace the transport")
+        log.debug("Other peer wants to replace the transport")
         try:
             self._parseElements(
                 jingle_elt, session, request, client, with_application=False
@@ -1028,7 +1028,7 @@
         content_name = None
         to_replace = []
 
-        for content_name, content_data in session["contents"].iteritems():
+        for content_name, content_data in session["contents"].items():
             try:
                 transport_elt = content_data.pop("transport_elt")
             except KeyError:
@@ -1038,7 +1038,7 @@
                 transport = self._transports[transport_ns]
             except KeyError:
                 log.warning(
-                    u"Other peer want to replace current transport with an unknown one: {}".format(
+                    "Other peer want to replace current transport with an unknown one: {}".format(
                         transport_ns
                     )
                 )
@@ -1093,7 +1093,7 @@
         @param jingle_elt(domish.Element): the <jingle> element
         @param session(dict): session data
         """
-        log.debug(u"new transport has been accepted")
+        log.debug("new transport has been accepted")
 
         try:
             self._parseElements(
@@ -1140,7 +1140,7 @@
         @param jingle_elt(domish.Element): the <jingle> element
         @param session(dict): session data
         """
-        log.debug(u"Jingle session {} has been accepted".format(session["id"]))
+        log.debug("Jingle session {} has been accepted".format(session["id"]))
 
         try:
             self._parseElements(
@@ -1152,7 +1152,7 @@
         # The parsing was OK, we send the <iq> result
         client.send(xmlstream.toResponse(request, "result"))
 
-        for content_name, content_data in session["contents"].iteritems():
+        for content_name, content_data in session["contents"].items():
             try:
                 transport_elt = content_data.pop("transport_elt")
             except KeyError:
@@ -1167,8 +1167,8 @@
                 )
 
 
+@implementer(iwokkel.IDisco)
 class XEP_0166_handler(xmlstream.XMPPHandler):
-    implements(iwokkel.IDisco)
 
     def __init__(self, plugin_parent):
         self.plugin_parent = plugin_parent