Changeset 110:ddf5580b7128 for wokkel
- Timestamp:
- Oct 1, 2008, 11:11:06 PM (14 years ago)
- Branch:
- wokkel-muc-client-support-24
- Convert:
- svn:b33ecbfc-034c-dc11-8662-000475d9059e/branches/wokkel-muc-client-support-24@71
- Location:
- wokkel
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
wokkel/muc.py
r108 r110 10 10 U{XEP-0045<http://www.xmpp.org/extensions/xep-0045.html>}. 11 11 """ 12 import datetime 12 13 13 14 from zope.interface import implements … … 28 29 NS_ROOMINFO = NS + '#roominfo' 29 30 NS_CONFIG = NS + '#roomconfig' 31 NS_REQUEST = NS + '#request' 32 33 NS_DELAY = 'urn:xmpp:delay' 30 34 31 35 # ad hoc commands … … 59 63 CHAT = MESSAGE +'[@type="chat"]' 60 64 61 GROUPCHAT = MESSAGE +'[@type="groupchat"]' 65 GROUPCHAT = MESSAGE +'[@type="groupchat"]/body' 66 SUBJECT = MESSAGE +'[@type="groupchat"]/body' 62 67 MESSAGE_ERROR = MESSAGE +'[@type="error"]' 63 68 69 STATUS_CODES = { # see http://www.xmpp.org/extensions/xep-0045.html#registrar-statuscodes 70 100: 71 {'name':'fulljid', 72 'stanza':'presence', 73 74 }, 75 201: 76 {'name':'created', 77 'stanza': 'presence', 78 'context':'Entering a room', 79 'purpose':'Inform user that a new room has been created' 80 }, 81 } 82 83 STATUS_CODE_CREATED = 201 64 84 65 85 … … 95 115 96 116 117 class ConfigureRequest(xmlstream.IQ): 118 """ 119 Configure MUC room request. 120 121 @ivar namespace: Request namespace. 122 @type namespace: C{str} 123 @ivar method: Type attribute of the IQ request. Either C{'set'} or C{'get'} 124 @type method: C{str} 125 """ 126 127 def __init__(self, xs, method='get', fields=[]): 128 xmlstream.IQ.__init__(self, xs, method) 129 q = self.addElement((NS_OWNER, 'query')) 130 if method == 'set': 131 # build data form 132 form = data_form.Form('submit', formNamespace=NS_CONFIG) 133 q.addChild(form.toElement()) 134 135 for f in fields: 136 # create a field 137 form.addField(f) 138 139 140 class GroupChat(domish.Element): 141 """ 142 """ 143 def __init__(self, to, body=None, subject=None, frm=None): 144 """To needs to be a string 145 """ 146 domish.Element.__init__(self, (None, 'message')) 147 self['type'] = 'groupchat' 148 self['to'] = to 149 if frm: 150 self['from'] = frm 151 if body: 152 self.addElement('body',None, body) 153 if subject: 154 self.addElement('subject',None, subject) 155 156 157 97 158 class Room(object): 98 159 """ … … 108 169 self.server = server 109 170 self.nick = nick 110 171 self.status = None 172 111 173 self.entity_id = jid.internJID(name+'@'+server+'/'+nick) 112 174 … … 146 208 147 209 210 class PasswordPresence(BasicPresence): 211 """ 212 """ 213 def __init__(self, to, password): 214 BasicPresence.__init__(self, to) 215 216 self.x.addElement('password', None, password) 217 218 219 class MessageVoice(GroupChat): 220 """ 221 """ 222 def __init__(self, to=None, frm=None): 223 GroupChat.__init__(self, to=to, frm=frm) 224 # build data form 225 form = data_form.Form('submit', formNamespace=NS_REQUEST) 226 form.addField(data_form.Field(var='muc#role', 227 value='participant', 228 label='Requested role')) 229 self.addChild(form.toElement()) 230 148 231 class PresenceError(BasicPresence): 149 232 """ … … 169 252 implements(IMUCClient) 170 253 254 rooms = {} 171 255 172 256 def connectionInitialized(self): 173 self.rooms = {} 174 257 self.xmlstream.addObserver(PRESENCE+"/x", self._onXPresence) 258 self.xmlstream.addObserver(GROUPCHAT, self._onGroupChat) 259 self.xmlstream.addObserver(SUBJECT, self._onSubject) 260 # add history 175 261 176 262 def _setRoom(self, room): … … 180 266 return self.rooms.get(room_jid.full().lower()) 181 267 268 269 def _onXPresence(self, prs): 270 """ 271 """ 272 if prs.x.uri == NS_USER: 273 self.receivedUserPresence(prs) 274 275 276 def _onGroupChat(self, msg): 277 """ 278 """ 279 self.receivedGroupChat(msg) 280 281 282 283 def _onSubject(self, msg): 284 """ 285 """ 286 self.receivedSubject(msg) 287 288 289 def _makeTimeStamp(self, stamp=None): 290 if stamp is None: 291 stamp = datetime.datetime.now() 292 293 return stamp.strftime('%Y%m%dT%H:%M:%S') 182 294 183 295 … … 193 305 # change the state of the room 194 306 r = self._getRoom(room_jid) 307 if r is None: 308 raise 195 309 r.state = 'joined' 310 311 # grab status 312 status = getattr(prs.x,'status',None) 313 if status: 314 r.status = status.getAttribute('code', None) 315 196 316 d.callback(r) 197 317 198 def userPresence(self, prs):318 def receivedUserPresence(self, prs): 199 319 """User Presence has been received 200 320 """ 201 321 pass 202 322 323 324 def receivedSubject(self, msg): 325 """ 326 """ 327 pass 203 328 204 329 def _cbDisco(self, iq): 205 330 # grab query 206 331 207 return iq.query332 return getattr(iq,'query', None) 208 333 209 334 def disco(self, entity, type='info'): … … 214 339 iq['to'] = entity 215 340 216 return iq.send().addCallback(self._cbDisco) 217 341 return iq.send().addBoth(self._cbDisco) 342 343 344 def configure(self, room_jid, **kwargs): 345 """Configure a room 346 """ 347 request = ConfigureRequest(self.xmlstream, method='set', **kwargs) 348 request['to'] = room_jid 349 350 return request.send() 351 352 def getConfigureForm(self, room_jid): 353 request = ConfigureRequest(self.xmlstream) 354 request['to'] = room_jid 355 return request.send() 356 218 357 219 358 def join(self, server, room, nick): … … 235 374 236 375 376 def groupChat(self, to, message, children=None): 377 """Send a groupchat message 378 """ 379 msg = GroupChat(to, body=message) 380 381 if children: 382 for c in children: 383 msg.addChild(c) 384 385 self.xmlstream.send(msg) 386 387 388 def subject(self, to, subject): 389 """ 390 """ 391 msg = GroupChat(to, subject=subject) 392 self.xmlstream.send(msg) 393 394 def voice(self, to): 395 """ 396 """ 397 msg = MessageVoice(to=to) 398 self.xmlstream.send(msg) 399 400 401 def history(self, to, message_list): 402 """ 403 """ 404 405 for m in message_list: 406 m['type'] = 'groupchat' 407 mto = m['to'] 408 frm = m.getAttribute('from', None) 409 m['to'] = to 410 411 d = m.addElement('delay', NS_DELAY) 412 d['stamp'] = self._makeTimeStamp() 413 d['from'] = mto 414 415 self.xmlstream.send(m) 416 -
wokkel/test/test_muc.py
r109 r110 49 49 self.protocol.xmlstream = self.stub.xmlstream 50 50 self.protocol.connectionInitialized() 51 51 self.test_room = 'test' 52 self.test_srv = 'conference.example.org' 53 self.test_nick = 'Nick' 54 55 self.room_jid = JID(self.test_room+'@'+self.test_srv+'/'+self.test_nick) 52 56 53 57 def test_interface(self): … … 120 124 """Test joining a room 121 125 """ 122 test_room = 'test' 123 test_srv = 'conference.example.org' 124 test_nick = 'Nick' 126 125 127 126 128 def cb(room): 127 self.assertEquals( test_room, room.name)128 129 d = self.protocol.join( test_srv, test_room,test_nick)129 self.assertEquals(self.test_room, room.name) 130 131 d = self.protocol.join(self.test_srv, self.test_room, self.test_nick) 130 132 d.addCallback(cb) 131 133 … … 135 137 136 138 # send back user presence, they joined 137 response = muc.UserPresence(frm= test_room+'@'+test_srv+'/'+test_nick)139 response = muc.UserPresence(frm=self.test_room+'@'+self.test_srv+'/'+self.test_nick) 138 140 self.stub.send(response) 139 141 return d … … 143 145 """Test joining a room and getting an error 144 146 """ 145 test_room = 'test'146 test_srv = 'conference.example.org'147 test_nick = 'Nick'148 147 149 148 def cb(error): … … 152 151 153 152 154 d = self.protocol.join( test_srv, test_room,test_nick)153 d = self.protocol.join(self.test_srv, self.test_room, self.test_nick) 155 154 d.addBoth(cb) 156 155 … … 163 162 'forbidden' 164 163 ), 165 frm= test_room+'@'+test_srv+'/'+test_nick)164 frm=self.room_jid.full()) 166 165 self.stub.send(response) 167 166 return d 168 167 168 def test_partRoom(self): 169 self.fail('Not Implemented') 170 171 172 def test_ban(self): 173 174 self.fail('Not Implemented') 175 176 def test_kick(self): 177 self.fail('Not Implemented') 178 179 180 def test_password(self): 181 """Test sending a password via presence to a password protected room. 182 """ 183 184 185 self.fail('Not Implemented') 186 187 def test_history(self): 188 189 self.fail('Not Implemented') 190 191 192 def test_oneToOneChat(self): 193 """Test converting a one to one chat 194 """ 195 archive = [] 196 thread = "e0ffe42b28561960c6b12b944a092794b9683a38" 197 # create messages 198 msg = domish.Element((None, 'message')) 199 msg['to'] = 'testing@example.com' 200 msg['type'] = 'chat' 201 msg.addElement('body', None, 'test') 202 msg.addElement('thread', None, thread) 203 204 archive.append(msg) 205 206 msg = domish.Element((None, 'message')) 207 msg['to'] = 'testing2@example.com' 208 msg['type'] = 'chat' 209 msg.addElement('body', None, 'yo') 210 msg.addElement('thread', None, thread) 211 212 archive.append(msg) 213 214 self.protocol.history(self.room_jid.userhost(), archive) 215 216 217 while len(self.stub.output)>0: 218 m = self.stub.output.pop() 219 # check for delay element 220 self.failUnless(m.name=='message', 'Wrong stanza') 221 self.failUnless(xpath.matches("/message/delay", m), 'Invalid history stanza') 222 223 224 def test_invite(self): 225 self.fail('Not Implemented') 226 227 228 def test_privateMessage(self): 229 self.fail('Not Implemented') 230 231 def test_register(self): 232 self.fail('Not Implemented') 233 234 def test_voice(self): 235 236 self.protocol.voice(self.room_jid.userhost()) 237 238 m = self.stub.output[-1] 239 self.failUnless(m.name=='message', "Need to be message stanza") 240 self.failUnless(getattr(m, 'x', None), 'No muc x element') 241 242 self.failUnless(xpath.matches("/message/x[@type='submit']/field/value[text()='%s']" % (muc.NS_REQUEST,), m), 'Invalid voice message stanza') 243 244 169 245 def test_roomConfigure(self): 170 246 171 test_room = 'test' 172 test_srv = 'conference.example.org' 173 test_nick = 'Nick' 174 175 self.fail('Not Implemented') 176 177 247 self.fail('Not Implemented') 248 249
Note: See TracChangeset
for help on using the changeset viewer.