]> jfr.im git - irc/quakenet/qwebirc.git/blame - qwebirc/ircclient.py
Add QTicket support!
[irc/quakenet/qwebirc.git] / qwebirc / ircclient.py
CommitLineData
9e769c12
CP
1import twisted, sys
2from twisted.words.protocols import irc
3from twisted.internet import reactor, protocol
4from twisted.web import resource, server
5from twisted.protocols import basic
6
7import hmac, time, config
8from config import HMACTEMPORAL
9HMACKEY = hmac.HMAC(key=config.HMACKEY)
10
11def hmacfn(*args):
12 h = HMACKEY.copy()
13 h.update("%d %s" % (int(time.time() / HMACTEMPORAL), " ".join(args)))
14 return h.hexdigest()
15
16class 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
83class 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
101def createIRC(*args, **kwargs):
102 f = QWebIRCFactory(*args, **kwargs)
103 reactor.connectTCP(config.IRCSERVER, config.IRCPORT, f)
104 return f
105
106if __name__ == "__main__":
107 e = createIRC(lambda x: 2, nick="slug__moo", ident="mooslug", ip="1.2.3.6", realname="mooooo")
8dc46dfa 108 reactor.run()