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()
Exemple #2
0
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()
Exemple #3
0
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