comparison src/plugins/plugin_xep_0045.py @ 712:f610864eb7a5

plugins (MUC, tools, games): generalize the generation of a unique room name when joining a MUC and no room is specified: - method to get the MUC service moved to plugin_xep_0045 - joinMUC returns the muc name (given by user or generated) - getUniqueName can receive a specified service in argument
author souliane <souliane@mailoo.org>
date Sun, 17 Nov 2013 16:59:12 +0100
parents 84a6e83157c2
children 8bd63daecdbf
comparison
equal deleted inserted replaced
711:c9792d0be499 712:f610864eb7a5
53 53
54 def __init__(self, host): 54 def __init__(self, host):
55 info(_("Plugin XEP_0045 initialization")) 55 info(_("Plugin XEP_0045 initialization"))
56 self.host = host 56 self.host = host
57 self.clients = {} 57 self.clients = {}
58 host.bridge.addMethod("joinMUC", ".plugin", in_sign='ssa{ss}s', out_sign='', method=self._join) 58 host.bridge.addMethod("joinMUC", ".plugin", in_sign='ssa{ss}s', out_sign='s', method=self._join)
59 host.bridge.addMethod("mucNick", ".plugin", in_sign='sss', out_sign='', method=self.mucNick) 59 host.bridge.addMethod("mucNick", ".plugin", in_sign='sss', out_sign='', method=self.mucNick)
60 host.bridge.addMethod("mucLeave", ".plugin", in_sign='ss', out_sign='', method=self.mucLeave, async = True) 60 host.bridge.addMethod("mucLeave", ".plugin", in_sign='ss', out_sign='', method=self.mucLeave, async = True)
61 host.bridge.addMethod("getRoomsJoined", ".plugin", in_sign='s', out_sign='a(sass)', method=self.getRoomsJoined) 61 host.bridge.addMethod("getRoomsJoined", ".plugin", in_sign='s', out_sign='a(sass)', method=self.getRoomsJoined)
62 host.bridge.addMethod("getRoomsSubjects", ".plugin", in_sign='s', out_sign='a(ss)', method=self.getRoomsSubjects) 62 host.bridge.addMethod("getRoomsSubjects", ".plugin", in_sign='s', out_sign='a(ss)', method=self.getRoomsSubjects)
63 host.bridge.addMethod("getUniqueRoomName", ".plugin", in_sign='s', out_sign='s', method=self.getUniqueName) 63 host.bridge.addMethod("getUniqueRoomName", ".plugin", in_sign='ss', out_sign='s', method=self.getUniqueName)
64 host.bridge.addSignal("roomJoined", ".plugin", signature='sasss') # args: room_jid, room_nicks, user_nick, profile 64 host.bridge.addSignal("roomJoined", ".plugin", signature='sasss') # args: room_jid, room_nicks, user_nick, profile
65 host.bridge.addSignal("roomLeft", ".plugin", signature='ss') # args: room_jid, profile 65 host.bridge.addSignal("roomLeft", ".plugin", signature='ss') # args: room_jid, profile
66 host.bridge.addSignal("roomUserJoined", ".plugin", signature='ssa{ss}s') # args: room_jid, user_nick, user_data, profile 66 host.bridge.addSignal("roomUserJoined", ".plugin", signature='ssa{ss}s') # args: room_jid, user_nick, user_data, profile
67 host.bridge.addSignal("roomUserLeft", ".plugin", signature='ssa{ss}s') # args: room_jid, user_nick, user_data, profile 67 host.bridge.addSignal("roomUserLeft", ".plugin", signature='ssa{ss}s') # args: room_jid, user_nick, user_data, profile
68 host.bridge.addSignal("roomUserChangedNick", ".plugin", signature='ssss') # args: room_jid, old_nick, new_nick, profile 68 host.bridge.addSignal("roomUserChangedNick", ".plugin", signature='ssss') # args: room_jid, old_nick, new_nick, profile
99 _sendBridgeSignal() 99 _sendBridgeSignal()
100 return room 100 return room
101 101
102 def __err_joining_room(self, failure, room_jid, nick, history_options, password, profile): 102 def __err_joining_room(self, failure, room_jid, nick, history_options, password, profile):
103 """Called when something is going wrong when joining the room""" 103 """Called when something is going wrong when joining the room"""
104 if failure.value.condition == 'conflict': 104 if hasattr(failure.value, "condition") and failure.value.condition == 'conflict':
105 # we have a nickname conflict, we try again with "_" suffixed to current nickname 105 # we have a nickname conflict, we try again with "_" suffixed to current nickname
106 nick += '_' 106 nick += '_'
107 return self.clients[profile].join(room_jid, nick, history_options, password).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile': profile}, errbackArgs=[room_jid, nick, history_options, password, profile]) 107 return self.clients[profile].join(room_jid, nick, history_options, password).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile': profile}, errbackArgs=[room_jid, nick, history_options, password, profile])
108 108 mess = _("Error when joining the room %s" % room_jid.userhost())
109 mess = _("Error when joining the room")
110 error(mess) 109 error(mess)
111 self.host.bridge.newAlert(mess, _("Group chat error"), "ERROR", profile) 110 self.host.bridge.newAlert(mess, _("Group chat error"), "ERROR", profile)
112 raise failure 111 raise failure
113 112
114 def getRoomsJoined(self, profile_key='@DEFAULT@'): 113 def getRoomsJoined(self, profile_key='@DEFAULT@'):
145 profile = self.host.memory.getProfileName(profile_key) 144 profile = self.host.memory.getProfileName(profile_key)
146 if not self.__check_profile(profile): 145 if not self.__check_profile(profile):
147 return [] 146 return []
148 return self.clients[profile].rec_subjects.values() 147 return self.clients[profile].rec_subjects.values()
149 148
150 def getUniqueName(self, profile_key='@DEFAULT@'): 149 def getMUCService(self, profile):
151 """Return unique name for room, avoiding collision""" 150 """Return the MUC service or None"""
151 muc_service = None
152 for service in self.host.memory.getServerServiceEntities("conference", "text", profile):
153 if not ".irc." in service.userhost():
154 #FIXME:
155 #This awfull ugly hack is here to avoid an issue with openfire: the irc gateway
156 #use "conference/text" identity (instead of "conference/irc"), there is certainly a better way
157 #to manage this, but this hack fill do it for test purpose
158 muc_service = service
159 break
160 return muc_service
161
162 def getUniqueName(self, muc_service="", profile_key='@DEFAULT@'):
163 """Return unique name for room, avoiding collision
164 @param muc_service: leave empty string to use the default service
165 @return: unique room userhost, or '' if an error occured.
166 """
152 #TODO: we should use #RFC-0045 10.1.4 when available here 167 #TODO: we should use #RFC-0045 10.1.4 when available here
153 #TODO: we should be able to select the MUC service here 168 profile = self.host.memory.getProfileName(profile_key)
154 return uuid.uuid1() 169 if not profile:
170 error(_("Unknown profile"))
171 return ""
172 room_name = uuid.uuid1()
173 print "\n\n===> room_name:", room_name
174 if muc_service == "":
175 muc_service = self.getMUCService(profile)
176 if not muc_service:
177 error(_("Can't find a MUC service"))
178 return ""
179 muc_service = muc_service.userhost()
180 return "%s@%s" % (room_name, muc_service)
155 181
156 def join(self, room_jid, nick, options, profile_key='@DEFAULT@'): 182 def join(self, room_jid, nick, options, profile_key='@DEFAULT@'):
157 def _errDeferred(exc_obj=Exception, txt='Error while joining room'): 183 def _errDeferred(exc_obj=Exception, txt='Error while joining room'):
158 d = defer.Deferred() 184 d = defer.Deferred()
159 d.errback(exc_obj(txt)) 185 d.errback(exc_obj(txt))
171 password = options["password"] if "password" in options else None 197 password = options["password"] if "password" in options else None
172 198
173 return self.clients[profile].join(room_jid, nick, history_options, password).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile': profile}, errbackArgs=[room_jid, nick, history_options, password, profile]) 199 return self.clients[profile].join(room_jid, nick, history_options, password).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile': profile}, errbackArgs=[room_jid, nick, history_options, password, profile])
174 200
175 def _join(self, room_jid_s, nick, options={}, profile_key='@DEFAULT@'): 201 def _join(self, room_jid_s, nick, options={}, profile_key='@DEFAULT@'):
176 """join method used by bridge: use the _join method, but doesn't return any deferred""" 202 """join method used by bridge: use the _join method, but doesn't return any deferred
203 @return the room userhost (given value or unique generated name)
204 """
177 profile = self.host.memory.getProfileName(profile_key) 205 profile = self.host.memory.getProfileName(profile_key)
178 if not self.__check_profile(profile): 206 if not self.__check_profile(profile):
179 return 207 return
208 if room_jid_s == "":
209 room_jid_s = self.getUniqueName(profile_key=profile_key)
180 try: 210 try:
181 room_jid = jid.JID(room_jid_s) 211 room_jid = jid.JID(room_jid_s)
182 except: 212 except:
183 mess = _("Invalid room jid: %s") % room_jid_s 213 mess = _("Invalid room jid: %s") % room_jid_s
184 warning(mess) 214 warning(mess)
185 self.host.bridge.newAlert(mess, _("Group chat error"), "ERROR", profile) 215 self.host.bridge.newAlert(mess, _("Group chat error"), "ERROR", profile)
186 return 216 return
187 d = self.join(room_jid, nick, options, profile) 217 d = self.join(room_jid, nick, options, profile)
188 d.addErrback(lambda x: warning(_('Error while joining room'))) # TODO: error management + signal in bridge 218 d.addErrback(lambda x: warning(_('Error while joining room'))) # TODO: error management + signal in bridge
219 return room_jid_s
189 220
190 def nick(self, room_jid, nick, profile_key): 221 def nick(self, room_jid, nick, profile_key):
191 profile = self.host.memory.getProfileName(profile_key) 222 profile = self.host.memory.getProfileName(profile_key)
192 if not self.__check_profile(profile): 223 if not self.__check_profile(profile):
193 raise exceptions.UnknownProfileError("Unknown or disconnected profile") 224 raise exceptions.UnknownProfileError("Unknown or disconnected profile")