diff src/core/sat_main.py @ 1367:f71a0fc26886

merged branch frontends_multi_profiles
author Goffi <goffi@goffi.org>
date Wed, 18 Mar 2015 10:52:28 +0100
parents ba87b940f07a
children 0befb14ecf62
line wrap: on
line diff
--- a/src/core/sat_main.py	Thu Feb 05 11:59:26 2015 +0100
+++ b/src/core/sat_main.py	Wed Mar 18 10:52:28 2015 +0100
@@ -83,14 +83,15 @@
         self.bridge.register("getVersion", lambda: C.APP_VERSION)
         self.bridge.register("getProfileName", self.memory.getProfileName)
         self.bridge.register("getProfilesList", self.memory.getProfilesList)
-        self.bridge.register("getEntityData", lambda _jid, keys, profile: self.memory.getEntityData(jid.JID(_jid), keys, profile))
+        self.bridge.register("getEntityData", lambda jid_, keys, profile: self.memory.getEntityData(jid.JID(jid_), keys, profile))
+        self.bridge.register("getEntitiesData", self.memory._getEntitiesData)
         self.bridge.register("asyncCreateProfile", self.memory.asyncCreateProfile)
         self.bridge.register("asyncDeleteProfile", self.memory.asyncDeleteProfile)
         self.bridge.register("asyncConnect", self.asyncConnect)
         self.bridge.register("disconnect", self.disconnect)
         self.bridge.register("getContacts", self.getContacts)
         self.bridge.register("getContactsFromGroup", self.getContactsFromGroup)
-        self.bridge.register("getLastResource", self.memory._getLastResource)
+        self.bridge.register("getMainResource", self.memory._getMainResource)
         self.bridge.register("getPresenceStatuses", self.memory._getPresenceStatuses)
         self.bridge.register("getWaitingSub", self.memory.getWaitingSub)
         self.bridge.register("getWaitingConf", self.getWaitingConf)
@@ -264,9 +265,13 @@
         for plugin in self.plugins.iteritems():
             if plugin[1].is_handler:
                 plugin[1].getHandler(profile).setHandlerParent(current)
-            connected_cb = getattr(plugin[1], "profileConnected", None)
+            connected_cb = getattr(plugin[1], "profileConnected", None) # profile connected is called after client is ready and roster is got
             if connected_cb:
                 plugin_conn_cb.append((plugin[0], connected_cb))
+            try:
+                yield plugin[1].profileConnecting(profile) # profile connecting is called before actually starting client
+            except AttributeError:
+                pass
 
         current.startService()
 
@@ -289,7 +294,7 @@
                                   {'name': plugin_conn_cb[idx][0], 'failure': result})
 
         yield list_d.addCallback(logPluginResults) # FIXME: we should have a timeout here, and a way to know if a plugin freeze
-        # TODO: mesure time to launch of each plugin
+        # TODO: mesure launch time of each plugin
 
     def _authenticateProfile(self, password, profile):
         """Authenticate the profile.
@@ -331,12 +336,15 @@
 
     def getContacts(self, profile_key):
         client = self.getClient(profile_key)
-        ret = []
-        for item in client.roster.getItems():  # we get all items for client's roster
-            # and convert them to expected format
-            attr = client.roster.getAttributes(item)
-            ret.append([item.jid.userhost(), attr, item.groups])
-        return ret
+        def got_roster(dummy):
+            ret = []
+            for item in client.roster.getItems():  # we get all items for client's roster
+                # and convert them to expected format
+                attr = client.roster.getAttributes(item)
+                ret.append([item.jid.userhost(), attr, item.groups])
+            return ret
+
+        return client.roster.got_roster.addCallback(got_roster)
 
     def getContactsFromGroup(self, group, profile_key):
         client = self.getClient(profile_key)
@@ -456,7 +464,7 @@
     def sendMessage(self, to_jid, msg, subject=None, mess_type='auto', extra={}, no_trigger=False, profile_key=C.PROF_KEY_NONE):
         #FIXME: check validity of recipient
         profile = self.memory.getProfileName(profile_key)
-        assert(profile)
+        assert profile
         client = self.profiles[profile]
         if extra is None:
             extra = {}
@@ -479,7 +487,7 @@
                 # we may have a groupchat message, we check if the we know this jid
                 try:
                     entity_type = self.memory.getEntityData(mess_data["to"], ['type'], profile)["type"]
-                    #FIXME: should entity_type manage ressources ?
+                    #FIXME: should entity_type manage resources ?
                 except (exceptions.UnknownEntityError, KeyError):
                     entity_type = "contact"
 
@@ -497,7 +505,7 @@
             if not self.trigger.point("sendMessage", mess_data, pre_xml_treatments, post_xml_treatments, profile):
                 return defer.succeed(None)
 
-        log.debug(_("Sending jabber message of type [%(type)s] to %(to)s...") % {"type": mess_data["type"], "to": to_jid.full()})
+        log.debug(_(u"Sending message (type {type}, to {to})").format(type=mess_data["type"], to=to_jid.full()))
 
         def cancelErrorTrap(failure):
             """A message sending can be cancelled by a plugin treatment"""
@@ -572,7 +580,7 @@
         if statuses is None:
             statuses = {}
         profile = self.memory.getProfileName(profile_key)
-        assert(profile)
+        assert profile
         priority = int(self.memory.getParamA("Priority", "Connection", profile_key=profile))
         self.profiles[profile].presence.available(to_jid, show, statuses, priority)
         #XXX: FIXME: temporary fix to work around openfire 3.7.0 bug (presence is not broadcasted to generating resource)
@@ -588,7 +596,7 @@
         @param raw_jid: unicode entity's jid
         @param profile_key: profile"""
         profile = self.memory.getProfileName(profile_key)
