pvl/irker/irc.py
author Tero Marttila <terom@paivola.fi>
Sat, 12 Jan 2013 23:02:09 +0200
changeset 108 d2c1485af725
parent 93 d85d825cbca7
child 110 af87b706e4a3
permissions -rw-r--r--
pvl.irker: implement irc username
81
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
"""
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
    IRC client, dispatching irker messages.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
"""
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     4
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     5
from twisted.internet import reactor, interfaces, protocol, defer, error
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
from twisted.words.protocols import irc
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     8
from twisted.internet import endpoints
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    10
from twisted.python import log
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    11
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
PORT = 6667
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    13
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    14
def url2endpoint (reactor, url) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    15
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    16
        Turn given urlparse URL into an endpoint.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    17
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    18
        Raises KeyError on unknown scheme.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    19
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    20
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    21
    SCHEMES = {
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    22
            'irc':      lambda : endpoints.TCP4ClientEndpoint(reactor, url.hostname, url.port or PORT),
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    23
    }
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    24
    
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    25
    return SCHEMES[url.scheme]()
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    26
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    27
def normalize (name) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    28
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    29
        Normalize a channel/nickname for comparisons in IRC.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    30
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    32
    return name.lower()
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    33
108
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
    34
def myusername ():
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
    35
    """
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
    36
        Return username current process is running under.
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
    37
    """
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
    38
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
    39
    import getpass
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
    40
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
    41
    return getpass.getuser()
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
    42
81
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    43
class IRCError (Exception) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    44
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    45
        A handled protocol error.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    46
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    47
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    48
    pass
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    49
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    50
class IRCChannel (object) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    51
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    52
        A joined channel on an IRC server.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    53
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    54
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    55
    ENCODING = 'utf-8'
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    56
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    57
    def __init__ (self, client, channel, encoding=ENCODING) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    58
        self.client = client
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    59
        self.channel = channel
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    60
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    61
        self.encoding = encoding
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    62
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    63
    def privmsg (self, *msgs) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    64
        for msg in msgs :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    65
            # XXX: encode
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    66
            self.client.msg(self.channel, msg.encode(self.encoding))
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    67
83
1cb48f2ba1e9 pvl.irker/irk: implement support for NOTICE
Tero Marttila <terom@paivola.fi>
parents: 81
diff changeset
    68
    def notice (self, *msgs) :
1cb48f2ba1e9 pvl.irker/irk: implement support for NOTICE
Tero Marttila <terom@paivola.fi>
parents: 81
diff changeset
    69
        for msg in msgs :
1cb48f2ba1e9 pvl.irker/irk: implement support for NOTICE
Tero Marttila <terom@paivola.fi>
parents: 81
diff changeset
    70
            self.client.notice(self.channel, msg.encode(self.encoding))
1cb48f2ba1e9 pvl.irker/irk: implement support for NOTICE
Tero Marttila <terom@paivola.fi>
parents: 81
diff changeset
    71
