Changeset 26

Show
Ignore:
Timestamp:
02/07/04 13:18:01 (5 years ago)
Author:
jajcus
Message:

- configurable network and channel encodings

Files:

Legend:

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

    r23 r26  
    2020    pass 
    2121 
     22evil_characters_re=re.compile(r"[\000-\010\013\014\016-\037]") 
     23def remove_evil_characters(s): 
     24    return evil_characters_re.sub(" ",s) 
     25 
     26color_re=re.compile(r"\x03\d\d|\x0f") 
     27def strip_colors(s): 
     28    return color_re.sub("",s) 
     29 
     30numeric_re=re.compile(r"\d\d\d") 
     31channel_re=re.compile(r"^[&#+!][^\000 \007 ,:\r\n]{1,49}$") 
     32nick_re=re.compile(r"^[a-zA-Z\x5b-\x60\x7b-\x7d\[\]\\`_^{|}][a-zA-Z\x5b-\x60\x7b-\x7d\[\]\\`_^{|}0-9-]{0,8}$") 
     33 
     34def escape_node_string(s): 
     35    s=s.replace(",quot,",'"') 
     36    s=s.replace(",amp,","&") 
     37    s=s.replace(",apos,","'") 
     38    s=s.replace(",slash,","/") 
     39    s=s.replace(",lt,","<") 
     40    s=s.replace(",gt,",">") 
     41    s=s.replace(",at,","@") 
     42    return s 
     43 
     44def unescape_node_string(s): 
     45    s=s.replace('"',",quot,") 
     46    s=s.replace("&",",amp,") 
     47    s=s.replace("'",",apos,") 
     48    s=s.replace("/",",slash,") 
     49    s=s.replace("<",",lt,") 
     50    s=s.replace(">",",gt,") 
     51    s=s.replace("@",",at,") 
     52    return s 
     53 
     54def node_to_channel(n,encoding): 
     55    s=n.encode(encoding,"strict") 
     56    s=escape_node_string(s) 
     57    if not channel_re.match(s): 
     58        raise ValueError,"Bad channel name: %r" % (s,) 
     59    return s 
     60 
     61def channel_to_node(ch,encoding): 
     62    s=unescape_node_string(ch) 
     63    n=unicode(s,encoding,"strict") 
     64    return n 
     65 
     66def node_to_nick(n,encoding): 
     67    s=n.encode(encoding,"strict") 
     68    s=escape_node_string(s) 
     69    if not nick_re.match(s): 
     70        raise ValueError,"Bad nick name: %r" % (s,) 
     71    return s 
     72 
     73def nick_to_node(ch,encoding): 
     74    s=unescape_node_string(ch) 
     75    n=unicode(s,encoding,"strict") 
     76    return n 
     77 
     78irc_translate_table=string.maketrans( 
     79        string.ascii_uppercase+"[]\\~", 
     80        string.ascii_lowercase+"{}|^") 
     81 
     82def normalize(s): 
     83    return s.translate(irc_translate_table) 
     84 
     85 
    2286class ConnectConfig: 
    2387    def __init__(self,node): 
     
    2690        self.port=int(node.xpathEval("port")[0].getContent()) 
    2791        self.secret=node.xpathEval("secret")[0].getContent() 
     92 
     93class ServerConfig: 
     94    def __init__(self,node): 
     95        self.host=node.getContent() 
     96        self.port=node.prop("port") 
     97        try: 
     98            self.port=int(self.port) 
     99            if self.port<1 or self.port>65535: 
     100                raise ValueError 
     101        except ValueError: 
     102            print >>sys.stderr,"Bad port value: %r, using default: 6667" % (self.port,) 
     103            self.port=6667 
     104 
     105class ChannelConfig: 
     106    def __init__(self,node): 
     107        self.name=node.getContent() 
     108        self.encoding=node.prop("encoding") 
    28109 
    29110class NetworkConfig: 
     
    34115        self.servers=[] 
    35116        for s in servers: 
    36             server=s.getContent() 
    37             port=s.prop("port") 
    38             try: 
    39                 port=int(port) 
    40                 if port<1 or port>65535: 
    41                     raise ValueError 
    42             except ValueError: 
    43                 print >>sys.stderr,"Bad port value: %r, using default: 6667" % (port,) 
    44                 port=6667 
    45             self.servers.append((server,port)) 
     117            self.servers.append(ServerConfig(s)) 
     118        channels=node.xpathEval("channel") 
     119        self.channels={} 
     120        if channels: 
     121            for c in channels: 
     122                ch=ChannelConfig(c) 
     123                self.channels[normalize(ch.name)]=ch 
    46124        self.default_encoding=node.prop("encoding") 
    47125    def get_servers(self): 
     
    49127        self.servers=self.servers[-1:]+self.servers[1:] 
    50128        return r 
     129    def get_channel_config(self,channel): 
     130        return self.channels.get(normalize(channel)) 
    51131 
    52132class Config: 
     
    64144        if self.doc: 
    65145            self.doc.freeDoc() 
    66  
    67 evil_characters_re=re.compile(r"[\000-\010\013\014\016-\037]") 
    68 def remove_evil_characters(s): 
    69     return evil_characters_re.sub(" ",s) 
    70  
    71 color_re=re.compile(r"\x03\d\d|\x0f") 
    72 def strip_colors(s): 
    73     return color_re.sub("",s) 
    74  
    75 numeric_re=re.compile(r"\d\d\d") 
    76 channel_re=re.compile(r"^[&#+!][^\000 \007 ,:\r\n]{1,49}$") 
    77 nick_re=re.compile(r"^[a-zA-Z\x5b-\x60\x7b-\x7d\[\]\\`_^{|}][a-zA-Z\x5b-\x60\x7b-\x7d\[\]\\`_^{|}0-9-]{0,8}$") 
    78  
    79 def escape_node_string(s): 
    80     s=s.replace(",quot,",'"') 
    81     s=s.replace(",amp,","&") 
    82     s=s.replace(",apos,","'") 
    83     s=s.replace(",slash,","/") 
    84     s=s.replace(",lt,","<") 
    85     s=s.replace(",gt,",">") 
    86     s=s.replace(",at,","@") 
    87     return s 
    88  
    89 def unescape_node_string(s): 
    90     s=s.replace('"',",quot,") 
    91     s=s.replace("&",",amp,") 
    92     s=s.replace("'",",apos,") 
    93     s=s.replace("/",",slash,") 
    94     s=s.replace("<",",lt,") 
    95     s=s.replace(">",",gt,") 
    96     s=s.replace("@",",at,") 
    97     return s 
    98  
    99 def node_to_channel(n,encoding): 
    100     s=n.encode(encoding,"strict") 
    101     s=escape_node_string(s) 
    102     if not channel_re.match(s): 
    103         raise ValueError,"Bad channel name: %r" % (s,) 
    104     return s 
    105  
    106 def channel_to_node(ch,encoding): 
    107     s=unescape_node_string(ch) 
    108     n=unicode(s,encoding,"strict") 
    109     return n 
    110  
    111 def node_to_nick(n,encoding): 
    112     s=n.encode(encoding,"strict") 
    113     s=escape_node_string(s) 
    114     if not nick_re.match(s): 
    115         raise ValueError,"Bad nick name: %r" % (s,) 
    116     return s 
    117  
    118 def nick_to_node(ch,encoding): 
    119     s=unescape_node_string(ch) 
    120     n=unicode(s,encoding,"strict") 
    121     return n 
    122  
    123 irc_translate_table=string.maketrans( 
    124         string.ascii_uppercase+"[]\\~", 
    125         string.ascii_lowercase+"{}|^") 
    126  
    127 def normalize(s): 
    128     return s.translate(irc_translate_table) 
    129146 
    130147class IRCUser: 
     
    234251        self.stanza=None 
    235252        self.room_jid=None 
    236         self.encoding=session.default_encoding 
     253        self.config=session.network.get_channel_config(name) 
     254        if self.config and self.config.encoding: 
     255            self.encoding=self.config.encoding 
     256        else: 
     257            self.encoding=session.default_encoding 
    237258        self.modes={} 
    238259        self.users=[] 
     
    525546        self.input_buffer="" 
    526547        self.used_for=[] 
    527         self.server="" 
     548        self.server=None 
    528549        self.join_requests=[] 
    529550        self.messages_to_channel=[] 
     
    658679        try: 
    659680            self.socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
    660             self.socket.connect(server
     681            self.socket.connect((server.host,server.port)
    661682        except (IOError,OSError,socket.error),err: 
    662683            self.debug("Server connect error: %r" % (err,)) 
     
    671692        user=sha.new(self.jid.bare().as_string()).hexdigest() 
    672693        self._send("USER %s 0 * :JJIGW User %s" % (user,user)) 
    673         self.server=server[0] 
     694        self.server=server 
    674695        self.cond.notify() 
    675696 
     
    860881        nprefix=normalize(prefix) 
    861882        nnick=normalize(self.nick) 
    862         nserver=normalize(self.server
     883        nserver=normalize(self.server.host
    863884        if nprefix==nnick or prefix and nprefix.startswith(nnick+"!"): 
    864885            return 
     
    872893        else: 
    873894            body=u"%s %r" % (command,params) 
    874         fr=JID(None,self.network.jid.domain,self.server
     895        fr=JID(None,self.network.jid.domain,self.server.host
    875896        m=Message(to=self.jid,fr=fr,body=body) 
    876897        self.component.send(m) 
     
    900921        finally: 
    901922            self.cond.release() 
    902         channel=stanza.get_to().node 
    903         channel=node_to_channel(channel,self.default_encoding) 
    904         if not channel_re.match(channel): 
    905             debug("Bad channel name: %r" % (channel,)) 
    906             return 
    907         body=stanza.get_body().encode(self.default_encoding,"replace") 
     923        channel_name=stanza.get_to().node 
     924        channel_name=node_to_channel(channel_name,self.default_encoding) 
     925        if not channel_re.match(channel_name): 
     926            self.debug("Bad channel name: %r" % (channel_name,)) 
     927            return 
     928        channel=self.channels.get(normalize(channel_name)) 
     929        if channel: 
     930            encoding=channel.encoding 
     931        else: 
     932            encoding=self.default_encoding 
     933        body=stanza.get_body().encode(encoding,"replace") 
    908934        body=body.replace("\n"," ").replace("\r"," ") 
    909935        if body.startswith("/me "): 
    910936            body="\001ACTION "+body[4:]+"\001" 
    911         self.send("PRIVMSG %s :%s" % (channel,body)) 
    912         channel=self.channels.get(normalize(channel)) 
     937        self.send("PRIVMSG %s :%s" % (channel_name,body)) 
    913938        if channel: 
    914             channel.irc_cmd_PRIVMSG(self.nick,"PRIVMSG",[channel.name,body]) 
     939            channel.irc_cmd_PRIVMSG(self.nick,"PRIVMSG",[channel_name,body]) 
    915940 
    916941    def message_to_user(self,stanza):