Beispiel #1
0
 def __init__(self, reactor):
     QWidget.__init__(self)
     self.ui = Ui_FileSenderWindow()
     self.ui.setupUi(self)
     self.reactor = reactor
     self._setStatus('Drag and drop files to be sent...')
     self.setWindowTitle(env.contactName + ' - ' + str(self.windowTitle()))
     self.setAcceptDrops(True)
     self.files = {}
     self.fileItems = {}
     self.connect(self.ui.fileList, SIGNAL('itemSelectionChanged()'),
                  self._onFileSelectionChanged)
     self.connect(self.ui.addFilesButton, SIGNAL('clicked()'),
                  self._onAddClicked)
     self.connect(self.ui.removeFilesButton, SIGNAL('clicked()'),
                  self._onRemoveClicked)
     self.connect(self.ui.removeAllButton, SIGNAL('clicked()'),
                  self._onRemoveAllClicked)
     self.connect(self.ui.sendFilesButton, SIGNAL('clicked()'),
                  self._onSendFilesClicked)
     self.connect(self.ui.closeButton, SIGNAL('clicked()'), self.close)
     self.state = self.SELECTINGFILES
Beispiel #2
0
 def __init__( self, reactor ) :
     QWidget.__init__( self )
     self.ui = Ui_FileSenderWindow()
     self.ui.setupUi( self )
     self.reactor = reactor
     self._setStatus( 'Drag and drop files to be sent...' )
     self.setWindowTitle( env.contactName + ' - ' + str(self.windowTitle()) )
     self.setAcceptDrops( True )
     self.files = {}
     self.fileItems = {}
     self.connect( self.ui.fileList, SIGNAL('itemSelectionChanged()'), self._onFileSelectionChanged )
     self.connect( self.ui.addFilesButton, SIGNAL('clicked()'), self._onAddClicked )
     self.connect( self.ui.removeFilesButton, SIGNAL('clicked()'), self._onRemoveClicked )
     self.connect( self.ui.removeAllButton, SIGNAL('clicked()'), self._onRemoveAllClicked )
     self.connect( self.ui.sendFilesButton, SIGNAL('clicked()'), self._onSendFilesClicked )
     self.connect( self.ui.closeButton, SIGNAL('clicked()'), self.close )
     self.state = self.SELECTINGFILES
