Changeset 40

Show
Ignore:
Timestamp:
02/08/04 18:24:43 (5 years ago)
Author:
jajcus
Message:

- topic change support
- muc status codes handling updated for the latest PyXMPP
- SIGPIPE handling

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/jjigw.py

    r37 r40  
    1515from pyxmpp import ClientStream,JID,Iq,Presence,Message,StreamError 
    1616import pyxmpp.jabberd 
    17 from pyxmpp.jabber.muc import MucPresence,MucX,MucUserX,MucItem,MUC_NS 
     17from pyxmpp.jabber.muc import MucPresence,MucX,MucUserX,MucItem,MUC_NS,MucStatus 
    1818 
    1919class JJIGWFatalError(RuntimeError): 
     
    260260        self.session=session 
    261261        self.state=None 
    262         self.stanza=None 
    263262        self.room_jid=None 
    264263        self.config=session.network.get_channel_config(name) 
     
    270269        self.users=[] 
    271270        self.muc=0 
     271        self.requests={} 
    272272 
    273273    def sync_user(self,user): 
     
    303303        self.debug("Joining channel %r" % (self.name,)) 
    304304        self.session.send("JOIN %s" % (self.name,)) 
    305         self.stanza=stanza.copy() 
     305        self.requests["JOIN"]=stanza.copy() 
    306306        self.state="join" 
    307307        if stanza.get_join_info(): 
     
    319319                        status.encode(self.encoding,"replace"))) 
    320320            self.state=None 
    321             self.stanza=None 
    322321        p=MucPresence(type="unavailable",fr=stanza.get_to(),to=stanza.get_from(),status=status) 
    323322        self.session.component.send(p) 
     
    354353                aff="none" 
    355354                role="participant" 
    356             ui=p.make_muc_userinfo(status=status
     355            ui=p.make_muc_userinfo(
    357356            if nick: 
    358357                nick=unicode(user.nick,self.encoding,"replace") 
    359358            it=MucItem(aff,role,user.jid(),nick=nick,actor=actor,reason=reason) 
    360359            ui.add_item(it) 
     360            if status: 
     361                ui.add_item(MucStatus(status)) 
    361362        return p 
    362363 
     
    406407                pass 
    407408        self.irc_cmd_MODE(prefix,command,params) 
     409         
     410    def irc_cmd_482(self,prefix,command,params): # ERR_CHANOPRIVSNEEDED 
     411        stanza=self.requests.get("TOPIC") 
     412        if stanza: 
     413            m=stanza.make_error_response("forbidden") 
     414            try: 
     415                del self.requests["TOPIC"] 
     416            except KeyError: 
     417                pass 
     418        else: 
     419            m=Message(fr=self.room_jid.bare(),to=self.session.jid, 
     420                    type="error", error_cond="forbidden") 
     421        self.session.component.send(m) 
     422 
     423    def irc_cmd_332(self,prefix,command,params): # RPL_TOPIC 
     424        topic=params[1] 
     425        m=Message(fr=self.room_jid.bare(),to=self.session.jid, 
     426                type="groupchat", subject=unicode(topic,self.encoding,"replace")) 
     427        self.session.component.send(m) 
     428         
     429    def irc_cmd_TOPIC(self,prefix,command,params): 
     430        if self.session.check_prefix(prefix): 
     431            try: 
     432                del self.requests["TOPIC"] 
     433            except KeyError: 
     434                pass 
     435        topic=params[1] 
     436        m=Message(fr=self.prefix_to_jid(prefix),to=self.session.jid, 
     437                type="groupchat", subject=unicode(topic,self.encoding,"replace")) 
     438        self.session.component.send(m) 
    408439         
    409440    def irc_cmd_MODE(self,prefix,command,params): 
     
    482513                    self.session.user.sync_delay-=1 
    483514                self.state="joined" 
    484                 self.stanza=None 
     515                try: 
     516                    del self.requests["JOIN"] 
     517                except KeyError: 
     518                    pass 
    485519                self.session.send("MODE %s" % (self.name,)) 
    486520                self.session.send("WHO %s" % (self.name,)) 
     
    526560        else: 
    527561            self.debug("Unknown CTCP command: %r %r" % (command,arg)) 
    528              
     562 
     563    def change_topic(self,topic,stanza): 
     564        topic=topic.encode(self.encoding,"replace") 
     565        topic=topic.replace("\n"," ").replace("\r"," ") 
     566        self.session.send("TOPIC %s :%s" % (self.name,topic)) 
     567        self.requests["TOPIC"]=stanza 
     568    
    529569    def __repr__(self): 
    530570        return "<IRCChannel %r>" % (self.name,) 
     
    615655        else: 
    616656            return 0 
     657 
     658    def check_prefix(self,prefix): 
     659        if "!" in prefix: 
     660            nick=prefix.split("!",1)[0] 
     661        else: 
     662            nick=prefix 
     663        return normalize(nick)==normalize(self.nick) 
    617664 
    618665    def thread_run(self): 
     
    886933            channel=user.channels[c] 
    887934            self.component.send(channel.get_user_presence(user)) 
    888             
     935     
    889936    def pass_input_to_user(self,prefix,command,params): 
    890937        if command in self.commands_dont_show: 
     
    925972 
    926973    def message_to_channel(self,stanza): 
     974        self.debug("message_to_channel(%r)" % (stanza,)) 
    927975        self.cond.acquire() 
    928976        try: 
     
    932980        finally: 
    933981            self.cond.release() 
     982        self.debug("message_to_channel: no need to wait") 
    934983        channel_name=stanza.get_to().node 
     984        self.debug("channel_name: %r" % (channel_name,)) 
    935985        channel_name=node_to_channel(channel_name,self.default_encoding) 
     986        self.debug("channel_name: %r" % (channel_name,)) 
    936987        if not channel_re.match(channel_name): 
    937988            self.debug("Bad channel name: %r" % (channel_name,)) 
    938989            return 
    939990        channel=self.channels.get(normalize(channel_name)) 
     991        self.debug("channel: %r" % (channel,)) 
    940992        if channel: 
    941993            encoding=channel.encoding 
    942994        else: 
    943995            encoding=self.default_encoding 
    944         body=stanza.get_body().encode(encoding,"replace") 
    945         body=body.replace("\n"," ").replace("\r"," ") 
    946         if body.startswith("/me "): 
    947             body="\001ACTION "+body[4:]+"\001" 
    948         self.send("PRIVMSG %s :%s" % (channel_name,body)) 
    949         if channel: 
    950             channel.irc_cmd_PRIVMSG(self.nick,"PRIVMSG",[channel_name,body]) 
     996        self.debug("encoding: %r" % (encoding,)) 
     997        subject=stanza.get_subject() 
     998        self.debug("subject: %r" % (subject,)) 
     999        if subject and channel: 
     1000            channel.change_topic(subject,stanza.copy()) 
     1001        body=stanza.get_body() 
     1002        self.debug("body: %r" % (body,)) 
     1003        if body: 
     1004            body=body.encode(encoding,"replace") 
     1005            body=body.replace("\n"," ").replace("\r"," ") 
     1006            self.debug("body: %r" % (body,)) 
     1007            if body.startswith("/me "): 
     1008                body="\001ACTION "+body[4:]+"\001" 
     1009            self.send("PRIVMSG %s :%s" % (channel_name,body)) 
     1010            if channel: 
     1011                channel.irc_cmd_PRIVMSG(self.nick,"PRIVMSG",[channel_name,body]) 
     1012        self.debug("message_to_channel: done") 
    9511013 
    9521014    def message_to_user(self,stanza): 
     
    9981060        self.shutdown=0 
    9991061        signal.signal(signal.SIGINT,self.signal_handler) 
     1062        signal.signal(signal.SIGPIPE,self.signal_handler) 
    10001063        signal.signal(signal.SIGTERM,self.signal_handler) 
    10011064        self.irc_sessions={}