class FileReceiverWindow(QWidget, FlashWindow): def __init__(self, reactor): QWidget.__init__(self) FlashWindow.__init__(self, reactor) self.ui = Ui_FileReceiverWindow() self.ui.setupUi(self) self.reactor = reactor self.setWindowTitle(env.displayName + ' - ' + str(self.windowTitle())) self.connect(self.ui.acceptButton, SIGNAL('clicked()'), self._onAcceptFiles) self.connect(self.ui.cancelButton, SIGNAL('clicked()'), self.close) tcpConnect(('127.0.0.1', env.port), self.reactor, self._onConnect) self._setStatus('Connecting to CSpace...') self.disconnected = False def _setStatus(self, text, isError=False): lines = text.split('\n') text = '<b>%s</b>' % '<br/>'.join(lines) if isError: text = '<font color=red>%s</font>' % text self.ui.status.setText(text) def _setError(self, text): self._setStatus(text, True) self.ui.cancelButton.setText('&Close') def _onConnect(self, connector): if connector.getError() != 0: self._setError('Error connecting to CSpace.') return sock = connector.getSock() self._setStatus('Accepting connection from %s.' % env.displayName) CSpaceAcceptor(sock, env.connectionId, self.reactor, self._onAccept) def _onAccept(self, err, sock): if err < 0: self._setError('Error accepting connection from %s.' % env.displayName) return self.rpcConn = RPCConnection(sock, self.reactor) self.fileClient = FileClient(self.rpcConn) self._setStatus('Fetching file list from %s...' % env.displayName) self.fileClient.callList('/', self._onList) def _onList(self, err, result): if err != 0: self._setError('Error fetching file list from %s.' % env.displayName) return self.files = [] for x in result: if not x.endswith('/'): self.files.append(x) self.ui.fileList.addItem(x) self._setStatus(('%s is sending the following files.\n' % env.displayName) + 'Would you like to accept?') self.ui.acceptButton.setEnabled(True) self.rpcConn.setCloseCallback(self._onClose) self.flash() def _onClose(self): self.disconnected = True self._setError('Disconnected.') self.ui.acceptButton.setEnabled(False) def _chooseTargetDir(self): defaultDir = os.path.expanduser('~/Desktop') if not os.path.isdir(defaultDir): defaultDir = QString() dir = localSettings().getString('Settings/FileReceiverSaveDir') if (not dir) or (not os.path.isdir(dir)): dir = defaultDir while True: dir = QFileDialog.getExistingDirectory( self, 'Choose directory to save the file(s)', dir) if dir.isEmpty(): return None dir = str(dir) existing = [] for f in self.files: if os.path.exists(os.path.join(dir, f)): existing.append(f) if not existing: break msg = 'The following file(s) already exist in\n%s.\nWould you like to overwrite?\n%s' % ( dir, '\n'.join(existing)) result = QMessageBox.question( self, 'Overwrite Prompt', msg, QMessageBox.Yes, QMessageBox.No, QMessageBox.Cancel | QMessageBox.Escape) if result == QMessageBox.Yes: break if result == QMessageBox.No: continue assert result == QMessageBox.Cancel return None localSettings().setString('Settings/FileReceiverSaveDir', dir) return dir def _onAcceptFiles(self): self.ui.acceptButton.setEnabled(False) targetDir = self._chooseTargetDir() if self.disconnected: return if not targetDir: self.ui.acceptButton.setEnabled(True) return self.targetDir = targetDir self.curFileId = 0 self.rpcConn.setCloseCallback(None) self.statusStub = RPCStub(self.rpcConn, 'TransferStatus') self._doTransfer() def _doTransfer(self): if self.curFileId >= len(self.files): self._setStatus('Completed.') self.ui.cancelButton.setText('&Close') self.rpcConn.close(deferred=True) return fname = self.files[self.curFileId] self.curFileId += 1 self._setStatus('Receiving file(%d/%d): %s' % (self.curFileId, len(self.files), fname)) remotePath = '/' + fname localPath = os.path.join(self.targetDir, fname) try: self.fetcher = FileFetcher(self.fileClient, remotePath, localPath, self._onTransfer) except (OSError, IOError), e: self._setError('Error saving file: %s' % localPath) return
class FileReceiverWindow( QWidget, FlashWindow ) : def __init__( self, reactor ) : QWidget.__init__( self ) FlashWindow.__init__( self, reactor ) self.ui = Ui_FileReceiverWindow() self.ui.setupUi( self ) self.reactor = reactor self.setWindowTitle( env.displayName + ' - ' + str(self.windowTitle()) ) self.connect( self.ui.acceptButton, SIGNAL('clicked()'), self._onAcceptFiles ) self.connect( self.ui.cancelButton, SIGNAL('clicked()'), self.close ) tcpConnect( ('127.0.0.1',env.port), self.reactor, self._onConnect ) self._setStatus( 'Connecting to CSpace...' ) self.disconnected = False def _setStatus( self, text, isError=False ) : lines = text.split( '\n' ) text = '<b>%s</b>' % '<br/>'.join(lines) if isError : text = '<font color=red>%s</font>' % text self.ui.status.setText( text ) def _setError( self, text ) : self._setStatus( text, True ) self.ui.cancelButton.setText( '&Close' ) def _onConnect( self, connector ) : if connector.getError() != 0 : self._setError( 'Error connecting to CSpace.' ) return sock = connector.getSock() self._setStatus( 'Accepting connection from %s.' % env.displayName ) CSpaceAcceptor( sock, env.connectionId, self.reactor, self._onAccept ) def _onAccept( self, err, sock ) : if err < 0 : self._setError( 'Error accepting connection from %s.' % env.displayName ) return self.rpcConn = RPCConnection( sock, self.reactor ) self.fileClient = FileClient( self.rpcConn ) self._setStatus( 'Fetching file list from %s...' % env.displayName ) self.fileClient.callList( '/', self._onList ) def _onList( self, err, result ) : if err != 0 : self._setError( 'Error fetching file list from %s.' % env.displayName ) return self.files = [] for x in result : if not x.endswith('/') : self.files.append( x ) self.ui.fileList.addItem( x ) self._setStatus( ('%s is sending the following files.\n' % env.displayName ) + 'Would you like to accept?' ) self.ui.acceptButton.setEnabled( True ) self.rpcConn.setCloseCallback( self._onClose ) self.flash() def _onClose( self ) : self.disconnected = True self._setError( 'Disconnected.' ) self.ui.acceptButton.setEnabled( False ) def _chooseTargetDir( self ) : defaultDir = os.path.expanduser( '~/Desktop' ) if not os.path.isdir(defaultDir) : defaultDir = QString() dir = localSettings().getString( 'Settings/FileReceiverSaveDir' ) if (not dir) or (not os.path.isdir(dir)) : dir = defaultDir while True : dir = QFileDialog.getExistingDirectory( self, 'Choose directory to save the file(s)', dir ) if dir.isEmpty() : return None dir = str(dir) existing = [] for f in self.files : if os.path.exists(os.path.join(dir,f)) : existing.append(f) if not existing : break msg = 'The following file(s) already exist in\n%s.\nWould you like to overwrite?\n%s' % (dir,'\n'.join(existing)) result = QMessageBox.question( self, 'Overwrite Prompt', msg, QMessageBox.Yes, QMessageBox.No, QMessageBox.Cancel|QMessageBox.Escape ) if result == QMessageBox.Yes : break if result == QMessageBox.No : continue assert result == QMessageBox.Cancel return None localSettings().setString( 'Settings/FileReceiverSaveDir', dir ) return dir def _onAcceptFiles( self ) : self.ui.acceptButton.setEnabled( False ) targetDir = self._chooseTargetDir() if self.disconnected : return if not targetDir : self.ui.acceptButton.setEnabled( True ) return self.targetDir = targetDir self.curFileId = 0 self.rpcConn.setCloseCallback( None ) self.statusStub = RPCStub( self.rpcConn, 'TransferStatus' ) self._doTransfer() def _doTransfer( self ) : if self.curFileId >= len(self.files) : self._setStatus( 'Completed.' ) self.ui.cancelButton.setText( '&Close' ) self.rpcConn.close( deferred=True ) return fname = self.files[self.curFileId] self.curFileId += 1 self._setStatus( 'Receiving file(%d/%d): %s' % (self.curFileId,len(self.files),fname) ) remotePath = '/' + fname localPath = os.path.join( self.targetDir, fname ) try : self.fetcher = FileFetcher( self.fileClient, remotePath, localPath, self._onTransfer ) except (OSError, IOError), e : self._setError( 'Error saving file: %s' % localPath ) return
class RouterServerHandler( object ) : (INITIAL,REGISTERED,CONNECTING,CLOSED) = range(4) def __init__( self, sock, reactor, routerState ) : self.rpcConn = RPCConnection( sock, reactor ) self.reactor = reactor self.routerState = routerState self.rpcConn.setCloseCallback( self.close ) self.rpcConn.setRequestCallback( self._onRequest ) self.requestTable = {} for msg in 'Ping Register Connect Accept'.split() : self.requestTable[msg] = getattr( self, '_do%s' % msg ) self.routerState.handlers[self] = 1 self.state = self.INITIAL self._lastActiveTime = time() def close( self ) : self.rpcConn.close() del self.routerState.handlers[self] if self.state == self.REGISTERED : del self.routerState.registered[self.routerId] elif self.state == self.CONNECTING : del self.routerState.connecting[self.connectionId] self.state = self.CLOSED def lastActiveTime( self ) : return self._lastActiveTime def sendIncoming( self, connectionId ) : assert self.state == self.REGISTERED self.rpcConn.oneway( connectionId ) def _onRequest( self, payload, ctx ) : self._lastActiveTime = time() try : assert type(payload) is list assert len(payload) >= 1 msg = payload.pop( 0 ) assert type(msg) is str handler = self.requestTable.get( msg ) assert handler is not None except : ctx.response( [-1] ) return handler( payload, ctx ) def _doPing( self, args, ctx ) : try : peerAddr = self.rpcConn.getSock().getpeername() except sock_error : ctx.response( [-1] ) return ctx.response( (0,peerAddr) ) def _doRegister( self, args, ctx ) : try : assert self.state == self.INITIAL assert len(args) == 0 except : ctx.response( (-1,'') ) return while True : routerId = rand_bytes( 20 ) if routerId not in self.routerState.registered : break self.routerId = routerId self.state = self.REGISTERED self.routerState.registered[routerId] = self ctx.response( (0,self.routerId) ) def _doConnect( self, args, ctx ) : try : assert self.state == self.INITIAL assert len(args) == 1 routerId = args[0] assert type(routerId) is str handler = self.routerState.registered.get( routerId ) assert handler is not None except : ctx.response( [-1] ) return while True : connectionId = rand_bytes( 20 ) if connectionId not in self.routerState.connecting : break self.connectionId = connectionId self.connectCtx = ctx self.state = self.CONNECTING self.routerState.connecting[connectionId] = self handler.sendIncoming( connectionId ) def finishConnect( self ) : assert self.state == self.CONNECTING self.connectCtx.response( [0] ) del self.routerState.connecting[self.connectionId] del self.routerState.handlers[self] sock = self.rpcConn.getSock() pendingWrite = self.rpcConn.getPendingWrite() self.rpcConn.shutdown() self.state = self.CLOSED return (sock,pendingWrite) def _doAccept( self, args, ctx ) : try : assert self.state == self.INITIAL assert len(args) == 1 connectionId = args[0] assert type(connectionId) is str handler = self.routerState.connecting.get( connectionId ) assert handler is not None except : ctx.response( [-1] ) return sock1,pendingWrite1 = handler.finishConnect() ctx.response( [0] ) del self.routerState.handlers[self] sock2 = self.rpcConn.getSock() pendingWrite2 = self.rpcConn.getPendingWrite() self.rpcConn.shutdown() self.state = self.CLOSED BridgeInitiator( sock1, pendingWrite1, sock2, pendingWrite2, self.reactor, self.routerState )