FTP Upload using CURL - With Overwrite Prompt

Hi Guys,

I was wondering if I could get a little help with my script.
Basically its an app to collate and transfer files via FTP.
It fully works in its current state if there are no files on the FTP server if there is not a file there with the same name.
What id like it to do is to prompt if a file already exists and either replaces or renames depending on the user response.

Heres the Code:

    on uploadFTP(folderName, finalFileDest)
        
        set nl to ASCII character 10
        set ftpUsername to "user.name"
        set ftpPassword to "Password1"
        set ftpHost to "[url=ftp://ftp.address.com/]ftp.address.com/[/url]"
        set ftpChangeDir to "Home/user.name"
        
        try
            do shell script ("/usr/bin/curl --disable-epsv --ftp-create-dirs -T " & quoted form of finalFileDest & " -u " & ftpUsername & ":" & ftpPassword & " " & "ftp://" & ftpHost & "/" & ftpChangeDir & "/")
            display dialog "Upload Done" -- Gets here if the file does not exist
        on error
            display dialog "Upload Failed" -- Gets here if the file does exist
        end try
    end uploadFTP

Im sure its something quote simple to tweak in the shell script but im not that familiar with that language.

Thanks guys

If I understand well, you may insert the instruction

set finalDest to my resolveConflicts(finalDest)

just before the try instruction

and add the handler :

on resolveConflicts(finalFileDest)
	# finalDest may be an Hfs path or a POSIX path
	tell application "System Events"
		set finalName to name of disk item finalFileDest
		set targetFolder to container of disk item finalFileDest
		if (exists disk item finalFileDest) then
			set nameExtension to name extension of disk item finalFileDest
			if the nameExtension is "" then
				set the trimmedName to the finalName
			else
				set the trimmedName to text 1 thru -(2 + (length of nameExtension)) of finalName
			end if
			set theIncrement to 1
			repeat
				set newName to (trimmedName & "_" & (theIncrement) & "." & nameExtension) as string
				if not (exists disk item newName of targetFolder) then
					set finalFileDest to (path of targetFolder as text) & newName
					exit repeat
				else
					set theIncrement to theIncrement + 1
				end if
			end repeat
		end if
	end tell
	return finalFileDest # now finalDest is an Hfs path
end resolveConflicts

Assuming that the original path : finalFileDest was myHd:folder:folder:file.ext
and that there is already such a file, the handler will insert a numerical value just before the dot preceding the name extension so that there is no file named file_x.ext in the destination folder.

The handler is able to treat Hfs or POSIX paths but as you use quoted form of POSIX path of finalDest I assume that finalDest is an Hfs path.
The handler is based upon an old one delivered by Apple in samples of folder action scripts.

You define the variable nl which you don’t use. If you need such variable elsewhere, it may be useful to point that there is already a predefined variable named linefeed whose contents is character id 10. Using it prevent you to use the deprecated feature ASCII character. There is also the predefined variable return whose value is character id 13.

set nlOld to ASCII character 10
set nl to character id 10
nl = linefeed --> true
nl = nlOld --> true

set crOld to ASCII character 13
set cr to character id 13
cr = return --> true
cr = crOld --> true

Yvan KOENIG running Sierra 10.12.3 in French (VALLAURIS, France) vendredi 3 février 2017 18:52:47

Hi Yvan,

Thanks for your reply.
I dont think however the script provided is what im looking for.

The finalFileDest variable to passed to this FTP module.
The variable simply point to a zip file that is generated from the script earlier on.
The FTP script is designed to grab that file and simply upload it to an FTP server.

The script fully works if there is not a file that already exists on the FTP server.
When there is a file on the FTP server with the same name it falls over.

do shell script ("/usr/bin/curl --disable-epsv –ftp-create-dirs -T " & quoted form of finalFileDest & " -u " & ftpUsername & “:” & ftpPassword & " " & “ftp://” & ftpHost & “/” & ftpChangeDir & “/”)

Im wondering if its something to do with the bits in bold?
Ive tried other combinations of that shell script but with no luck

Thanks Again

I apologize but I don’t know every features of curl which I use only in the other direction : download some datas.

Maybe the instruction may be edited to define the name of the final file.

If this feature is unavailable, you may do the job in three steps.
(1) move the file in an area where it can’t conflicts with an existing one,
(2) rename it with the new name
(3) upload it to the final location

Maybe a simpler scheme may be used:
rename the original file with the new name before uploading it.
Possibly reset the original name to the original file when the upload is done. ADDED

Of course, the given handler must be modified so that it check the availability of the file in the final folder on the network.

Yvan KOENIG running Sierra 10.12.3 in French (VALLAURIS, France) lundi 6 février 2017 17:36:12

I think the advice here should help:

http://unix.stackexchange.com/questions/19608/how-can-i-specify-that-curl-via-command-line-overwrites-a-file-if-it-already-e
The easy way here is not elegant- it assumes any error returned to Applescript by the “do shell script command” is due to a file name conflict, which certainly may not be the case. I would try to return the error from the shell to Applescript, parse it, and then only provide options for replacing or renaming the file if the error really was a name conflict, otherwise, just return the error. I don’t have an FTP server with write permission handy ATM to test, but here’s an outline of the changes I’d make:

on uploadFTP(folderName, finalFileDest)
	
	set nl to ASCII character 10
	set ftpUsername to "user.name"
	set ftpPassword to "Password1"
	set ftpHost to "[url=ftp://ftp.address.com/]ftp.address.com/[/url]"
	set ftpChangeDir to "Home/user.name"
	
	try
		do shell script ("/usr/bin/curl --disable-epsv --ftp-create-dirs -T " & quoted form of finalFileDest & " -u " & ftpUsername & ":" & ftpPassword & " " & "ftp://" & ftpHost & "/" & ftpChangeDir & "/")
		display dialog "Upload Done" -- Gets here if the file does not exist
	on error
		display dialog "There was an error with the upload, which may be due to the file already existing on the server." buttons {"Replace Existing File on Server", "Upload file with a different name."}
		if the button returned of the result is "Replace Existing File on Server" then
			-- Insert "do shell script" for curl using the ">" syntax for file replacement
		else
			-- Display Dialog with the currently used file name and a text field for the user to modify it, and then update the filename at the end of the "finalFileDest" path to the new name and try your original curl line again. Ideally, this should be done inside a repeat loop, because the user could keep choosing file names that exist on the server.
		end if
	end try
end uploadFTP

Note that using curl to ftp, I don’t think you can load the directory contents? It might be more elegant to just use FTP or SFTP so you can return the directory contents to Applescript and make reasonable default suggestions for modifying the file name to avoid conflicts. ie, right now, someone could have already uploaded “the_file_name.txt” and then already gone through this and uploaded “the_file_name_2.txt” and “the_file_name3.txt” and your user can be kept guessing names until they end up mashing the keyboard so it will finally let them upload "“the_file_name_456%jldjlk$.txt”

But maybe that won’t be an issue in your case.