| author | Tero Marttila <terom@paivola.fi> |
| Tue, 19 Feb 2013 19:27:51 +0200 | |
| changeset 220 | e533260bcefd |
| parent 127 | f143171884f9 |
| permissions | -rw-r--r-- |
|
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 |
Irker protocol implementation. |
|
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 protocol, defer |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
6 |
from twisted.protocols import basic |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
7 |
from twisted.python import log |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
8 |
|
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
9 |
import json, urlparse |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
10 |
|
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
11 |
class Irk (basic.LineOnlyReceiver) : |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
12 |
""" |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
13 |
A connected Irk client. |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
14 |
""" |
|
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 |
delimiter = '\n' |
|
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 |
def connectionMade (self) : |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
19 |
self.transport.logPrefix = self.logPrefix |
|
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 |
log.msg("connected", self)
|
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
22 |
|
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
23 |
def connectionLost (self, reason) : |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
24 |
log.err("connection lost", reason)
|
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
25 |
|
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
26 |
def error (self, *args) : |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
27 |
log.err(*args) |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
28 |
self.transport.loseConnection() |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
29 |
|
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
30 |
def lineReceived (self, line) : |
|
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 |
JSON -> in |
|
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 |
|
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
35 |
try : |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
36 |
irk = json.loads(line) |
|
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 |
except ValueError as ex : |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
39 |
# invalid |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
40 |
return self.error(ex, line) |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
41 |
|
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
42 |
# dispatch |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
43 |
self.factory.irkReceived(irk).addErrback(self.error, line) |
|
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 |
def __str__ (self) : |
|
93
d85d825cbca7
pvl.irker: handle missing transport in logPrefix (only happens when daemonized, for whatever reason)
Tero Marttila <terom@paivola.fi>
parents:
83
diff
changeset
|
46 |
if not self.transport : return 'Irk' |
|
d85d825cbca7
pvl.irker: handle missing transport in logPrefix (only happens when daemonized, for whatever reason)
Tero Marttila <terom@paivola.fi>
parents:
83
diff
changeset
|
47 |
|
|
81
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
48 |
host = self.transport.getHost() |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
49 |
peer = self.transport.getPeer() |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
50 |
|
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
51 |
return "{host.host}:{host.port}:{peer.host}".format(host=host, peer=peer)
|
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
52 |
|
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
53 |
logPrefix = __str__ |
|
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 |
class IrkFactory (protocol.ServerFactory) : |
|
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 |
Manage connected Irk clients. |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
58 |
""" |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
59 |
|
| 127 | 60 |
MAXATTR = 16 |
61 |
||
|
81
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
62 |
protocol = Irk |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
63 |
|
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
64 |
def __init__ (self, irc) : |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
65 |
self.irc = irc |
|
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 |
@defer.inlineCallbacks |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
68 |
def irkReceived (self, irk) : |
|
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 |
Deffered to handle lookup of target, and then sending message. |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
71 |
|
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
72 |
Errbacks on failures. |
|
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 |
|
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
75 |
log.msg(str(irk)) |
|
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 |
if not 'to' in irk : |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
78 |
raise ValueError("missing target: to")
|
|
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 |
# MUST NOT be unicode |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
81 |
# XXX: ValueError? |
| 127 | 82 |
url = urlparse.urlparse(str(irk.pop('to')))
|
|
81
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
83 |
|
| 127 | 84 |
# connect, register, join |
|
81
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
85 |
target = yield self.irc.target(url) |
|
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
86 |
|
| 127 | 87 |
# dispatch attrs |
88 |
for attr, value in irk.iteritems() : |
|
89 |
if len(attr) >= self.MAXATTR or not attr.islower() : |
|
90 |
raise ValueError("invalid attr: %s" % (attr, ))
|
|
91 |
||
92 |
method = getattr(self, 'irk_' + attr, None) |
|
93 |
||
94 |
if not method : |
|
95 |
raise ValueError("unknown attr: %s" % (attr, ))
|
|
|
81
448ed86d0510
pvl.irker: irker reimplementation in Twisted
Tero Marttila <terom@paivola.fi>
parents:
diff
changeset
|
96 |
|
|
83
1cb48f2ba1e9
pvl.irker/irk: implement support for NOTICE
Tero Marttila <terom@paivola.fi>
parents:
81
diff
changeset
|
97 |
if value : |
|
1cb48f2ba1e9
pvl.irker/irk: implement support for NOTICE
Tero Marttila <terom@paivola.fi>
parents:
81
diff
changeset
|
98 |
value = unicode(value) |
| 127 | 99 |
else : |
100 |
value = None |
|
|
83
1cb48f2ba1e9
pvl.irker/irk: implement support for NOTICE
Tero Marttila <terom@paivola.fi>
parents:
81
diff
changeset
|
101 |
|
| 127 | 102 |
method(target, value) |
103 |
||
104 |
# XXX: explicitly enable? |
|
105 |
def irk_privmsg (self, target, value) : |
|
106 |
""" |
|
107 |
Send PRIVMSG to target. |
|
108 |
""" |
|
109 |
||
110 |
if not value : |
|
111 |
# legacy |
|
112 |
return |
|
113 |
||
114 |
target.privmsg(value) |
|
115 |
||
116 |
def irk_notice (self, target, value) : |
|
117 |
""" |
|
118 |
Send NOTICE to target. |
|
119 |
""" |
|
120 |
||
121 |
if not value : |
|
122 |
raise ValueError("empty notice")
|
|
123 |
||
124 |
target.notice(value) |
|
125 |
||
126 |
# TODO: refcounting vs join! |
|
127 |
def irk_part (self, target, value) : |
|
128 |
""" |
|
129 |
PART target. |
|
130 |
""" |
|
131 |
||
132 |
# value is optional |
|
133 |
target.part(value) |