From 0b6326e1cce9e85430fa8015f35a9c19d5d59aaf Mon Sep 17 00:00:00 2001
From: mathieui <mathieui@mathieui.net>
Date: Sun, 14 Feb 2021 11:45:03 +0100
Subject: XEP-0012: API changes.

---
 docs/api/plugins/xep_0012.rst             | 36 +++++++++++++++++++++
 itests/test_last_activity.py              |  2 +-
 slixmpp/plugins/xep_0012/last_activity.py | 54 ++++++++++++++++++++++---------
 3 files changed, 75 insertions(+), 17 deletions(-)

diff --git a/docs/api/plugins/xep_0012.rst b/docs/api/plugins/xep_0012.rst
index 9a12eac3..8e72ee2a 100644
--- a/docs/api/plugins/xep_0012.rst
+++ b/docs/api/plugins/xep_0012.rst
@@ -9,6 +9,42 @@ XEP-0012: Last Activity
     :exclude-members: session_bind, plugin_init, plugin_end
 
 
+Internal API methods
+--------------------
+
+This plugin uses an in-memory storage by default to keep track of the
+received and sent last activities.
+
+.. glossary::
+
+    get_last_activity
+        - **jid**: :class:`~.JID` of whom to retrieve the last activity
+        - **node**: unused
+        - **ifrom**: who the request is from (None = local)
+        - **args**: ``None`` or an :class:`~.Iq` that is requesting the
+        - **returns**
+          information.
+
+        Get the last activity of a JID from the storage.
+
+    set_last_activity
+        - **jid**: :class:`~.JID` of whom to set the last activity
+        - **node**: unused
+        - **ifrom**: unused
+        - **args**: A dict containing ``'seconds'`` and ``'status'``
+          ``{'seconds': Optional[int], 'status': Optional[str]}``
+
+        Set the last activity of a JID in the storage.
+
+    del_last_activity
+        - **jid**: :class:`~.JID` to delete from the storage
+        - **node**: unused
+        - **ifrom**: unused
+        - **args**: unused
+
+        Remove the last activity of a JID from the storage.
+
+
 Stanza elements
 ---------------
 
diff --git a/itests/test_last_activity.py b/itests/test_last_activity.py
index 3d36b4b8..ed3173e2 100644
--- a/itests/test_last_activity.py
+++ b/itests/test_last_activity.py
@@ -18,7 +18,7 @@ class TestLastActivity(SlixIntegration):
 
     async def test_activity(self):
         """Check we can set and get last activity"""
-        self.clients[0]['xep_0012'].set_last_activity(
+        await self.clients[0]['xep_0012'].set_last_activity(
             status='coucou',
             seconds=4242,
         )
diff --git a/slixmpp/plugins/xep_0012/last_activity.py b/slixmpp/plugins/xep_0012/last_activity.py
index 27e16e21..61531431 100644
--- a/slixmpp/plugins/xep_0012/last_activity.py
+++ b/slixmpp/plugins/xep_0012/last_activity.py
@@ -16,7 +16,7 @@ from slixmpp import future_wrapper, JID
 from slixmpp.stanza import Iq
 from slixmpp.exceptions import XMPPError
 from slixmpp.xmlstream import JID, register_stanza_plugin
-from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.handler import CoroutineCallback
 from slixmpp.xmlstream.matcher import StanzaPath
 from slixmpp.plugins.xep_0012 import stanza, LastActivity
 
@@ -41,7 +41,7 @@ class XEP_0012(BasePlugin):
         self._last_activities = {}
 
         self.xmpp.register_handler(
-            Callback('Last Activity',
+            CoroutineCallback('Last Activity',
                  StanzaPath('iq@type=get/last_activity'),
                  self._handle_get_last_activity))
 
@@ -62,28 +62,50 @@ class XEP_0012(BasePlugin):
     def session_bind(self, jid):
         self.xmpp['xep_0030'].add_feature('jabber:iq:last')
 
-    def begin_idle(self, jid: Optional[JID] = None, status: str = None):
+    def begin_idle(self, jid: Optional[JID] = None, status: Optional[str] = None) -> Future:
         """Reset the last activity for the given JID.
 
+        .. versionchanged:: 1.8.0
+            This function now returns a Future.
+
         :param status: Optional status.
         """
-        self.set_last_activity(jid, 0, status)
+        return self.set_last_activity(jid, 0, status)
+
+    def end_idle(self, jid: Optional[JID] = None) -> Future:
+        """Remove the last activity of a JID.
 
-    def end_idle(self, jid=None):
-        self.del_last_activity(jid)
+        .. versionchanged:: 1.8.0
+            This function now returns a Future.
+        """
+        return self.del_last_activity(jid)
 
-    def start_uptime(self, status=None):
-        self.set_last_activity(None, 0, status)
+    def start_uptime(self, status: Optional[str] = None) -> Future:
+        """
+        .. versionchanged:: 1.8.0
+            This function now returns a Future.
+        """
+        return self.set_last_activity(None, 0, status)
 
-    def set_last_activity(self, jid=None, seconds=None, status=None):
-        self.api['set_last_activity'](jid, args={
+    def set_last_activity(self, jid=None, seconds=None, status=None) -> Future:
+        """Set last activity for a JID.
+
+        .. versionchanged:: 1.8.0
+            This function now returns a Future.
+        """
+        return self.api['set_last_activity'](jid, args={
             'seconds': seconds,
-            'status': status})
+            'status': status
+        })
 
-    def del_last_activity(self, jid):
-        self.api['del_last_activity'](jid)
+    def del_last_activity(self, jid: JID) -> Future:
+        """Remove the last activity of a JID.
+
+        .. versionchanged:: 1.8.0
+            This function now returns a Future.
+        """
+        return self.api['del_last_activity'](jid)
 
-    @future_wrapper
     def get_last_activity(self, jid: JID, local: bool = False,
                           ifrom: Optional[JID] = None, **iqkwargs) -> Future:
         """Get last activity for a specific JID.
@@ -109,10 +131,10 @@ class XEP_0012(BasePlugin):
         iq.enable('last_activity')
         return iq.send(**iqkwargs)
 
-    def _handle_get_last_activity(self, iq: Iq):
+    async def _handle_get_last_activity(self, iq: Iq):
         log.debug("Received last activity query from " + \
                   "<%s> to <%s>.", iq['from'], iq['to'])
-        reply = self.api['get_last_activity'](iq['to'], None, iq['from'], iq)
+        reply = await self.api['get_last_activity'](iq['to'], None, iq['from'], iq)
         reply.send()
 
     # =================================================================
-- 
cgit v1.2.3