Ignore:
Timestamp:
Aug 15, 2011, 9:35:16 AM (11 years ago)
Author:
Ralph Meijer <ralphm@…>
Branch:
wokkel-muc-client-support-24
Message:

Redo admin requests using generic.Request.

This changes all role and affiliation management functionality to use a
subclass of generic.Request.

The methods for retrieving affiliation or role lists now return lists of
AdminItems, instead of modifying a Room instance and returning that. This
is because affiliation changes can also be done when not in the room.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wokkel/muc.py

    r149 r150  
    107107
    108108
    109 class AdminRequest(xmlstream.IQ):
    110     """
    111     A basic admin iq request.
    112 
    113     @ivar method: Type attribute of the IQ request. Either C{'set'} or C{'get'}
    114     @type method: C{str}
    115     """
    116 
    117     def __init__(self, xs, method='get'):
    118         xmlstream.IQ.__init__(self, xs, method)
    119         q = self.addElement((NS_MUC_ADMIN, 'query'))
     109class AdminItem(object):
     110    """
     111    Item representing role and/or affiliation for admin request.
     112    """
     113
     114    def __init__(self, affiliation=None, role=None, entity=None, nick=None,
     115                       reason=None):
     116        self.affiliation = affiliation
     117        self.role = role
     118        self.entity = entity
     119        self.nick = nick
     120        self.reason = reason
     121
     122
     123    def toElement(self):
     124        element = domish.Element((NS_MUC_ADMIN, 'item'))
     125
     126        if self.entity:
     127            element['jid'] = self.entity.full()
     128
     129        if self.nick:
     130            element['nick'] = self.nick
     131
     132        if self.affiliation:
     133            element['affiliation'] = self.affiliation
     134
     135        if self.role:
     136            element['role'] = self.role
     137
     138        if self.reason:
     139            element.addElement('reason', content=self.reason)
     140
     141        return element
     142
     143
     144    @classmethod
     145    def fromElement(Class, element):
     146        item = Class()
     147
     148        if element.hasAttribute('jid'):
     149            item.entity = jid.JID(element['jid'])
     150
     151        item.nick = element.getAttribute('nick')
     152        item.affiliation = element.getAttribute('affiliation')
     153        item.role = element.getAttribute('role')
     154
     155        for child in element.elements(NS_MUC_ADMIN, 'reason'):
     156            item.reason = unicode(child)
     157
     158        return item
     159
     160
     161
     162class AdminStanza(generic.Request):
     163    """
     164    An admin request or response.
     165    """
     166
     167    childParsers = {(NS_MUC_ADMIN, 'query'): '_childParser_query'}
     168
     169    def toElement(self):
     170        element = generic.Request.toElement(self)
     171        element.addElement((NS_MUC_ADMIN, 'query'))
     172
     173        if self.items:
     174            for item in self.items:
     175                element.query.addChild(item.toElement())
     176
     177        return element
     178
     179
     180    def _childParser_query(self, element):
     181        self.items = []
     182        for child in element.elements(NS_MUC_ADMIN, 'item'):
     183            self.items.append(AdminItem.fromElement(child))
    120184
    121185
     
    161225
    162226        return element
    163 
    164 
    165 
    166 class AffiliationRequest(AdminRequest):
    167     """
    168     Register room request.
    169 
    170     @ivar method: Type attribute of the IQ request. Either C{'set'} or C{'get'}
    171     @type method: C{str}
    172 
    173     @ivar affiliation: The affiliation type to send to room.
    174     @type affiliation: C{str}
    175     """
    176 
    177     def __init__(self, xs, method='get', affiliation='none',
    178                        entityOrNick=None, reason=None):
    179         AdminRequest.__init__(self, xs, method)
    180 
    181         self.affiliation = affiliation
    182         self.reason = reason
    183         if entityOrNick:
    184             self.items([entityOrNick])
    185 
    186     def items(self, entities=None):
    187         """
    188         Set or Get the items list for this affiliation request.
    189         """
    190         if entities:
    191             for entityOrNick in entities:
    192                 item = self.query.addElement('item')
    193                 item['affiliation'] = self.affiliation
    194                 try:
    195                     item['jid'] = entityOrNick.full()
    196                 except AttributeError:
    197                     item['nick'] = entityOrNick
    198 
    199                 if self.reason:
    200                     item.addElement('reason', content=self.reason)
    201 
    202         return self.query.elements()
    203 
    204 
    205 
    206 class RoleRequest(AdminRequest):
    207     def __init__(self, xs, method='get', role='none',
    208                        entityOrNick=None, reason=None):
    209         AdminRequest.__init__(self, xs, method)
    210 
    211         item = self.query.addElement('item')
    212         item['role'] = role
    213         try:
    214             item['jid'] = entityOrNick.full()
    215         except AttributeError:
    216             item['nick'] = entityOrNick
    217 
    218         if reason:
    219             item.addElement('reason', content=self.reason)
    220227
    221228
     
    10991106        Send a request for an affiliation list in a room.
    11001107        """
    1101         iq = AffiliationRequest(self.xmlstream,
    1102                                 method='get',
    1103                                 affiliation=affiliation,
    1104                                 )
    1105         iq['to'] = roomJID.userhost()
    1106         return iq.send()
     1108        def cb(response):
     1109            stanza = AdminStanza.fromElement(response)
     1110            return stanza.items
     1111
     1112        request = AdminStanza(recipient=roomJID, stanzaType='get')
     1113        request.items = [AdminItem(affiliation=affiliation)]
     1114        d = self.request(request)
     1115        d.addCallback(cb)
     1116        return d
    11071117
    11081118
    11091119    def _getRoleList(self, roomJID, role):
    11101120        """
    1111         Send a role request.
    1112         """
    1113         iq = RoleRequest(self.xmlstream,
    1114                          method='get',
    1115                          role=role,
    1116                          )
    1117         iq['to'] = roomJID.full()
    1118         return iq.send()
    1119 
    1120 
    1121     def _setAffiliationList(self, iq, affiliation, occupantJID):
    1122         # set a rooms affiliation list
    1123         room = self._getRoom(occupantJID)
    1124         if room is not None:
    1125             affiliation_list = []
    1126             setattr(room, affiliation, [])
    1127 
    1128             for item in iq.query.elements():
    1129                 nick = item.getAttribute('nick', None)
    1130                 entity = item.getAttribute('jid', None)
    1131                 role = item.getAttribute('role', None)
    1132                 user = None
    1133                 if nick is None and entity is None:
    1134                     raise Exception, 'bad attributes in item list'
    1135                 if nick is not None:
    1136                     user = room.getUser(nick)
    1137                 if user is None:
    1138                     user = User(nick, entity=jid.internJID(entity))
    1139                     user.affiliation = 'member'
    1140                 if role is not None:
    1141                     user.role = role
    1142 
    1143                 affiliation_list.append(user)
    1144 
    1145             setattr(room, affiliation, affiliation_list)
    1146         return room
     1121        Send a request for a role list in a room.
     1122        """
     1123        def cb(response):
     1124            stanza = AdminStanza.fromElement(response)
     1125            return stanza.items
     1126
     1127        request = AdminStanza(recipient=roomJID, stanzaType='get')
     1128        request.items = [AdminItem(role=role)]
     1129        d = self.request(request)
     1130        d.addCallback(cb)
     1131        return d
    11471132
    11481133
     
    11541139        @type roomJID: L{jid.JID}
    11551140        """
    1156         d = self._getAffiliationList(roomJID, 'member')
    1157         d.addCallback(self._setAffiliationList, 'members', roomJID)
    1158         return d
     1141        return self._getAffiliationList(roomJID, 'member')
    11591142
    11601143
     
    11661149        @type roomJID: L{jid.JID}
    11671150        """
    1168         d = self._getAffiliationList(roomJID, 'admin')
    1169         d.addCallback(self._setAffiliationList, 'admin', roomJID)
    1170         return d
     1151        return self._getAffiliationList(roomJID, 'admin')
    11711152
    11721153
     
    11781159        @type roomJID: L{jid.JID}
    11791160        """
    1180         d = self._getAffiliationList(roomJID, 'outcast')
    1181         d.addCallback(self._setAffiliationList, 'outcast', roomJID)
    1182         return d
     1161        return self._getAffiliationList(roomJID, 'outcast')
    11831162
    11841163
     
    11871166        Get an owner list from a room.
    11881167
    1189         @param roomJID: The room jabber/xmpp entity id for the requested member
    1190             list.
    1191         @type roomJID: L{jid.JID}
    1192         """
    1193         d = self._getAffiliationList(roomJID, 'owner')
    1194         d.addCallback(self._setAffiliationList, 'owner', roomJID)
     1168        @param roomJID: The bare JID of the room.
     1169        @type roomJID: L{jid.JID}
     1170        """
     1171        return self._getAffiliationList(roomJID, 'owner')
     1172
     1173
     1174    def getModeratorList(self, roomJID):
     1175        """
     1176        Get the moderator list of a room.
     1177
     1178        @param roomJID: The bare JID of the room.
     1179        @type roomJID: L{jid.JID}
     1180        """
     1181        d = self._getRoleList(roomJID, 'moderator')
    11951182        return d
    11961183
     
    12971284
    12981285
    1299     def _setAffiliation(self, roomJID, entityOrNick, affiliation,
     1286    def _setAffiliation(self, roomJID, entity, affiliation,
    13001287                              reason=None, sender=None):
    13011288        """
    13021289        Send a request to change an entity's affiliation to a MUC room.
    13031290        """
    1304         iq = AffiliationRequest(self.xmlstream,
    1305                                 method='set',
    1306                                 entityOrNick=entityOrNick,
    1307                                 affiliation=affiliation,
    1308                                 reason=reason)
    1309         iq['to'] = roomJID.userhost()
    1310         if sender is not None:
    1311             iq['from'] = unicode(sender)
    1312 
    1313         return iq.send()
    1314 
    1315 
    1316     def _setRole(self, roomJID, entityOrNick, role,
     1291        request = AdminStanza(recipient=roomJID, sender=sender,
     1292                               stanzaType='set')
     1293        item = AdminItem(entity=entity, affiliation=affiliation, reason=reason)
     1294        request.items = [item]
     1295        return self.request(request)
     1296
     1297
     1298    def _setRole(self, roomJID, nick, role,
    13171299                       reason=None, sender=None):
    1318         # send a role request
    1319         iq = RoleRequest(self.xmlstream,
    1320                          method='set',
    1321                          role=role,
    1322                          entityOrNick=entityOrNick,
    1323                          reason=reason)
    1324 
    1325         iq['to'] = roomJID.userhost()
    1326         if sender is not None:
    1327             iq['from'] = unicode(sender)
    1328         return iq.send()
    1329 
    1330 
    1331     def modifyAffiliationList(self, frm, roomJID, jid_list, affiliation):
     1300        """
     1301        Send a request to change an occupant's role in a MUC room.
     1302        """
     1303        request = AdminStanza(recipient=roomJID, sender=sender,
     1304                               stanzaType='set')
     1305        item = AdminItem(nick=nick, role=role, reason=reason)
     1306        request.items = [item]
     1307        return self.request(request)
     1308
     1309
     1310    def modifyAffiliationList(self, roomJID, entities, affiliation,
     1311                                    sender=None):
    13321312        """
    13331313        Modify an affiliation list.
    13341314
    1335         @param frm: The entity sending the request.
    1336         @type frm: L{jid.JID}
    1337 
    1338         @param roomJID: The bare JID of the room.
    1339         @type roomJID: L{jid.JID}
    1340 
    1341         @param entities: The list of entities to change in a room. This can be
    1342             a nick or a full jid.
    1343         @type jid_list: L{list} of C{unicode} for nicks. L{list} of L{jid.JID}
    1344             for jids.
    1345 
    1346         @param affiliation: The affilation to change.
     1315        @param roomJID: The bare JID of the room.
     1316        @type roomJID: L{jid.JID}
     1317
     1318        @param entities: The list of entities to change for a room.
     1319        @type entities: L{list} of L{jid.JID}
     1320
     1321        @param affiliation: The affilation to the entities will acquire.
    13471322        @type affiliation: C{unicode}
    13481323
    1349         """
    1350         iq = AffiliationRequest(self.xmlstream,
    1351                                 method='set',
    1352                                 affiliation=affiliation,
    1353                                 )
    1354         iq.items(jid_list)
    1355         iq['to'] = roomJID.userhost()
    1356         iq['from'] = frm.full()
    1357         return iq.send()
     1324        @param sender: The entity sending the request.
     1325        @type sender: L{jid.JID}
     1326
     1327        """
     1328        request = AdminStanza(recipient=roomJID, sender=sender,
     1329                               stanzaType='set')
     1330        request.items = [AdminItem(entity=entity, affiliation=affiliation)
     1331                         for entity in entities]
     1332
     1333        return self.request(request)
    13581334
    13591335
     
    13741350        @type sender: L{jid.JID}
    13751351        """
    1376         return self._setRole(roomJID, entityOrNick=nick,
     1352        return self._setRole(roomJID, nick=nick,
    13771353                             role='participant',
    13781354                             reason=reason, sender=sender)
     
    13971373        @type sender: L{jid.JID}
    13981374        """
    1399         return self._setRole(roomJID, entityOrNick=nick, role='visitor',
     1375        return self._setRole(roomJID, nick=nick, role='visitor',
    14001376                             reason=reason, sender=sender)
    14011377
     
    14171393        @type sender: L{jid.JID}
    14181394        """
    1419         return self._setRole(roomJID, entityOrNick=nick, role='moderator',
     1395        return self._setRole(roomJID, nick=nick, role='moderator',
    14201396                             reason=reason, sender=sender)
    14211397
     
    14411417
    14421418
    1443     def kick(self, roomJID, entityOrNick, reason=None, sender=None):
     1419    def kick(self, roomJID, nick, reason=None, sender=None):
    14441420        """
    14451421        Kick a user from a MUC room.
     
    14481424        @type roomJID: L{jid.JID}
    14491425
    1450         @param entityOrNick: The occupant to be banned.
    1451         @type entityOrNick: L{jid.JID} or C{unicode}
     1426        @param nick: The occupant to be banned.
     1427        @type nick: C{unicode}
    14521428
    14531429        @param reason: The reason given for the kick.
     
    14571433        @type sender: L{jid.JID}
    14581434        """
    1459         return self._setAffiliation(roomJID, entityOrNick, 'none',
    1460                                     reason=reason, sender=sender)
     1435        return self._setRole(roomJID, nick, 'none',
     1436                             reason=reason, sender=sender)
Note: See TracChangeset for help on using the changeset viewer.