class FtpClient(QWidget): def __init__(self, parent=None): super(FtpClient, self).__init__(parent) self.ftp = FTP() self.setupGui() self.downloads = [] self.remote.homeButton.clicked.connect(self.cdToRemoteHomeDirectory) self.remote.fileList.itemDoubleClicked.connect( self.cdToRemoteDirectory) self.remote.fileList.itemClicked.connect( lambda: self.remote.downloadButton.setEnabled(True)) self.remote.backButton.clicked.connect(self.cdToRemoteBackDirectory) self.remote.nextButton.clicked.connect(self.cdToRemoteNextDirectory) self.remote.downloadButton.clicked.connect( lambda: Thread(target=self.download).start()) self.remote.refreshButton.clicked.connect(self.updateRemoteFileList) self.local.homeButton.clicked.connect(self.cdToLocalHomeDirectory) self.local.fileList.itemDoubleClicked.connect(self.cdToLocalDirectory) self.local.fileList.itemClicked.connect( lambda: self.local.uploadButton.setEnabled(True)) self.local.backButton.clicked.connect(self.cdToLocalBackDirectory) self.local.nextButton.clicked.connect(self.cdToLocalNextDirectory) self.local.uploadButton.clicked.connect( lambda: Thread(target=self.upload).start()) self.local.connectButton.clicked.connect(self.connect) self.local.refreshButton.clicked.connect(self.updateLocalFileList) self.progressDialog = ProgressDialog(self) def setupGui(self): self.resize(1200, 650) self.local = LocalGuiWidget(self) self.remote = RemoteGuiWidget(self) main_layout = QHBoxLayout() main_layout.addWidget(self.remote) main_layout.addWidget(self.local) main_layout.setSpacing(0) self.setLayout(main_layout) def initialize(self): self.localBrowseRec = [] self.remoteBrowseRec = [] self.pwd = self.ftp.pwd() self.local_pwd = os.getenv('HOME') self.remoteOriginPath = self.pwd self.localOriginPath = self.local_pwd self.localBrowseRec.append(self.local_pwd) self.remoteBrowseRec.append(self.pwd) self.downloadToRemoteFileList() self.loadToLocaFileList() def disconnect(self): pass def connect(self): try: from urlparse import urlparse except ImportError: from urllib.parse import urlparse result = QInputDialog.getText(self, 'Connect To Host', 'Host Address', QLineEdit.Normal) if not result[1]: return try: host = str(result[0].toUtf8()) except AttributeError: host = str(result[0]) try: if urlparse(host).hostname: self.ftp.connect(host=urlparse(host).hostname, port=21, timeout=10) else: self.ftp.connect(host=host, port=21, timeout=10) self.login() except Exception as error: raise error def login(self): ask = loginDialog(self) if not ask: return else: user, passwd = ask[:2] self.ftp.user = user self.ftp.passwd = passwd self.ftp.set_pasv(False) self.ftp.login(user=user, passwd=passwd) self.initialize() def downloadToRemoteFileList(self): self.remote.refreshButton.setEnabled(True) self.remoteWordList = [] self.remoteDir = {} self.ftp.dir('.', self.addItemToRemoteFileList) self.remote.completerModel.setStringList(self.remoteWordList) def loadToLocaFileList(self): self.local.refreshButton.setEnabled(True) self.localWordList = [] self.localDir = {} for f in os.listdir(self.local_pwd): pathname = os.path.join(self.local_pwd, f) self.addItemToLocalFileList(fileProperty(pathname)) self.local.completerModel.setStringList(self.localWordList) def addItemToRemoteFileList(self, content): mode, num, owner, group, size, date, filename = self.parseFileInfo( content) if content.startswith('d'): icon = qIcon('folder.png') pathname = os.path.join(self.pwd, filename) self.remoteDir[pathname] = True self.remoteWordList.append(filename) else: icon = qIcon('file.png') item = QTreeWidgetItem() item.setIcon(0, icon) for n, i in enumerate((filename, size, owner, group, date, mode)): item.setText(n, i) self.remote.fileList.addTopLevelItem(item) if not self.remote.fileList.currentItem(): self.remote.fileList.setCurrentItem( self.remote.fileList.topLevelItem(0)) self.remote.fileList.setEnabled(True) def addItemToLocalFileList(self, content): mode, num, owner, group, size, date, filename = self.parseFileInfo( content) if content.startswith('d'): icon = qIcon('folder.png') pathname = os.path.join(self.local_pwd, filename) self.localDir[pathname] = True self.localWordList.append(filename) else: icon = qIcon('file.png') item = QTreeWidgetItem() item.setIcon(0, icon) for n, i in enumerate((filename, size, owner, group, date, mode)): item.setText(n, i) self.local.fileList.addTopLevelItem(item) if not self.local.fileList.currentItem(): self.local.fileList.setCurrentItem( self.local.fileList.topLevelItem(0)) self.local.fileList.setEnabled(True) def parseFileInfo(self, file): """ parse files information "drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib" result like follower "drwxr-xr-x", "2", "root", "wheel", "1024 Nov 17 1993", "lib" """ item = [f for f in file.split(' ') if f != ''] mode, num, owner, group, size, date, filename = (item[0], item[1], item[2], item[3], item[4], ' '.join(item[5:8]), ' '.join(item[8:])) return mode, num, owner, group, size, date, filename def cdToRemotePath(self): try: pathname = str(self.remote.pathEdit.text().toUtf8()) except AttributeError: pathname = str(self.remote.pathEdit.text()) try: self.ftp.cwd(pathname) except: return self.cwd = pathname.startswith( os.path.sep) and pathname or os.path.join(self.pwd, pathname) self.updateRemoteFileList() self.remote.backButton.setEnabled(True) if os.path.abspath(pathname) != self.remoteOriginPath: self.remote.homeButton.setEnabled(True) else: self.remote.homeButton.setEnabled(False) def cdToRemoteDirectory(self, item): pathname = os.path.join(self.pwd, str(item.text(0))) if not self.isRemoteDir(pathname): return self.remoteBrowseRec.append(pathname) self.ftp.cwd(pathname) self.pwd = self.ftp.pwd() self.updateRemoteFileList() self.remote.backButton.setEnabled(True) if pathname != self.remoteOriginPath: self.remote.homeButton.setEnabled(True) def cdToRemoteBackDirectory(self): pathname = self.remoteBrowseRec[self.remoteBrowseRec.index(self.pwd) - 1] if pathname != self.remoteBrowseRec[0]: self.remote.backButton.setEnabled(True) else: self.remote.backButton.setEnabled(False) if pathname != self.remoteOriginPath: self.remote.homeButton.setEnabled(True) else: self.remote.homeButton.setEnabled(False) self.remote.nextButton.setEnabled(True) self.pwd = pathname self.ftp.cwd(pathname) self.updateRemoteFileList() def cdToRemoteNextDirectory(self): pathname = self.remoteBrowseRec[self.remoteBrowseRec.index(self.pwd) + 1] if pathname != self.remoteBrowseRec[-1]: self.remote.nextButton.setEnabled(True) else: self.remote.nextButton.setEnabled(False) self.remote.backButton.setEnabled(True) if pathname != self.remoteOriginPath: self.remote.homeButton.setEnabled(True) else: self.remote.homeButton.setEnabled(False) self.remote.backButton.setEnabled(True) self.pwd = pathname self.ftp.cwd(pathname) self.updateRemoteFileList() def cdToRemoteHomeDirectory(self): self.ftp.cwd(self.remoteOriginPath) self.pwd = self.remoteOriginPath self.updateRemoteFileList() self.remote.homeButton.setEnabled(False) def cdToLocalPath(self): try: pathname = str(self.local.pathEdit.text().toUtf8()) except AttributeError: pathname = str(self.local.pathEdit.text()) pathname = pathname.endswith(os.path.sep) and pathname or os.path.join( self.local_pwd, pathname) if not os.path.exists(pathname) and not os.path.isdir(pathname): return else: self.localBrowseRec.append(pathname) self.local_pwd = pathname self.updateLocalFileList() self.local.backButton.setEnabled(True) print(pathname, self.localOriginPath) if os.path.abspath(pathname) != self.localOriginPath: self.local.homeButton.setEnabled(True) else: self.local.homeButton.setEnabled(False) def cdToLocalDirectory(self, item): pathname = os.path.join(self.local_pwd, str(item.text(0))) if not self.isLocalDir(pathname): return self.localBrowseRec.append(pathname) self.local_pwd = pathname self.updateLocalFileList() self.local.backButton.setEnabled(True) if pathname != self.localOriginPath: self.local.homeButton.setEnabled(True) def cdToLocalBackDirectory(self): pathname = self.localBrowseRec[ self.localBrowseRec.index(self.local_pwd) - 1] if pathname != self.localBrowseRec[0]: self.local.backButton.setEnabled(True) else: self.local.backButton.setEnabled(False) if pathname != self.localOriginPath: self.local.homeButton.setEnabled(True) else: self.local.homeButton.setEnabled(False) self.local.nextButton.setEnabled(True) self.local_pwd = pathname self.updateLocalFileList() def cdToLocalNextDirectory(self): pathname = self.localBrowseRec[ self.localBrowseRec.index(self.local_pwd) + 1] if pathname != self.localBrowseRec[-1]: self.local.nextButton.setEnabled(True) else: self.local.nextButton.setEnabled(False) if pathname != self.localOriginPath: self.local.homeButton.setEnabled(True) else: self.local.homeButton.setEnabled(False) self.local.backButton.setEnabled(True) self.local_pwd = pathname self.updateLocalFileList() def cdToLocalHomeDirectory(self): self.local_pwd = self.localOriginPath self.updateLocalFileList() self.local.homeButton.setEnabled(False) def updateLocalFileList(self): self.local.fileList.clear() self.loadToLocaFileList() def updateRemoteFileList(self): self.remote.fileList.clear() self.downloadToRemoteFileList() def isLocalDir(self, dirname): return self.localDir.get(dirname, None) def isRemoteDir(self, dirname): return self.remoteDir.get(dirname, None) def download(self): item = self.remote.fileList.currentItem() filesize = int(item.text(1)) try: srcfile = os.path.join(self.pwd, str(item.text(0).toUtf8())) dstfile = os.path.join(self.local_pwd, str(item.text(0).toUtf8())) except AttributeError: srcfile = os.path.join(self.pwd, str(item.text(0))) dstfile = os.path.join(self.local_pwd, str(item.text(0))) pb = self.progressDialog.addProgress( type='download', title=srcfile, size=filesize, ) pb.show() def callback(data): pb.set_value(data) file.write(data) file = open(dstfile, 'wb') fp = FTP() fp.set_pasv(False) fp.connect(host=self.ftp.host, port=self.ftp.port, timeout=self.ftp.timeout) fp.login(user=self.ftp.user, passwd=self.ftp.passwd) try: fp.retrbinary(cmd='RETR ' + srcfile, callback=callback) except: pb.destroy() def upload(self): item = self.local.fileList.currentItem() filesize = int(item.text(1)) try: srcfile = os.path.join(self.local_pwd, str(item.text(0).toUtf8())) dstfile = os.path.join(self.pwd, str(item.text(0).toUtf8())) except AttributeError: srcfile = os.path.join(self.local_pwd, str(item.text(0))) dstfile = os.path.join(self.pwd, str(item.text(0))) pb = self.progressDialog.addProgress( type='upload', title=srcfile, size=filesize, ) pb.show() file = open(srcfile, 'rb') fp = FTP() fp.connect(host=self.ftp.host, port=self.ftp.port, timeout=self.ftp.timeout) fp.login(user=self.ftp.user, passwd=self.ftp.passwd) fp.set_pasv(False) try: fp.storbinary(cmd='STOR ' + dstfile, fp=file, callback=pb.set_value) except: pb.destroy()
class FtpClient(QWidget): def __init__(self, parent=None): super(FtpClient, self).__init__(parent) self.ftp = FTP() self.setup_gui() self.downloads = [] self.localBrowseRec = [] self.remoteBrowseRec = [] self.local_pwd = os.getenv('HOME') self.ftp_hostname = '' self.ftp_username = '' self.ftp_password = '' # self.ftp_hostname = os.getenv('ftp_hostname') # self.ftp_username = os.getenv('ftp_username') # self.ftp_password = os.getenv('ftp_password') self.local.pathEdit.setText(self.local_pwd) self.localOriginPath = self.local_pwd self.localBrowseRec.append(self.local_pwd) self.load_to_local_filelist() # Signals self.remote.homeButton.clicked.connect(self.cd_to_remote_home_directory) self.remote.fileList.itemDoubleClicked.connect(self.cd_to_remote_directory) self.remote.fileList.itemClicked.connect(lambda: self.remote.downloadButton.setEnabled(True)) self.remote.backButton.clicked.connect(self.cd_to_remote_back_directory) self.remote.nextButton.clicked.connect(self.cd_to_remote_next_directory) self.remote.downloadButton.clicked.connect(lambda: Thread(target=self.download).start()) self.remote.connectButton.clicked.connect(self.connect) # QObject.connect(self.remote.pathEdit, pyqtSignal('returnPressed( )'), self.cd_to_remote_path) self.remote.pathEdit.returnPressed.connect(self.cd_to_remote_path) self.local.homeButton.clicked.connect(self.cd_to_local_home_directory) self.local.fileList.itemDoubleClicked.connect(self.cd_to_local_directory) self.local.fileList.itemClicked.connect(lambda: self.local.uploadButton.setEnabled(True)) self.local.backButton.clicked.connect(self.cd_to_local_back_directory) self.local.nextButton.clicked.connect(self.cd_to_local_next_directory) self.local.uploadButton.clicked.connect(lambda: Thread(target=self.upload).start()) self.local.connectButton.clicked.connect(self.connect) # QObject.connect(self.local.pathEdit, pyqtSignal('returnPressed( )'), self.cd_to_local_path) self.local.pathEdit.returnPressed.connect(self.cd_to_local_path) self.progressDialog = ProgressDialog(self) def setup_gui(self): self.resize(1200, 650) self.local = LocalGuiWidget(self) self.remote = RemoteGuiWidget(self) mainLayout = QHBoxLayout() mainLayout.addWidget(self.local) mainLayout.addWidget(self.remote) mainLayout.setSpacing(0) # mainLayout.setMargin(5) self.setLayout(mainLayout) def initialize(self): # self.localBrowseRec = [] # self.remoteBrowseRec = [] self.pwd = self.ftp.pwd() # self.local_pwd = os.getenv('HOME') self.remoteOriginPath = self.pwd # self.localOriginPath = self.local_pwd # self.localBrowseRec.append(self.local_pwd) self.remoteBrowseRec.append(self.pwd) self.download_to_remote_filelist() # self.loadToLocaFileList() def disconnect(self): pass def connect(self): if not bool(self.ftp_hostname): try: from urlparse import urlparse except ImportError: from urllib.parse import urlparse result = QInputDialog.getText(self, 'Connect To Host', 'Host Address', QLineEdit.Normal) if not result[1]: return try: self.ftp_hostname = str(result[0]) except AttributeError: self.ftp_hostname = str(result[0]) try: if self.ftp_hostname: self.ftp.connect(host=self.ftp_hostname, port=21, timeout=10) else: self.ftp.connect(host=self.ftp_hostname, port=21, timeout=10) self.login() except Exception as error: raise error def login(self): # if not bool(self.ftp_username) or bool(self.ftp_password): ask = loginDialog(self) if not ask: return else: self.ftp_username, self.ftp_password = ask[:2] # self.ftp.user = self.ftp_username # self.ftp.passwd = self.ftp_password self.ftp.login(user=self.ftp_username, passwd=self.ftp_password) self.initialize() self.remote.pathEdit.setText(self.pwd) ''' def connect(self, address, port=21, timeout=10): from urlparse import urlparse if urlparse(address).hostname: self.ftp.connect(urlparse(address).hostname, port, timeout) else: self.ftp.connect(address, port, timeout) def login(self, name=None, passwd=None): if not name: self.ftp.login( ) else: self.ftp.login(name, passwd) self.ftp.user, self.ftp.passwd = (user, passwd) self.initialize( ) ''' # ---------------------------------------------------------------------------------# ## the download_to_remote_filelist with load_to_local_filelist is doing the same thing ## # ---------------------------------------------------------------------------------# def download_to_remote_filelist(self): """ download file and directory list from FTP Server """ self.remoteWordList = [] self.remoteDir = {} self.ftp.dir('.', self.add_item_to_remote_filelist) self.remote.completerModel.setStringList(self.remoteWordList) self.remote.fileList.sortByColumn(0, Qt.SortOrder.AscendingOrder) def load_to_local_filelist(self): """ load file and directory list from local computer """ self.localWordList = [] self.localDir = {} for f in os.listdir(self.local_pwd): pathname = os.path.join(self.local_pwd, f) self.add_item_to_local_filelist(fileProperty(pathname)) self.local.completerModel.setStringList(self.localWordList) self.local.fileList.sortByColumn(0, Qt.SortOrder.AscendingOrder) def add_item_to_remote_filelist(self, content): mode, num, owner, group, filesize_human, date, filename, size = self.parse_file_info(content) if content.startswith('d'): icon = qIcon('folder.png') pathname = os.path.join(self.pwd, filename) self.remoteDir[pathname] = True self.remoteWordList.append(filename) else: icon = qIcon('file.png') item = QTreeWidgetItem() item.setIcon(0, icon) for n, i in enumerate((filename, filesize_human, owner, group, date, mode, size)): item.setText(n, i) self.remote.fileList.addTopLevelItem(item) if not self.remote.fileList.currentItem(): self.remote.fileList.setCurrentItem(self.remote.fileList.topLevelItem(0)) self.remote.fileList.setEnabled(True) def add_item_to_local_filelist(self, content): mode, num, owner, group, filesize_human, date, filename, size = self.parse_file_info(content) if content.startswith('d'): icon = qIcon('folder.png') pathname = os.path.join(self.local_pwd, filename) self.localDir[pathname] = True self.localWordList.append(filename) else: icon = qIcon('file.png') item = QTreeWidgetItem() item.setIcon(0, icon) for n, i in enumerate((filename, filesize_human, owner, group, date, mode, size)): # print((filename, size, owner, group, date, mode)) item.setText(n, i) self.local.fileList.addTopLevelItem(item) if not self.local.fileList.currentItem(): self.local.fileList.setCurrentItem(self.local.fileList.topLevelItem(0)) self.local.fileList.setEnabled(True) def parse_file_info(self, file): """ parse files information "drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib" result like follower "drwxr-xr-x", "2", "root", "wheel", "1024 Nov 17 1993", "lib" """ item = [f for f in file.split(' ') if f != ''] mode, num, owner, group, size, date, filename = ( item[0], item[1], item[2], item[3], item[4], ' '.join(item[5:8]), ' '.join(item[8:])) filesize_human = HumanBytes.format(int(size), precision=2) return mode, num, owner, group, filesize_human, date, filename, size # --------------------------# ## for remote file system ## # --------------------------# def cd_to_remote_path(self): try: pathname = str(self.remote.pathEdit.text()) except AttributeError: pathname = str(self.remote.pathEdit.text()) try: self.ftp.cwd(pathname) except: return self.cwd = pathname.startswith(os.path.sep) and pathname or os.path.join(self.pwd, pathname) self.update_remote_filelist() self.remote.pathEdit.setText(self.cwd) self.remote.backButton.setEnabled(True) if os.path.abspath(pathname) != self.remoteOriginPath: self.remote.homeButton.setEnabled(True) else: self.remote.homeButton.setEnabled(False) def cd_to_remote_directory(self, item, column): pathname = os.path.join(self.pwd, str(item.text(0))) if not self.is_remote_dir(pathname): return self.remoteBrowseRec.append(pathname) self.ftp.cwd(pathname) self.pwd = self.ftp.pwd() self.remote.pathEdit.setText(self.pwd) self.update_remote_filelist() self.remote.backButton.setEnabled(True) if pathname != self.remoteOriginPath: self.remote.homeButton.setEnabled(True) def cd_to_remote_back_directory(self): pathname = self.remoteBrowseRec[self.remoteBrowseRec.index(self.pwd) - 1] if pathname != self.remoteBrowseRec[0]: self.remote.backButton.setEnabled(True) else: self.remote.backButton.setEnabled(False) if pathname != self.remoteOriginPath: self.remote.homeButton.setEnabled(True) else: self.remote.homeButton.setEnabled(False) self.remote.nextButton.setEnabled(True) self.pwd = pathname self.ftp.cwd(pathname) self.update_remote_filelist() self.remote.pathEdit.setText(self.pwd) def cd_to_remote_next_directory(self): pathname = self.remoteBrowseRec[self.remoteBrowseRec.index(self.pwd) + 1] if pathname != self.remoteBrowseRec[-1]: self.remote.nextButton.setEnabled(True) else: self.remote.nextButton.setEnabled(False) self.remote.backButton.setEnabled(True) if pathname != self.remoteOriginPath: self.remote.homeButton.setEnabled(True) else: self.remote.homeButton.setEnabled(False) self.remote.backButton.setEnabled(True) self.pwd = pathname self.ftp.cwd(pathname) self.update_remote_filelist() self.remote.pathEdit.setText(self.pwd) def cd_to_remote_home_directory(self): self.ftp.cwd(self.remoteOriginPath) self.pwd = self.remoteOriginPath self.update_remote_filelist() self.remote.pathEdit.setText(self.pwd) self.remote.homeButton.setEnabled(False) # -------------------------# ## for local file system ## # -------------------------# def cd_to_local_path(self): try: pathname = str(self.local.pathEdit.text()) except AttributeError: pathname = str(self.local.pathEdit.text()) pathname = pathname.endswith(os.path.sep) and pathname or os.path.join(self.local_pwd, pathname) if not os.path.exists(pathname) and not os.path.isdir(pathname): return else: self.localBrowseRec.append(pathname) self.local_pwd = pathname self.update_local_filelist() self.local.pathEdit.setText(self.local_pwd) self.local.backButton.setEnabled(True) print(pathname, self.localOriginPath) if os.path.abspath(pathname) != self.localOriginPath: self.local.homeButton.setEnabled(True) else: self.local.homeButton.setEnabled(False) def cd_to_local_directory(self, item, column): pathname = os.path.join(self.local_pwd, str(item.text(0))) if not self.is_local_dir(pathname): return self.localBrowseRec.append(pathname) self.local_pwd = pathname self.update_local_filelist() self.local.pathEdit.setText(self.local_pwd) self.local.backButton.setEnabled(True) if pathname != self.localOriginPath: self.local.homeButton.setEnabled(True) def cd_to_local_back_directory(self): pathname = self.localBrowseRec[self.localBrowseRec.index(self.local_pwd) - 1] if pathname != self.localBrowseRec[0]: self.local.backButton.setEnabled(True) else: self.local.backButton.setEnabled(False) if pathname != self.localOriginPath: self.local.homeButton.setEnabled(True) else: self.local.homeButton.setEnabled(False) self.local.nextButton.setEnabled(True) self.local_pwd = pathname self.update_local_filelist() self.local.pathEdit.setText(self.local_pwd) def cd_to_local_next_directory(self): pathname = self.localBrowseRec[self.localBrowseRec.index(self.local_pwd) + 1] if pathname != self.localBrowseRec[-1]: self.local.nextButton.setEnabled(True) else: self.local.nextButton.setEnabled(False) if pathname != self.localOriginPath: self.local.homeButton.setEnabled(True) else: self.local.homeButton.setEnabled(False) self.local.backButton.setEnabled(True) self.local_pwd = pathname self.update_local_filelist() self.local.pathEdit.setText(self.local_pwd) def cd_to_local_home_directory(self): self.local_pwd = self.localOriginPath self.update_local_filelist() self.local.pathEdit.setText(self.local_pwd) self.local.homeButton.setEnabled(False) def update_local_filelist(self): self.local.fileList.clear() self.load_to_local_filelist() def update_remote_filelist(self): self.remote.fileList.clear() self.download_to_remote_filelist() def is_local_dir(self, dirname): return self.localDir.get(dirname, None) def is_remote_dir(self, dirname): return self.remoteDir.get(dirname, None) def download(self): item = self.remote.fileList.currentItem() filesize = int(item.text(6)) try: srcfile = os.path.join(self.pwd, str(item.text(0))) dstfile = os.path.join(self.local_pwd, str(item.text(0))) except AttributeError: srcfile = os.path.join(self.pwd, str(item.text(0))) dstfile = os.path.join(self.local_pwd, str(item.text(0))) pb = self.progressDialog.addProgress( type='download', title=srcfile, size=filesize, ) def callback(data): pb.set_value(data) file.write(data) file = open(dstfile, 'wb') fp = FTP() fp.connect(host=self.ftp_hostname, port=self.ftp.port, timeout=self.ftp.timeout) fp.login(user=self.ftp_username, passwd=self.ftp_password) fp.retrbinary(cmd='RETR ' + srcfile, callback=callback) def upload(self): item = self.local.fileList.currentItem() print(item) # filesize = int(item.text(1)) filesize = int(item.text(6)) try: srcfile = os.path.join(self.local_pwd, str(item.text(0))) dstfile = os.path.join(self.pwd, str(item.text(0))) except AttributeError: srcfile = os.path.join(self.local_pwd, str(item.text(0))) dstfile = os.path.join(self.pwd, str(item.text(0))) pb = self.progressDialog.addProgress( type='upload', title=srcfile, size=filesize, ) file = open(srcfile, 'rb') fp = FTP() fp.connect(host=self.ftp_hostname, port=self.ftp.port, timeout=self.ftp.timeout) fp.login(user=self.ftp_username, passwd=self.ftp_password) fp.storbinary(cmd='STOR ' + dstfile, fp=file, callback=pb.set_value)
class FtpClient(QtGui.QWidget): def __init__(self, parent=None): super(FtpClient, self).__init__(parent) self.ftp = FTP( ) self.setupGui( ) self.downloads=[ ] self.remote.homeButton.clicked.connect(self.cdToRemoteHomeDirectory) self.remote.fileList.itemDoubleClicked.connect(self.cdToRemoteDirectory) self.remote.fileList.itemClicked.connect(lambda: self.remote.downloadButton.setEnabled(True)) self.remote.backButton.clicked.connect(self.cdToRemoteBackDirectory) self.remote.nextButton.clicked.connect(self.cdToRemoteNextDirectory) self.remote.downloadButton.clicked.connect(lambda: Thread(target=self.download).start()) QObject.connect(self.remote.pathEdit, SIGNAL('returnPressed( )'), self.cdToRemotePath) self.local.homeButton.clicked.connect(self.cdToLocalHomeDirectory) self.local.fileList.itemDoubleClicked.connect(self.cdToLocalDirectory) self.local.fileList.itemClicked.connect(lambda: self.local.uploadButton.setEnabled(True)) self.local.backButton.clicked.connect(self.cdToLocalBackDirectory) self.local.nextButton.clicked.connect(self.cdToLocalNextDirectory) self.local.uploadButton.clicked.connect(lambda: Thread(target=self.upload).start()) self.local.connectButton.clicked.connect(self.connect) QObject.connect(self.local.pathEdit, SIGNAL('returnPressed( )'), self.cdToLocalPath) self.progressDialog = ProgressDialog(self) def setupGui(self): self.resize(1200, 650) self.local = LocalGuiWidget(self) self.remote = RemoteGuiWidget(self) mainLayout = QtGui.QHBoxLayout( ) mainLayout.addWidget(self.remote) mainLayout.addWidget(self.local) mainLayout.setSpacing(0) mainLayout.setMargin(5) self.setLayout(mainLayout) def initialize(self): self.localBrowseRec = [ ] self.remoteBrowseRec = [ ] self.pwd = self.ftp.pwd( ) self.local_pwd = os.getenv('HOME') self.remoteOriginPath = self.pwd self.localOriginPath = self.local_pwd self.localBrowseRec.append(self.local_pwd) self.remoteBrowseRec.append(self.pwd) self.downloadToRemoteFileList( ) self.loadToLocaFileList( ) def disconnect(self): pass def connect(self): try: from urlparse import urlparse except ImportError: from urllib.parse import urlparse result = QtGui.QInputDialog.getText(self, 'Connect To Host', 'Host Address', QtGui.QLineEdit.Normal) if not result[1]: return try: host = str(result[0].toUtf8()) except AttributeError: host = str(result[0]) try: if urlparse(host).hostname: self.ftp.connect(host=urlparse(host).hostname, port=21, timeout=10) else: self.ftp.connect(host=host, port=21, timeout=10) self.login() except Exception as error: raise error def login(self): ask = loginDialog(self) if not ask: return else: user, passwd = ask[:2] self.ftp.user = user self.ftp.passwd = passwd self.ftp.login(user=user, passwd=passwd) self.initialize( ) ''' def connect(self, address, port=21, timeout=10): from urlparse import urlparse if urlparse(address).hostname: self.ftp.connect(urlparse(address).hostname, port, timeout) else: self.ftp.connect(address, port, timeout) def login(self, name=None, passwd=None): if not name: self.ftp.login( ) else: self.ftp.login(name, passwd) self.ftp.user, self.ftp.passwd = (user, passwd) self.initialize( ) ''' #---------------------------------------------------------------------------------# ## the downloadToRemoteFileList with loadToLocalFileList is doing the same thing ## #---------------------------------------------------------------------------------# def downloadToRemoteFileList(self): """ download file and directory list from FTP Server """ self.remoteWordList = [ ] self.remoteDir = { } self.ftp.dir('.', self.addItemToRemoteFileList) self.remote.completerModel.setStringList(self.remoteWordList) def loadToLocaFileList(self): """ load file and directory list from local computer """ self.localWordList = [ ] self.localDir = { } for f in os.listdir(self.local_pwd): pathname = os.path.join(self.local_pwd, f) self.addItemToLocalFileList(fileProperty(pathname)) self.local.completerModel.setStringList(self.localWordList) def addItemToRemoteFileList(self, content): mode, num, owner, group, size, date, filename = self.parseFileInfo(content) if content.startswith('d'): icon = qIcon('folder.png') pathname = os.path.join(self.pwd, filename) self.remoteDir[ pathname] = True self.remoteWordList.append(filename) else: icon = qIcon('file.png') item = QtGui.QTreeWidgetItem( ) item.setIcon(0, icon) for n, i in enumerate((filename, size, owner, group, date, mode)): item.setText(n, i) self.remote.fileList.addTopLevelItem(item) if not self.remote.fileList.currentItem(): self.remote.fileList.setCurrentItem(self.remote.fileList.topLevelItem(0)) self.remote.fileList.setEnabled(True) def addItemToLocalFileList(self, content): mode, num, owner, group, size, date, filename = self.parseFileInfo(content) if content.startswith('d'): icon = qIcon('folder.png') pathname = os.path.join(self.local_pwd, filename) self.localDir[ pathname ] = True self.localWordList.append(filename) else: icon = qIcon('file.png') item = QtGui.QTreeWidgetItem( ) item.setIcon(0, icon) for n, i in enumerate((filename, size, owner, group, date, mode)): #print((filename, size, owner, group, date, mode)) item.setText(n, i) self.local.fileList.addTopLevelItem(item) if not self.local.fileList.currentItem(): self.local.fileList.setCurrentItem(self.local.fileList.topLevelItem(0)) self.local.fileList.setEnabled(True) def parseFileInfo(self, file): """ parse files information "drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib" result like follower "drwxr-xr-x", "2", "root", "wheel", "1024 Nov 17 1993", "lib" """ item = [f for f in file.split(' ') if f != ''] mode, num, owner, group, size, date, filename = ( item[0], item[1], item[2], item[3], item[4], ' '.join(item[5:8]), ' '.join(item[8:])) return (mode, num, owner, group, size, date, filename) #--------------------------# ## for remote file system ## #--------------------------# def cdToRemotePath(self): try: pathname = str(self.remote.pathEdit.text().toUtf8()) except AttributeError: pathname = str(self.remote.pathEdit.text()) try: self.ftp.cwd(pathname) except: return self.cwd = pathname.startswith(os.path.sep) and pathname or os.path.join(self.pwd, pathname) self.updateRemoteFileList( ) self.remote.backButton.setEnabled(True) if os.path.abspath(pathname) != self.remoteOriginPath: self.remote.homeButton.setEnabled(True) else: self.remote.homeButton.setEnabled(False) def cdToRemoteDirectory(self, item, column): pathname = os.path.join(self.pwd, str(item.text(0))) if not self.isRemoteDir(pathname): return self.remoteBrowseRec.append(pathname) self.ftp.cwd(pathname) self.pwd = self.ftp.pwd( ) self.updateRemoteFileList( ) self.remote.backButton.setEnabled(True) if pathname != self.remoteOriginPath: self.remote.homeButton.setEnabled(True) def cdToRemoteBackDirectory(self): pathname = self.remoteBrowseRec[ self.remoteBrowseRec.index(self.pwd)-1 ] if pathname != self.remoteBrowseRec[0]: self.remote.backButton.setEnabled(True) else: self.remote.backButton.setEnabled(False) if pathname != self.remoteOriginPath: self.remote.homeButton.setEnabled(True) else: self.remote.homeButton.setEnabled(False) self.remote.nextButton.setEnabled(True) self.pwd = pathname self.ftp.cwd(pathname) self.updateRemoteFileList( ) def cdToRemoteNextDirectory(self): pathname = self.remoteBrowseRec[self.remoteBrowseRec.index(self.pwd)+1] if pathname != self.remoteBrowseRec[-1]: self.remote.nextButton.setEnabled(True) else: self.remote.nextButton.setEnabled(False) self.remote.backButton.setEnabled(True) if pathname != self.remoteOriginPath: self.remote.homeButton.setEnabled(True) else: self.remote.homeButton.setEnabled(False) self.remote.backButton.setEnabled(True) self.pwd = pathname self.ftp.cwd(pathname) self.updateRemoteFileList( ) def cdToRemoteHomeDirectory(self): self.ftp.cwd(self.remoteOriginPath) self.pwd = self.remoteOriginPath self.updateRemoteFileList( ) self.remote.homeButton.setEnabled(False) #-------------------------# ## for local file system ## #-------------------------# def cdToLocalPath(self): try: pathname = str(self.local.pathEdit.text( ).toUtf8()) except AttributeError: pathname = str(self.local.pathEdit.text()) pathname = pathname.endswith(os.path.sep) and pathname or os.path.join(self.local_pwd, pathname) if not os.path.exists(pathname) and not os.path.isdir(pathname): return else: self.localBrowseRec.append(pathname) self.local_pwd = pathname self.updateLocalFileList( ) self.local.backButton.setEnabled(True) print(pathname, self.localOriginPath) if os.path.abspath(pathname) != self.localOriginPath: self.local.homeButton.setEnabled(True) else: self.local.homeButton.setEnabled(False) def cdToLocalDirectory(self, item, column): pathname = os.path.join(self.local_pwd, str(item.text(0))) if not self.isLocalDir(pathname): return self.localBrowseRec.append(pathname) self.local_pwd = pathname self.updateLocalFileList( ) self.local.backButton.setEnabled(True) if pathname != self.localOriginPath: self.local.homeButton.setEnabled(True) def cdToLocalBackDirectory(self): pathname = self.localBrowseRec[ self.localBrowseRec.index(self.local_pwd)-1 ] if pathname != self.localBrowseRec[0]: self.local.backButton.setEnabled(True) else: self.local.backButton.setEnabled(False) if pathname != self.localOriginPath: self.local.homeButton.setEnabled(True) else: self.local.homeButton.setEnabled(False) self.local.nextButton.setEnabled(True) self.local_pwd = pathname self.updateLocalFileList( ) def cdToLocalNextDirectory(self): pathname = self.localBrowseRec[self.localBrowseRec.index(self.local_pwd)+1] if pathname != self.localBrowseRec[-1]: self.local.nextButton.setEnabled(True) else: self.local.nextButton.setEnabled(False) if pathname != self.localOriginPath: self.local.homeButton.setEnabled(True) else: self.local.homeButton.setEnabled(False) self.local.backButton.setEnabled(True) self.local_pwd = pathname self.updateLocalFileList( ) def cdToLocalHomeDirectory(self): self.local_pwd = self.localOriginPath self.updateLocalFileList( ) self.local.homeButton.setEnabled(False) def updateLocalFileList(self): self.local.fileList.clear( ) self.loadToLocaFileList( ) def updateRemoteFileList(self): self.remote.fileList.clear( ) self.downloadToRemoteFileList( ) def isLocalDir(self, dirname): return self.localDir.get(dirname, None) def isRemoteDir(self, dirname): return self.remoteDir.get(dirname, None) def download(self): item = self.remote.fileList.currentItem( ) filesize = int(item.text(1)) try: srcfile = os.path.join(self.pwd, str(item.text(0).toUtf8())) dstfile = os.path.join(self.local_pwd, str(item.text(0).toUtf8())) except AttributeError: srcfile = os.path.join(self.pwd, str(item.text(0))) dstfile = os.path.join(self.local_pwd, str(item.text(0))) pb = self.progressDialog.addProgress( type='download', title=srcfile, size=filesize, ) def callback(data): pb.set_value(data) file.write(data) file = open(dstfile, 'wb') fp = FTP( ) fp.connect(host=self.ftp.host, port=self.ftp.port, timeout=self.ftp.timeout) fp.login(user=self.ftp.user, passwd=self.ftp.passwd) fp.retrbinary(cmd='RETR '+srcfile, callback=callback) def upload(self): item = self.local.fileList.currentItem( ) filesize = int(item.text(1)) try: srcfile = os.path.join(self.local_pwd, str(item.text(0).toUtf8())) dstfile = os.path.join(self.pwd, str(selected_item.text(0).toUtf8())) except AttributeError: srcfile = os.path.join(self.local_pwd, str(item.text(0))) dstfile = os.path.join(self.pwd, str(selected_item.text(0))) pb = self.progressDialog.addProgress( type='upload', title=srcfile, size=filesize, ) file = open(srcfile, 'rb') fp = FTP( ) fp.connect(host=self.ftp.host, port=self.ftp.port, timeout=self.ftp.timeout) fp.login(user=self.ftp.user, passwd=self.ftp.passwd) fp.storbinary(cmd='STOR '+dstfile, fp=file, callback=pb.set_value)