-
Notifications
You must be signed in to change notification settings - Fork 288
/
transformedpoetry.py
126 lines (78 loc) · 3.23 KB
/
transformedpoetry.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# This is the Twisted Poetry Transform Server, version 1.0
import sys
import optparse
from twisted.internet.protocol import ServerFactory
from twisted.protocols.basic import NetstringReceiver
from twisted.python import log
def parse_args():
usage = """usage: %prog [options]
This is the Poetry Transform Server.
Run it like this:
python transformedpoetry.py
If you are in the base directory of the twisted-intro package,
you could run it like this:
python twisted-server-1/transformedpoetry.py --port 11000
to provide poetry transformation on port 11000.
"""
parser = optparse.OptionParser(usage)
help = "The port to listen on. Default to a random available port."
parser.add_option('--port', type='int', help=help)
help = "The interface to listen on. Default is localhost."
parser.add_option('--iface', help=help, default='localhost')
options, args = parser.parse_args()
if len(args) != 0:
parser.error('Bad arguments.')
return options
class TransformService(object):
def cummingsify(self, poem):
return poem.lower()
class TransformProtocol(NetstringReceiver):
'''The goal of separating the protocol and service ideally would put the
utf8 processing in the service. However python names are now unicode.
That means we can not use a byte string in the getattr call.
I put the decode into stringReceived and overrode sendString to encode the data.
Ideally we would probably want the decode/encode in the TransformService.
The error handling was modified to provide feedback about what was truly failing.
The original except returning None was not helpful.
'''
def stringReceived(self, request):
if b'.' not in request: # bad request
self.transport.loseConnection()
return
xform_name, poem = request.decode('utf8').split('.', 1)
self.xformRequestReceived(xform_name, poem)
def sendString(self, string):
# Netstrings are really byte strings
super().sendString(string.encode('utf8'))
def xformRequestReceived(self, xform_name, poem):
new_poem = self.factory.transform(xform_name, poem)
if new_poem is not None:
self.sendString(new_poem)
self.transport.loseConnection()
class TransformFactory(ServerFactory):
protocol = TransformProtocol
def __init__(self, service):
self.service = service
def transform(self, xform_name, poem):
thunk = getattr(self, 'xform_%s' % (xform_name,), None)
if thunk is None: # no such transform
log.msg("%r no such transform" % xform_name)
return None
try:
return thunk(poem)
except:
log.msg(sys.exc_info()[0])
return None # transform failed
def xform_cummingsify(self, poem):
return self.service.cummingsify(poem)
def main():
options = parse_args()
service = TransformService()
factory = TransformFactory(service)
from twisted.internet import reactor
port = reactor.listenTCP(options.port or 0, factory,
interface=options.iface)
print('Serving transforms on %s.' % (port.getHost(),))
reactor.run()
if __name__ == '__main__':
main()