]>
Commit | Line | Data |
---|---|---|
9e769c12 CP |
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" | |
8dc46dfa | 18 | |
9e769c12 CP |
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()) | |
ace37679 CP |
34 | |
35 | if command == "001" and self.__perform: | |
36 | for x in self.__perform: | |
37 | self.write(x) | |
38 | ||
9e769c12 CP |
39 | def badMessage(self, args): |
40 | self("badmessage", args) | |
41 | ||
42 | def handleCommand(self, command, prefix, params): | |
43 | self("c", command, prefix, params) | |
44 | ||
45 | def __call__(self, *args): | |
46 | self.factory.publisher.event(args) | |
47 | ||
48 | def write(self, data): | |
49 | self.transport.write("%s\r\n" % irc.lowQuote(data.encode("utf-8"))) | |
50 | ||
51 | def connectionMade(self): | |
52 | basic.LineReceiver.connectionMade(self) | |
53 | ||
8dc46dfa | 54 | self.lastError = None |
9e769c12 CP |
55 | f = self.factory.ircinit |
56 | nick, ident, ip, realname = f["nick"], f["ident"], f["ip"], f["realname"] | |
ace37679 | 57 | self.__perform = f.get("perform") |
9e769c12 CP |
58 | |
59 | hmac = hmacfn(ident, ip) | |
60 | self.write("USER %s bleh bleh %s %s :%s" % (ident, ip, hmac, realname)) | |
61 | self.write("NICK %s" % nick) | |
62 | ||
63 | self.factory.client = self | |
64 | self("connect") | |
65 | ||
66 | def connectionLost(self, reason): | |
8dc46dfa CP |
67 | if self.lastError: |
68 | self.disconnect("Connection to IRC server lost: %s" % self.lastError) | |
69 | else: | |
70 | self.disconnect("Connection to IRC server lost.") | |
9e769c12 CP |
71 | self.factory.client = None |
72 | basic.LineReceiver.connectionLost(self, reason) | |
8dc46dfa CP |
73 | |
74 | def error(self, message): | |
75 | self.lastError = message | |
76 | self.write("QUIT :qwebirc exception: %s" % message) | |
77 | self.transport.loseConnection() | |
78 | ||
79 | def disconnect(self, reason): | |
80 | self("disconnect", reason) | |
81 | self.factory.publisher.disconnect() | |
9e769c12 CP |
82 | |
83 | class QWebIRCFactory(protocol.ClientFactory): | |
84 | protocol = QWebIRCClient | |
85 | def __init__(self, publisher, **kwargs): | |
86 | self.client = None | |
87 | self.publisher = publisher | |
88 | self.ircinit = kwargs | |
89 | ||
90 | def write(self, data): | |
91 | self.client.write(data) | |
8dc46dfa CP |
92 | |
93 | def error(self, reason): | |
94 | self.client.error(reason) | |
95 | ||
623b5428 CP |
96 | def clientConnectionFailed(self, connector, reason): |
97 | protocol.ClientFactory.clientConnectionFailed(self, connector, reason) | |
98 | self.publisher.event(["disconnect", "Connection to IRC server failed."]) | |
99 | self.publisher.disconnect() | |
8dc46dfa | 100 | |
9e769c12 CP |
101 | def createIRC(*args, **kwargs): |
102 | f = QWebIRCFactory(*args, **kwargs) | |
103 | reactor.connectTCP(config.IRCSERVER, config.IRCPORT, f) | |
104 | return f | |
105 | ||
106 | if __name__ == "__main__": | |
107 | e = createIRC(lambda x: 2, nick="slug__moo", ident="mooslug", ip="1.2.3.6", realname="mooooo") | |
8dc46dfa | 108 | reactor.run() |