comparison src/plugins/plugin_xep_0045.py @ 1083:e8731b02f5ea

plugin XEP-0045: small refactorization + clean on profile's disconnection
author souliane <souliane@mailoo.org>
date Mon, 23 Jun 2014 16:07:13 +0200
parents 246712d2e7bc
children 4286a19e9e8a
comparison
equal deleted inserted replaced
1082:246712d2e7bc 1083:e8731b02f5ea
88 def assign_service(service): 88 def assign_service(service):
89 client = self.host.getClient(profile) 89 client = self.host.getClient(profile)
90 client.muc_service = service 90 client.muc_service = service
91 return self.getMUCService(profile_key=profile).addCallback(assign_service) 91 return self.getMUCService(profile_key=profile).addCallback(assign_service)
92 92
93 def __check_profile(self, profile): 93 def checkClient(self, profile):
94 """check if profile is used and connected 94 """Check if the profile is connected and has used the MUC feature.
95 95
96 if profile known but disconnected, remove it from known profiles 96 If profile was using MUC feature but is now disconnected, remove it from the client list.
97 @param profile: profile to check 97 @param profile: profile to check
98 @return: True if the profile is known and connected, else False""" 98 @return: True if the profile is connected and has used the MUC feature, else False"""
99 if not profile or profile not in self.clients or not self.host.isConnected(profile): 99 if not profile or profile not in self.clients or not self.host.isConnected(profile):
100 log.error(_('Unknown or disconnected profile (%s)') % profile) 100 log.error(_('Unknown or disconnected profile (%s)') % profile)
101 if profile in self.clients: 101 if profile in self.clients:
102 del self.clients[profile] 102 del self.clients[profile]
103 return False 103 return False
104 return True 104 return True
105
106 def getProfileAssertInRoom(self, room_jid, profile_key):
107 """Retrieve the profile name, assert that it's connected and participating in the given room.
108
109 @param room_jid (JID): room JID
110 @param profile_key (str): %(doc_profile_key)
111 @return: the profile name
112 """
113 profile = self.host.memory.getProfileName(profile_key)
114 if not self.checkClient(profile):
115 raise exceptions.ProfileUnknownError("Unknown or disconnected profile")
116 if room_jid.userhost() not in self.clients[profile].joined_rooms:
117 raise UnknownRoom("This room has not been joined")
118 return profile
105 119
106 def __room_joined(self, room, profile): 120 def __room_joined(self, room, profile):
107 """Called when the user is in the requested room""" 121 """Called when the user is in the requested room"""
108 122
109 def _sendBridgeSignal(ignore=None): 123 def _sendBridgeSignal(ignore=None):
139 153
140 def getRoomsJoined(self, profile_key=C.PROF_KEY_NONE): 154 def getRoomsJoined(self, profile_key=C.PROF_KEY_NONE):
141 """Return room where user is""" 155 """Return room where user is"""
142 profile = self.host.memory.getProfileName(profile_key) 156 profile = self.host.memory.getProfileName(profile_key)
143 result = [] 157 result = []
144 if not self.__check_profile(profile): 158 if not self.checkClient(profile):
145 return result 159 return result
146 for room in self.clients[profile].joined_rooms.values(): 160 for room in self.clients[profile].joined_rooms.values():
147 result.append((room.roomJID.userhost(), [user.nick for user in room.roster.values()], room.nick)) 161 result.append((room.roomJID.userhost(), [user.nick for user in room.roster.values()], room.nick))
148 return result 162 return result
149 163
152 166
153 @param room_jid_s: unicode room id 167 @param room_jid_s: unicode room id
154 @profile_key: profile 168 @profile_key: profile
155 @return: nick or empty string in case of error""" 169 @return: nick or empty string in case of error"""
156 profile = self.host.memory.getProfileName(profile_key) 170 profile = self.host.memory.getProfileName(profile_key)
157 if not self.__check_profile(profile) or room_jid_s not in self.clients[profile].joined_rooms: 171 if not self.checkClient(profile) or room_jid_s not in self.clients[profile].joined_rooms:
158 return '' 172 return ''
159 return self.clients[profile].joined_rooms[room_jid_s].nick 173 return self.clients[profile].joined_rooms[room_jid_s].nick
160 174
161 def getRoomNickOfUser(self, room, user_jid, secure=True): 175 def getRoomNickOfUser(self, room, user_jid, secure=True):
162 """Returns the nick of the given user in the room. 176 """Returns the nick of the given user in the room.
208 222
209 @param room: jid of the room to configure 223 @param room: jid of the room to configure
210 @param profile_key: %(doc_profile_key)s 224 @param profile_key: %(doc_profile_key)s
211 @return: configuration form as XMLUI 225 @return: configuration form as XMLUI
212 """ 226 """
213 profile = self.host.memory.getProfileName(profile_key) 227 profile = self.getProfileAssertInRoom(room_jid, profile_key)
214 if not self.__check_profile(profile):
215 raise exceptions.ProfileUnknownError("Unknown or disconnected profile")
216 if room_jid.userhost() not in self.clients[profile].joined_rooms:
217 raise UnknownRoom(D_("This room has not been joined"))
218 228
219 def config2XMLUI(result): 229 def config2XMLUI(result):
220 if not result: 230 if not result:
221 return "" 231 return ""
222 session_id, session_data = self._sessions.newSession(profile=profile) 232 session_id, session_data = self._sessions.newSession(profile=profile)
246 del self._sessions[raw_data["session_id"]] 256 del self._sessions[raw_data["session_id"]]
247 return d 257 return d
248 258
249 def isNickInRoom(self, room_jid, nick, profile): 259 def isNickInRoom(self, room_jid, nick, profile):
250 """Tell if a nick is currently present in a room""" 260 """Tell if a nick is currently present in a room"""
251 profile = self.host.memory.getProfileName(profile) 261 profile = self.getProfileAssertInRoom(room_jid, profile)
252 if not self.__check_profile(profile):
253 raise exceptions.ProfileUnknownError("Unknown or disconnected profile")
254 if room_jid.userhost() not in self.clients[profile].joined_rooms:
255 raise UnknownRoom("This room has not been joined")
256 return self.clients[profile].joined_rooms[room_jid.userhost()].inRoster(muc.User(nick)) 262 return self.clients[profile].joined_rooms[room_jid.userhost()].inRoster(muc.User(nick))
257 263
258 def getRoomsSubjects(self, profile_key=C.PROF_KEY_NONE): 264 def getRoomsSubjects(self, profile_key=C.PROF_KEY_NONE):
259 """Return received subjects of rooms""" 265 """Return received subjects of rooms"""
260 profile = self.host.memory.getProfileName(profile_key) 266 profile = self.host.memory.getProfileName(profile_key)
261 if not self.__check_profile(profile): 267 if not self.checkClient(profile):
262 return [] 268 return []
263 return self.clients[profile].rec_subjects.values() 269 return self.clients[profile].rec_subjects.values()
264 270
265 @defer.inlineCallbacks 271 @defer.inlineCallbacks
266 def getMUCService(self, jid_=None, profile_key=C.PROF_KEY_NONE): 272 def getMUCService(self, jid_=None, profile_key=C.PROF_KEY_NONE):
309 d = defer.Deferred() 315 d = defer.Deferred()
310 d.errback(exc_obj(txt)) 316 d.errback(exc_obj(txt))
311 return d 317 return d
312 318
313 profile = self.host.memory.getProfileName(profile_key) 319 profile = self.host.memory.getProfileName(profile_key)
314 if not self.__check_profile(profile): 320 if not self.checkClient(profile):
315 return _errDeferred() 321 return _errDeferred()
316 if room_jid.userhost() in self.clients[profile].joined_rooms: 322 if room_jid.userhost() in self.clients[profile].joined_rooms:
317 log.warning(_('%(profile)s is already in room %(room_jid)s') % {'profile': profile, 'room_jid': room_jid.userhost()}) 323 log.warning(_('%(profile)s is already in room %(room_jid)s') % {'profile': profile, 'room_jid': room_jid.userhost()})
318 return _errDeferred() 324 return _errDeferred()
319 log.info(_("[%(profile)s] is joining room %(room)s with nick %(nick)s") % {'profile': profile, 'room': room_jid.userhost(), 'nick': nick}) 325 log.info(_("[%(profile)s] is joining room %(room)s with nick %(nick)s") % {'profile': profile, 'room': room_jid.userhost(), 'nick': nick})
330 def _join(self, room_jid_s, nick, options={}, profile_key=C.PROF_KEY_NONE): 336 def _join(self, room_jid_s, nick, options={}, profile_key=C.PROF_KEY_NONE):
331 """join method used by bridge: use the join method, but doesn't return any deferred 337 """join method used by bridge: use the join method, but doesn't return any deferred
332 @return the room userhost (given value or unique generated name) 338 @return the room userhost (given value or unique generated name)
333 """ 339 """
334 profile = self.host.memory.getProfileName(profile_key) 340 profile = self.host.memory.getProfileName(profile_key)
335 if not self.__check_profile(profile): 341 if not self.checkClient(profile):
336 return 342 return
337 if room_jid_s == "": 343 if room_jid_s == "":
338 room_jid_s = self.getUniqueName(profile_key=profile_key) 344 room_jid_s = self.getUniqueName(profile_key=profile_key)
339 try: 345 try:
340 room_jid = jid.JID(room_jid_s) 346 room_jid = jid.JID(room_jid_s)
346 self.join(room_jid, nick, options, profile) 352 self.join(room_jid, nick, options, profile)
347 # TODO: error management + signal in bridge 353 # TODO: error management + signal in bridge
348 return room_jid_s 354 return room_jid_s
349 355
350 def nick(self, room_jid, nick, profile_key): 356 def nick(self, room_jid, nick, profile_key):
351 profile = self.host.memory.getProfileName(profile_key) 357 profile = self.getProfileAssertInRoom(room_jid, profile_key)
352 if not self.__check_profile(profile):
353 raise exceptions.ProfileUnknownError("Unknown or disconnected profile")
354 if room_jid.userhost() not in self.clients[profile].joined_rooms:
355 raise UnknownRoom("This room has not been joined")
356 return self.clients[profile].nick(room_jid, nick) 358 return self.clients[profile].nick(room_jid, nick)
357 359
358 def leave(self, room_jid, profile_key): 360 def leave(self, room_jid, profile_key):
359 profile = self.host.memory.getProfileName(profile_key) 361 profile = self.getProfileAssertInRoom(room_jid, profile_key)
360 if not self.__check_profile(profile):
361 raise exceptions.ProfileUnknownError("Unknown or disconnected profile")
362 if room_jid.userhost() not in self.clients[profile].joined_rooms:
363 raise UnknownRoom("This room has not been joined")
364 return self.clients[profile].leave(room_jid) 362 return self.clients[profile].leave(room_jid)
365 363
366 def subject(self, room_jid, subject, profile_key): 364 def subject(self, room_jid, subject, profile_key):
367 profile = self.host.memory.getProfileName(profile_key) 365 profile = self.getProfileAssertInRoom(room_jid, profile_key)
368 if not self.__check_profile(profile):
369 raise exceptions.ProfileUnknownError("Unknown or disconnected profile")
370 if room_jid.userhost() not in self.clients[profile].joined_rooms:
371 raise UnknownRoom("This room has not been joined")
372 return self.clients[profile].subject(room_jid, subject) 366 return self.clients[profile].subject(room_jid, subject)
373 367
374 def mucNick(self, room_jid_s, nick, profile_key=C.PROF_KEY_NONE): 368 def mucNick(self, room_jid_s, nick, profile_key=C.PROF_KEY_NONE):
375 """Change nickname in a room""" 369 """Change nickname in a room"""
376 return self.nick(jid.JID(room_jid_s), nick, profile_key) 370 return self.nick(jid.JID(room_jid_s), nick, profile_key)
380 return self.leave(jid.JID(room_jid_s), profile_key) 374 return self.leave(jid.JID(room_jid_s), profile_key)
381 375
382 def getHandler(self, profile): 376 def getHandler(self, profile):
383 self.clients[profile] = SatMUCClient(self) 377 self.clients[profile] = SatMUCClient(self)
384 return self.clients[profile] 378 return self.clients[profile]
379
380 def profileDisconnected(self, profile):
381 try:
382 del self.clients[profile]
383 except KeyError:
384 pass
385 385
386 def kick(self, nick, room_jid, options={}, profile_key=C.PROF_KEY_NONE): 386 def kick(self, nick, room_jid, options={}, profile_key=C.PROF_KEY_NONE):
387 """ 387 """
388 Kick a participant from the room 388 Kick a participant from the room
389 @param nick (str): nick of the user to kick 389 @param nick (str): nick of the user to kick
390 @param room_jid_s (JID): jid of the room 390 @param room_jid_s (JID): jid of the room
391 @param options (dict): attribute with extra info (reason, password) as in #XEP-0045 391 @param options (dict): attribute with extra info (reason, password) as in #XEP-0045
392 @param profile_key (str): %(doc_profile_key)s 392 @param profile_key (str): %(doc_profile_key)s
393 """ 393 """
394 profile = self.host.memory.getProfileName(profile_key) 394 profile = self.getProfileAssertInRoom(room_jid, profile_key)
395 if not self.__check_profile(profile):
396 raise exceptions.ProfileUnknownError("Unknown or disconnected profile")
397 if room_jid.userhost() not in self.clients[profile].joined_rooms:
398 raise UnknownRoom("This room has not been joined")
399 return self.clients[profile].kick(room_jid, nick, reason=options.get('reason', None)) 395 return self.clients[profile].kick(room_jid, nick, reason=options.get('reason', None))
400 396
401 def ban(self, entity_jid, room_jid, options={}, profile_key=C.PROF_KEY_NONE): 397 def ban(self, entity_jid, room_jid, options={}, profile_key=C.PROF_KEY_NONE):
402 """ 398 """
403 Ban an entity from the room 399 Ban an entity from the room
406 @param options: attribute with extra info (reason, password) as in #XEP-0045 402 @param options: attribute with extra info (reason, password) as in #XEP-0045
407 @param profile_key (str): %(doc_profile_key)s 403 @param profile_key (str): %(doc_profile_key)s
408 """ 404 """
409 assert(not entity_jid.resource) 405 assert(not entity_jid.resource)
410 assert(not room_jid.resource) 406 assert(not room_jid.resource)
411 profile = self.host.memory.getProfileName(profile_key) 407 profile = self.getProfileAssertInRoom(room_jid, profile_key)
412 if not self.__check_profile(profile):
413 raise exceptions.ProfileUnknownError("Unknown or disconnected profile")
414 if room_jid.userhost() not in self.clients[profile].joined_rooms:
415 raise UnknownRoom("This room has not been joined")
416 return self.clients[profile].ban(room_jid, entity_jid, reason=options.get('reason', None)) 408 return self.clients[profile].ban(room_jid, entity_jid, reason=options.get('reason', None))
417 409
418 def affiliate(self, entity_jid, room_jid, options=None, profile_key=C.PROF_KEY_NONE): 410 def affiliate(self, entity_jid, room_jid, options=None, profile_key=C.PROF_KEY_NONE):
419 """ 411 """
420 Change the affiliation of an entity 412 Change the affiliation of an entity
424 @param profile_key (str): %(doc_profile_key)s 416 @param profile_key (str): %(doc_profile_key)s
425 """ 417 """
426 assert(not entity_jid.resource) 418 assert(not entity_jid.resource)
427 assert(not room_jid.resource) 419 assert(not room_jid.resource)
428 assert('affiliation' in options) 420 assert('affiliation' in options)
429 profile = self.host.memory.getProfileName(profile_key) 421 profile = self.getProfileAssertInRoom(room_jid, profile_key)
430 if not self.__check_profile(profile):
431 raise exceptions.ProfileUnknownError("Unknown or disconnected profile")
432 if room_jid.userhost() not in self.clients[profile].joined_rooms:
433 raise UnknownRoom("This room has not been joined")
434 # TODO: handles reason and nick 422 # TODO: handles reason and nick
435 return self.clients[profile].modifyAffiliationList(room_jid, [entity_jid], options['affiliation']) 423 return self.clients[profile].modifyAffiliationList(room_jid, [entity_jid], options['affiliation'])
436 424
437 # Text commands # 425 # Text commands #
438 426
624 return 612 return
625 user = self.clients[profile].joined_rooms[target_jid.userhost()].getUser(target_jid.resource) 613 user = self.clients[profile].joined_rooms[target_jid.userhost()].getUser(target_jid.resource)
626 whois_msg.append(_("Nickname: %s") % user.nick) 614 whois_msg.append(_("Nickname: %s") % user.nick)
627 if user.entity: 615 if user.entity:
628 whois_msg.append(_("Entity: %s") % user.entity) 616 whois_msg.append(_("Entity: %s") % user.entity)
629 if user.affiliation!='none': 617 if user.affiliation != 'none':
630 whois_msg.append(_("Affiliation: %s") % user.affiliation) 618 whois_msg.append(_("Affiliation: %s") % user.affiliation)
631 if user.role!='none': 619 if user.role != 'none':
632 whois_msg.append(_("Role: %s") % user.role) 620 whois_msg.append(_("Role: %s") % user.role)
633 if user.status: 621 if user.status:
634 whois_msg.append(_("Status: %s") % user.status) 622 whois_msg.append(_("Status: %s") % user.status)
635 if user.show: 623 if user.show:
636 whois_msg.append(_("Show: %s") % user.show) 624 whois_msg.append(_("Show: %s") % user.show)
644 self.host = plugin_parent.host 632 self.host = plugin_parent.host
645 muc.MUCClient.__init__(self) 633 muc.MUCClient.__init__(self)
646 self.joined_rooms = {} # FIXME: seem to do the same thing as MUCClient's _rooms attribute, must be removed 634 self.joined_rooms = {} # FIXME: seem to do the same thing as MUCClient's _rooms attribute, must be removed
647 self.rec_subjects = {} 635 self.rec_subjects = {}
648 self.__changing_nicks = set() # used to keep trace of who is changing nick, 636 self.__changing_nicks = set() # used to keep trace of who is changing nick,
649 # and to discard userJoinedRoom signal in this case 637 # and to discard userJoinedRoom signal in this case
650 print "init SatMUCClient OK" 638 print "init SatMUCClient OK"
651 639
652 def subject(self, room, subject): 640 def subject(self, room, subject):
653 return muc.MUCClientProtocol.subject(self, room, subject) 641 return muc.MUCClientProtocol.subject(self, room, subject)
654 642