changeset 2489:fabbb4dbd99e

Merge devel.
author Karol 'grzywacz' Nowak <grzywacz@sul.uni.lodz.pl>
date Sun, 22 Jul 2007 03:27:45 +0200
parents 8fb3dc91df77 (current diff) c707250dca17 (diff)
children b9e0a8a1f14c
files
diffstat 2 files changed, 91 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/_tests/test_PageEditor.py	Sat Jul 21 02:33:34 2007 +0200
+++ b/MoinMoin/_tests/test_PageEditor.py	Sun Jul 22 03:27:45 2007 +0200
@@ -170,34 +170,38 @@
         return page.getPagePath(use_underlay=0, check_create=0)
 
 
-def testSave(request):
-    """Test if saveText() is interrupted if PagePreSave event handler returns Abort"""
-
-    def handler(event):
-        from MoinMoin.events import Abort
-        return Abort("This is just a test")
-
-    pagename = u'AutoCreatedMoinMoinTemporaryTestPageFortestSave'
-    testtext = u'ThisIsSomeStupidTestPageText!'
+class TestSave:
+    
+    def setup_method(self, method):
+        self.old_handlers = self.request.cfg.event_handlers
+        gain_superuser_rights(self.request)
+        
+    def teardown_method(self, method):
+        self.request.cfg.event_handlers = self.old_handlers
+        
+    def testSaveAbort(self):
+        """Test if saveText() is interrupted if PagePreSave event handler returns Abort"""
+    
+        def handler(event):
+            from MoinMoin.events import Abort
+            return Abort("This is just a test")
+    
+        pagename = u'AutoCreatedMoinMoinTemporaryTestPageFortestSave'
+        testtext = u'ThisIsSomeStupidTestPageText!'
 
-    gain_superuser_rights(request)
-    cfg = request.cfg
-    cfg.event_handlers = [handler]
-
-    page = Page(request, pagename)
-    if page.exists():
-        deleter = PageEditor(request, pagename)
-        deleter.deletePage()
-        print 'BODY:', deleter.body
-
-    editor = PageEditor(request, pagename)
-    print 'BODY:', editor.body
-    editor.saveText(testtext, 0)
-
-    print "PageEditor can't save a page if Abort is returned from PreSave event handlers"
-    page = Page(request, pagename)
-    assert page.body != testtext
+        self.request.cfg.event_handlers = [handler]
+        
+        page = Page(self.request, pagename)
+        if page.exists():
+            deleter = PageEditor(self.request, pagename)
+            deleter.deletePage()
+    
+        editor = PageEditor(self.request, pagename)
+        editor.saveText(testtext, 0)
+    
+        print "PageEditor can't save a page if Abort is returned from PreSave event handlers"
+        page = Page(self.request, pagename)
+        assert page.body != testtext
 
 
 coverage_modules = ['MoinMoin.PageEditor']
-
--- a/jabberbot/xmppbot.py	Sat Jul 21 02:33:34 2007 +0200
+++ b/jabberbot/xmppbot.py	Sun Jul 22 03:27:45 2007 +0200
@@ -27,11 +27,19 @@
     This class handles some logic related to keeping track of
     contact availability, status, etc."""
 
+    # Default Time To Live of a contact. If there are no registered
+    # resources for that period of time, the contact should be removed
+    default_ttl = 3600 * 24 # default of one day
+
     def __init__(self, jid, resource, priority, show, language=None):
         self.jid = jid
         self.resources = {resource: {'show': show, 'priority': priority, 'forms': False}}
         self.language = language
 
+        # The last time when this contact was seen online.
+        # This value has meaning for offline contacts only.
+        self.last_online = None
+
         # Queued messages, waiting for contact to change its "show"
         # status to something different than "dnd". The messages should
         # also be sent when contact becomes "unavailable" directly from
@@ -39,6 +47,14 @@
         # the next time she becomes "available".
         self.messages = []
 
+    def is_valid(self, current_time):
+        """Check if this contact entry is still valid and should be kept
+
+        @param time: current time in seconds
+
+        """
+        # No resources == offline
+        return self.resources or current_time < self.last_online + self.default_ttl
 
     def add_resource(self, resource, show, priority):
         """Adds information about a connected resource
@@ -49,6 +65,7 @@
 
         """
         self.resources[resource] = {'show': show, 'priority': priority}
+        self.last_online = None
 
     def set_supports_forms(self, resource):
         if resource in self.resources:
@@ -71,6 +88,9 @@
         else:
             raise ValueError("No such resource!")
 
+        if not self.resources:
+            self.last_online = time.time()
+
     def is_dnd(self):
         """Checks if contact is DoNotDisturb
 
@@ -87,7 +107,8 @@
                 max_prio = resource['priority']
                 max_prio_show = resource['show']
 
-        return max_prio_show == u'dnd'
+        # If there are no resources the contact is offline, not dnd
+        return self.resources and max_prio_show == u'dnd'
 
     def set_show(self, resource, show):
         """Sets show property for a given resource
@@ -135,6 +156,12 @@
         # A dictionary of contact objects, ordered by bare JID
         self.contacts = {}
 
+        # The last time when contacts were checked for expiration, in seconds
+        self.last_expiration = time.time()
+
+        # How often should the contacts be checked for expiration, in seconds
+        self.contact_check = 600
+
         self.known_xmlrpc_cmds = [cmd.GetPage, cmd.GetPageHTML, cmd.GetPageList, cmd.GetPageInfo, cmd.Search]
         self.internal_commands = ["ping", "help", "searchform"]
 
@@ -154,7 +181,7 @@
     def loop(self, timeout=1):
         """Main event loop - stream and command handling"""
 
-        while 1:
+        while True:
             stream = self.get_stream()
             if not stream:
                 break
@@ -165,6 +192,26 @@
                 while self.poll_commands(): pass
                 self.idle()
 
+    def idle(self):
+        """Do some maintenance"""
+
+        Client.idle(self)
+
+        current_time = time.time()
+        if self.last_expiration + self.contact_check < current_time:
+            self.expire_contacts(current_time)
+            self.last_expiration = current_time
+
+    def expire_contacts(self, current_time):
+        """Check which contats have been offline for too long and should be removed
+
+        @param current_time: current time in seconds
+
+        """
+        for jid, contact in self.contacts.items():
+            if not contact.is_valid(current_time):
+                del self.contacts[jid]
+
     def getText(self, jid):
         """Returns a getText function (_) for the given JID
 
@@ -515,7 +562,7 @@
                 # alive the next time this contact becomes available.
                 if len(contact.resources) == 1:
                     self.send_queued_messages(contact, ignore_dnd=True)
-                    del self.contacts[bare_jid]
+                    contact.remove_resource(jid.resource)
                 else:
                     contact.remove_resource(jid.resource)
 
@@ -571,16 +618,21 @@
         else:
             self.contacts[bare_jid] = Contact(jid, jid.resource, priority, show)
             self.supports_dataforms(jid)
-
-            # Request user's language now. This is suboptimal, but caching
-            # should fix it in the future.
-            request = cmd.GetUserLanguage(bare_jid)
-            self.from_commands.put_nowait(request)
+            self.get_user_language(bare_jid)
             self.log.debug(self.contacts[bare_jid])
 
         # Confirm that we've handled this stanza
         return True
 
+    def get_user_language(self, jid):
+        """Request user's language setting from the wiki
+
+        @param jid: bare Jabber ID of the user to query for
+        @type jid: unicode
+        """
+        request = cmd.GetUserLanguage(jid)
+        self.from_commands.put_nowait(request)
+
     def supports_dataforms(self, jid):
         """Check if a clients supports data forms.