pvl/irker/irc.py
author Tero Marttila <terom@paivola.fi>
Fri, 11 Jan 2013 22:04:11 +0200
changeset 84 e5f36ec2e8d2
parent 83 1cb48f2ba1e9
child 93 d85d825cbca7
permissions -rw-r--r--
pvl.irker.irc: handle channel kick/part
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
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    34
class IRCError (Exception) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    35
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    36
        A handled protocol error.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    37
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    38
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    39
    pass
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    40
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    41
class IRCChannel (object) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    42
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    43
        A joined channel on an IRC server.
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
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    46
    ENCODING = 'utf-8'
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
    def __init__ (self, client, channel, encoding=ENCODING) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    49
        self.client = client
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    50
        self.channel = channel
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
        self.encoding = encoding
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
    def privmsg (self, *msgs) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    55
        for msg in msgs :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    56
            # XXX: encode
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    57
            self.client.msg(self.channel, msg.encode(self.encoding))
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    58
83
1cb48f2ba1e9 pvl.irker/irk: implement support for NOTICE
Tero Marttila <terom@paivola.fi>
parents: 81
diff changeset
    59
    def notice (self, *msgs) :
1cb48f2ba1e9 pvl.irker/irk: implement support for NOTICE
Tero Marttila <terom@paivola.fi>
parents: 81
diff changeset
    60
        for msg in msgs :
1cb48f2ba1e9 pvl.irker/irk: implement support for NOTICE
Tero Marttila <terom@paivola.fi>
parents: 81
diff changeset
    61
            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
    62
