From 6b8e85e6dac4598b0359e812502bc0a74bec33fc Mon Sep 17 00:00:00 2001 From: David Rousselie Date: Wed, 28 May 2008 19:11:20 +0200 Subject: [PATCH] implement Last Activity (XEP-012) darcs-hash:20080528171120-86b55-bcb3bc0c25cb2ea16f90db428b340842cdff941b.gz --- src/jcl/jabber/component.py | 9 +++++++-- src/jcl/jabber/presence.py | 13 +++++++++++++ src/jcl/jabber/tests/presence.py | 30 +++++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/jcl/jabber/component.py b/src/jcl/jabber/component.py index c32bf95..d16d828 100644 --- a/src/jcl/jabber/component.py +++ b/src/jcl/jabber/component.py @@ -35,6 +35,7 @@ import signal import re import traceback import string +import time from Queue import Queue @@ -59,7 +60,7 @@ from jcl.jabber.presence import AccountPresenceAvailableHandler, \ RootPresenceAvailableHandler, AccountPresenceUnavailableHandler, \ RootPresenceUnavailableHandler, AccountPresenceSubscribeHandler, \ RootPresenceSubscribeHandler, AccountPresenceUnsubscribeHandler, \ - RootPresenceUnsubscribeHandler + RootPresenceUnsubscribeHandler, DefaultIQLastHandler from jcl.jabber.register import RootSetRegisterHandler, \ AccountSetRegisterHandler, AccountTypeSetRegisterHandler from jcl.jabber.vcard import DefaultVCardHandler @@ -646,12 +647,14 @@ class JCLComponent(Component, object): AccountSetRegisterHandler(self), AccountTypeSetRegisterHandler(self)]] self.vcard_handlers = [[DefaultVCardHandler(self)]] + self.iqlast_handlers = [[DefaultIQLastHandler(self)]] self.__logger = logging.getLogger("jcl.jabber.JCLComponent") self.lang = lang self.running = False self.wait_event = threading.Event() self._restart = False + self.last_activity = int(time.time()) signal.signal(signal.SIGINT, self.signal_handler) signal.signal(signal.SIGTERM, self.signal_handler) @@ -666,6 +669,7 @@ class JCLComponent(Component, object): """ self.spool_dir += "/" + unicode(self.jid) self.running = True + self.last_activity = int(time.time()) self.connect() timer_thread = threading.Thread(target=self.time_handler, name="TimerThread") @@ -867,7 +871,8 @@ class JCLComponent(Component, object): """ Handle IQ-get "jabber:iq:last" requests. """ - # TODO + self.__logger.debug("IQ:Last request") + self.apply_registered_behavior(self.iqlast_handlers, info_query) return 1 def handle_get_gateway(self, info_query): diff --git a/src/jcl/jabber/presence.py b/src/jcl/jabber/presence.py index cde8dcb..53c8622 100644 --- a/src/jcl/jabber/presence.py +++ b/src/jcl/jabber/presence.py @@ -21,6 +21,8 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## +import time + from pyxmpp.presence import Presence from pyxmpp.message import Message @@ -28,6 +30,17 @@ from jcl.jabber import Handler from jcl.model import account import jcl.jabber as jabber +class DefaultIQLastHandler(Handler): + """Handle jabber:iq:last request""" + + def handle(self, stanza, lang_class, data): + """Return same presence as receive one""" + result = stanza.make_result_response() + query = result.new_query("jabber:iq:last") + query.setProp("seconds", + unicode(int(time.time()) - self.component.last_activity)) + return [result] + class DefaultPresenceHandler(Handler): """Handle presence""" diff --git a/src/jcl/jabber/tests/presence.py b/src/jcl/jabber/tests/presence.py index 6d932b8..3329dbb 100644 --- a/src/jcl/jabber/tests/presence.py +++ b/src/jcl/jabber/tests/presence.py @@ -24,20 +24,47 @@ import unittest import tempfile import os from ConfigParser import ConfigParser +import time from pyxmpp.presence import Presence from pyxmpp.message import Message +from pyxmpp.iq import Iq from jcl.jabber.component import JCLComponent from jcl.jabber.presence import DefaultSubscribeHandler, \ DefaultUnsubscribeHandler, DefaultPresenceHandler, \ RootPresenceAvailableHandler, AccountPresenceAvailableHandler, \ - AccountPresenceUnavailableHandler + AccountPresenceUnavailableHandler, DefaultIQLastHandler from jcl.model.account import User, LegacyJID, Account from jcl.lang import Lang from jcl.tests import JCLTestCase +class DefaultIQLastHandler_TestCase(JCLTestCase): + def setUp(self): + JCLTestCase.setUp(self, tables=[User, LegacyJID, Account]) + self.comp = JCLComponent("jcl.test.com", + "password", + "localhost", + "5347", + None) + self.handler = DefaultIQLastHandler(self.comp) + + def test_handle(self): + info_query = Iq(from_jid="user1@test.com", + to_jid="jcl.test.com", + stanza_type="get") + self.comp.last_activity = int(time.time()) + time.sleep(1) + result = self.handler.handle(info_query, None, []) + self.assertEquals(len(result), 1) + self.assertEquals(result[0].get_to(), "user1@test.com") + self.assertEquals(result[0].get_from(), "jcl.test.com") + self.assertEquals(result[0].get_type(), "result") + self.assertNotEquals(result[0].xmlnode.children, None) + self.assertEquals(result[0].xmlnode.children.name, "query") + self.assertEquals(int(result[0].xmlnode.children.prop("seconds")), 1) + class DefaultSubscribeHandler_TestCase(unittest.TestCase): def setUp(self): self.handler = DefaultSubscribeHandler(None) @@ -362,6 +389,7 @@ class AccountPresenceUnavailableHandler_TestCase(JCLTestCase): def suite(): test_suite = unittest.TestSuite() + test_suite.addTest(unittest.makeSuite(DefaultIQLastHandler_TestCase, 'test')) test_suite.addTest(unittest.makeSuite(DefaultSubscribeHandler_TestCase, 'test')) test_suite.addTest(unittest.makeSuite(DefaultUnsubscribeHandler_TestCase, 'test')) test_suite.addTest(unittest.makeSuite(DefaultPresenceHandler_TestCase, 'test'))