changeset 54:f25c4077f6b9

addind contact + subscription management + misc - removed bad html_sanitize (not needed in Label !) - added isContactInRoster method in ContactPanel
author Goffi <goffi@goffi.org>
date Sat, 28 May 2011 20:18:14 +0200
parents dc7861390f10
children d5266c41ca24
files browser_side/contact.py browser_side/dialog.py browser_side/panels.py libervia.py libervia.tac
diffstat 5 files changed, 91 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/browser_side/contact.py	Sat May 28 20:14:38 2011 +0200
+++ b/browser_side/contact.py	Sat May 28 20:18:14 2011 +0200
@@ -30,7 +30,6 @@
 from pyjamas.dnd import makeDraggable
 from pyjamas.ui.DragWidget import DragWidget, DragContainer
 from jid import JID
-from tools import html_sanitize
 
 class DragLabel(DragWidget):
 
@@ -66,7 +65,7 @@
 class GroupLabel(DragLabel, Label):
     def __init__(self, group):
         self.group = group
-        Label.__init__(self, html_sanitize(group)) #, Element=DOM.createElement('div')
+        Label.__init__(self, group) #, Element=DOM.createElement('div')
         self.setStyleName('group')
         DragLabel.__init__(self, group, "GROUP")
     
@@ -75,7 +74,7 @@
     def __init__(self, jid, name=None):
         if not name:
             name=jid
-        Label.__init__(self, html_sanitize(name))
+        Label.__init__(self, name)
         self.jid=jid
         self.setStyleName('contact')
         DragLabel.__init__(self, jid, "CONTACT")
@@ -141,14 +140,14 @@
         _title = ContactTitleLabel('Contacts')
         DOM.setStyleAttribute(_title.getElement(), "cursor", "pointer")
 
-        self._contactList = ContactList()
-        self._contactList.setStyleName('contactList')
+        self._contact_list = ContactList()
+        self._contact_list.setStyleName('contactList')
         self._groupList = GroupList(self)
         self._groupList.setStyleName('groupList')
         
         self.vPanel.add(_title)
         self.vPanel.add(self._groupList)
-        self.vPanel.add(self._contactList)
+        self.vPanel.add(self._contact_list)
         self.add(self.vPanel)
         self.setStyleName('contactBox')
 
@@ -163,7 +162,7 @@
                 self._groupList.add(group)
                 self.host.uni_box.addKey("@%s: " % group)
             self.groups[group].add(jid)
-        self._contactList.add(jid)
+        self._contact_list.add(jid)
 
     def setConnected(self, jid, resource, availability, priority, statuses):
         """Set connection status"""
@@ -177,7 +176,7 @@
             if not self.connected.has_key(jid):
                 self.connected[jid] = {}
             self.connected[jid][resource] = (availability, priority, statuses)
-        self._contactList.setState(jid, availability)
+        self._contact_list.setState(jid, availability)
 
     def getConnected(self):
         """return a list of all jid (bare jid) connected"""
@@ -192,6 +191,13 @@
            return True
        return False
 
+    def isContactInRoster(self, contact_jid):
+        """Test if the contact is in our roster list"""
+        for _contact_label in self._contact_list:
+            if contact_jid == _contact_label.jid:
+                return True
+        return False
+
     def getGroups(self):
         return self.groups.keys()
 
@@ -206,12 +212,12 @@
 
     def onMouseEnter(self, sender):
         if isinstance(sender, GroupLabel):
-            for contact in self._contactList:
+            for contact in self._contact_list:
                 if contact.jid in self.groups[sender.group]:
                     contact.addStyleName("selected")
     
     def onMouseLeave(self, sender):
         if isinstance(sender, GroupLabel):
-            for contact in self._contactList:
+            for contact in self._contact_list:
                 if contact.jid in self.groups[sender.group]:
                     contact.removeStyleName("selected")
--- a/browser_side/dialog.py	Sat May 28 20:14:38 2011 +0200
+++ b/browser_side/dialog.py	Sat May 28 20:18:14 2011 +0200
@@ -208,6 +208,10 @@
         
         self.setWidget(main_panel)
 
+    def getSelectedGroups(self):
+        """Return a list of selected groups"""
+        return self.list_box.getSelectedValues()
+
     def setAvailableGroups(self, groups):
         _groups = list(set(groups))
         _groups.sort()