81
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    63
    def errback (self, failure) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    64
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    65
            Fail any pending requests.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    66
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    67
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    68
        log.msg('IRCChannel.errback', self, failure)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    69
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    70
    def __str__ (self) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    71
        return self.client.url(self.channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    72
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    73
class IRCClient (irc.IRCClient) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    74
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    75
        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
    76
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    77
        Joins to channels.
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
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    80
    performLogin = False
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
    def __init__ (self, factory) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83
        self.factory = factory
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    84
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    85
        self.nickname = None
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    86
        self.hostname = None
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
        self._registering = None
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    89
        self._channels = { }
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    90
84
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
    91
        # TODO: smarter/configurable queueing?
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
    92
        self.lineRate = 1.0
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
    93
81
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    94
    def connectionMade (self) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    95
        self.hostname = self.transport.getPeer().host
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    96
        self.transport.logPrefix = self.logPrefix
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    97
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    98
        log.msg("connectionMade", self, self.transport)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    99
        irc.IRCClient.connectionMade(self)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   100
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   101
    def sendLine (self, line) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   102
        irc.IRCClient.sendLine(self, line)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   103
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   104
        log.msg(">>>", line)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   105
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   106
    def lineReceived (self, line) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   107
        log.msg("<<<", line)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   108
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   109
        irc.IRCClient.lineReceived(self, line)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   110
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   111
    ## Register
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   112
    def register (self, nickname, username=None, password=None) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   113
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   114
            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
   115
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   116
            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
   117
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   118
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   119
        if self._registering :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   120
            raise Exception("register: already registering")
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   121
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   122
        self.username = username
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   123
        self.password = password
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
        log.msg("register", nickname)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   126
        irc.IRCClient.register(self, nickname)
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
        # defer
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   129
        d = self._registering = defer.Deferred()
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
        return d
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   132
    
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   133
    # irc_ERR_NICKNAMEINUSE
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   134
    # alterCollidedNick
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   135
    # irc_ERR_ERRONEUSNICKNAME
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
    def irc_ERR_PASSWDMISMATCH (self, prefix, params) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   138
        err = IRCError('ERR_PASSWDMISMATCH')
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   139
        log.err(err)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   140
        self._registering.errback(err)
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
    def irc_RPL_WELCOME (self, prefix, params) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   143
        self.hostname = prefix
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   144
        irc.IRCClient.irc_RPL_WELCOME(self, prefix, params)
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 signedOn (self) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   147
        log.msg("signedOn", self.nickname)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   148
        irc.IRCClient.signedOn(self)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   149
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   150
        # defer
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   151
        d = self._registering
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   152
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   153
        if not d :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   154
            raise Exception("signedOn: not registering?")
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   155
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   156
        self._registering = None
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   157
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   158
        d.callback(self.nickname)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   159
    
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   160
    ## Channels
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   161
    def join (self, channel, key=None) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   162
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   163
            Join the given channel.
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
            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
   166
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   167
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   168
        irc.IRCClient.join(self, channel, key=key)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   169
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   170
        d = self._channels[normalize(channel)] = defer.Deferred()
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
        return d
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
    # ERR_CHANNELISFULL
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   175
    # ERR_INVITEONLYCHAN
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   176
    # ERR_BANNEDFROMCHAN
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   177
    # ERR_BADCHANNELKEY
84
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   178
    
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   179
    def _close_channel (self, channel) :
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   180
        """
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   181
            Remove channel from our list of channels.
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   182
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   183
            TODO: purge queued messages for channel?
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   184
        """
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   185
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   186
        del self._channels[normalize(channel)]
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 left (self, channel) :
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   189
        log.msg('IRCClient.left', channel)
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   190
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   191
        self._close_channel(channel)
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   192
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   193
    def kickedFrom (self, channel, kicker, message) :
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   194
        log.msg('IRCClient.kicked', channel, kicker, message)
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   195
        
e5f36ec2e8d2 pvl.irker.irc: handle channel kick/part
Tero Marttila <terom@paivola.fi>
parents: 83
diff changeset
   196
        self._close_channel(channel)
81
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   197
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   198
    def joined (self, channel) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   199
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   200
            Have joined given channel.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   201
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   202
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   203
        lookup = normalize(channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   204
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   205
        d = self._channels[lookup]
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   206
        channel = self._channels[lookup] = IRCChannel(self, channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   207
        d.callback(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
    @defer.inlineCallbacks
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   210
    def channel (self, channel, key=None) :
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
            Defer a joined IRCChannel.
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
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   215
        lookup = normalize(channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   216
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   217
        log.msg('IRCClient.channel', lookup, channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   218
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   219
        if lookup not in self._channels :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   220
            channel = yield self.join(channel, key)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   221
        else :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   222
            # wait or get
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   223
            yield self._channels[lookup]
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   224
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   225
        channel = self._channels[lookup]
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   226
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   227
        log.msg('IRCClient.channel', lookup, channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   228
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   229
        defer.returnValue(channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   230
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   231
    ## 
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   232
    def irc_ERR_CANNOTSENDTOCHAN (self, prefix, params) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   233
        nick, channel, error = params
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   234
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   235
        log.err(IRCError(channel, error))
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   236
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   237
    ## Quit
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   238
    def irc_ERROR (self, prefix, params) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   239
        msg, = params
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
        log.err(IRCError(None, msg))
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   242
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   243
    def connectionLost (self, reason) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   244
        irc.IRCClient.connectionLost(self, reason)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   245
        log.err(reason)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   246
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   247
        if self._registering :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   248
            self._registering.errback(reason)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   249
            self._registering = None
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   250
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   251
        # unregister channels
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   252
        for channel in self._channels :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   253
            # errback Deferred or IRCChannel
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   254
            self._channels[channel].errback(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
        self._channels = { }
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   257
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   258
        # unregister client
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   259
        self.factory.clientLost(self)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   260
    
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   261
    ## Logging
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   262
    def url (self, target=None) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   263
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   264
            Format as URL.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   265
        """
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
        # XXX: no isinstance() support
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   268
        if interfaces.ITCPTransport.providedBy(self.transport) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   269
            scheme = 'irc'
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   270
        else :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   271
            # TODO: ssl?
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   272
            scheme = None
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   273
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   274
        peer = self.transport.getPeer()
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   275
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   276
        if peer.port == PORT :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   277
            peer = "{irc.hostname}".format(irc=self, peer=peer)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   278
        else :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   279
            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
   280
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   281
        if target :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   282
            path = str(target)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   283
        else :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   284
            path = None
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   285
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   286
        return ''.join(part for part in (
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   287
            scheme, '://' if scheme else None,
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   288
            self.nickname, '@' if self.nickname else None,
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   289
            peer,
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   290
            '/' if path else None, path
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   291
        ) if part)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   292
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   293
    __str__ = url
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   294
    logPrefix = url
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   295
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   296
class IRCFactory (protocol.ClientFactory) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   297
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   298
        Manage Clients and Targets
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   299
    """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   300
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   301
    NICKNAME = 'irker'
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   302
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   303
    def __init__ (self, nickname=NICKNAME) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   304
        # default nickname
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   305
        self.nickname = nickname
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
        # (scheme, host, port, nick) -> IRCClient
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   308
        self.clients = {}
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   309
    
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   310
    def buildProtocol (self, addr) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   311
        return IRCClient(self)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   312
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   313
    def clientLost (self, client) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   314
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   315
            Given IRCClient is no more.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   316
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   317
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   318
        log.msg("IRCFactory.clientLost", client)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   319
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   320
        # remove from our clients
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   321
        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
   322
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   323
    @defer.inlineCallbacks
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   324
    def connect (self, url) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   325
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   326
            Defer a connected, registered Client for given URL.
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
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   329
        endpoint = url2endpoint(reactor, url)
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
        log.msg('IRCFactory.connect', url, ':', endpoint)
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
        # connect
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   334
        try :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   335
            client = yield endpoint.connect(self)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   336
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   337
        except error.ConnectError as ex :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   338
            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
   339
            raise
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
        else :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   342
            log.msg('IRCFactory.connect', url, ':', endpoint, ':', client)
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
        # register
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   345
        try :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   346
            nickname = yield client.register(url.username or self.nickname, url.password)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   347
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   348
        except Exception as ex :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   349
            log.err("register", ex)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   350
            raise
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   351
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   352
        log.msg('IRCFactory.connect', url, ':', endpoint, ':', client, ':', nickname)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   353
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   354
        # okay!
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   355
        defer.returnValue(client)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   356
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   357
    @defer.inlineCallbacks
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   358
    def client (self, url) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   359
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   360
            Return IRCClient for given URL.
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
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   363
        lookup = (url.scheme, url.hostname, url.port, url.username)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   364
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   365
        if lookup not in self.clients :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   366
            # deferred for connect
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   367
            connect = self.clients[lookup] = self.connect(url)
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
            try :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   370
                # wait on deferred, and then store IRCClient
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   371
                self.clients[lookup] = yield connect
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
            except Exception as ex :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   374
                # failed, remove the attempted connect
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   375
                del self.clients[lookup]
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   376
                raise
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
        else :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   379
            # wait for result, if deferred
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   380
            # 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
   381
            yield self.clients[lookup]
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
        # connected client
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   384
        client = self.clients[lookup]
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
        log.msg('IRCFactory.client', url, ":", client)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   387
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   388
        defer.returnValue(client)
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
    @defer.inlineCallbacks
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   391
    def target (self, url) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   392
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   393
            Return IRCChannel for given URL.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   394
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   395
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   396
        client = yield self.client(url)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   397
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   398
        channel = '#' + url.path.lstrip('/')
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   399
        channel = yield client.channel(channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   400
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   401
        log.msg('IRCFactory.target', url, ":", channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   402
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   403
        defer.returnValue(channel)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   404
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   405
    @defer.inlineCallbacks
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   406
    def privmsg (self, url, *msg) :
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   407
        """
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   408
            Dispatch given messages to given target.
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   409
        """
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
        target = yield self.target(url)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   412
        
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   413
        log.msg('IRCFactory.privmsg', url, ":", target, ':', *msg)
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   414
448ed86d0510 pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   415
        target.privmsg(*msg)