Skip to content

"on_incomplete_file_received" callback doesn't work #655

@Program2113

Description

@Program2113

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

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions