changeset 1378:3dae6964c071

quick_frontends, primitivus: move the chat states logic to quick_frontend
author souliane <souliane@mailoo.org>
date Fri, 20 Mar 2015 16:28:19 +0100
parents 017270e6eea4
children da2ea16fabc6
files frontends/src/primitivus/chat.py frontends/src/quick_frontend/constants.py frontends/src/quick_frontend/quick_app.py frontends/src/quick_frontend/quick_chat.py frontends/src/tools/jid.py
diffstat 5 files changed, 70 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/src/primitivus/chat.py	Fri Mar 20 16:25:38 2015 +0100
+++ b/frontends/src/primitivus/chat.py	Fri Mar 20 16:28:19 2015 +0100
@@ -150,25 +150,29 @@
             menu.addMenu(_("Action"), _("Send file"), self.onSendFileRequest)
         return menu
 
-    def updateChatState(self, from_jid, state):
-        if self.type == C.CHAT_GROUP:
-            if from_jid == C.ENTITY_ALL:
-                occupants = self.occupants
-            else:
-                nick = from_jid.resource
-                if not nick:
-                    log.debug("no nick found for chatstate")
-                    return
-                occupants = [nick]
-            options = self.present_wid.getAllValues()
-            for index in xrange(0, len(options)):
-                nick = options[index].value
-                if nick in occupants:
-                    options[index] = (nick, '%s %s' % (C.MUC_USER_STATES[state], nick))
-            self.present_wid.changeValues(options)
-            self.host.redraw()
-        else:
-            self.title_dynamic = '({})'.format(state)
+    def setOccupantStates(self, occupant_jid, states):
+        """Set a MUC occupant's states.
+
+        @param occupant_jid (jid.JID): occupant to update
+        @param states (dict{unicode: unicode}): new states
+        """
+        options = self.present_wid.getAllValues()
+        for index in xrange(0, len(options)):
+            nick = options[index].value
+            if nick == occupant_jid.resource:
+                options[index] = (nick, "%s %s" % (u''.join(states.values()), nick))
+                self.present_wid.changeValues(options)
+                break
+        self.host.redraw()
+
+    def setContactStates(self, contact_jid, states):
+        """Set a one2one contact's states.
+
+        @param contact_jid (jid.JID): contact
+        @param states (dict{unicode: unicode}): new states
+        """
+        self.title_dynamic = ' '.join([u'({})'.format(state) for state in states.values()])
+        self.host.redraw()
 
     def _presentClicked(self, list_wid, clicked_wid):
         assert self.type == C.CHAT_GROUP
--- a/frontends/src/quick_frontend/constants.py	Fri Mar 20 16:25:38 2015 +0100
+++ b/frontends/src/quick_frontend/constants.py	Fri Mar 20 16:28:19 2015 +0100
@@ -42,8 +42,7 @@
     XMLUI_STATUS_CANCELLED = constants.Const.XMLUI_DATA_CANCELLED
 
     # MUC