--- a/browser_side/panels.py	Sat May 28 20:14:38 2011 +0200
+++ b/browser_side/panels.py	Sat May 28 20:18:14 2011 +0200
@@ -55,6 +55,7 @@
 from datetime import datetime
 from time import time
 import dialog
+import re
 
 class MenuCmd:
 
@@ -120,9 +121,11 @@
         edit = TextBox()
 
         def addContactCb(sender):
-            if not edit.getText():
-                Window.alert('You must enter a contact JID')
+            if not re.match(r'^.+@.+\..+',edit.getText(), re.IGNORECASE):
+                Window.alert('You must enter a valid contact JID (like "contact@libervia.org")')
                 _dialog.show()
+            else:
+                self.host.bridge.call('addContact', None, edit.getText(), '', _dialog.getSelectedGroups() )
 
         label = Label("new contact identifier (JID):")
         edit.setText('@libervia.org')
@@ -629,7 +632,7 @@
             normal: general info like "toto has joined the room"
             me: "/me" information like "/me clenches his fist" ==> "toto clenches his fist"
         """
-        _wid = Label(html_sanitize(msg))
+        _wid = Label(msg)
         if type == 'normal':
             _wid.setStyleName('chatTextInfo')
         elif type == 'me':
--- a/libervia.py	Sat May 28 20:14:38 2011 +0200
+++ b/libervia.py	Sat May 28 20:18:14 2011 +0200
@@ -27,8 +27,9 @@
 from pyjamas.JSONService import JSONProxy
 from browser_side.register import RegisterPanel, RegisterBox
 from browser_side.contact import ContactPanel
-from browser_side import panels
+from browser_side import panels, dialog
 from browser_side.jid import JID
+from browser_side.tools import html_sanitize
 
 class LiberviaJsonProxy(JSONProxy):
     def __init__(self, *args, **kwargs):
@@ -65,9 +66,9 @@
 class BridgeCall(LiberviaJsonProxy):
     def __init__(self):
         LiberviaJsonProxy.__init__(self, "/json_api",
-                        ["getContacts", "sendMessage", "sendMblog", "getMblogNodes", "getProfileJid", "getHistory", "getPresenceStatus",
+                        ["getContacts", "addContact", "sendMessage", "sendMblog", "getMblogNodes", "getProfileJid", "getHistory", "getPresenceStatus",
                          "joinMUC", "getRoomJoined", "launchTarotGame", "getTarotCardsPaths", "tarotGameReady", "tarotGameContratChoosed",
-                         "tarotGamePlayCards"])
+                         "tarotGamePlayCards", "getWaitingSub", "subscription"])
 
 class BridgeSignals(LiberviaJsonProxy):
     def __init__(self):
@@ -154,6 +155,7 @@
         self.bridge_signals.call('getSignals', self._getSignalsCB)
         #We want to know our own jid
         self.bridge.call('getProfileJid', self._getProfileJidCB)
+        
 
     def _getContactsCB(self, contacts_data):
         for contact in contacts_data:
@@ -187,13 +189,17 @@
              name == 'tarotGameYourTurn' or \
              name == 'tarotGameScore':
             self._tarotGameGenericCb(name, args[0], args[1:])
+        elif name == 'subscribe':
+            self._subscribeCb(*args)
 
     def _getProfileJidCB(self, jid):
         self.whoami = JID(jid)
         #we can now ask our status
-        self.bridge.call('getPresenceStatus', self._getPresenceStatusCB)
-        #and the rooms where we are
-        self.bridge.call('getRoomJoined', self._getRoomJoinedCB)
+        self.bridge.call('getPresenceStatus', self._getPresenceStatusCb)
+        #the rooms where we are
+        self.bridge.call('getRoomJoined', self._getRoomJoinedCb)
+        #and if there is any subscription request waiting for us
+        self.bridge.call('getWaitingSub', self._getWaitingSubCb)
 
     ## Signals callbacks ##
 
@@ -261,16 +267,43 @@
             if isinstance(panel,panels.ChatPanel) and panel.type == 'group' and panel.target.bare == room_jid:
                 getattr(panel.getGame("Tarot"), event_name)(*args) 
 
-    def _getPresenceStatusCB(self, presence_data):
+    def _getPresenceStatusCb(self, presence_data):
         for entity in presence_data:
             for resource in presence_data[entity]:
                 args = presence_data[entity][resource]
                 self._presenceUpdateCb("%s/%s" % (entity, resource), *args)
 
-    def _getRoomJoinedCB(self, room_data):
+    def _getRoomJoinedCb(self, room_data):
         for room in room_data:
             self._roomJoinedCb(*room)
 
+    def _getWaitingSubCb(self, waiting_sub):
+        for sub in waiting_sub:
+            self._subscribeCb(waiting_sub[sub], sub)
+
+    def _subscribeCb(self, sub_type, entity):
+        if sub_type == 'subscribed':
+            dialog.SimpleDialog('Subscription confirmation', 'The contact <b>%s</b> has added you to his/her contact list' % html_sanitize(entity)).show()
+
+        elif sub_type == 'unsubscribed':
+            dialog.SimpleDialog('Subscription refusal', 'The contact <b>%s</b> has refused to add you in his/her contact list' % html_sanitize(entity)).show()
+
+        elif sub_type == 'subscribe':
+            #The user want to subscribe to our presence
+            _dialog = None
+            msg = HTML('The contact <b>%s</b> want to add you in his/her contact list, do you accept ?' % html_sanitize(entity))
+            
+            def ok_cb():
+                self.bridge.call('subscription', None, "subscribed", entity, '', _dialog.getSelectedGroups())
+            def cancel_cb():
+                self.bridge.call('subscription', None, "unsubscribed", entity, '', '')
+            
+            _dialog = dialog.GroupSelector([msg], self.contact_panel.getGroups(), [], ok_cb, cancel_cb)
+            _dialog.setHTML('<b>Add contact request</b>')
+            _dialog.show()
+
+            
+
 if __name__ == '__main__':
     pyjd.setup("http://localhost:8080/libervia.html")
     app = SatWebFrontend()
--- a/libervia.tac	Sat May 28 20:14:38 2011 +0200
+++ b/libervia.tac	Sat May 28 20:18:14 2011 +0200
@@ -142,6 +142,25 @@
         profile = ISATSession(self.session).profile
         return self.sat_host.bridge.getContacts(profile)
 
+    def jsonrpc_addContact(self, entity, name, groups):
+        """Subscribe to contact presence, and add it to the given groups"""
+        profile = ISATSession(self.session).profile
+        self.sat_host.bridge.addContact(entity, profile)
+        self.sat_host.bridge.updateContact(entity, name, groups, profile)
+
+    def jsonrpc_subscription(self, sub_type, entity, name, groups):
+        """Confirm (or infirm) subscription,
+        and setup user roster in case of subscription"""
+        profile = ISATSession(self.session).profile
+        self.sat_host.bridge.subscription(sub_type, entity, profile)
+        if sub_type == 'subscribed':
+            self.sat_host.bridge.updateContact(entity, name, groups, profile)
+
+    def jsonrpc_getWaitingSub(self):
+        """Return list of room already joined by user"""
+        profile = ISATSession(self.session).profile
+        return self.sat_host.bridge.getWaitingSub(profile) 
+
     def jsonrpc_setStatus(self, status):
         """Change the status"""
         profile = ISATSession(self.session).profile
@@ -323,6 +342,8 @@
         """Create a new account, or return error
         @param args: dict of args as given by the form
         @return: "REGISTRATION" in case of success"""
+        #TODO: must be moved in SàT core
+
         try:
             profile = login = args['login'][0]
             email = args['email'][0]
@@ -428,6 +449,7 @@
         d = defer.Deferred()
         self.sat_host.bridge.getMblogNodes(profile, d.callback, d.errback)
         d.addCallback(self._fillMblogNodes, _session)
+
         if finish:
             request.write('LOGGED')
             request.finish()
@@ -556,7 +578,8 @@
         self.bridge.register("connectionError", self.signal_handler.connectionError)
         self.bridge.register("actionResult", self.action_handler.actionResultCb, "request") 
         for signal_name in ['presenceUpdate', 'personalEvent', 'newMessage', 'roomJoined', 'roomUserJoined', 'roomUserLeft', 'tarotGameStarted', 'tarotGameNew',
-                            'tarotGameChooseContrat', 'tarotGameShowCards', 'tarotGameInvalidCards', 'tarotGameCardsPlayed', 'tarotGameYourTurn', 'tarotGameScore']:
+                            'tarotGameChooseContrat', 'tarotGameShowCards', 'tarotGameInvalidCards', 'tarotGameCardsPlayed', 'tarotGameYourTurn', 'tarotGameScore',
+                            'subscribe']:
             self.bridge.register(signal_name, self.signal_handler.getGenericCb(signal_name))
         root.putChild('json_signal_api', self.signal_handler)
         root.putChild('json_api', MethodHandler(self))