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