def moveFile(ftpPath, oldPath, newPath, passiveMode=False):
    with connection(ftpPath, passiveMode) as ftp:
        url = parseUrl(ftpPath)
        filename = url['filename']
        log.info("Moving File " + filename)
        try:
            ftp.rename(oldPath, newPath)
        except Exception as e:
            raise handleError(e, 'move', {
                'oldPath': ftpPath,
                'newPath': newPath
            })
def login(ftp, username=None, password=None):
    try:
        log.info("Logging in")
        if username:
            ftp.login(username, password)
        else:
            ftp.login()
    except Exception as e:
        raise handleError(e, 'login', {
            'username': username,
            'password': password
        })
def downloadFile(ftpPath, outputFile, passiveMode=True):
    with connection(ftpPath, passiveMode) as ftp:
        url = parseUrl(ftpPath)
        filename = url['filename']
        log.info("Downloading file " + filename)
        try:
            ftp.retrbinary('RETR ' + filename, open(outputFile, 'wb').write)
        except Exception as e:
            raise handleError(e, 'download', {
                'url': ftpPath,
                'outputFile': outputFile
            })
def deleteFile(ftpPath, passiveMode=True):
    with connection(ftpPath, passiveMode,
                    creatingMissingDirectories=False) as ftp:
        url = parseUrl(ftpPath)
        filename = url['filename']
        log.info("Deleting the file " + filename)
        try:
            ftp.delete(filename)
            return True
        except Exception as e:
            raise handleError(e, 'delete', {
                'filename': filename,
                'url': ftpPath
            })
def connect(host, port=None, protocol='ftp', timeout=30):
    # Establish the connection
    try:
        log.info("Connecting to " + protocol.upper() + " host " + host)
        if protocol == 'ftp':
            ftp = FTP()
        elif protocol == 'ftps':
            ftp = FTP_TLS()
            ftp.ssl_version = ssl.PROTOCOL_TLSv1
        # Python 3 expects port to be 0 if the default should be used
        if sys.version_info > (3, ) and port is None:
            port = 0
        ftp.connect(host, port, timeout)
        if protocol == 'ftps':
            ftp.prot_p()
    except Exception as e:
        raise handleError(e, 'connect', {'host': host, 'port': port})

    return ftp
def uploadFile(filePath, ftpPath, passiveMode=True):
    with connection(ftpPath, passiveMode,
                    creatingMissingDirectories=True) as ftp:
        url = parseUrl(ftpPath)
        filename = url['filename']
        try:
            file = open(filePath, 'rb')
        except Exception as e:
            raise handleError(e, 'open', {'path': filePath})

        log.info("Uploading the file")
        try:
            ftp.storbinary('STOR ' + filename, file)
        except Exception as e:
            file.close()
            raise handleError(e, 'upload', {
                'filename': filename,
                'url': ftpPath
            })

        file.close()
        return True
def changeDirectory(ftp, path, createMissing=False):
    log.info("Changing working directory to " + path)
    errmsg = "change directory to " + str(path) + ", "
    directories = path.split('/')
    for directory in directories:
        try:
            ftp.cwd(directory)
        except Exception as e:
            error = handleError(e)
            if createMissing and error.type == 'FILE_NOT_FOUND':
                try:
                    ftp.mkd(directory)
                except Exception as e:
                    raise handleError(e, "changeDirectoryMkd", {
                        'path': path,
                        'dir': dir
                    })
            else:
                raise handleError(e, "changeDirectory", {
                    'path': path,
                    'dir': dir
                })