diff sat/plugins/plugin_xep_0198.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 af9d71303605
children 87b8808ac49d
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0198.py	Wed Jul 31 11:31:22 2019 +0200
+++ b/sat/plugins/plugin_xep_0198.py	Tue Aug 13 19:08:41 2019 +0200
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 
 # SàT plugin for managing raw XML log
@@ -28,26 +28,26 @@
 from twisted.internet import task, reactor
 from functools import partial
 from wokkel import disco, iwokkel
-from zope.interface import implements
+from zope.interface import implementer
 import collections
 import time
 
 log = getLogger(__name__)
 
 PLUGIN_INFO = {
-    C.PI_NAME: u"Stream Management",
-    C.PI_IMPORT_NAME: u"XEP-0198",
-    C.PI_TYPE: u"XEP",
+    C.PI_NAME: "Stream Management",
+    C.PI_IMPORT_NAME: "XEP-0198",
+    C.PI_TYPE: "XEP",
     C.PI_MODES: C.PLUG_MODE_BOTH,
-    C.PI_PROTOCOLS: [u"XEP-0198"],
+    C.PI_PROTOCOLS: ["XEP-0198"],
     C.PI_DEPENDENCIES: [],
-    C.PI_RECOMMENDATIONS: [u"XEP-0045", u"XEP-0313"],
-    C.PI_MAIN: u"XEP_0198",
-    C.PI_HANDLER: u"yes",
-    C.PI_DESCRIPTION: _(u"""Implementation of Stream Management"""),
+    C.PI_RECOMMENDATIONS: ["XEP-0045", "XEP-0313"],
+    C.PI_MAIN: "XEP_0198",
+    C.PI_HANDLER: "yes",
+    C.PI_DESCRIPTION: _("""Implementation of Stream Management"""),
 }
 
-NS_SM = u"urn:xmpp:sm:3"
+NS_SM = "urn:xmpp:sm:3"
 SM_ENABLED = '/enabled[@xmlns="' + NS_SM + '"]'
 SM_RESUMED = '/resumed[@xmlns="' + NS_SM + '"]'
 SM_FAILED = '/failed[@xmlns="' + NS_SM + '"]'
@@ -94,7 +94,7 @@
         if enabled:
             if self._enabled:
                 raise exceptions.InternalError(
-                    u"Stream Management can't be enabled twice")
+                    "Stream Management can't be enabled twice")
             self._enabled = True
             callback, kw = self.callback_data
             self.timer = task.LoopingCall(callback, **kw)
@@ -119,7 +119,7 @@
         self.last_ack_r = 0
         if self.req_timer is not None:
             if self.req_timer.active():
-                log.error(u"req_timer has been called/cancelled but not reset")
+                log.error("req_timer has been called/cancelled but not reset")
             else:
                 self.req_timer.cancel()
             self.req_timer = None
@@ -134,7 +134,7 @@
     def __init__(self, host):
         log.info(_("Plugin Stream Management initialization"))
         self.host = host
-        host.registerNamespace(u'sm', NS_SM)
+        host.registerNamespace('sm', NS_SM)
         host.trigger.add("stream_hooks", self.addHooks)
         host.trigger.add("xml_init", self._XMLInitTrigger)
         host.trigger.add("disconnecting", self._disconnectingTrigger)
@@ -142,12 +142,12 @@
         try:
             self._ack_timeout = int(host.memory.getConfig("", "ack_timeout", ACK_TIMEOUT))
         except ValueError:
-            log.error(_(u"Invalid ack_timeout value, please check your configuration"))
+            log.error(_("Invalid ack_timeout value, please check your configuration"))
             self._ack_timeout = ACK_TIMEOUT
         if not self._ack_timeout:
-            log.info(_(u"Ack timeout disabled"))
+            log.info(_("Ack timeout disabled"))
         else:
-            log.info(_(u"Ack timeout set to {timeout}s").format(
+            log.info(_("Ack timeout set to {timeout}s").format(
                 timeout=self._ack_timeout))
 
     def profileConnecting(self, client):
@@ -165,11 +165,11 @@
 
     def _XMLInitTrigger(self, client):
         """Enable or resume a stream mangement"""
-        if not (NS_SM, u'sm') in client.xmlstream.features:
+        if not (NS_SM, 'sm') in client.xmlstream.features:
             log.warning(_(
-                u"Your server doesn't support stream management ({namespace}), this is "
-                u"used to improve connection problems detection (like network outages). "
-                u"Please ask your server administrator to enable this feature.".format(
+                "Your server doesn't support stream management ({namespace}), this is "
+                "used to improve connection problems detection (like network outages). "
+                "Please ask your server administrator to enable this feature.".format(
                 namespace=NS_SM)))
             return True
         session = client._xep_0198_session
@@ -187,7 +187,7 @@
         if session.resume_enabled:
             # we are resuming a session
             resume_elt = domish.Element((NS_SM, 'resume'))
-            resume_elt['h'] = unicode(session.in_counter)
+            resume_elt['h'] = str(session.in_counter)
             resume_elt['previd'] = session.session_id
             client.send(resume_elt)
             session.resuming = True
@@ -197,7 +197,7 @@
             # we start a new session
             assert session.out_counter == 0
             enable_elt = domish.Element((NS_SM, 'enable'))
-            enable_elt[u'resume'] = u'true'
+            enable_elt['resume'] = 'true'
             client.send(enable_elt)
             session.enabled = True
             return True
@@ -246,14 +246,14 @@
         if server_acked > session.buffer_idx:
             diff = server_acked - session.buffer_idx
             try:
-                for i in xrange(diff):
+                for i in range(diff):
                     session.buffer.pop()
             except IndexError:
                 log.error(
-                    u"error while cleaning buffer, invalid index (buffer is empty):\n"
-                    u"diff = {diff}\n"
-                    u"server_acked = {server_acked}\n"
-                    u"buffer_idx = {buffer_id}".format(
+                    "error while cleaning buffer, invalid index (buffer is empty):\n"
+                    "diff = {diff}\n"
+                    "server_acked = {server_acked}\n"
+                    "buffer_idx = {buffer_id}".format(
                         diff=diff, server_acked=server_acked,
                         buffer_id=session.buffer_idx))
             session.buffer_idx += diff
@@ -272,15 +272,15 @@
                 break
             else:
                 if ((discard_results
-                     and stanza.name == u'iq'
-                     and stanza.getAttribute(u'type') == 'result')):
+                     and stanza.name == 'iq'
+                     and stanza.getAttribute('type') == 'result')):
                     continue
                 client.send(stanza)
 
     def sendAck(self, client):
         """Send an answer element with current IN counter"""
         a_elt = domish.Element((NS_SM, 'a'))
-        a_elt['h'] = unicode(client._xep_0198_session.in_counter)
+        a_elt['h'] = str(client._xep_0198_session.in_counter)
         client.send(a_elt)
 
     def requestAck(self, client):
@@ -298,9 +298,9 @@
         normal_host, normal_port = connector.normal_location
         del connector.normal_location
         log.warning(_(
-            u"Connection failed using location given by server (host: {host}, port: "
-            u"{port}), switching to normal host and port (host: {normal_host}, port: "
-            u"{normal_port})".format(host=connector.host, port=connector.port,
+            "Connection failed using location given by server (host: {host}, port: "
+            "{port}), switching to normal host and port (host: {normal_host}, port: "
+            "{normal_port})".format(host=connector.host, port=connector.port,
                                      normal_host=normal_host, normal_port=normal_port)))
         connector.host, connector.port = normal_host, normal_port
         connector.connectionFailed = connector.connectionFailed_ori
@@ -312,14 +312,14 @@
         session.in_counter = 0
 
         # we check that resuming is possible and that we have a session id
-        resume = C.bool(enabled_elt.getAttribute(u'resume'))
-        session_id = enabled_elt.getAttribute(u'id')
+        resume = C.bool(enabled_elt.getAttribute('resume'))
+        session_id = enabled_elt.getAttribute('id')
         if not session_id:
-            log.warning(_(u'Incorrect <enabled/> element received, no "id" attribute'))
+            log.warning(_('Incorrect <enabled/> element received, no "id" attribute'))
         if not resume or not session_id:
             log.warning(_(
-                u"You're server doesn't support session resuming with stream management, "
-                u"please contact your server administrator to enable it"))
+                "You're server doesn't support session resuming with stream management, "
+                "please contact your server administrator to enable it"))
             return
 
         session.session_id = session_id
@@ -330,7 +330,7 @@
 
         # location, in case server want resuming session to be elsewhere
         try:
-            location = enabled_elt[u'location']
+            location = enabled_elt['location']
         except KeyError:
             pass
         else:
@@ -339,7 +339,7 @@
                 domain, port = location.split(':', 1)
                 port = int(port)
             except ValueError:
-                log.warning(_(u"Invalid location received: {location}")
+                log.warning(_("Invalid location received: {location}")
                     .format(location=location))
             else:
                 session.location = (domain, port)
@@ -354,17 +354,17 @@
 
         # resuming time
         try:
-            max_s = int(enabled_elt[u'max'])
+            max_s = int(enabled_elt['max'])
         except (ValueError, KeyError) as e:
             if isinstance(e, ValueError):
-                log.warning(_(u'Invalid "max" attribute'))
+                log.warning(_('Invalid "max" attribute'))
             max_s = RESUME_MAX
-            log.info(_(u"Using default session max value ({max_s} s).".format(
+            log.info(_("Using default session max value ({max_s} s).".format(
                 max_s=max_s)))
-            log.info(_(u"Stream Management enabled"))
+            log.info(_("Stream Management enabled"))
         else:
             log.info(_(
-                u"Stream Management enabled, with a resumption time of {res_m} min"
+                "Stream Management enabled, with a resumption time of {res_m} min"
                 .format(res_m = max_s/60)))
         session.session_max = max_s
 
@@ -380,8 +380,8 @@
         # now we can continue the session
         session.enabled = True
         d_time = time.time() - session.disconnected_time
-        log.info(_(u"Stream session resumed (disconnected for {d_time} s, {count} "
-                   u"stanza(s) resent)").format(d_time=int(d_time), count=resend_count))
+        log.info(_("Stream session resumed (disconnected for {d_time} s, {count} "
+                   "stanza(s) resent)").format(d_time=int(d_time), count=resend_count))
 
     def onFailed(self, failed_elt, client):
         session = client._xep_0198_session
@@ -393,11 +393,11 @@
             del session.resuming
         except AttributeError:
             # stream management can't be started at all
-            msg = _(u"Can't use stream management")
+            msg = _("Can't use stream management")
             if condition_elt is None:
-                log.error(msg + u'.')
+                log.error(msg + '.')
             else:
-                log.error(_(u"{msg}: {reason}").format(
+                log.error(_("{msg}: {reason}").format(
                 msg=msg, reason=condition_elt.name))
         else:
             # only stream resumption failed, we can try full session init
@@ -406,12 +406,12 @@
             #      jid. This is experimental and may not be safe. It may be more
             #      secured to abord the connection and restart everything with a fresh
             #      client.
-            msg = _(u"stream resumption not possible, restarting full session")
+            msg = _("stream resumption not possible, restarting full session")
 
             if condition_elt is None:
-                log.warning(u'{msg}.'.format(msg=msg))
+                log.warning('{msg}.'.format(msg=msg))
             else:
-                log.warning(u"{msg}: {reason}".format(
+                log.warning("{msg}: {reason}".format(
                     msg=msg, reason=condition_elt.name))
             # stream resumption failed, but we still can do normal stream management
             # we restore attributes as if the session was new, and init stream
@@ -420,9 +420,9 @@
             if client.conn_deferred.called:
                 client.conn_deferred = defer.Deferred()
             else:
-                log.error(u"conn_deferred should be called at this point")
-            plg_0045 = self.host.plugins.get(u'XEP-0045')
-            plg_0313 = self.host.plugins.get(u'XEP-0313')
+                log.error("conn_deferred should be called at this point")
+            plg_0045 = self.host.plugins.get('XEP-0045')
+            plg_0313 = self.host.plugins.get('XEP-0313')
 
             # FIXME: we should call all loaded plugins with generic callbacks
             #        (e.g. prepareResume and resume), so a hot resuming can be done
@@ -493,14 +493,14 @@
         try:
             server_acked = int(a_elt['h'])
         except ValueError:
-            log.warning(_(u"Server returned invalid ack element, disabling stream "
-                          u"management: {xml}").format(xml=a_elt))
+            log.warning(_("Server returned invalid ack element, disabling stream "
+                          "management: {xml}").format(xml=a_elt))
             session.enabled = False
             return
 
         if server_acked > session.out_counter:
-            log.error(_(u"Server acked more stanzas than we have sent, disabling stream "
-                        u"management."))
+            log.error(_("Server acked more stanzas than we have sent, disabling stream "
+                        "management."))
             session.reset()
             return
 
@@ -509,17 +509,17 @@
 
     def onAckTimeOut(self, client):
         """Called when a requested ACK has not been received in time"""
-        log.info(_(u"Ack was not received in time, aborting connection"))
+        log.info(_("Ack was not received in time, aborting connection"))
         transport = client.xmlstream.transport
         if transport is None:
-            log.warning(u"transport was already removed")
+            log.warning("transport was already removed")
         else:
             transport.abortConnection()
         client._xep_0198_session.req_timer = None
 
 
+@implementer(iwokkel.IDisco)
 class XEP_0198_handler(xmlstream.XMPPHandler):
-    implements(iwokkel.IDisco)
 
     def __init__(self, plugin_parent):
         self.plugin_parent = plugin_parent