81
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    72
    def errback (self, failure) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    73
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    74
            Fail any pending requests.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    75
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    76
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    77
        log.msg('IRCChannel.errback', self, failure)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    78
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    79
    def __str__ (self) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    80
        return self.client.url(self.channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    81
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    82
class IRCClient (irc.IRCClient) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    84
        A connection to an IRC server with a specific, requested nickname.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    85
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    86
        Joins to channels.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    87
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    88
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    89
    performLogin = False
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    90
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    91
    def __init__ (self, factory) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    92
        self.factory = factory
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    93
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    94
        self.nickname = None
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    95
        self.hostname = None
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    96
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    97
        self._registering = None
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    98
        self._channels = { }
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    99
84
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   100
        # TODO: smarter/configurable queueing?
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   101
        self.lineRate = 1.0
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   102
81
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   103
    def connectionMade (self) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   104
        self.hostname = self.transport.getPeer().host
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   105
        self.transport.logPrefix = self.logPrefix
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   106
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   107
        log.msg("connectionMade", self, self.transport)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   108
        irc.IRCClient.connectionMade(self)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   109
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   110
    def sendLine (self, line) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   111
        irc.IRCClient.sendLine(self, line)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   112
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   113
        log.msg(">>>", line)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   114
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   115
    def lineReceived (self, line) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   116
        log.msg("<<<", line)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   117
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   118
        irc.IRCClient.lineReceived(self, line)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   119
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   120
    ## Register
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   121
    def register (self, nickname, username=None, password=None) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   122
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   123
            Register to the server, choosing a nickname based on the given nickname.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   124
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   125
            Returns a Deferred that callbacks with our actual nickname once we have registered, or errbacks with an IRCError.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   126
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   127
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   128
        if self._registering :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   129
            raise Exception("register: already registering")
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   130
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   131
        self.username = username
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   132
        self.password = password
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   133
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   134
        log.msg("register", nickname)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   135
        irc.IRCClient.register(self, nickname)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   136
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   137
        # defer
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   138
        d = self._registering = defer.Deferred()
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   139
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   140
        return d
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   141
    
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   142
    # irc_ERR_NICKNAMEINUSE
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   143
    # alterCollidedNick
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   144
    # irc_ERR_ERRONEUSNICKNAME
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   145
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   146
    def irc_ERR_PASSWDMISMATCH (self, prefix, params) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   147
        err = IRCError('ERR_PASSWDMISMATCH')
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   148
        log.err(err)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   149
        self._registering.errback(err)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   150
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   151
    def irc_RPL_WELCOME (self, prefix, params) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   152
        self.hostname = prefix
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   153
        irc.IRCClient.irc_RPL_WELCOME(self, prefix, params)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   154
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   155
    def signedOn (self) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   156
        log.msg("signedOn", self.nickname)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   157
        irc.IRCClient.signedOn(self)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   158
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   159
        # defer
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   160
        d = self._registering
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   161
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   162
        if not d :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   163
            raise Exception("signedOn: not registering?")
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   164
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   165
        self._registering = None
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   166
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   167
        d.callback(self.nickname)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   168
    
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   169
    ## Channels
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   170
    def join (self, channel, key=None) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   171
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   172
            Join the given channel.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   173
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   174
            Returns a deferred that callbacks with the IRCChannel once joined, or errbacks.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   175
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   176
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   177
        irc.IRCClient.join(self, channel, key=key)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   178
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   179
        d = self._channels[normalize(channel)] = defer.Deferred()
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   180
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   181
        return d
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   182
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   183
    # ERR_CHANNELISFULL
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   184
    # ERR_INVITEONLYCHAN
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   185
    # ERR_BANNEDFROMCHAN
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   186
    # ERR_BADCHANNELKEY
84
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   187
    
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   188
    def _close_channel (self, channel) :
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   189
        """
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   190
            Remove channel from our list of channels.
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   191
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   192
            TODO: purge queued messages for channel?
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   193
        """
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   194
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   195
        del self._channels[normalize(channel)]
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   196
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   197
    def left (self, channel) :
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   198
        log.msg('IRCClient.left', channel)
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   199
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   200
        self._close_channel(channel)
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   201
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   202
    def kickedFrom (self, channel, kicker, message) :
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   203
        log.msg('IRCClient.kicked', channel, kicker, message)
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   204
        
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   205
        self._close_channel(channel)
81
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   206
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   207
    def joined (self, channel) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   208
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   209
            Have joined given channel.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   210
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   211
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   212
        lookup = normalize(channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   213
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   214
        d = self._channels[lookup]
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   215
        channel = self._channels[lookup] = IRCChannel(self, channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   216
        d.callback(channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   217
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   218
    @defer.inlineCallbacks
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   219
    def channel (self, channel, key=None) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   220
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   221
            Defer a joined IRCChannel.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   222
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   223
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   224
        lookup = normalize(channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   225
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   226
        log.msg('IRCClient.channel', lookup, channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   227
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   228
        if lookup not in self._channels :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   229
            channel = yield self.join(channel, key)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   230
        else :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   231
            # wait or get
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   232
            yield self._channels[lookup]
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   233
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   234
        channel = self._channels[lookup]
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   235
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   236
        log.msg('IRCClient.channel', lookup, channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   237
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   238
        defer.returnValue(channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   239
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   240
    ## 
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   241
    def irc_ERR_CANNOTSENDTOCHAN (self, prefix, params) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   242
        nick, channel, error = params
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   243
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   244
        log.err(IRCError(channel, error))
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   245
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   246
    ## Quit
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   247
    def irc_ERROR (self, prefix, params) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   248
        msg, = params
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   249
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   250
        log.err(IRCError(None, msg))
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   251
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   252
    def connectionLost (self, reason) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   253
        irc.IRCClient.connectionLost(self, reason)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   254
        log.err(reason)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   255
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   256
        if self._registering :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   257
            self._registering.errback(reason)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   258
            self._registering = None
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   259
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   260
        # unregister channels
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   261
        for channel in self._channels :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   262
            # errback Deferred or IRCChannel
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   263
            self._channels[channel].errback(reason)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   264
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   265
        self._channels = { }
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   266
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   267
        # unregister client
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   268
        self.factory.clientLost(self)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   269
    
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   270
    ## Logging
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   271
    def url (self, target=None) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   272
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   273
            Format as URL.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   274
        """
93
d85d825cbca7 pvl.irker: handle missing transport in logPrefix (only happens when daemonized, for whatever reason)
Tero Marttila <terom@paivola.fi>
parents: 84
diff changeset
   275
d85d825cbca7 pvl.irker: handle missing transport in logPrefix (only happens when daemonized, for whatever reason)
Tero Marttila <terom@paivola.fi>
parents: 84
diff changeset
   276
        if not self.transport : return 'IRC'
81
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   277
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   278
        # XXX: no isinstance() support
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   279
        if interfaces.ITCPTransport.providedBy(self.transport) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   280
            scheme = 'irc'
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   281
        else :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   282
            # TODO: ssl?
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   283
            scheme = None
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   284
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   285
        peer = self.transport.getPeer()
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   286
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   287
        if peer.port == PORT :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   288
            peer = "{irc.hostname}".format(irc=self, peer=peer)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   289
        else :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   290
            peer = "{irc.hostname}:{peer.port}".format(irc=self, peer=peer)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   291
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   292
        if target :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   293
            path = str(target)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   294
        else :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   295
            path = None
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   296
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   297
        return ''.join(part for part in (
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   298
            scheme, '://' if scheme else None,
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   299
            self.nickname, '@' if self.nickname else None,
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   300
            peer,
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   301
            '/' if path else None, path
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   302
        ) if part)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   303
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   304
    __str__ = url
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   305
    logPrefix = url
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   306
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   307
class IRCFactory (protocol.ClientFactory) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   308
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   309
        Manage Clients and Targets
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   310
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   311
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   312
    NICKNAME = 'irker'
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   313
108
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
   314
    def __init__ (self, nickname=NICKNAME, username=None) :
81
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   315
        # default nickname
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   316
        self.nickname = nickname
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   317
108
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
   318
        if username is True :
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
   319
            # system
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
   320
            self.username = myusername()
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
   321
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
   322
        else :
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
   323
            self.username = username
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
   324
81
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   325
        # (scheme, host, port, nick) -> IRCClient
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   326
        self.clients = {}
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   327
    
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   328
    def buildProtocol (self, addr) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   329
        return IRCClient(self)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   330
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   331
    def clientLost (self, client) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   332
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   333
            Given IRCClient is no more.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   334
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   335
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   336
        log.msg("IRCFactory.clientLost", client)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   337
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   338
        # remove from our clients
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   339
        self.clients = dict((k, c) for k, c in self.clients.iteritems() if c != client)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   340
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   341
    @defer.inlineCallbacks
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   342
    def connect (self, url) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   343
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   344
            Defer a connected, registered Client for given URL.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   345
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   346
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   347
        endpoint = url2endpoint(reactor, url)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   348
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   349
        log.msg('IRCFactory.connect', url, ':', endpoint)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   350
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   351
        # connect
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   352
        try :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   353
            client = yield endpoint.connect(self)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   354
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   355
        except error.ConnectError as ex :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   356
            log.err(ex, ': '.join(str(x) for x in ('IRCFactory.connect', url, endpoint)))
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   357
            raise
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   358
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   359
        else :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   360
            log.msg('IRCFactory.connect', url, ':', endpoint, ':', client)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   361
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   362
        # register
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   363
        try :
108
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
   364
            nickname = yield client.register(url.username or self.nickname, 
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
   365
                    username    = self.username,
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
   366
                    password    = url.password, 
d2c1485af725 pvl.irker: implement irc username
Tero Marttila <terom@paivola.fi>
parents: 93
diff changeset
   367
            )
81
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   368
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   369
        except Exception as ex :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   370
            log.err("register", ex)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   371
            raise
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   372
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   373
        log.msg('IRCFactory.connect', url, ':', endpoint, ':', client, ':', nickname)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   374
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   375
        # okay!
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   376
        defer.returnValue(client)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   377
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   378
    @defer.inlineCallbacks
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   379
    def client (self, url) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   380
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   381
            Return IRCClient for given URL.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   382
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   383
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   384
        lookup = (url.scheme, url.hostname, url.port, url.username)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   385
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   386
        if lookup not in self.clients :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   387
            # deferred for connect
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   388
            connect = self.clients[lookup] = self.connect(url)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   389
            
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   390
            try :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   391
                # wait on deferred, and then store IRCClient
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   392
                self.clients[lookup] = yield connect
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   393
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   394
            except Exception as ex :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   395
                # failed, remove the attempted connect
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   396
                del self.clients[lookup]
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   397
                raise
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   398
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   399
        else :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   400
            # wait for result, if deferred
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   401
            # XXX: this yields None, since the first inlineCallbacks yielding on the deferred returns None in its callback
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   402
            yield self.clients[lookup]
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   403
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   404
        # connected client
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   405
        client = self.clients[lookup]
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   406
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   407
        log.msg('IRCFactory.client', url, ":", client)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   408
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   409
        defer.returnValue(client)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   410
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   411
    @defer.inlineCallbacks
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   412
    def target (self, url) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   413
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   414
            Return IRCChannel for given URL.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   415
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   416
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   417
        client = yield self.client(url)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   418
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   419
        channel = '#' + url.path.lstrip('/')
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   420
        channel = yield client.channel(channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   421
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   422
        log.msg('IRCFactory.target', url, ":", channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   423
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   424
        defer.returnValue(channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   425
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   426
    @defer.inlineCallbacks
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   427
    def privmsg (self, url, *msg) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   428
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   429
            Dispatch given messages to given target.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   430
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   431
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   432
        target = yield self.target(url)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   433
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   434
        log.msg('IRCFactory.privmsg', url, ":", target, ':', *msg)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   435
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   436
        target.privmsg(*msg)