1 """SpecCommand module
2
3 This module defines the classes Spec command
4 objects
5
6 Classes:
7 BaseSpecCommand
8 SpecCommand
9 SpecCommandA
10 """
11
12 __author__ = 'Matias Guijarro'
13 __version__ = '1.0'
14
15 import types
16 import logging
17 from SpecConnection import SpecClientNotConnectedError
18 from SpecReply import SpecReply
19 import SpecConnectionsManager
20 import SpecEventsDispatcher
21 import SpecWaitObject
22
24 """Base class for SpecCommand objects"""
25 - def __init__(self, command = None, connection = None, callbacks = None):
26 self.command = None
27 self.connection = None
28 self.specVersion = None
29 self.isConnected = self.isSpecConnected
30
31 if connection is not None:
32 if type(connection) in (types.UnicodeType, types.StringType):
33
34
35
36 self.connectToSpec(str(connection))
37 else:
38 self.connection = connection
39
40 if command is not None:
41 self.setCommand(command)
42
43
46
47
49 return self.connection is not None and self.connection.isSpecConnected()
50
51
53 if self.isSpecConnected():
54 try:
55 status_channel = self.connection.getChannel("status/ready")
56 status = status_channel.read()
57 except:
58 pass
59 else:
60 return status
61
62 return False
63
64
66 self.command = command
67
68
70 return '<SpecCommand object, command=%s>' % self.command or ''
71
72
74 if self.command is None:
75 return
76
77 if self.connection is None or not self.connection.isSpecConnected():
78 return
79
80 if self.connection.serverVersion < 3:
81 func = False
82
83 if 'function' in kwargs:
84 func = kwargs['function']
85
86
87
88
89 args = map(repr, args)
90
91 if func:
92
93 command = self.command + '(' + ','.join(args) + ')'
94 else:
95
96 command = self.command + ' ' + ' '.join(args)
97 else:
98
99 command = [self.command] + list(args)
100
101 return self.executeCommand(command)
102
103
106
107
108
110 """SpecCommand objects execute macros and wait for results to get back"""
111 - def __init__(self, command, connection, timeout = None):
114
115
121
122
124 if self.connection.serverVersion < 3:
125 connectionCommand = 'send_msg_cmd_with_return'
126 else:
127 if type(command) == types.StringType:
128 connectionCommand = 'send_msg_cmd_with_return'
129 else:
130 connectionCommand = 'send_msg_func_with_return'
131
132 return SpecWaitObject.waitReply(self.connection, connectionCommand, (command, ), self.__timeout)
133
134
135
137 """SpecCommandA is the asynchronous version of SpecCommand.
138 It allows custom waiting by subclassing."""
140 self.__callback = None
141 self.__error_callback = None
142 self.__callbacks = {
143 'connected': None,
144 'disconnected': None,
145 'statusChanged': None,
146 }
147 callbacks = kwargs.get("callbacks", {})
148 for cb_name in self.__callbacks.iterkeys():
149 if callable(callbacks.get(cb_name)):
150 self.__callbacks[cb_name] = SpecEventsDispatcher.callableObjectRef(callbacks[cb_name])
151
152 BaseSpecCommand.__init__(self, *args, **kwargs)
153
154
156 if self.connection is not None:
157 SpecEventsDispatcher.disconnect(self.connection, 'connected', self.connected)
158 SpecEventsDispatcher.disconnect(self.connection, 'disconnected', self.disconnected)
159
160 self.connection = SpecConnectionsManager.SpecConnectionsManager().getConnection(specVersion)
161 self.specVersion = specVersion
162
163 SpecEventsDispatcher.connect(self.connection, 'connected', self.connected)
164 cb = self.__callbacks.get("connected")
165 if cb is not None:
166 cb = cb()
167 SpecEventsDispatcher.connect(self.connection, 'connected', cb)
168 SpecEventsDispatcher.connect(self.connection, 'disconnected', self.disconnected)
169 cb = self.__callbacks.get("disconnected")
170 if cb is not None:
171 cb = cb()
172 SpecEventsDispatcher.connect(self.connection, 'disconnected', cb)
173 self.connection.registerChannel("status/ready", self.statusChanged)
174 cb = self.__callbacks.get("statusChanged")
175 if cb is not None:
176 cb = cb()
177 SpecEventsDispatcher.connect(self.connection, 'statusChanged', cb)
178
179 if self.connection.isSpecConnected():
180 self.connected()
181 else:
182 SpecWaitObject.waitConnection(self.connection, timeout)
183 SpecEventsDispatcher.dispatch()
184
185
188
189
192
193
196
197
208
209
211 self.__callback = kwargs.get("callback", None)
212 self.__error_callback = kwargs.get("error_callback", None)
213
214 return BaseSpecCommand.__call__(self, *args, **kwargs)
215
216
218 if reply.error:
219 if callable(self.__error_callback):
220 try:
221 self.__error_callback()
222 except:
223 logging.getLogger("SpecClient").exception("Error while calling error callback (command=%s,spec version=%s)", self.command, self.specVersion)
224 self.__error_callback = None
225 else:
226 if callable(self.__callback):
227 try:
228 self.__callback(reply.data)
229 except:
230 logging.getLogger("SpecClient").exception("Error while calling error callback (command=%s,spec version=%s)", self.command, self.specVersion)
231 self.__callback = None
232
233
236
237
239 if self.connection is None or not self.connection.isSpecConnected():
240 return
241
242 self.connection.abort()
243