changeset 801:02ee9ef95277

plugin XEP-0045, primitivus: added MUC configuration
author Goffi <goffi@goffi.org>
date Tue, 04 Feb 2014 18:06:12 +0100
parents e0770d977d58
children 9007bb133009
files frontends/src/primitivus/chat.py src/core/sat_main.py src/plugins/plugin_xep_0045.py
diffstat 3 files changed, 63 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/src/primitivus/chat.py	Tue Feb 04 18:04:32 2014 +0100
+++ b/frontends/src/primitivus/chat.py	Tue Feb 04 18:06:12 2014 +0100
@@ -24,6 +24,7 @@
 from sat_frontends.quick_frontend.quick_chat import QuickChat
 from sat_frontends.primitivus.card_game import CardGame
 from sat_frontends.quick_frontend.quick_utils import escapePrivate, unescapePrivate
+from sat_frontends.primitivus.xmlui import XMLUI
 import time
 from sat.tools.jid  import JID
 
@@ -131,7 +132,9 @@
         menu = sat_widgets.Menu(self.host.loop)
         if self.type == 'group':
             game = _("Game")
+            muc = _("MUC")
             menu.addMenu(game, "Tarot", self.onTarotRequest)
+            menu.addMenu(muc, _("Configure room"), self.onConfigureRoom)
         elif self.type == 'one2one':
             menu.addMenu(_("Action"), _("Send file"), self.onSendFileRequest)
         return menu
@@ -335,6 +338,13 @@
         else:
             self.host.bridge.tarotGameCreate(self.id, list(self.occupants), self.host.profile)
 
+    def onConfigureRoom(self, menu):
+        def gotUI(xmlui):
+            self.host.addWindow(XMLUI(self.host, xmlui))
+        def configureError(failure):
+            self.host.showPopUp(sat_widgets.Alert(_("Error"), unicode(failure), ok_cb=self.host.removePopUp))
+        self.host.bridge.configureRoom(self.id, self.host.profile, callback=gotUI, errback=configureError)
+
     def onSendFileRequest(self, menu):
         dialog = FileDialog(ok_cb=self.onFileSelected, cancel_cb=self.host.removePopUp)
         self.host.showPopUp(dialog, 80, 80)
--- a/src/core/sat_main.py	Tue Feb 04 18:04:32 2014 +0100
+++ b/src/core/sat_main.py	Tue Feb 04 18:06:12 2014 +0100
@@ -903,7 +903,8 @@
         @param help_string: string used to indicate what the menu do (can be show as a tooltip).
             /!\ use D_() instead of _() for translations
         @param type: one of:
-            - NORMAL: classical menu, can be shown in a menubar on top (e.g. something like File/Open)
+            - GLOBAL: classical menu, can be shown in a menubar on top (e.g. something like File/Open)
+            - ROOM: like a global menu, but only shown in multi-user chat
             - JID_CONTEXT: contextual menu, used with any jid (e.g.: ad hoc commands, jid is already filled)
             - ROSTER_JID_CONTEXT: like JID_CONTEXT, but restricted to jids in roster.
             - ROSTER_GROUP_CONTEXT: contextual menu, used with group (e.g.: publish microblog, group is already filled)
--- a/src/plugins/plugin_xep_0045.py	Tue Feb 04 18:04:32 2014 +0100
+++ b/src/plugins/plugin_xep_0045.py	Tue Feb 04 18:06:12 2014 +0100
@@ -23,10 +23,12 @@
 from twisted.words.protocols.jabber import jid
 
 from sat.core import exceptions
+from sat.memory import memory
 
 import uuid
 
 from wokkel import muc
+from sat.tools import xml_tools
 
 
 try:
@@ -56,18 +58,21 @@
         info(_("Plugin XEP_0045 initialization"))
         self.host = host
         self.clients = {}
+        self._sessions = memory.Sessions()
         host.bridge.addMethod("joinMUC", ".plugin", in_sign='ssa{ss}s', out_sign='s', method=self._join)
         host.bridge.addMethod("mucNick", ".plugin", in_sign='sss', out_sign='', method=self.mucNick)
