class TaskRemote(wx.EvtHandler): """ The class to perform the remote operations for task. """ state_fn = '.nagara' def __init__(self, task, use_network=True): """Constructor.""" self.__task = task self.initialize_event() self.__configs = Config().get_common()['location'] self.__state = RemoteState(self) def initialize_event(self): wx.EvtHandler.__init__(self) self.__received_event = NagaraEvent(self) # property: events @property def received_event(self): return self.__received_event # property: path @property def path(self): """Return the remote absolute path.""" return self.__path def get_channel(self): return self.__channel # property: host def get_host(self): return self.__host def set_host(self, host): self.__host = host dirname = self.__task.local.dirname self.__nagara_root = self.__configs[self.__host]['workdir'] self.__path = self.__nagara_root + '/' + self.__task.local.dirname host = property(get_host, set_host) def connect(self): """Connect to remote host by config.""" if self.__channel: if ( socket.gethostbyname(self.__host) != self.__channel.get_host_by_ip() ): if self.__channel.is_communicating(): raise connection.ConnectionException() else: self.__channel.close() try: host_config = self.__configs[self.__host]['ssh'] except: message = 'Not found host configuration.' raise TaskRemoteException(message) self.__channel = Connection( host = host_config['address'], username = host_config['username'], password = host_config['password'], ) else: pass else: if self.__host: try: host_config = self.__configs[self.__host]['ssh'] except: message = 'Not found host configuration.' raise TaskRemoteException(message) self.__channel = Connection( host = host_config['address'], username = host_config['username'], password = host_config['password'], ) else: self.__host = self.__configs['default'] try: host_config = self.__configs[self.__host]['ssh'] except: message = 'Not found host configuration.' raise TaskRemoteException(message) self.__channel = Connection( host = host_config['address'], username = host_config['username'], password = host_config['password'], ) def create(self): """Create the remote task directory.""" configs = self.__task.get_configs() host = self.__task.host remote_root = configs[host]['rootdir'] chan = self.__task.get_channel() if not chan.exists(remote_root): chan.mkdir(remote_root) if not chan.exists(self.__path): chan.mkdir(self.__path) # def setConnection(self, conn): # """Set the connection to remote host.""" # self.__conn = conn # def getConnection(self): # """Get the connection to remote host.""" # return self.__conn def receive_all(self, force=False): """Put the local task to a directory on the remote project dir.""" try: local_dir_ local_dir_path = self.__task.local.path self.__channel.putdir(local_dir_path, self.__path) self.received_event.fire() except: raise TaskRemoteReceivingError() def receive_file(self, fn): try: local_dir_path = self.__task.local.path local_fn = os.path.join(local_dir_path, fn) remote_fn = self.__path + '/' + fn self.__channel.put(local_fn, remote_fn) except: raise TaskRemoteReceivingError() def send_all(self): self.__task.getdir output_file_list = self.__task.get_all_out_files() other_file_list = self.__task.get_all_con_files() try: local_dir_path = self.__task.local.path self.__channel.getdir(rdir, ldir) rdir = self.__path conn = self.__task.getConnection() conn.getDir(rdir, ldir) except: pass def send_file(self, remote_fn): pass #self.__channel # return conn.get(remote_fn, self.__task.local.getPath()) @threaded def tail(self, remote_fn, output): conn = self.__task.getConnection() rfile = conn.open(remote_fn, mode='r', pipeline=True) while True: where = rfile.tell() line = rfile.readline() if not line: time.sleep(10) rfile.seek(where) else: output.write(line), # already has newline # or + generator + external method def is_local(self): return False def do_excecutable(self): conn.execute('chmod u+x '+ run_script) @threaded def check_files(self): # task_remote.receive_all_files() time_sum = 0 while True: if self.is_received_all_files(): break time.sleep(CHECK_TIME) time_sum += CHECK_TIME if time_sum >= SYNC_TIME_LIMIT: raise ReceivingRemoteStateException() self.__state.change_to_runnable() def define_host(self): pass def delete(self): """Delete the remote directory.""" if not self.isNone(): self.__task.getConnection().execute('rm -rf '+self.__path) self.setNone()
class StateClient(threading.Thread): def __init__(self, ownId, ownName=None, host=None, port=None): self.api_version="v2" print ownId, ownName, host, port self.eventq = [] self.eventqc = threading.Condition() self.ownid = ownId if ownName == None: self.devName = 'default' else: self.devname = ownName if host == None: host = 'kurre.soberit.hut.fi' if port == None: port = '80' self.kurreClient = Connection(host, port) self.prefix = '/api/v2/device/' self.running=False self.micThread = soundLvl.SoundLvl() self.calThread = calSource.CalSource() self.calThread.init(self) self.micThread.init(self) self.add_state_event( 'TalkingDevice', 'isWilling', 'True' ) threading.Thread.__init__(self) self.setDaemon(True) def set_printer(self, printer): self.kurreClient.set_printer(printer) self.printer = printer def add_state_event(self, iface, method, value, arg_name=None, arg_val=None): #print 'add state event called, params:', iface, method, value, arg_name, arg_val self.eventqc.acquire() #form the method path method_path = self.ownid + '/interface/' + iface + '/method/' + method if arg_name == None: new_event = { "method": "PUT", "method_path": method_path, 'data': {'value':value} } else: new_event = { "method": "PUT", "method_path": method_path, 'data': {'value':value, 'arguments':{arg_name: arg_val}} } if new_event in self.eventq: pass else: self.eventq.append( new_event ) self.eventqc.notify() self.eventqc.release() def run(self): self.running = True self.calThread.start() self.micThread.start() while self.running: #check for items in q self.eventqc.acquire() #print self.eventq for event in self.eventq: print 'processing event:', event #post for update, put for create if event['method'] == "PUT": repl_status = self.kurreClient.put( self.prefix + event["method_path"] + '/', event["data"] ) elif event['method'] == "POST": repl_status = self.kurreClient.post( self.prefix + event["method_path"] + '/', event["data"] ) #print 'repl status', repl_status if isinstance(repl_status, Exception): print repl_status elif repl_status != 201 and repl_status != 204: apip_struct = event['method_path'].split('/') if len(apip_struct) == 5: # we were making a state value update method_name = apip_struct.pop() method_path = '/'.join(apip_struct) event['data']['method_name'] = method_name event['method'] = "POST" event['method_path'] = method_path #print 'put failed, modified event added', event # no need to update again with put, since creation updates value as well elif len(apip_struct) == 4: # state value creation failed # create the interface iface_name = apip_struct[2] method_path = self.ownid + '/interface' data = {"interface_name": iface_name} new_event = { 'method':'POST', 'method_path': method_path, 'data': data } if new_event in self.eventq: pass #no need to add else: self.eventq.append(new_event) #print 'post failed, modified event added', new_event elif len(apip_struct) == 3: # interface could not be created method_path = self.prefix data = { 'mac_address': self.ownid, "name": self.devname } new_event = { 'method':'POST', 'method_path': method_path, 'data': data } if new_event in self.eventq: pass else: self.eventq.append( new_event ) else: #print 'event', event, 'handled, removing.' self.eventq.remove(event) #print 'event processed' if not self.eventq: #print 'eventq empty stateclient sleeping' self.eventqc.wait() else: print 'could not process all events, trying again in 5' self.eventqc.wait(5) def stop(self): #stop drivers print "Stopping StateClient" self.calThread.stop() self.micThread.stop() self.running = False self.eventqc.acquire() self.eventqc.notify() self.eventqc.release()
class _TahoeFS(FS): def __init__(self, dircap, autorun, largefilesize, webapi): self.dircap = dircap if not dircap.endswith('/') else dircap[:-1] self.autorun = autorun self.largefilesize = largefilesize self.connection = Connection(webapi) self.tahoeutil = TahoeUtil(webapi) self.readonly = dircap.startswith('URI:DIR2-RO') super(_TahoeFS, self).__init__(thread_synchronize=_thread_synchronize_default) def _log(self, level, message): if not logger.isEnabledFor(level): return logger.log(level, u'(%d) %s' % (id(self), unicode(message).encode('ASCII', 'replace'))) def _fixpath(self, path): return abspath(normpath(path)) def _get_file_handler(self, path): if not self.autorun: if path.lower().startswith('/autorun.'): self._log(DEBUG, 'Access to file %s denied' % path) return NullFile() return self.getrange(path, 0) @_fix_path def getpathurl(self, path, allow_none=False, webapi=None): ''' Retrieve URL where the file/directory is stored ''' if webapi == None: webapi = self.connection.webapi self._log(DEBUG, "Retrieving URL for %s over %s" % (path, webapi)) path = self.tahoeutil.fixwinpath(path, False) return u"%s/uri/%s%s" % (webapi, self.dircap, path) @_fix_path def getrange(self, path, offset, length=None): path = self.tahoeutil.fixwinpath(path, False) return self.connection.get(u'/uri/%s%s' % (self.dircap, path), offset=offset, length=length) @_fix_path def setcontents(self, path, file, chunk_size=64*1024): self._log(INFO, 'Uploading file %s' % path) path = self.tahoeutil.fixwinpath(path, False) size=None if self.readonly: raise errors.UnsupportedError('read only filesystem') # Workaround for large files: # First create zero file placeholder, then # upload final content. if self.largefilesize != None and getattr(file, 'read', None): # As 'file' can be also a string, need to check, # if 'file' looks like duck. Sorry, file. file.seek(0, SEEK_END) size = file.tell() file.seek(0) if size > self.largefilesize: self.connection.put(u'/uri/%s%s' % (self.dircap, path), "PyFilesystem.TahoeFS: Upload started, final size %d" % size) self.connection.put(u'/uri/%s%s' % (self.dircap, path), file, size=size) @_fix_path def getinfo(self, path): self._log(INFO, 'Reading meta for %s' % path) info = self.tahoeutil.info(self.dircap, path) #import datetime #info['created_time'] = datetime.datetime.now() #info['modified_time'] = datetime.datetime.now() #info['accessed_time'] = datetime.datetime.now() return info