]> jfr.im git - irc/quakenet/qwebirc.git/blob - qwebirc/ircclient.py
Add connection dialog.
[irc/quakenet/qwebirc.git] / qwebirc / ircclient.py
1 import twisted, sys
2 from twisted.words.protocols import irc
3 from twisted.internet import reactor, protocol
4 from twisted.web import resource, server
5 from twisted.protocols import basic
6
7 import hmac, time, config
8 from config import HMACTEMPORAL
9 HMACKEY = hmac.HMAC(key=config.HMACKEY)
10
11 def hmacfn(*args):
12 h = HMACKEY.copy()
13 h.update("%d %s" % (int(time.time() / HMACTEMPORAL), " ".join(args)))
14 return h.hexdigest()
15
16 class QWebIRCClient(basic.LineReceiver):
17 delimiter = "\n"
18
19 def dataReceived(self, data):
20 basic.LineReceiver.dataReceived(self, data.replace("\r", ""))
21
22 def lineReceived(self, line):
23 line = irc.lowDequote(line)
24 try:
25 line = line.decode("utf-8")
26 except UnicodeDecodeError:
27 line = line.decode("iso-8859-1", "ignore")
28
29 try:
30 prefix, command, params = irc.parsemsg(line)
31 self.handleCommand(command, prefix, params)
32 except irc.IRCBadMessage:
33 self.badMessage(line, *sys.exc_info())
34
35 def badMessage(self, args):
36 self("badmessage", args)
37
38 def handleCommand(self, command, prefix, params):
39 self("c", command, prefix, params)
40
41 def __call__(self, *args):
42 self.factory.publisher.event(args)
43
44 def write(self, data):
45 self.transport.write("%s\r\n" % irc.lowQuote(data.encode("utf-8")))
46
47 def connectionMade(self):
48 basic.LineReceiver.connectionMade(self)
49
50 self.lastError = None
51 f = self.factory.ircinit
52 nick, ident, ip, realname = f["nick"], f["ident"], f["ip"], f["realname"]
53
54 hmac = hmacfn(ident, ip)
55 self.write("USER %s bleh bleh %s %s :%s" % (ident, ip, hmac, realname))
56 self.write("NICK %s" % nick)
57
58 self.factory.client = self
59 self("connect")
60
61 def connectionLost(self, reason):
62 if self.lastError:
63 self.disconnect("Connection to IRC server lost: %s" % self.lastError)
64 else:
65 self.disconnect("Connection to IRC server lost.")
66 self.factory.client = None
67 basic.LineReceiver.connectionLost(self, reason)
68
69 def error(self, message):
70 self.lastError = message
71 self.write("QUIT :qwebirc exception: %s" % message)
72 self.transport.loseConnection()
73
74 def disconnect(self, reason):
75 self("disconnect", reason)
76 self.factory.publisher.disconnect()
77
78 class QWebIRCFactory(protocol.ClientFactory):
79 protocol = QWebIRCClient
80 def __init__(self, publisher, **kwargs):
81 self.client = None
82 self.publisher = publisher
83 self.ircinit = kwargs
84
85 def write(self, data):
86 self.client.write(data)
87
88 def error(self, reason):
89 self.client.error(reason)
90
91 def clientConnectionFailed(self, reason):
92 protocol.ClientFactory.clientConnectionFailed(reason)
93 self.client.disconnect("Connection to IRC server failed.")
94
95 def createIRC(*args, **kwargs):
96 f = QWebIRCFactory(*args, **kwargs)
97 reactor.connectTCP(config.IRCSERVER, config.IRCPORT, f)
98 return f
99
100 if __name__ == "__main__":
101 e = createIRC(lambda x: 2, nick="slug__moo", ident="mooslug", ip="1.2.3.6", realname="mooooo")
102 reactor.run()