-        host.bridge.addMethod("mucLeave", ".plugin", in_sign='ss', out_sign='', method=self.mucLeave, async = True)
+        host.bridge.addMethod("mucLeave", ".plugin", in_sign='ss', out_sign='', method=self.mucLeave, async=True)
         host.bridge.addMethod("getRoomsJoined", ".plugin", in_sign='s', out_sign='a(sass)', method=self.getRoomsJoined)
         host.bridge.addMethod("getRoomsSubjects", ".plugin", in_sign='s', out_sign='a(ss)', method=self.getRoomsSubjects)
         host.bridge.addMethod("getUniqueRoomName", ".plugin", in_sign='ss', out_sign='s', method=self.getUniqueName)
+        host.bridge.addMethod("configureRoom", ".plugin", in_sign='ss', out_sign='s', method=self._configureRoom, async=True)
         host.bridge.addSignal("roomJoined", ".plugin", signature='sasss')  # args: room_jid, room_nicks, user_nick, profile
         host.bridge.addSignal("roomLeft", ".plugin", signature='ss')  # args: room_jid, profile
         host.bridge.addSignal("roomUserJoined", ".plugin", signature='ssa{ss}s')  # args: room_jid, user_nick, user_data, profile
         host.bridge.addSignal("roomUserLeft", ".plugin", signature='ssa{ss}s')  # args: room_jid, user_nick, user_data, profile
         host.bridge.addSignal("roomUserChangedNick", ".plugin", signature='ssss')  # args: room_jid, old_nick, new_nick, profile
         host.bridge.addSignal("roomNewSubject", ".plugin", signature='sss')  # args: room_jid, subject, profile
+        self.__submit_conf_id = host.registerCallback(self._submitConfiguration, with_data=True)
 
     def __check_profile(self, profile):
         """check if profile is used and connected
@@ -169,6 +174,51 @@
                 nicks.append(nick)
         return nicks, missing
 
+    def _configureRoom(self, room_jid_s, profile_key='@NONE@'):
+        d = self.configureRoom(jid.JID(room_jid_s), profile_key)
+        d.addCallback(lambda xmlui: xmlui.toXml())
+        return d
+
+    def configureRoom(self, room_jid, profile_key='@NONE@'):
+        """ return the room configuration form
+        @param room: jid of the room to configure
+        @param profile_key: %(doc_profile_key)s
+        @return: configuration form as XMLUI
+
+        """
+        profile = self.host.memory.getProfileName(profile_key)
+        if not self.__check_profile(profile):
+            raise exceptions.ProfileUnknownError("Unknown or disconnected profile")
+        if room_jid.userhost() not in self.clients[profile].joined_rooms:
+            raise UnknownRoom("This room has not been joined")
+
+        def config2XMLUI(result):
+            if not result:
+                return ""
+            session_id, session_data = self._sessions.newSession(profile=profile)
+            session_data["room_jid"] = room_jid
+            xmlui = xml_tools.dataForm2XMLUI(result, submit_id=self.__submit_conf_id)
+            xmlui.session_id = session_id
+            return xmlui
+
+        d = self.clients[profile].getConfiguration(room_jid)
+        d.addCallback(config2XMLUI)
+        return d
+
+    def _submitConfiguration(self, raw_data, profile):
+        try:
+            session_data = self._sessions.profileGet(raw_data["session_id"], profile)
+        except KeyError:
+            warning ("session id doesn't exist, session has probably expired")
+            # TODO: send error dialog
+            return defer.succeed({})
+
+        data = xml_tools.XMLUIResult2DataFormResult(raw_data)
+        d = self.clients[profile].configure(session_data['room_jid'], data)
+        d.addCallback(lambda ignore: {})
+        del self._sessions[raw_data["session_id"]]
+        return d
+
     def isNickInRoom(self, room_jid, nick, profile):
         """Tell if a nick is currently present in a room"""
         profile = self.host.memory.getProfileName(profile)