Mercurial > libervia-backend
comparison src/plugins/plugin_xep_0045.py @ 1358:bf3f669a6052 frontends_multi_profiles
plugins XEP-0045, XEP-0249, parrot: use JID instead of unicode in many methods + class attributes
author | souliane <souliane@mailoo.org> |
---|---|
date | Wed, 11 Mar 2015 12:35:21 +0100 |
parents | c01cbd8fc8dd |
children | 876c9fbd0b3d |
comparison
equal
deleted
inserted
replaced
1357:f296a54af386 | 1358:bf3f669a6052 |
---|---|
115 @return: the profile name | 115 @return: the profile name |
116 """ | 116 """ |
117 profile = self.host.memory.getProfileName(profile_key) | 117 profile = self.host.memory.getProfileName(profile_key) |
118 if not self.checkClient(profile): | 118 if not self.checkClient(profile): |
119 raise exceptions.ProfileUnknownError("Unknown or disconnected profile") | 119 raise exceptions.ProfileUnknownError("Unknown or disconnected profile") |
120 if room_jid.userhost() not in self.clients[profile].joined_rooms: | 120 if room_jid not in self.clients[profile].joined_rooms: |
121 raise UnknownRoom("This room has not been joined") | 121 raise UnknownRoom("This room has not been joined") |
122 return profile | 122 return profile |
123 | 123 |
124 def __room_joined(self, room, profile): | 124 def __room_joined(self, room, profile): |
125 """Called when the user is in the requested room""" | 125 """Called when the user is in the requested room""" |
126 | 126 |
127 def _sendBridgeSignal(ignore=None): | 127 def _sendBridgeSignal(ignore=None): |
128 self.host.bridge.roomJoined(room.roomJID.userhost(), [user.nick for user in room.roster.values()], room.nick, profile) | 128 self.host.bridge.roomJoined(room.roomJID.userhost(), [user.nick for user in room.roster.values()], room.nick, profile) |
129 | 129 |
130 room_jid_s = room.roomJID.userhost() | 130 self.clients[profile].joined_rooms[room.roomJID] = room |
131 self.clients[profile].joined_rooms[room_jid_s] = room | |
132 if room.locked: | 131 if room.locked: |
133 #FIXME: the current behaviour is to create an instant room | 132 # FIXME: the current behaviour is to create an instant room |
134 #and send the signal only when the room is unlocked | 133 # and send the signal only when the room is unlocked |
135 #a proper configuration management should be done | 134 # a proper configuration management should be done |
136 print "room locked !" | 135 print "room locked !" |
137 self.clients[profile].configure(room.roomJID, {}).addCallbacks(_sendBridgeSignal, lambda x: log.error(_('Error while configuring the room'))) | 136 self.clients[profile].configure(room.roomJID, {}).addCallbacks(_sendBridgeSignal, lambda x: log.error(_('Error while configuring the room'))) |
138 else: | 137 else: |
139 _sendBridgeSignal() | 138 _sendBridgeSignal() |
140 return room | 139 return room |
162 return result | 161 return result |
163 for room in self.clients[profile].joined_rooms.values(): | 162 for room in self.clients[profile].joined_rooms.values(): |
164 result.append((room.roomJID.userhost(), [user.nick for user in room.roster.values()], room.nick)) | 163 result.append((room.roomJID.userhost(), [user.nick for user in room.roster.values()], room.nick)) |
165 return result | 164 return result |
166 | 165 |
167 def getRoomNick(self, room_jid_s, profile_key=C.PROF_KEY_NONE): | 166 def getRoomNick(self, room_jid, profile_key=C.PROF_KEY_NONE): |
168 """return nick used in room by user | 167 """return nick used in room by user |
169 | 168 |
170 @param room_jid_s: unicode room id | 169 @param room_jid (jid.JID): JID of the room |
171 @profile_key: profile | 170 @profile_key: profile |
172 @return: nick or empty string in case of error""" | 171 @return: nick or empty string in case of error""" |
173 profile = self.host.memory.getProfileName(profile_key) | 172 profile = self.host.memory.getProfileName(profile_key) |
174 if not self.checkClient(profile) or room_jid_s not in self.clients[profile].joined_rooms: | 173 if not self.checkClient(profile) or room_jid not in self.clients[profile].joined_rooms: |
175 return '' | 174 return '' |
176 return self.clients[profile].joined_rooms[room_jid_s].nick | 175 return self.clients[profile].joined_rooms[room_jid].nick |
177 | 176 |
178 def getRoomNickOfUser(self, room, user_jid, secure=True): | 177 def getRoomNickOfUser(self, room, user_jid, secure=True): |
179 """Returns the nick of the given user in the room. | 178 """Returns the nick of the given user in the room. |
180 | 179 |
181 @room: instance of wokkel.muc.Room | 180 @param room (wokkel.muc.Room): the room |
182 @user: JID or unicode (JID userhost). | 181 @param user (jid.JID): bare JID of the user |
183 @param secure: set to True for a secure check | 182 @param secure (bool): set to True for a secure check |
184 @return: the nick or None if the user didn't join the room. | 183 @return: unicode or None if the user didn't join the room. |
185 """ | 184 """ |
186 if not isinstance(user_jid, jid.JID): | |
187 user_jid = jid.JID(user_jid).userhostJID() | |
188 for user in room.roster.values(): | 185 for user in room.roster.values(): |
189 if user.entity is not None: | 186 if user.entity is not None: |
190 if user.entity.userhostJID() == user_jid.userhostJID(): | 187 if user.entity.userhostJID() == user_jid.userhostJID(): |
191 return user.nick | 188 return user.nick |
192 elif not secure: | 189 elif not secure: |
197 return None | 194 return None |
198 | 195 |
199 def getRoomNicksOfUsers(self, room, users=[], secure=True): | 196 def getRoomNicksOfUsers(self, room, users=[], secure=True): |
200 """Returns the nicks of the given users in the room. | 197 """Returns the nicks of the given users in the room. |
201 | 198 |
202 @room: instance of wokkel.muc.Room | 199 @param room (wokkel.muc.Room): the room |
203 @users: list of JID or unicode (JID userhost). | 200 @param users (list[jid.JID]): list of users |
204 @param secure: set to True for a secure check | 201 @param secure (True): set to True for a secure check |
205 @return: (x, y) with x a list containing the nicks of | 202 @return: a couple (x, y) with: |
206 the users who are in the room, and y the missing users. | 203 - x (list[unicode]): nicks of the users who are in the room |
204 - y (list[jid.JID]): JID of the missing users. | |
207 """ | 205 """ |
208 nicks = [] | 206 nicks = [] |
209 missing = [] | 207 missing = [] |
210 for user in users: | 208 for user in users: |
211 nick = self.getRoomNickOfUser(room, user, secure) | 209 nick = self.getRoomNickOfUser(room, user, secure) |
229 try: | 227 try: |
230 room_jid = jid.JID(menu_data['room_jid']) | 228 room_jid = jid.JID(menu_data['room_jid']) |
231 except KeyError: | 229 except KeyError: |
232 log.error(_("room_jid key is not present !")) | 230 log.error(_("room_jid key is not present !")) |
233 return defer.fail(exceptions.DataError) | 231 return defer.fail(exceptions.DataError) |
232 | |
234 def xmluiReceived(xmlui): | 233 def xmluiReceived(xmlui): |
235 return {"xmlui": xmlui.toXml()} | 234 return {"xmlui": xmlui.toXml()} |
236 return self.configureRoom(room_jid, profile).addCallback(xmluiReceived) | 235 return self.configureRoom(room_jid, profile).addCallback(xmluiReceived) |
237 | 236 |
238 def configureRoom(self, room_jid, profile_key=C.PROF_KEY_NONE): | 237 def configureRoom(self, room_jid, profile_key=C.PROF_KEY_NONE): |
275 return d | 274 return d |
276 | 275 |
277 def isNickInRoom(self, room_jid, nick, profile): | 276 def isNickInRoom(self, room_jid, nick, profile): |
278 """Tell if a nick is currently present in a room""" | 277 """Tell if a nick is currently present in a room""" |
279 profile = self.getProfileAssertInRoom(room_jid, profile) | 278 profile = self.getProfileAssertInRoom(room_jid, profile) |
280 return self.clients[profile].joined_rooms[room_jid.userhost()].inRoster(muc.User(nick)) | 279 return self.clients[profile].joined_rooms[room_jid].inRoster(muc.User(nick)) |
281 | 280 |
282 def getRoomsSubjects(self, profile_key=C.PROF_KEY_NONE): | 281 def getRoomsSubjects(self, profile_key=C.PROF_KEY_NONE): |
283 """Return received subjects of rooms""" | 282 """Return received subjects of rooms""" |
284 profile = self.host.memory.getProfileName(profile_key) | 283 profile = self.host.memory.getProfileName(profile_key) |
285 if not self.checkClient(profile): | 284 if not self.checkClient(profile): |
294 @param profile_key: %(doc_profile_key)s | 293 @param profile_key: %(doc_profile_key)s |
295 """ | 294 """ |
296 muc_service = None | 295 muc_service = None |
297 services = yield self.host.findServiceEntities("conference", "text", jid_, profile_key=profile_key) | 296 services = yield self.host.findServiceEntities("conference", "text", jid_, profile_key=profile_key) |
298 for service in services: | 297 for service in services: |
299 if not ".irc." in service.userhost(): | 298 if ".irc." not in service.userhost(): |
300 # FIXME: | 299 # FIXME: |
301 # This ugly hack is here to avoid an issue with openfire: the IRC gateway | 300 # This ugly hack is here to avoid an issue with openfire: the IRC gateway |
302 # use "conference/text" identity (instead of "conference/irc") | 301 # use "conference/text" identity (instead of "conference/irc") |
303 muc_service = service | 302 muc_service = service |
304 break | 303 break |
311 """Return unique name for a room, avoiding collision | 310 """Return unique name for a room, avoiding collision |
312 | 311 |
313 @param muc_service (jid.JID) : leave empty string to use the default service | 312 @param muc_service (jid.JID) : leave empty string to use the default service |
314 @return: jid.JID (unique room bare JID) | 313 @return: jid.JID (unique room bare JID) |
315 """ | 314 """ |
316 #TODO: we should use #RFC-0045 10.1.4 when available here | 315 # TODO: we should use #RFC-0045 10.1.4 when available here |
317 client = self.host.getClient(profile_key) | 316 client = self.host.getClient(profile_key) |
318 room_name = uuid.uuid1() | 317 room_name = uuid.uuid1() |
319 if muc_service is None: | 318 if muc_service is None: |
320 try: | 319 try: |
321 muc_service = client.muc_service | 320 muc_service = client.muc_service |
335 return d | 334 return d |
336 | 335 |
337 profile = self.host.memory.getProfileName(profile_key) | 336 profile = self.host.memory.getProfileName(profile_key) |
338 if not self.checkClient(profile): | 337 if not self.checkClient(profile): |
339 return _errDeferred() | 338 return _errDeferred() |
340 if room_jid.userhost() in self.clients[profile].joined_rooms: | 339 if room_jid in self.clients[profile].joined_rooms: |
341 log.warning(_('%(profile)s is already in room %(room_jid)s') % {'profile': profile, 'room_jid': room_jid.userhost()}) | 340 log.warning(_('%(profile)s is already in room %(room_jid)s') % {'profile': profile, 'room_jid': room_jid.userhost()}) |
342 return _errDeferred() | 341 return _errDeferred() |
343 log.info(_("[%(profile)s] is joining room %(room)s with nick %(nick)s") % {'profile': profile, 'room': room_jid.userhost(), 'nick': nick}) | 342 log.info(_("[%(profile)s] is joining room %(room)s with nick %(nick)s") % {'profile': profile, 'room': room_jid.userhost(), 'nick': nick}) |
344 | 343 |
345 if "history" in options: | 344 if "history" in options: |
470 if mess_data['type'] != "groupchat": | 469 if mess_data['type'] != "groupchat": |
471 self.host.plugins[C.TEXT_CMDS].feedBackWrongContext('join', 'groupchat', mess_data, profile) | 470 self.host.plugins[C.TEXT_CMDS].feedBackWrongContext('join', 'groupchat', mess_data, profile) |
472 return False | 471 return False |
473 | 472 |
474 if mess_data["unparsed"].strip(): | 473 if mess_data["unparsed"].strip(): |
475 room = self.host.plugins[C.TEXT_CMDS].getRoomJID(mess_data["unparsed"].strip(), mess_data["to"].host) | 474 room_jid = self.host.plugins[C.TEXT_CMDS].getRoomJID(mess_data["unparsed"].strip(), mess_data["to"].host) |
476 nick = (self.getRoomNick(mess_data["to"].userhost(), profile) or | 475 nick = (self.getRoomNick(room_jid, profile) or |
477 self.host.getClient(profile).jid.user) | 476 self.host.getClient(profile).jid.user) |
478 self.join(room, nick, {}, profile) | 477 self.join(room_jid, nick, {}, profile) |
479 | 478 |
480 return False | 479 return False |
481 | 480 |
482 def cmd_leave(self, mess_data, profile): | 481 def cmd_leave(self, mess_data, profile): |
483 """quit a room""" | 482 """quit a room""" |
629 | 628 |
630 def _whois(self, whois_msg, mess_data, target_jid, profile): | 629 def _whois(self, whois_msg, mess_data, target_jid, profile): |
631 """ Add MUC user information to whois """ | 630 """ Add MUC user information to whois """ |
632 if mess_data['type'] != "groupchat": | 631 if mess_data['type'] != "groupchat": |
633 return | 632 return |
634 if target_jid.userhost() not in self.clients[profile].joined_rooms: | 633 if target_jid.userhostJID() not in self.clients[profile].joined_rooms: |
635 log.warning(_("This room has not been joined")) | 634 log.warning(_("This room has not been joined")) |
636 return | 635 return |
637 user = self.clients[profile].joined_rooms[target_jid.userhost()].getUser(target_jid.resource) | 636 user = self.clients[profile].joined_rooms[target_jid.userhostJID()].getUser(target_jid.resource) |
638 whois_msg.append(_("Nickname: %s") % user.nick) | 637 whois_msg.append(_("Nickname: %s") % user.nick) |
639 if user.entity: | 638 if user.entity: |
640 whois_msg.append(_("Entity: %s") % user.entity) | 639 whois_msg.append(_("Entity: %s") % user.entity) |
641 if user.affiliation != 'none': | 640 if user.affiliation != 'none': |
642 whois_msg.append(_("Affiliation: %s") % user.affiliation) | 641 whois_msg.append(_("Affiliation: %s") % user.affiliation) |
648 whois_msg.append(_("Show: %s") % user.show) | 647 whois_msg.append(_("Show: %s") % user.show) |
649 | 648 |
650 def presenceTrigger(self, presence_elt, client): | 649 def presenceTrigger(self, presence_elt, client): |
651 # XXX: shouldn't it be done by the server ?!! | 650 # XXX: shouldn't it be done by the server ?!! |
652 muc_client = self.clients[client.profile] | 651 muc_client = self.clients[client.profile] |
653 for room_jid_s, room in muc_client.joined_rooms.items(): | 652 for room_jid, room in muc_client.joined_rooms.iteritems(): |
654 elt = copy.deepcopy(presence_elt) | 653 elt = copy.deepcopy(presence_elt) |
655 elt['to'] = room_jid_s + '/' + room.nick | 654 elt['to'] = room_jid.userhost() + '/' + room.nick |
656 client.presence.send(elt) | 655 client.presence.send(elt) |
657 return True | 656 return True |
658 | 657 |
659 | 658 |
660 class SatMUCClient (muc.MUCClient): | 659 class SatMUCClient (muc.MUCClient): |
661 #implements(iwokkel.IDisco) | 660 # implements(iwokkel.IDisco) |
662 | 661 |
663 def __init__(self, plugin_parent): | 662 def __init__(self, plugin_parent): |
664 self.plugin_parent = plugin_parent | 663 self.plugin_parent = plugin_parent |
665 self.host = plugin_parent.host | 664 self.host = plugin_parent.host |
666 muc.MUCClient.__init__(self) | 665 muc.MUCClient.__init__(self) |
667 self.joined_rooms = {} # FIXME: seem to do the same thing as MUCClient's _rooms attribute, must be removed | |
668 self.rec_subjects = {} | 666 self.rec_subjects = {} |
669 self.__changing_nicks = set() # used to keep trace of who is changing nick, | 667 self.__changing_nicks = set() # used to keep trace of who is changing nick, |
670 # and to discard userJoinedRoom signal in this case | 668 # and to discard userJoinedRoom signal in this case |
671 print "init SatMUCClient OK" | 669 print "init SatMUCClient OK" |
672 | 670 |
671 @property | |
672 def joined_rooms(self): | |
673 return self._rooms | |
674 | |
673 def subject(self, room, subject): | 675 def subject(self, room, subject): |
674 return muc.MUCClientProtocol.subject(self, room, subject) | 676 return muc.MUCClientProtocol.subject(self, room, subject) |
675 | 677 |
676 def unavailableReceived(self, presence): | 678 def unavailableReceived(self, presence): |
677 #XXX: we override this method to manage nickname change | 679 # XXX: we override this method to manage nickname change |
678 #TODO: feed this back to Wokkel | 680 # TODO: feed this back to Wokkel |
679 """ | 681 """ |
680 Unavailable presence was received. | 682 Unavailable presence was received. |
681 | 683 |
682 If this was received from a MUC room occupant JID, that occupant has | 684 If this was received from a MUC room occupant JID, that occupant has |
683 left the room. | 685 left the room. |
712 return | 714 return |
713 if user.nick == room.nick: | 715 if user.nick == room.nick: |
714 # we left the room | 716 # we left the room |
715 room_jid_s = room.roomJID.userhost() | 717 room_jid_s = room.roomJID.userhost() |
716 log.info(_("Room [%(room)s] left (%(profile)s))") % {"room": room_jid_s, | 718 log.info(_("Room [%(room)s] left (%(profile)s))") % {"room": room_jid_s, |
717 "profile": self.parent.profile}) | 719 "profile": self.parent.profile}) |
718 self.host.memory.delEntityCache(room.roomJID, profile_key=self.parent.profile) | 720 self.host.memory.delEntityCache(room.roomJID, profile_key=self.parent.profile) |
719 del self.plugin_parent.clients[self.parent.profile].joined_rooms[room_jid_s] | |
720 self.host.bridge.roomLeft(room.roomJID.userhost(), self.parent.profile) | 721 self.host.bridge.roomLeft(room.roomJID.userhost(), self.parent.profile) |
721 else: | 722 else: |
722 log.debug(_("user %(nick)s left room (%(room_id)s)") % {'nick': user.nick, 'room_id': room.occupantJID.userhost()}) | 723 log.debug(_("user %(nick)s left room (%(room_id)s)") % {'nick': user.nick, 'room_id': room.occupantJID.userhost()}) |
723 user_data = {'entity': user.entity.full() if user.entity else '', 'affiliation': user.affiliation, 'role': user.role} | 724 user_data = {'entity': user.entity.full() if user.entity else '', 'affiliation': user.affiliation, 'role': user.role} |
724 self.host.bridge.roomUserLeft(room.roomJID.userhost(), user.nick, user_data, self.parent.profile) | 725 self.host.bridge.roomUserLeft(room.roomJID.userhost(), user.nick, user_data, self.parent.profile) |
732 def receivedGroupChat(self, room, user, body): | 733 def receivedGroupChat(self, room, user, body): |
733 log.debug('receivedGroupChat: room=%s user=%s body=%s' % (room.roomJID.full(), user, body)) | 734 log.debug('receivedGroupChat: room=%s user=%s body=%s' % (room.roomJID.full(), user, body)) |
734 | 735 |
735 def receivedHistory(self, room, user, message): | 736 def receivedHistory(self, room, user, message): |
736 # http://xmpp.org/extensions/xep-0045.html#enter-history | 737 # http://xmpp.org/extensions/xep-0045.html#enter-history |
737 #log.debug('receivedHistory: room=%s user=%s body=%s' % (room.roomJID.full(), user, message)) | 738 # log.debug('receivedHistory: room=%s user=%s body=%s' % (room.roomJID.full(), user, message)) |
738 pass | 739 pass |
739 | 740 |
740 def receivedSubject(self, room, user, subject): | 741 def receivedSubject(self, room, user, subject): |
741 # http://xmpp.org/extensions/xep-0045.html#enter-subject | 742 # http://xmpp.org/extensions/xep-0045.html#enter-subject |
742 log.debug(_("New subject for room (%(room_id)s): %(subject)s") % {'room_id': room.roomJID.full(), 'subject': subject}) | 743 log.debug(_("New subject for room (%(room_id)s): %(subject)s") % {'room_id': room.roomJID.full(), 'subject': subject}) |