1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """
24 FUDI protocol implementation in Python using Twisted.
25
26 Simple ASCII based protocol from Miller Puckette for Pure Data.
27 """
28
29 import types
30
31 from twisted.internet import reactor
32 from twisted.internet.protocol import Protocol
33 from twisted.internet.protocol import ClientCreator
34 from twisted.internet.protocol import Factory
35 from twisted.internet.protocol import ClientFactory
36 from twisted.protocols import basic
37 from twisted.python import log
38
39 VERBOSE = False
40
42 """
43 Converts int, float, string to FUDI atoms string.
44 :param data: list of basic types variables.
45 Public FUDI message converter
46 """
47
48
49 txt = str(selector)
50 for atom in atoms:
51 txt = txt + " %s" % (atom)
52 txt = txt + " ;\r\n"
53 return txt
54
56 """
57 FUDI protocol implementation in Python.
58
59 Simple ASCII based protocol from Miller Puckette for Pure Data.
60 """
61
62
63
64 delimiter = ';'
65
67 if VERBOSE:
68 print "FUDI: data:", data
69 try:
70 message = data.split(";")[0].strip()
71 except KeyError:
72 log.msg("Got a line without trailing semi-colon.")
73 else:
74 if VERBOSE:
75 print "FUDI: message:", message
76 atoms = message.split()
77 if len(atoms) > 0:
78 output = []
79 selector = atoms[0]
80 for atom in atoms[1:]:
81 atom = atom.strip()
82 if VERBOSE:
83 print "FUDI: > atom:", atom
84 if atom.isdigit():
85 output.append(int(atom))
86 else:
87 try:
88 val = float(atom)
89 output.append(atom)
90 except ValueError:
91 output.append(str(atom))
92 if self.factory.callbacks.has_key(selector):
93 if VERBOSE:
94 print "FUDI: Calling :", selector, output
95 try:
96 self.factory.callbacks[selector](self, *output)
97 except TypeError, e:
98 print "FUDI:lineReceived():", e.message
99 else:
100
101 print "FUDI: Invalid selector %s." % (selector)
102
104 """
105 Converts int, float, string to FUDI atoms and sends them.
106 :param data: list of basic types variables.
107 """
108 if VERBOSE:
109 print "send_message", selector, atoms
110 txt = to_fudi(selector, *atoms)
111 if VERBOSE:
112 print "FUDI: sending", txt
113 self.transport.write(txt)
114
116 """
117 Factory for FUDI receivers.
118
119 You should attach FUDI message callbacks to an instance of this.
120 """
121 protocol = FUDIProtocol
124
126 if type(callback) not in (types.FunctionType, types.MethodType):
127 raise TypeError("Callback '%s' is not callable" % repr(callback))
128 self.callbacks[selector] = callback
129
131 """
132 Creates a FUDI sender.
133
134 When connected, will call its callbacks with the sender instance.
135 :return: deferred instance
136 """
137 if tcp:
138 deferred = ClientCreator(reactor, FUDIProtocol).connectTCP(host, port)
139 else:
140 deferred = ClientCreator(reactor, FUDIProtocol).connectUDP(host, port)
141 return deferred
142
143 if __name__ == "__main__":
144 VERBOSE = True
145
146 - def ping(protocol, *args):
147 print "received ping", args
148 reactor.stop()
149
151 protocol.send_message("ping", 1, 2.0, "bang")
152 print "sent ping"
153
155 print "Error trying to connect.", failure
156 reactor.stop()
157
158 PORT_NUMBER = 15555
159
160 s = FUDIServerFactory()
161 s.register_message("ping", ping)
162 reactor.listenTCP(PORT_NUMBER, s)
163
164 create_FUDI_client('localhost', PORT_NUMBER).addCallback(on_connected).addErrback(on_error)
165 reactor.run()
166