comparison src/plugins/plugin_xep_0045.py @ 405:10b4f577d0c0

MUC update to follow wokkel's MUC branch update - bridge methods have been updated (API change) - plugin XEP-0045 has been updated
author Goffi <goffi@goffi.org>
date Sat, 08 Oct 2011 18:43:17 +0200
parents f964dcec1611
children b03b38b20c18
comparison
equal deleted inserted replaced
404:6a1c6c41b91b 405:10b4f577d0c0
56 56
57 def __init__(self, host): 57 def __init__(self, host):
58 info(_("Plugin XEP_0045 initialization")) 58 info(_("Plugin XEP_0045 initialization"))
59 self.host = host 59 self.host = host
60 self.clients={} 60 self.clients={}
61 host.bridge.addMethod("joinMUC", ".plugin", in_sign='ssss', out_sign='', method=self._join) 61 host.bridge.addMethod("joinMUC", ".plugin", in_sign='ssa{ss}s', out_sign='', method=self._join)
62 host.bridge.addMethod("getRoomJoined", ".plugin", in_sign='s', out_sign='a(ssass)', method=self.getRoomJoined) 62 host.bridge.addMethod("getRoomsJoined", ".plugin", in_sign='s', out_sign='a(sass)', method=self.getRoomsJoined)
63 host.bridge.addMethod("getRoomSubjects", ".plugin", in_sign='s', out_sign='a(sss)', method=self.getRoomSubjects) 63 host.bridge.addMethod("getRoomsSubjectss", ".plugin", in_sign='s', out_sign='a(ss)', method=self.getRoomsSubjectss)
64 host.bridge.addMethod("getUniqueRoomName", ".plugin", in_sign='s', out_sign='s', method=self.getUniqueName) 64 host.bridge.addMethod("getUniqueRoomName", ".plugin", in_sign='s', out_sign='s', method=self.getUniqueName)
65 host.bridge.addSignal("roomJoined", ".plugin", signature='ssasss') #args: room_id, room_service, room_nicks, user_nick, profile 65 host.bridge.addSignal("roomJoined", ".plugin", signature='sasss') #args: room_jid, room_nicks, user_nick, profile
66 host.bridge.addSignal("roomUserJoined", ".plugin", signature='sssa{ss}s') #args: room_id, room_service, 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='sssa{ss}s') #args: room_id, room_service, 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("roomNewSubject", ".plugin", signature='ssss') #args: room_id, room_service, subject, profile 68 host.bridge.addSignal("roomNewSubject", ".plugin", signature='sss') #args: room_jid, subject, profile
69 69
70 def __check_profile(self, profile): 70 def __check_profile(self, profile):
71 """check if profile is used and connected 71 """check if profile is used and connected
72 if profile known but disconnected, remove it from known profiles 72 if profile known but disconnected, remove it from known profiles
73 @param profile: profile to check 73 @param profile: profile to check
80 return True 80 return True
81 81
82 def __room_joined(self, room, profile): 82 def __room_joined(self, room, profile):
83 """Called when the user is in the requested room""" 83 """Called when the user is in the requested room"""
84 def _sendBridgeSignal(ignore=None): 84 def _sendBridgeSignal(ignore=None):
85 self.host.bridge.roomJoined(room.roomIdentifier, room.service, [user.nick for user in room.roster.values()], room.nick, profile) 85 self.host.bridge.roomJoined(room.roomJID.userhost(), [user.nick for user in room.roster.values()], room.nick, profile)
86 86
87 room_jid = room.roomIdentifier+'@'+room.service 87 room_jid_s = room.roomJID.userhost()
88 self.clients[profile].joined_rooms[room_jid] = room 88 self.clients[profile].joined_rooms[room_jid_s] = room
89 if room.status == '201': 89 if room.status == '201':
90 #FIXME: the current behaviour is to create an instant room 90 #FIXME: the current behaviour is to create an instant room
91 #and send the signal only when the room is unlocked 91 #and send the signal only when the room is unlocked
92 #a proper configuration management should be done 92 #a proper configuration management should be done
93 #TODO: wokkel's muc currently doesn't manage correctly message from the room 93 self.clients[profile].configure(room_jid_s).addCallbacks(_sendBridgeSignal, lambda x: error(_('Error while configuring the room')))
94 # service (without resource) in room.getUser
95 self.clients[profile].configure(room_jid).addCallbacks(_sendBridgeSignal, lambda x: error(_('Error while configuring the room')))
96 else: 94 else:
97 _sendBridgeSignal() 95 _sendBridgeSignal()
98 return room 96 return room
99 97
100 98
102 """Called when something is going wrong when joining the room""" 100 """Called when something is going wrong when joining the room"""
103 mess = _("Error when joining the room") 101 mess = _("Error when joining the room")
104 error (mess) 102 error (mess)
105 self.host.bridge.newAlert(mess, _("Group chat error"), "ERROR", profile) 103 self.host.bridge.newAlert(mess, _("Group chat error"), "ERROR", profile)
106 104
107 def getRoomJoined(self, profile_key='@DEFAULT@'): 105 def getRoomsJoined(self, profile_key='@DEFAULT@'):
108 """Return room where user is""" 106 """Return room where user is"""
109 profile = self.host.memory.getProfileName(profile_key) 107 profile = self.host.memory.getProfileName(profile_key)
110 result = [] 108 result = []
111 if not self.__check_profile(profile): 109 if not self.__check_profile(profile):
112 return result 110 return result
113 for room in self.clients[profile].joined_rooms.values(): 111 for room in self.clients[profile].joined_rooms.values():
114 result.append((room.roomIdentifier, room.service, [user.nick for user in room.roster.values()], room.nick)) 112 result.append((room.roomJID.userhost(), [user.nick for user in room.roster.values()], room.nick))
115 return result 113 return result
116 114
117 def getRoomNick(self, room_jid, profile_key='@DEFAULT@'): 115 def getRoomNick(self, room_jid, profile_key='@DEFAULT@'):
118 """return nick used in room by user 116 """return nick used in room by user
119 @param room_jid: unicode room id 117 @param room_jid: unicode room id
123 if not self.__check_profile(profile) or not self.clients[profile].joined_rooms.has_key(room_jid): 121 if not self.__check_profile(profile) or not self.clients[profile].joined_rooms.has_key(room_jid):
124 return '' 122 return ''
125 return self.clients[profile].joined_rooms[room_jid].nick 123 return self.clients[profile].joined_rooms[room_jid].nick
126 124
127 125
128 def getRoomSubjects(self, profile_key='@DEFAULT@'): 126 def getRoomsSubjectss(self, profile_key='@DEFAULT@'):
129 """Return received subjects of rooms""" 127 """Return received subjects of rooms"""
130 profile = self.host.memory.getProfileName(profile_key) 128 profile = self.host.memory.getProfileName(profile_key)
131 if not self.__check_profile(profile): 129 if not self.__check_profile(profile):
132 return [] 130 return []
133 return self.clients[profile].rec_subjects.values() 131 return self.clients[profile].rec_subjects.values()
136 """Return unique name for room, avoiding collision""" 134 """Return unique name for room, avoiding collision"""
137 #TODO: we should use #RFC-0045 10.1.4 when available here 135 #TODO: we should use #RFC-0045 10.1.4 when available here
138 #TODO: we should be able to select the MUC service here 136 #TODO: we should be able to select the MUC service here
139 return uuid.uuid1() 137 return uuid.uuid1()
140 138
141 def join(self, service, roomId, nick, profile_key='@DEFAULT@'): 139 def join(self, room_jid, nick, options, profile_key='@DEFAULT@'):
142 def _errDeferred(exc_obj = Exception, txt='Error while joining room'): 140 def _errDeferred(exc_obj = Exception, txt='Error while joining room'):
143 d = defer.Deferred() 141 d = defer.Deferred()
144 d.errback(exc_obj(txt)) 142 d.errback(exc_obj(txt))
145 143
146 profile = self.host.memory.getProfileName(profile_key) 144 profile = self.host.memory.getProfileName(profile_key)
147 if not self.__check_profile(profile): 145 if not self.__check_profile(profile):
148 return _errDeferred() 146 return _errDeferred()
149 room_jid = roomId+'@'+service 147 if self.clients[profile].joined_rooms.has_key(room_jid.userhost()):
150 if self.clients[profile].joined_rooms.has_key(room_jid): 148 warning(_('%(profile)s is already in room %(room_jid)s') % {'profile':profile, 'room_jid':room_jid.userhost()})
151 warning(_('%(profile)s is already in room %(room_jid)s') % {'profile':profile, 'room_jid':room_jid})
152 return _errDeferred() 149 return _errDeferred()
153 info (_("[%(profile)s] is joining room %(room)s with nick %(nick)s") % {'profile':profile,'room':roomId+'@'+service, 'nick':nick}) 150 info (_("[%(profile)s] is joining room %(room)s with nick %(nick)s") % {'profile':profile,'room':room_jid.userhost(), 'nick':nick})
154 try: 151
155 return self.clients[profile].join(service, roomId, nick).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile':profile}, errbackKeywords={'profile':profile}) 152 history_options = options["history"] == "True" if options.has_key("history") else None
156 except: 153 password = options["password"] if options.has_key("password") else None
157 #XXX: this is a ugly workaround as MUCClient thrown an error if there is invalid chars in the room jid (like with the default string) 154
158 #FIXME: must be removed when MUCClient manage this better 155 return self.clients[profile].join(room_jid, nick, history_options, password).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile':profile}, errbackKeywords={'profile':profile})
159 d = _errDeferred(txt="ugly workaround") 156
160 d.addErrback(self.__err_joining_room, profile) 157 def _join(self, room_jid, nick, options={}, profile_key='@DEFAULT@'):
161 return d
162
163 def _join(self, service, roomId, nick, profile_key='@DEFAULT@'):
164 """join method used by bridge: use the _join method, but doesn't return any deferred""" 158 """join method used by bridge: use the _join method, but doesn't return any deferred"""
165 d = self.join(service, roomId, nick, profile_key) 159 d = self.join(jid.JID(room_jid), nick, options, profile_key)
166 d.addErrback(lambda x: warning(_('Error while joining room'))) #TODO: error management + signal in bridge 160 d.addErrback(lambda x: warning(_('Error while joining room'))) #TODO: error management + signal in bridge
167 161
168 def getHandler(self, profile): 162 def getHandler(self, profile):
169 self.clients[profile] = SatMUCClient(self) 163 self.clients[profile] = SatMUCClient(self)
170 return self.clients[profile] 164 return self.clients[profile]
187 181
188 def userJoinedRoom(self, room, user): 182 def userJoinedRoom(self, room, user):
189 debug (_("user %(nick)s has joined room (%(room_id)s)") % {'nick':user.nick, 'room_id':room.occupantJID.userhost()}) 183 debug (_("user %(nick)s has joined room (%(room_id)s)") % {'nick':user.nick, 'room_id':room.occupantJID.userhost()})
190 if not self.host.trigger.point("MUC user joined", room, user, self.parent.profile): 184 if not self.host.trigger.point("MUC user joined", room, user, self.parent.profile):
191 return 185 return
192 user_data={'entity':user.entity or '', 'affiliation':user.affiliation, 'role':user.role} 186 user_data={'entity':user.entity.full() if user.entity else '', 'affiliation':user.affiliation, 'role':user.role}
193 self.host.bridge.roomUserJoined(room.roomIdentifier, room.service, user.nick, user_data, self.parent.profile) 187 self.host.bridge.roomUserJoined(room.roomJID.userhost(), user.nick, user_data, self.parent.profile)
194 188
195 def userLeftRoom(self, room, user): 189 def userLeftRoom(self, room, user):
196 debug (_("user %(nick)s left room (%(room_id)s)") % {'nick':user.nick, 'room_id':room.occupantJID.userhost()}) 190 debug (_("user %(nick)s left room (%(room_id)s)") % {'nick':user.nick, 'room_id':room.occupantJID.userhost()})
197 user_data={'entity':user.entity or '', 'affiliation':user.affiliation, 'role':user.role} 191 user_data={'entity':user.entity.full() if user.entity else '', 'affiliation':user.affiliation, 'role':user.role}
198 self.host.bridge.roomUserLeft(room.roomIdentifier, room.service, user.nick, user_data, self.parent.profile) 192 self.host.bridge.roomUserLeft(room.rooJID.userhost(), user.nick, user_data, self.parent.profile)
199 193
200 def userUpdatedStatus(self, room, user, show, status): 194 def userUpdatedStatus(self, room, user, show, status):
201 print("FIXME: MUC status not managed yet") 195 print("FIXME: MUC status not managed yet")
202 #FIXME: gof 196 #FIXME: gof
203 197
204 def receivedSubject(self, occupantJID, subject): 198 def receivedSubject(self, room, user, subject):
205 room = self._getRoom(occupantJID) 199 debug (_("New subject for room (%(room_id)s): %(subject)s") % {'room_id':room.roomJID.full(),'subject':subject})
206 debug (_("New subject for room (%(room_id)s): %(subject)s") % {'room_id':room.occupantJID.userhost(),'subject':subject}) 200 self.rec_subjects[room.roomJID.userhost()] = (room.roomJID.userhost(), subject)
207 room_jid = room.roomIdentifier+'@'+room.service 201 self.host.bridge.roomNewSubject(room.roomJID.userhost(), subject, self.parent.profile)
208 self.rec_subjects[room_jid] = (room.roomIdentifier, room.service, subject)
209 self.host.bridge.roomNewSubject(room.roomIdentifier, room.service, subject, self.parent.profile)
210 202
211 #def connectionInitialized(self): 203 #def connectionInitialized(self):
212 #pass 204 #pass
213 205
214 #def getDiscoInfo(self, requestor, target, nodeIdentifier=''): 206 #def getDiscoInfo(self, requestor, target, nodeIdentifier=''):