Beispiel #3
0
class FileSenderWindow( QWidget ) :
    SELECTINGFILES = 0
    CONNECTINGCSPACE = 1
    CONNECTINGUSER = 2
    OFFERINGFILES = 3
    def __init__( self, reactor ) :
        QWidget.__init__( self )
        self.ui = Ui_FileSenderWindow()
        self.ui.setupUi( self )
        self.reactor = reactor
        self._setStatus( 'Drag and drop files to be sent...' )
        self.setWindowTitle( env.contactName + ' - ' + str(self.windowTitle()) )
        self.setAcceptDrops( True )
        self.files = {}
        self.fileItems = {}
        self.connect( self.ui.fileList, SIGNAL('itemSelectionChanged()'), self._onFileSelectionChanged )
        self.connect( self.ui.addFilesButton, SIGNAL('clicked()'), self._onAddClicked )
        self.connect( self.ui.removeFilesButton, SIGNAL('clicked()'), self._onRemoveClicked )
        self.connect( self.ui.removeAllButton, SIGNAL('clicked()'), self._onRemoveAllClicked )
        self.connect( self.ui.sendFilesButton, SIGNAL('clicked()'), self._onSendFilesClicked )
        self.connect( self.ui.closeButton, SIGNAL('clicked()'), self.close )
        self.state = self.SELECTINGFILES

    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 )

    def _removeFile( self, item ) :
        info = self.fileItems.pop( item )
        self.ui.fileList.takeItem( self.ui.fileList.row(item) )
        fname = os.path.split( info[0] )[1]
        del self.files[fname.lower()]
        if not self.files :
            self.ui.sendFilesButton.setEnabled( False )
            self.ui.removeAllButton.setEnabled( False )

    def _addFile( self, f ) :
        if not os.path.isfile(f) : return False
        fname = os.path.split(f)[1]
        k = fname.lower()
        info = self.files.get( k, None )
        if info is not None :
            self._removeFile( info[1] )
        item = QListWidgetItem( fname, self.ui.fileList )
        info = [f,item]
        self.files[k] = info
        self.fileItems[item] = info
        self.ui.sendFilesButton.setEnabled( True )
        self.ui.removeAllButton.setEnabled( True )

    def _onFileSelectionChanged( self ) :
        if self.state != self.SELECTINGFILES : return
        selectCount = 0
        for item in self.fileItems.keys() :
            if self.ui.fileList.isItemSelected(item) :
                selectCount += 1
        self.ui.removeFilesButton.setEnabled( selectCount > 0 )

    def dragEnterEvent( self, ev ) :
        if self.state != self.SELECTINGFILES :
            return
        mimeData = ev.mimeData()
        if mimeData.hasUrls() :
            isLocal = True
            for url in mimeData.urls() :
                if url.toLocalFile().isEmpty() :
                    isLocal = False
            if isLocal :
                ev.acceptProposedAction()

    def dropEvent( self, ev ) :
        if self.state != self.SELECTINGFILES : return
        mimeData = ev.mimeData()
        if mimeData.hasUrls() :
            for url in mimeData.urls() :
                f = url.toLocalFile()
                if not f.isEmpty() :
                    self._addFile( str(f) )
            self._onFileSelectionChanged()
            ev.acceptProposedAction()

    def _onAddClicked( self ) :
        defaultDir = os.path.expanduser( '~/Desktop' )
        if not os.path.isdir(defaultDir) :
            defaultDir = ''
        openDir = localSettings().getString( 'Settings/FileSenderOpenDir' )
        if (not openDir) or (not os.path.isdir(openDir)) :
            openDir = defaultDir
        fileList = QFileDialog.getOpenFileNames( self, 'Select file(s) to add...', openDir )
        for f in fileList :
            self._addFile( str(f) )
        if len(fileList) :
            openDir = os.path.split( str(fileList[0]) )[0]
            localSettings().setString( 'Settings/FileSenderOpenDir', openDir )
        self._onFileSelectionChanged()

    def _onRemoveClicked( self ) :
        selItems = [ i for i in self.fileItems.keys() if self.ui.fileList.isItemSelected(i) ]
        for item in selItems :
            self._removeFile( item )
        self._onFileSelectionChanged()

    def _onRemoveAllClicked( self ) :
        for item in self.fileItems.keys() :
            self._removeFile( item )
        self._onFileSelectionChanged()

    def _onSendFilesClicked( self ) :
        self.setAcceptDrops( False )
        self.ui.fileList.clearSelection()
        self.ui.fileList.setSelectionMode( QAbstractItemView.NoSelection )
        self.ui.addFilesButton.setEnabled( False )
        self.ui.removeFilesButton.setEnabled( False )
        self.ui.removeAllButton.setEnabled( False )
        self.ui.sendFilesButton.setEnabled( False )
        self._doConnect()

    def _doConnect( self ) :
        def onConnect( connector ) :
            self.connectOp = None
            if connector.getError() != 0 :
                self._setError( 'Unable to connect to CSpace.' )
                return
            self._doConnectUser( connector.getSock() )
        self.connectOp = tcpConnect( ('127.0.0.1',env.port), self.reactor, onConnect )
        self._setStatus( 'Connecting to CSpace...' )
        self.state = self.CONNECTINGCSPACE

    def _doConnectUser( self, sock ) :
        self._setStatus( 'Connecting to %s...' % env.contactName )
        self.state = self.CONNECTINGUSER
        def onConnect( err, sock ) :
            if err < 0 :
                self._setError( 'Error connecting to %s.' % env.contactName )
                return
            self._doOfferFiles( sock )
        connector = CSpaceConnector( sock, env.contactName, 'FileTransfer',
                self.reactor, onConnect )
        self.connectOp = connector.getOp()

    def _doOfferFiles( self, sock ) :
        self._setStatus( 'Sending request ...' )
        self.state = self.OFFERINGFILES
        fileList = []
        for row in range(self.ui.fileList.count()) :
            item = self.ui.fileList.item( row )
            fileList.append( self.fileItems[item][0] )
        self.rpcConn = RPCConnection( sock, self.reactor )
        self.switchboard = RPCSwitchboard( self.rpcConn )
        self.fs = FlatFS( fileList )
        self.fileServer = FileServer( self.fs, self.switchboard )

        pending = {}
        for i,f in enumerate(fileList) :
            pending[os.path.split(f)[1].lower()] = i
        def onClose() :
            if pending :
                self._setError( 'Disconnected.' )
            else :
                self._setStatus( 'Completed.' )
        def onTransferStatus( payload ) :
            if type(payload) is not ListType : return
            if len(payload) != 4 : return
            for x in payload :
                if type(x) is not IntType : return
                if x < 0 : return
            fileId,numFiles,transferred,fileSize = payload
            if numFiles != len(fileList) : return
            if not (1 <= fileId <= numFiles) : return
            if transferred > fileSize : return
            fname = os.path.split(fileList[fileId-1])[1]
            lfname = fname.lower()
            pos = pending.get( lfname, None )
            if pos is None : return
            if transferred == fileSize :
                percent = 100
                del pending[lfname]
            else :
                percent = transferred*100 / fileSize
            self._setStatus( 'Sending file (%d/%d): %s (%d%%)'
                    % (pos+1,len(fileList),fname,percent) )
        self.switchboard.addOnewayAgent( 'TransferStatus', onTransferStatus )
        self.rpcConn.setCloseCallback( onClose )

    def closeEvent( self, ev ) :
        ev.accept()
        delaygc( self )