-    ALL_OCCUPANTS = 1
-    MUC_USER_STATES = {
+    USER_CHAT_STATES = {
         "active": u'✔',
         "inactive": u'☄',
         "gone": u'✈',
--- a/frontends/src/quick_frontend/quick_app.py	Fri Mar 20 16:25:38 2015 +0100
+++ b/frontends/src/quick_frontend/quick_app.py	Fri Mar 20 16:28:19 2015 +0100
@@ -574,16 +574,22 @@
         log.debug("new subject for room [%(room_jid)s]: %(subject)s" % {'room_jid': room_jid, "subject": subject})
 
     def chatStateReceivedHandler(self, from_jid_s, state, profile):
-        """Called when a new chat state is received.
+        """Called when a new chat state (XEP-0085) is received.
 
-        @param from_jid_s: JID of the contact who sent his state, or '@ALL@'
-        @param state: new state (string)
-        @profile: current profile
+        @param from_jid_s (unicode): JID of a contact or C.ENTITY_ALL
+        @param state (unicode): new state
+        @param profile (unicode): current profile
         """
         from_jid = jid.JID(from_jid_s) if from_jid_s != C.ENTITY_ALL else C.ENTITY_ALL
         for widget in self.widgets.getWidgets(quick_chat.QuickChat):
-            if from_jid == C.ENTITY_ALL or from_jid.bare == widget.target.bare:
-                widget.updateChatState(from_jid, state)
+            if profile != widget.profile:
+                continue
+            to_display = C.USER_CHAT_STATES[state] if (state and widget.type == C.CHAT_GROUP) else state
+            if widget.type == C.CHAT_GROUP and from_jid_s == C.ENTITY_ALL:
+                for occupant in [jid.newResource(self.target, nick) for nick in widget.occupants]:
+                    widget.updateEntityState(occupant, 'chat_state', to_display)
+            elif from_jid.bare == widget.target.bare:  # roster contact or MUC occupant
+                widget.updateEntityState(from_jid, 'chat_state', to_display)
 
     def personalEventHandler(self, sender, event_type, data):
         """Called when a PEP event is received.
--- a/frontends/src/quick_frontend/quick_chat.py	Fri Mar 20 16:25:38 2015 +0100
+++ b/frontends/src/quick_frontend/quick_chat.py	Fri Mar 20 16:28:19 2015 +0100
@@ -23,7 +23,7 @@
 from sat_frontends.tools import jid
 from sat_frontends.quick_frontend import quick_widgets
 from sat_frontends.quick_frontend.constants import Const as C
-
+from collections import OrderedDict
 
 try:
     # FIXME: to be removed when an acceptable solution is here
@@ -34,6 +34,8 @@
 
 class QuickChat(quick_widgets.QuickWidget):
 
+    visible_states = ['chat_state']
+
     def __init__(self, host, target, type_=C.CHAT_ONE2ONE, profiles=None):
         """
         @param type_: can be C.CHAT_ONE2ONE for single conversation or C.CHAT_GROUP for chat à la IRC
@@ -207,12 +209,25 @@
         """
         raise NotImplementedError
 
-    def updateChatState(self, from_jid, state):
-        """Set the chat state (XEP-0085) of the contact.
+    def updateEntityState(self, entity, type_, value):
+        """Update a state value for the given entity.
 
-        @param state: the new chat state
+        @param entity (jid.JID): entity to update
+        @param type_ (unicode): type of state (e.g. 'chat_state')
+        @param value (unicode): new value
         """
-        raise NotImplementedError
+        contact_list = self.host.contact_lists[self.profile]
+        contact_list.setCache(entity, type_, value)
+        clist = self.host.contact_lists[self.profile]
+        states = OrderedDict()
+        for key in self.visible_states:
+            value = clist.getCache(entity, key)
+            if value:
+                states[key] = value
+        if self.type == C.CHAT_GROUP:
+            self.setOccupantStates(entity, states)
+        else:
+            self.setContactStates(entity, states)
 
     def addGamePanel(self, widget):
         """Insert a game panel to this Chat dialog.
--- a/frontends/src/tools/jid.py	Fri Mar 20 16:25:38 2015 +0100
+++ b/frontends/src/tools/jid.py	Fri Mar 20 16:28:19 2015 +0100
@@ -20,7 +20,7 @@
 
 # hack to use this module with pyjamas
 try:
-    unicode('') # XXX: unicode doesn't exist in pyjamas
+    unicode('')  # XXX: unicode doesn't exist in pyjamas
 
     # normal version
     class BaseJID(unicode):
@@ -38,14 +38,15 @@
                 node_end = 0
             domain_end = self.find('/')
             if domain_end == 0:
-               raise ValueError("a jid can't start with '/'")
+                raise ValueError("a jid can't start with '/'")
             if domain_end == -1:
                 domain_end = len(self)
             self.node = self[:node_end] or None
             self.domain = self[(node_end + 1) if node_end else 0:domain_end]
             self.resource = self[domain_end + 1:] or None
 
-except (TypeError, AttributeError): # Error raised is not the same depending on pyjsbuild options
+except (TypeError, AttributeError):  # Error raised is not the same depending on pyjsbuild options
+
     # pyjamas version
     class BaseJID(object):
         def __init__(self, jid_str):
@@ -113,3 +114,13 @@
         """
         # TODO: implement real check, according to the RFC http://tools.ietf.org/html/rfc6122
         return self.domain != ""
+
+
+def newResource(entity, resource):
+    """Build a new JID from the given entity and resource.
+
+    @param entity (JID): original JID
+    @param resource (unicode): new resource
+    @return: a new JID instance
+    """
+    return JID(u"%s/%s" % (entity.bare, resource))