-
-
Notifications
You must be signed in to change notification settings - Fork 270
Open
Description
I have a requirement where the server should be able to detect whether the file uploaded by the client is fully received or not. To simulate this process, I have uploaded multiple files (of size >150mb) to the server and intentionally closed the connection in the middle of the upload. The callback did work sometimes but it missed in as many times. I don't know the reason, but I think of it as an issue with the library itself. I'm sharing the server and client code for reference.
##Client Script##
import ftplib
import os
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QProgressBar, QPushButton, QVBoxLayout, QWidget
class FTPClient:
def __init__(self, host, port, username, password):
self.host = host
self.port = port
self.username = username
self.password = password
self.ftp = None
def connect(self):
try:
self.ftp = ftplib.FTP()
self.ftp.connect(self.host, self.port)
self.ftp.login(self.username, self.password)
print(f"Connected to {self.host}:{self.port}")
except ftplib.all_errors as e:
print(f"Error connecting to FTP server: {e}")
return False
return True
def upload_file(self, file_paths, progress_callback):
try:
for file_path in file_paths:
file_size = os.path.getsize(file_path)
with open(file_path, 'rb') as file:
def handle_progress(block):
progress_callback(file.tell(), file_size)
try:
self.ftp.storbinary(f'STOR {os.path.basename(file_path)}', file, 1024, callback=handle_progress)
print(f'File {file_path} uploaded successfully.')
except (ftplib.error_temp, ftplib.error_perm) as e:
print(f'Error during file upload: {e}')
continue # Continue with the next file
except ftplib.all_errors as e:
print(f'Error uploading file: {e}')
def close(self):
if self.ftp:
self.ftp.quit()
class FTPClientApp(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("FTP Client")
self.setGeometry(100, 100, 400, 200)
self.ftp_client = None
self.progress_bar = QProgressBar(self)
self.progress_bar.setGeometry(50, 50, 300, 30)
self.upload_button = QPushButton("Upload File", self)
self.upload_button.setGeometry(150, 100, 100, 40)
self.upload_button.clicked.connect(self.upload_file)
def upload_file(self):
file_path, _ = QFileDialog.getOpenFileNames(self, "Select Files to Upload")
if file_path:
self.progress_bar.setValue(0)
self.ftp_client = FTPClient("localhost", 2121, "user", "12345")
if self.ftp_client.connect():
self.upload_button.setEnabled(False)
self.ftp_client.upload_file(file_path, self.update_progress)
self.upload_button.setEnabled(True)
self.ftp_client.close()
def update_progress(self, bytes_sent, total_size):
progress = (bytes_sent / total_size) * 100
self.progress_bar.setValue(int(progress))
if __name__ == "__main__":
app = QApplication([])
window = FTPClientApp()
window.show()
app.exec_()
##Server Script##
import os
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
from pyftpdlib.authorizers import DummyAuthorizer
class MyHandler(FTPHandler):
def on_connect(self):
print("%s:%s connected" % (self.remote_ip, self.remote_port))
def on_disconnect(self):
# do something when client disconnects
pass
def on_login(self, username):
# do something when user login
pass
def on_logout(self, username):
# do something when user logs out
pass
def on_file_sent(self, file):
# do something when a file has been sent
pass
def on_file_received(self, file):
# do something when a file has been received
pass
def on_incomplete_file_sent(self, file):
# do something when a file is partially sent
pass
def on_incomplete_file_received(self, file):
# remove partially uploaded files
print(f"File incompletely shared: {file}")
import os
os.remove(file)
def main():
homedir = os.path.dirname(os.path.abspath(__file__))
print(homedir)
authorizer = DummyAuthorizer()
authorizer.add_user('user', '1234asff5', homedir=homedir, perm='elradfmwMT')
authorizer.add_anonymous(homedir=homedir)
handler = MyHandler
handler.authorizer = authorizer
server = FTPServer(('', 2121), handler)
server.serve_forever()
Metadata
Metadata
Assignees
Labels
No labels