-        assert(profile)
+        assert profile
         to_jid = jid.JID(raw_jid)
         log.debug(_('subsciption request [%(subs_type)s] for %(jid)s') % {'subs_type': subs_type, 'jid': to_jid.full()})
         if subs_type == "subscribe":
@@ -606,8 +614,8 @@
     def addContact(self, to_jid, profile_key):
         """Add a contact in roster list"""
         profile = self.memory.getProfileName(profile_key)
-        assert(profile)
-        #self.profiles[profile].roster.addItem(to_jid)  #XXX: disabled (cf http://wokkel.ik.nu/ticket/56))
+        assert profile
+        # presence is sufficient, as a roster push will be sent according to RFC 6121 ยง3.1.2
         self.profiles[profile].presence.subscribe(to_jid)
 
     def _updateContact(self, to_jid_s, name, groups, profile_key):
@@ -616,12 +624,12 @@
     def updateContact(self, to_jid, name, groups, profile_key):
         """update a contact in roster list"""
         profile = self.memory.getProfileName(profile_key)
-        assert(profile)
+        assert profile
         groups = set(groups)
         roster_item = RosterItem(to_jid)
         roster_item.name = name or None
         roster_item.groups = set(groups)
-        self.profiles[profile].roster.updateItem(roster_item)
+        return self.profiles[profile].roster.setItem(roster_item)
 
     def _delContact(self, to_jid_s, profile_key):
         return self.delContact(jid.JID(to_jid_s), profile_key)
@@ -629,10 +637,9 @@
     def delContact(self, to_jid, profile_key):
         """Remove contact from roster list"""
         profile = self.memory.getProfileName(profile_key)
-        assert(profile)
-        self.profiles[profile].roster.removeItem(to_jid)
-        self.profiles[profile].presence.unsubscribe(to_jid)
-
+        assert profile
+        self.profiles[profile].presence.unsubscribe(to_jid)  # is not asynchronous
+        return self.profiles[profile].roster.removeItem(to_jid)
 
     ## Discovery ##
     # discovery methods are shortcuts to self.memory.disco
@@ -770,6 +777,9 @@
         @profile_key: %(doc_profile_key)s
         @return: a deferred which fire a dict where key can be:
             - xmlui: a XMLUI need to be displayed
+            - validated: if present, can be used to launch a callback, it can have the values
+                - C.BOOL_TRUE
+                - C.BOOL_FALSE
         """
         profile = self.memory.getProfileName(profile_key)
         if not profile:
@@ -848,6 +858,7 @@
 
     def getMenus(self, language='', security_limit=C.NO_SECURITY_LIMIT):
         """Return all menus registered
+
         @param language: language used for translation, or empty string for default
         @param security_limit: %(doc_security_limit)s
         @return: array of tuple with:
@@ -855,7 +866,9 @@
             - menu type
             - raw menu path (array of strings)
             - translated menu path
-
+            - extra (dict(unicode, unicode)): extra data where key can be:
+                - icon: name of the icon to use (TODO)
+                - help_url: link to a page with more complete documentation (TODO)
         """
         ret = []
         for menu_id, menu_data in self._menus.iteritems():
@@ -867,7 +880,8 @@
             languageSwitch(language)
             path_i18n = [_(elt) for elt in path]
             languageSwitch()
-            ret.append((menu_id, type_, path, path_i18n))
+            extra = {} # TODO: manage extra data like icon
+            ret.append((menu_id, type_, path, path_i18n, extra))
 
         return ret