Changeset 56
- Timestamp:
- 02/14/04 20:19:13 (5 years ago)
- Files:
-
- trunk/jjigw.py (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/jjigw.py
r54 r56 18 18 import pyxmpp.jabberd 19 19 from pyxmpp.jabber.muc import MucPresence,MucX,MucUserX,MucItem,MUC_NS,MucStatus 20 from pyxmpp.jabber.muc import MucIq,MucAdminQuery,MUC_ADMIN_NS 20 21 21 22 class JJIGWFatalError(RuntimeError): … … 187 188 self.current_thread=None 188 189 189 def sync_in_channel(self,channel): 190 def descr(self): 191 if self.user and self.host: 192 return "%s(%s@%s)" % (self.nick,self.user,self.host) 193 else: 194 return self.nick 195 196 def sync_in_channel(self,channel,status=None): 190 197 if self.sync_delay>0: 191 198 return 192 199 elif self.sync_delay<0: 193 200 self.debug("Warning: %r.sync_delay<0" % (self,)) 194 return channel.sync_user(self )201 return channel.sync_user(self,status=status) 195 202 196 203 def join_channel(self,channel): … … 198 205 self.sync_in_channel(channel) 199 206 200 def leave_channel(self,channel ):207 def leave_channel(self,channel,status=None): 201 208 try: 202 209 del self.channels[normalize(channel.name)] 203 self.sync_in_channel(channel )210 self.sync_in_channel(channel,status=status) 204 211 except KeyError: 205 212 pass … … 282 289 self.users=[] 283 290 self.muc=0 284 self.requests={} 285 286 def sync_user(self,user): 291 self.requests=[] 292 293 def get_request(self,commands): 294 for command,stanza in self.requests: 295 if command in commands: 296 try: 297 self.requests.remove((command,stanza)) 298 except ValueError: 299 pass 300 return command,stanza 301 return None,None 302 303 def add_request(self,command,stanza): 304 self.requests.append((command,stanza.copy())) 305 if len(self.requests)>10: 306 self.requests=self.requests[-10:] 307 308 def sync_user(self,user,status=None): 287 309 if user.channels.has_key(normalize(self.name)): 288 310 if user not in self.users: … … 298 320 % (unicode(user.nick,self.encoding,"replace"),)) 299 321 if self.state: 300 p=self.get_user_presence(user )322 p=self.get_user_presence(user,status=status) 301 323 self.session.component.send(p) 302 324 … … 316 338 self.debug("Joining channel %r" % (self.name,)) 317 339 self.session.send("JOIN %s" % (self.name,)) 318 self. requests["JOIN"]=stanza.copy()340 self.add_request("JOIN",stanza) 319 341 self.state="join" 320 342 if stanza.get_join_info(): … … 422 444 423 445 def irc_cmd_482(self,prefix,command,params): # ERR_CHANOPRIVSNEEDED 424 stanza=self.requests.get("TOPIC") 425 if stanza: 426 m=stanza.make_error_response("forbidden") 427 try: 428 del self.requests["TOPIC"] 429 except KeyError: 430 pass 446 self.irc_error_response(prefix,command,params,["TOPIC","KICK"],"forbidden") 447 448 def irc_cmd_461(self,prefix,command,params): # ERR_NEEDMOREPARAMS 449 self.irc_error_response(prefix,command,params,["TOPIC","KICK"],"bad-request") 450 451 def irc_cmd_403(self,prefix,command,params): # ERR_NOSUCHCHANNEL 452 self.irc_error_response(prefix,command,params,["KICK"],"recipient-unavailable") 453 454 def irc_cmd_476(self,prefix,command,params): # ERR_BADCHANMASK 455 self.irc_error_response(prefix,command,params,["KICK"],"bad-request") 456 457 def irc_cmd_441(self,prefix,command,params): # ERR_USERNOTINCHANNEL 458 self.irc_error_response(prefix,command,params,["KICK"],"item-not-found") 459 460 def irc_cmd_442(self,prefix,command,params): # ERR_NOTONCHANNEL 461 self.irc_error_response(prefix,command,params,["TOPIC","KICK"],"forbidden") 462 463 def irc_cmd_477(self,prefix,command,params): # ERR_NOCHANMODES 464 self.irc_error_response(prefix,command,params,["TOPIC"],"not-acceptable") 465 466 def irc_error_response(self,prefix,command,params,requests,condition): 467 command,stanza=self.get_request(requests) 468 if command: 469 m=stanza.make_error_response(condition) 431 470 else: 432 471 m=Message(fr=self.room_jid.bare(),to=self.session.jid, 433 type="error", error_cond= "forbidden")472 type="error", error_cond=condition) 434 473 self.session.component.send(m) 435 474 475 def irc_cmd_331(self,prefix,command,params): # RPL_NOTOPIC 476 m=Message(fr=self.room_jid.bare(),to=self.session.jid, type="groupchat", subject=u"") 477 self.session.component.send(m) 478 436 479 def irc_cmd_332(self,prefix,command,params): # RPL_TOPIC 437 480 topic=remove_evil_characters(params[1]) … … 439 482 type="groupchat", subject=unicode(topic,self.encoding,"replace")) 440 483 self.session.component.send(m) 441 484 442 485 def irc_cmd_TOPIC(self,prefix,command,params): 443 if self.session.check_prefix(prefix): 444 try: 445 del self.requests["TOPIC"] 446 except KeyError: 447 pass 486 self.get_request(("TOPIC",)) 448 487 topic=remove_evil_characters(params[1]) 449 488 m=Message(fr=self.prefix_to_jid(prefix),to=self.session.jid, … … 458 497 if params_str: 459 498 params_str=" "+params_str 460 self.send_notice_message(u"Mode chage: [%s%s] by %s" 499 if "!" in prefix: 500 nick,iuser=prefix.split("!",1) 501 iuser="(%s)" % (user,) 502 else: 503 nick,iuser=prefix,"" 504 self.send_notice_message(u"Mode chage: [%s%s] by %s%s" 461 505 % (unicode(params[1],self.encoding,"replace"), 462 506 unicode(params_str,self.encoding,"replace"), 463 unicode(prefix,self.encoding,"replace")), 507 unicode(nick,self.encoding,"replace"), 508 unicode(iuser,self.encoding,"replace")), 464 509 0) 465 510 self.irc_mode_changed(prefix,command,params) … … 535 580 self.session.user.sync_delay-=1 536 581 self.state="joined" 537 try: 538 del self.requests["JOIN"] 539 except KeyError: 540 pass 582 self.get_request(("JOIN",)) 541 583 self.session.send("MODE %s" % (self.name,)) 542 584 self.session.send("WHO %s" % (self.name,)) … … 557 599 self.send_notice_message(u"%s has left" 558 600 % (unicode(user.nick,self.encoding,"replace"),)) 601 602 def irc_cmd_KICK(self,prefix,command,params): 603 actor=self.session.get_user(prefix) 604 user=self.session.get_user(params[1]) 605 try: 606 self.users.remove(user) 607 except ValueError: 608 pass 609 self.send_notice_message(u"%s was kicked by %s" 610 % (unicode(user.descr(),self.encoding,"replace"), 611 unicode(actor.descr(),self.encoding,"replace")), 612 0) 613 user.leave_channel(self,status=307) 559 614 560 615 def irc_cmd_PRIVMSG(self,prefix,command,params): … … 587 642 topic=topic.replace("\n"," ").replace("\r"," ") 588 643 self.session.send("TOPIC %s :%s" % (self.name,topic)) 589 self.requests["TOPIC"]=stanza 644 self.add_request("TOPIC",stanza) 645 646 def kick_user(self,nick,reason,stanza): 647 self.session.send("KICK %s %s :%s" % (self.name,nick,reason)) 648 self.add_request("KICK",stanza) 590 649 591 650 def __repr__(self): … … 1056 1115 self.channels[normalize(channel.name)]=channel 1057 1116 1117 def get_channel(self,jid): 1118 channel_name=jid.node 1119 channel_name=node_to_channel(channel_name,self.default_encoding) 1120 if not channel_re.match(channel_name): 1121 self.debug("Bad channel name: %r" % (channel_name,)) 1122 return None 1123 return self.channels.get(normalize(channel_name)) 1124 1058 1125 def message_to_channel(self,stanza): 1059 1126 self.debug("message_to_channel(%r)" % (stanza,)) … … 1065 1132 finally: 1066 1133 self.cond.release() 1067 self.debug("message_to_channel: no need to wait") 1068 channel_name=stanza.get_to().node 1069 self.debug("channel_name: %r" % (channel_name,)) 1070 channel_name=node_to_channel(channel_name,self.default_encoding) 1071 self.debug("channel_name: %r" % (channel_name,)) 1072 if not channel_re.match(channel_name): 1073 self.debug("Bad channel name: %r" % (channel_name,)) 1074 return 1075 channel=self.channels.get(normalize(channel_name)) 1134 channel=self.get_channel(stanza.get_to()) 1135 if not channel: 1136 e=stanza.make_error_response("bad-request") 1137 self.component.send(e) 1138 return 1076 1139 self.debug("channel: %r" % (channel,)) 1077 1140 if channel: … … 1092 1155 if body.startswith("/me "): 1093 1156 body="\001ACTION "+body[4:]+"\001" 1094 self.send("PRIVMSG %s :%s" % (channel_name,body)) 1095 if channel: 1096 channel.irc_cmd_PRIVMSG(self.nick,"PRIVMSG",[channel_name,body]) 1157 self.send("PRIVMSG %s :%s" % (channel.name,body)) 1158 channel.irc_cmd_PRIVMSG(self.nick,"PRIVMSG",[channel.name,body]) 1097 1159 self.debug("message_to_channel: done") 1098 1160 … … 1263 1325 self.stream.set_iq_get_handler("query","jabber:iq:register",self.get_register) 1264 1326 self.stream.set_iq_set_handler("query","jabber:iq:register",self.set_register) 1327 self.stream.set_iq_set_handler("query",MUC_ADMIN_NS,self.set_muc_admin) 1265 1328 self.disco_info.add_feature("jabber:iq:version") 1266 1329 self.disco_info.add_feature("jabber:iq:register") … … 1272 1335 self.stream.set_message_handler("normal",self.message) 1273 1336 1337 def set_muc_admin(self,iq): 1338 to=iq.get_to() 1339 fr=iq.get_from() 1340 if not to.node: 1341 self.debug("admin request sent to JID without a node") 1342 iq=iq.make_error_response("feature-not-implemented") 1343 self.stream.send(iq) 1344 return 1 1345 if to.resource or not (to.node[0] in "#+!" or to.node.startswith(",amp,")): 1346 self.debug("admin request sent not to a channel") 1347 iq=iq.make_error_response("not-acceptable") 1348 self.stream.send(iq) 1349 return 1 1350 1351 iq=MucIq(iq) 1352 sess=self.irc_sessions.get(fr.as_unicode()) 1353 if not sess: 1354 self.debug("User session not found") 1355 iq=iq.make_error_response("recipient-unavailable") 1356 self.stream.send(iq) 1357 return 1 1358 1359 channel=sess.get_channel(to) 1360 if not channel: 1361 self.debug("Channel not found") 1362 iq=iq.make_error_response("recipient-unavailable") 1363 self.stream.send(iq) 1364 return 1 1365 1366 query=iq.get_muc_child() 1367 if not isinstance(query,MucAdminQuery): 1368 self.debug("Bad query content") 1369 iq=iq.make_error_response("bad-request") 1370 self.stream.send(iq) 1371 return 1 1372 1373 items=query.get_items() 1374 if not items: 1375 self.debug("No items in query") 1376 iq=iq.make_error_response("bad-request") 1377 self.stream.send(iq) 1378 return 1 1379 item=items[0] 1380 if item.role=="none": 1381 channel.kick_user(item.nick,item.reason,iq) 1382 else: 1383 self.debug("Unknown admin action") 1384 iq=iq.make_error_response("feature-not-implemented") 1385 self.stream.send(iq) 1386 return 1 1387 1274 1388 def get_version(self,iq): 1275 1389 iq=iq.make_result_response()
