gpt4 book ai didi

python - 使用 Python 创建 FTP 客户端

转载 作者:太空狗 更新时间:2023-10-30 01:49:45 25 4
gpt4 key购买 nike

自从我开始使用 Internet 以来,我一直想创建自己的 ftp 客户端。现在我正在学习 Python,我正在考虑创建一个作为练习/个人项目。

我在想,

  • 你们推荐哪些图书馆? ftplib 就足够了吗?或者您会推荐另一个图书馆(最好是有好的文档的图书馆)吗?
  • 我正在考虑使用 wxPython。这是个好主意吗?我应该先学习它吗?
  • 我拥有网络开发背景。你们会给我什么提示/建议?

如果有任何指导/帮助,我将不胜感激。提前致谢! :)

最佳答案

听起来您想制作一个具有 GUI 的程序。我可以推荐在您的应用程序的那部分使用 PyQt 吗? ftplib 应该适合您的 FTP 支持,您可以找到文档 right here .

或者对于 FTP 支持,您可以使用 PyQt 框架的 QtNetwork 模块中的 QFtp 类。以下是 PyQt 附带的 FTP 客户端示例。图片随附。

#!/usr/bin/env python

"""PyQt4 port of the network/ftp example from Qt v4.x"""

# This is only needed for Python v2 but is harmless for Python v3.
import sip
sip.setapi('QString', 2)

from PyQt4 import QtCore, QtGui, QtNetwork

import ftp_rc


class FtpWindow(QtGui.QDialog):
def __init__(self, parent=None):
super(FtpWindow, self).__init__(parent)

self.isDirectory = {}
self.currentPath = ''
self.ftp = None
self.outFile = None

ftpServerLabel = QtGui.QLabel("Ftp &server:")
self.ftpServerLineEdit = QtGui.QLineEdit('ftp.trolltech.com')
ftpServerLabel.setBuddy(self.ftpServerLineEdit)

self.statusLabel = QtGui.QLabel("Please enter the name of an FTP server.")

self.fileList = QtGui.QTreeWidget()
self.fileList.setEnabled(False)
self.fileList.setRootIsDecorated(False)
self.fileList.setHeaderLabels(("Name", "Size", "Owner", "Group", "Time"))
self.fileList.header().setStretchLastSection(False)

self.connectButton = QtGui.QPushButton("Connect")
self.connectButton.setDefault(True)

self.cdToParentButton = QtGui.QPushButton()
self.cdToParentButton.setIcon(QtGui.QIcon(':/images/cdtoparent.png'))
self.cdToParentButton.setEnabled(False)

self.downloadButton = QtGui.QPushButton("Download")
self.downloadButton.setEnabled(False)

self.quitButton = QtGui.QPushButton("Quit")

buttonBox = QtGui.QDialogButtonBox()
buttonBox.addButton(self.downloadButton,
QtGui.QDialogButtonBox.ActionRole)
buttonBox.addButton(self.quitButton, QtGui.QDialogButtonBox.RejectRole)

self.progressDialog = QtGui.QProgressDialog(self)

self.fileList.itemActivated.connect(self.processItem)
self.fileList.currentItemChanged.connect(self.enableDownloadButton)
self.progressDialog.canceled.connect(self.cancelDownload)
self.connectButton.clicked.connect(self.connectOrDisconnect)
self.cdToParentButton.clicked.connect(self.cdToParent)
self.downloadButton.clicked.connect(self.downloadFile)
self.quitButton.clicked.connect(self.close)

topLayout = QtGui.QHBoxLayout()
topLayout.addWidget(ftpServerLabel)
topLayout.addWidget(self.ftpServerLineEdit)
topLayout.addWidget(self.cdToParentButton)
topLayout.addWidget(self.connectButton)

mainLayout = QtGui.QVBoxLayout()
mainLayout.addLayout(topLayout)
mainLayout.addWidget(self.fileList)
mainLayout.addWidget(self.statusLabel)
mainLayout.addWidget(buttonBox)
self.setLayout(mainLayout)

self.setWindowTitle("FTP")

def sizeHint(self):
return QtCore.QSize(500, 300)

def connectOrDisconnect(self):
if self.ftp:
self.ftp.abort()
self.ftp.deleteLater()
self.ftp = None

self.fileList.setEnabled(False)
self.cdToParentButton.setEnabled(False)
self.downloadButton.setEnabled(False)
self.connectButton.setEnabled(True)
self.connectButton.setText("Connect")
self.setCursor(QtCore.Qt.ArrowCursor)

return

self.setCursor(QtCore.Qt.WaitCursor)

self.ftp = QtNetwork.QFtp(self)
self.ftp.commandFinished.connect(self.ftpCommandFinished)
self.ftp.listInfo.connect(self.addToList)
self.ftp.dataTransferProgress.connect(self.updateDataTransferProgress)

self.fileList.clear()
self.currentPath = ''
self.isDirectory.clear()

url = QtCore.QUrl(self.ftpServerLineEdit.text())
if not url.isValid() or url.scheme().lower() != 'ftp':
self.ftp.connectToHost(self.ftpServerLineEdit.text(), 21)
self.ftp.login()
else:
self.ftp.connectToHost(url.host(), url.port(21))