Beispiel #4
0
class FileSenderWindow(QWidget):
    SELECTINGFILES = 0
    CONNECTINGCSPACE = 1
    CONNECTINGUSER = 2
    OFFERINGFILES = 3

    def __init__(self, reactor):
        QWidget.__init__(self)
        self.ui = Ui_FileSenderWindow()
        self.ui.setupUi(self)
        self.reactor = reactor
        self._setStatus('Drag and drop files to be sent...')
        self.setWindowTitle(env.contactName + ' - ' + str(self.windowTitle()))
        self.setAcceptDrops(True)
        self.files = {}
        self.fileItems = {}
        self.connect(self.ui.fileList, SIGNAL('itemSelectionChanged()'),
                     self._onFileSelectionChanged)
        self.connect(self.ui.addFilesButton, SIGNAL('clicked()'),
                     self._onAddClicked)
        self.connect(self.ui.removeFilesButton, SIGNAL('clicked()'),
                     self._onRemoveClicked)
        self.connect(self.ui.removeAllButton, SIGNAL('clicked()'),
                     self._onRemoveAllClicked)
        self.connect(self.ui.sendFilesButton, SIGNAL('clicked()'),
                     self._onSendFilesClicked)
        self.connect(self.ui.closeButton, SIGNAL('clicked()'), self.close)
        self.state = self.SELECTINGFILES

    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)

    def _removeFile(self, item):
        info = self.fileItems.pop(item)
        self.ui.fileList.takeItem(self.ui.fileList.row(item))
        fname = os.path.split(info[0])[1]
        del self.files[fname.lower()]
        if not self.files:
            self.ui.sendFilesButton.setEnabled(False)
            self.ui.removeAllButton.setEnabled(False)

    def _addFile(self, f):
        if not os.path.isfile(f): return False
        fname = os.path.split(f)[1]
        k = fname.lower()
        info = self.files.get(k, None)
        if info is not None:
            self._removeFile(info[1])
        item = QListWidgetItem(fname, self.ui.fileList)
        info = [f, item]
        self.files[k] = info
        self.fileItems[item] = info
        self.ui.sendFilesButton.setEnabled(True)
        self.ui.removeAllButton.setEnabled(True)

    def _onFileSelectionChanged(self):
        if self.state != self.SELECTINGFILES: return
        selectCount = 0
        for item in self.fileItems.keys():
            if self.ui.fileList.isItemSelected(item):
                selectCount += 1
        self.ui.removeFilesButton.setEnabled(selectCount > 0)

    def dragEnterEvent(self, ev):
        if self.state != self.SELECTINGFILES:
            return
        mimeData = ev.mimeData()
        if mimeData.hasUrls():
            isLocal = True
            for url in mimeData.urls():
                if url.toLocalFile().isEmpty():
                    isLocal = False
            if isLocal:
                ev.acceptProposedAction()

    def dropEvent(self, ev):
        if self.state != self.SELECTINGFILES: return
        mimeData = ev.mimeData()
        if mimeData.hasUrls():
            for url in mimeData.urls():
                f = url.toLocalFile()
                if not f.isEmpty():
                    self._addFile(str(f))
            self._onFileSelectionChanged()
            ev.acceptProposedAction()

    def _onAddClicked(self):
        defaultDir = os.path.expanduser('~/Desktop')
        if not os.path.isdir(defaultDir):
            defaultDir = ''
        openDir = localSettings().getString('Settings/FileSenderOpenDir')
        if (not openDir) or (not os.path.isdir(openDir)):
            openDir = defaultDir
        fileList = QFileDialog.getOpenFileNames(self,
                                                'Select file(s) to add...',
                                                openDir)
        for f in fileList:
            self._addFile(str(f))
        if len(fileList):
            openDir = os.path.split(str(fileList[0]))[0]
            localSettings().setString('Settings/FileSenderOpenDir', openDir)
        self._onFileSelectionChanged()

    def _onRemoveClicked(self):
        selItems = [
            i for i in self.fileItems.keys()
            if self.ui.fileList.isItemSelected(i)
        ]
        for item in selItems:
            self._removeFile(item)
        self._onFileSelectionChanged()

    def _onRemoveAllClicked(self):
        for item in self.fileItems.keys():
            self._removeFile(item)
        self._onFileSelectionChanged()

    def _onSendFilesClicked(self):
        self.setAcceptDrops(False)
        self.ui.fileList.clearSelection()
        self.ui.fileList.setSelectionMode(QAbstractItemView.NoSelection)
        self.ui.addFilesButton.setEnabled(False)
        self.ui.removeFilesButton.setEnabled(False)
        self.ui.removeAllButton.setEnabled(False)
        self.ui.sendFilesButton.setEnabled(False)
        self._doConnect()

    def _doConnect(self):
        def onConnect(connector):
            self.connectOp = None
            if connector.getError() != 0:
                self._setError('Unable to connect to CSpace.')
                return
            self._doConnectUser(connector.getSock())

        self.connectOp = tcpConnect(('127.0.0.1', env.port), self.reactor,
                                    onConnect)
        self._setStatus('Connecting to CSpace...')
        self.state = self.CONNECTINGCSPACE

    def _doConnectUser(self, sock):
        self._setStatus('Connecting to %s...' % env.contactName)
        self.state = self.CONNECTINGUSER

        def onConnect(err, sock):
            if err < 0:
                self._setError('Error connecting to %s.' % env.contactName)
                return
            self._doOfferFiles(sock)

        connector = CSpaceConnector(sock, env.contactName, 'FileTransfer',
                                    self.reactor, onConnect)
        self.connectOp = connector.getOp()

    def _doOfferFiles(self, sock):
        self._setStatus('Sending request ...')
        self.state = self.OFFERINGFILES
        fileList = []
        for row in range(self.ui.fileList.count()):
            item = self.ui.fileList.item(row)
            fileList.append(self.fileItems[item][0])
        self.rpcConn = RPCConnection(sock, self.reactor)
        self.switchboard = RPCSwitchboard(self.rpcConn)
        self.fs = FlatFS(fileList)
        self.fileServer = FileServer(self.fs, self.switchboard)

        pending = {}
        for i, f in enumerate(fileList):
            pending[os.path.split(f)[1].lower()] = i

        def onClose():
            if pending:
                self._setError('Disconnected.')
            else:
                self._setStatus('Completed.')

        def onTransferStatus(payload):
            if type(payload) is not ListType: return
            if len(payload) != 4: return
            for x in payload:
                if type(x) is not IntType: return
                if x < 0: return
            fileId, numFiles, transferred, fileSize = payload
            if numFiles != len(fileList): return
            if not (1 <= fileId <= numFiles): return
            if transferred > fileSize: return
            fname = os.path.split(fileList[fileId - 1])[1]
            lfname = fname.lower()
            pos = pending.get(lfname, None)
            if pos is None: return
            if transferred == fileSize:
                percent = 100
                del pending[lfname]
            else:
                percent = transferred * 100 / fileSize
            self._setStatus('Sending file (%d/%d): %s (%d%%)' %
                            (pos + 1, len(fileList), fname, percent))

        self.switchboard.addOnewayAgent('TransferStatus', onTransferStatus)
        self.rpcConn.setCloseCallback(onClose)

    def closeEvent(self, ev):
        ev.accept()
        delaygc(self)