user_name = url.userName()
if user_name:
try:
# Python v3.
user_name = bytes(user_name, encoding='latin1')
except:
# Python v2.
pass

self.ftp.login(QtCore.QUrl.fromPercentEncoding(user_name), url.password())
else:
self.ftp.login()

if url.path():
self.ftp.cd(url.path())

self.fileList.setEnabled(True)
self.connectButton.setEnabled(False)
self.connectButton.setText("Disconnect")
self.statusLabel.setText("Connecting to FTP server %s..." % self.ftpServerLineEdit.text())

def downloadFile(self):
fileName = self.fileList.currentItem().text(0)

if QtCore.QFile.exists(fileName):
QtGui.QMessageBox.information(self, "FTP",
"There already exists a file called %s in the current "
"directory." % fileName)
return

self.outFile = QtCore.QFile(fileName)
if not self.outFile.open(QtCore.QIODevice.WriteOnly):
QtGui.QMessageBox.information(self, "FTP",
"Unable to save the file %s: %s." % (fileName, self.outFile.errorString()))
self.outFile = None
return

self.ftp.get(self.fileList.currentItem().text(0), self.outFile)

self.progressDialog.setLabelText("Downloading %s..." % fileName)
self.downloadButton.setEnabled(False)
self.progressDialog.exec_()

def cancelDownload(self):
self.ftp.abort()

def ftpCommandFinished(self, _, error):
self.setCursor(QtCore.Qt.ArrowCursor)

if self.ftp.currentCommand() == QtNetwork.QFtp.ConnectToHost:
if error:
QtGui.QMessageBox.information(self, "FTP",
"Unable to connect to the FTP server at %s. Please "
"check that the host name is correct." % self.ftpServerLineEdit.text())
self.connectOrDisconnect()
return

self.statusLabel.setText("Logged onto %s." % self.ftpServerLineEdit.text())
self.fileList.setFocus()
self.downloadButton.setDefault(True)
self.connectButton.setEnabled(True)
return

if self.ftp.currentCommand() == QtNetwork.QFtp.Login:
self.ftp.list()

if self.ftp.currentCommand() == QtNetwork.QFtp.Get:
if error:
self.statusLabel.setText("Canceled download of %s." % self.outFile.fileName())
self.outFile.close()
self.outFile.remove()
else:
self.statusLabel.setText("Downloaded %s to current directory." % self.outFile.fileName())
self.outFile.close()

self.outFile = None
self.enableDownloadButton()
self.progressDialog.hide()
elif self.ftp.currentCommand() == QtNetwork.QFtp.List:
if not self.isDirectory:
self.fileList.addTopLevelItem(QtGui.QTreeWidgetItem(["<empty>"]))
self.fileList.setEnabled(False)

def addToList(self, urlInfo):
item = QtGui.QTreeWidgetItem()
item.setText(0, urlInfo.name())
item.setText(1, str(urlInfo.size()))
item.setText(2, urlInfo.owner())
item.setText(3, urlInfo.group())
item.setText(4, urlInfo.lastModified().toString('MMM dd yyyy'))

if urlInfo.isDir():
icon = QtGui.QIcon(':/images/dir.png')
else:
icon = QtGui.QIcon(':/images/file.png')
item.setIcon(0, icon)

self.isDirectory[urlInfo.name()] = urlInfo.isDir()
self.fileList.addTopLevelItem(item)
if not self.fileList.currentItem():
self.fileList.setCurrentItem(self.fileList.topLevelItem(0))
self.fileList.setEnabled(True)

def processItem(self, item):
name = item.text(0)
if self.isDirectory.get(name):
self.fileList.clear()
self.isDirectory.clear()
self.currentPath += '/' + name
self.ftp.cd(name)
self.ftp.list()
self.cdToParentButton.setEnabled(True)
self.setCursor(QtCore.Qt.WaitCursor)

def cdToParent(self):
self.setCursor(QtCore.Qt.WaitCursor)
self.fileList.clear()
self.isDirectory.clear()

dirs = self.currentPath.split('/')
if len(dirs) > 1:
self.currentPath = ''
self.cdToParentButton.setEnabled(False)
self.ftp.cd('/')
else:
self.currentPath = '/'.join(dirs[:-1])
self.ftp.cd(self.currentPath)

self.ftp.list()

def updateDataTransferProgress(self, readBytes, totalBytes):
self.progressDialog.setMaximum(totalBytes)
self.progressDialog.setValue(readBytes)

def enableDownloadButton(self):
current = self.fileList.currentItem()
if current:
currentFile = current.text(0)
self.downloadButton.setEnabled(not self.isDirectory.get(currentFile))
else:
self.downloadButton.setEnabled(False)


if __name__ == '__main__':

import sys

app = QtGui.QApplication(sys.argv)
ftpWin = FtpWindow()
ftpWin.show()
sys.exit(ftpWin.exec_())

关于python - 使用 Python 创建 FTP 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1995046/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com