cURl and Folders on the FTP

Hi All,
I am working on a script the reads the folders on the FTP site, gives a choice of the folders and then appends this to the ftp server info so that I can upload a file directly into the particular folder. Uploading to the root is fine, but trying to append a folder on the end of the ftp gives me the error:

Result:
error " % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed

0 0 0 0 0 0 0 0 --:–:-- --:–:-- --:–:-- 0
curl: (25) Failed FTP upload: 553" number 25

The script is:


set theOutput to paragraphs of (do shell script "curl ftp://website.org --user user:pass | awk '/dr/ {print $9, $10}'")

choose from list theOutput

set NameEntered to item 1 of result


set thefolder to NameEntered
set theServer2 to "ftp://website.org" & "/" & NameEntered
set theServer1 to "ftp://website.org"
log theServer1

set filename to choose file with prompt "Please choose a file"


do shell script "curl -u user:pass -T {" & quoted form of POSIX path of filename & "} " & theServer2



Everything is good until I try to use theServer2. Thank you.

Two little problems:

  • The folder names awk returns have a space at the end. Get rid of that.
  • The slash at the end is missing.

If you got it running, please post the result. It looks like some nice idea to steal from :wink:

Regards, Jürgen

Second reply:

I had a look at the resulting string before I had a closer look at the code. What is the field $10, you are trying to get from awk?

If I omit it and add the slash, the code works:

set theOutput to paragraphs of (do shell script "curl ftp://website.org --user user:pass | awk '/dr/ {print $9}'")

choose from list theOutput

set NameEntered to (item 1 of result) & "/"


set thefolder to NameEntered
set theServer2 to "ftp://website.org" & "/" & NameEntered
set theServer1 to "ftp://website.org"
log theServer1

set filename to choose file with prompt "Please choose a file"


do shell script "curl -u user:pass -T {" & quoted form of POSIX path of filename & "} " & theServer2

Regards, Jürgen

Hi Juergen,
Thanks for the reply. I will give those a shot, basically, I will show you the print out minus the $9 and $10 and then with it.

So, before, it is the whole tab delimited line:

drwxr-xr-x 2 506 506 4096 Jan 21 03:22 Aleta
drwxr-xr-x 2 506 506 4096 Dec 13 17:27 Alex Fees
drwxr-xr-x 4 506 506 4096 Jan 13 21:40 Angie Weidinger
drwxr-xr-x 2 506 506 4096 Sep 20 19:39 Bad Dog MFH
drwxr-xr-x 2 506 506 4096 Nov 09 17:34 Bkae
drwxr-xr-x 6 506 506 4096 Dec 13 17:04 Brenda Madden

so, I counted over and since the fields in awk are dictated by a space, I wanted to include the last name so it would be $9 and $10.

Aleta
Alex Fees
Angie Weidinger
Bad Dog
Bkae
Brenda Madden

I suppose I could just make all the names single names without spaces to get around this. I will take your thoughts. Feel free to steal, not too much to it, but I am using it to be “Smart” about an ftp uploader I am working on.

Hi Juergen,
I think I figured out the $9 and $10 thing. Basically, I think that spaces in terminal are respresented by the forward slash "". Therefore, somehow I would have had to make those names with spaces to be separated by a slash. Probably a way to do this iterating through the list with delimiters. Don’t really know how to do that, but will play around with it.

Hi pickup,

one possible approach:

In that listing, folder names start at character 57. That should be reliable, at least on that server. Putting the entire lines into the output list (should be $0 in awk) and reducing it by some loop like

--...
repeat with i from 1 to (count theOutput)
	set item i of theOutput to (text 57 thru -1 of item i of theOutput)
end repeat
--...

should return the proper names (including “Bad Dog MFH” with two spaces.

Another note: Im not good at awk but I think the search pattern should be '/^dr/, not '/dr/, to make sure it only looks for dr at the beginning of a line. Your pattern would fine a file named “bedrock” as well.

Jürgen

Hi,

the shell string filters directories and skips also those which end with a dot or double dot.
A repeat loop prints out all fields from 9 to the end.
As the directory names end all with a space (caused by the repeat loop) the last character must be cut


set theOutput to paragraphs of (do shell script "curl ftp://website.org --user user:pass | awk '/^dr/ && !/\\.$/  {for (i = 9; i <= NF; i++) printf \"%s \", $i; printf \"\\n\"; }'")
set chosenItem to choose from list theOutput
if chosenItem is false then return
set theDirectory to text 1 thru -2 of item 1 of chosenItem

HI Guys,
That makes sense. Also good point on the ^. That could have caused errors in some directories. This whole thing makes more sense. Thanks again. I am really working through awk and trying to learn how to parse files better.

Thanks again.

I agree that awk and other unix tools to parse text are complex. They are powerful and useful but I could never write the parsing line that StefanK did. I’m better at applescript parsing using text item delimiters etc. As such I used applescript to do the parsing. I commented each line to tell you why I did it. I basically repeat backwards through each line, when I reach the first number I know I found the index that allows me to get the ending text (eg. the folder name).

NOTE: this assumes there are no numbers in the folder names.

set curlOutput to "drwxr-xr-x    2 506      506          4096 Jan 21 03:22 Aleta 
drwxr-xr-x    2 506      506          4096 Dec 13 17:27 Alex Fees 
drwxr-xr-x    4 506      506          4096 Jan 13 21:40 Angie Weidinger 
drwxr-xr-x    2 506      506          4096 Sep 20 19:39 Bad Dog MFH 
drwxr-xr-x    2 506      506          4096 Nov 09 17:34 Bkae 
drwxr-xr-x    6 506      506          4096 Dec 13 17:04 Brenda Madden "

set folderNames to {}
set theLines to paragraphs of curlOutput

repeat with thisLine in theLines -- repeat through the lines
	repeat with i from (count of thisLine) to 1 by -1 -- repeat backwards through a line
		try
			(character i of thisLine) as number -- check if the character is a number
			exit repeat -- if it is a number we exit the repeat loop
		end try
	end repeat
	
	-- use the value of i + 2 to get the rest of the text from this line
	-- only get text to character -2 to eliminate the space at the end of each line
	set end of folderNames to text (i + 2) thru -2 of thisLine
end repeat
return folderNames

Hi Guys,
Well after some research, I have come up with this code that uses awk to start and go to the end of the line. It works in terminal, but once I put it in Applescript as a “do shell script” it gives me an error:

Expected “,” but found identifier.

This is given to me on the “AB” placement. Basically, I used “AB” as way to help you identify where the problem i occurring, but it would just add an AB between each field. The problem is that somehow Applescript doesn’t translate a do shell script the same as Terminal.

Any thoughts?


ls -l | awk -v nr=9 '{ for (x=nr; x<=NF; x++) {printf $x "AB"; }; print "a" }' 



Thank you for your help. This code in Terminal is working well so far.

You could avoid all the awk processing of the output of the curl listing by specifying that you only want the names of the files/folders on the FTP server (see ‘man curl’ in the Terminal for details, or see http://curl.haxx.se/docs/manpage.html ):


set ftpURL to "ftp://ftp.mozilla.org"
set ftpCommand to "curl " & quoted form of ftpURL & " --list-only"
do shell script ftpCommand

Note also that it is a good idea for avoiding problems to use the quoted form of the URL. It doesn’t hurt to put the various pieces of a shell command into variables, and then the whole thing into a variable - it makes trouble-shooting and logging much easier.

Hello Krioni,
Thank you for the reply. I will do some reading and then test and post some code. Basically, I am parsing the files only so I can look at the changes in files each day and download the new files posted on the FTP site. I know there are programs, but I wanted to know how it works.

Thank you for your help.

Hi Krioni,
How are you doing? I was wondering in the --list only command, how do you pass a password and username to this?

I tried:


set ftpURL to "ftp://website.com -user user:pass"
set ftpCommand to "curl " & quoted form of ftpURL & " --list-only"
do shell script ftpCommand


I am still reading, but so far, not having too much luck. Thanks again

You have a mistake in your code there. The ftpURL should be only the URL and not including other curl parameters. Here’s a change:

set myUser to "YOUR_USER_NAME"
set myPass to "YOUR_PASSWORD"
set ftpURL to "ftp://website.com"
set ftpCommand to "curl " & quoted form of ftpURL & " --user " & quoted form of (myUser & ":" & myPass) & " --list-only"
do shell script ftpCommand

Also note that the parameters for curl are either a single dash followed by a single letter ( i.e. -u ) or are double-dashes followed by a more-descriptive word (i.e. --user ). I also made it a little bit easier to change the username and/or password by separating them into AppleScript variables instead of hardcoding them into the command.

An alternative would be to put the username and password into the URL like this:

set myUser to "YOUR_USER_NAME"
set myPass to "YOUR_PASSWORD"
set ftpURL to "ftp://" & myUser & ":" & myPass & "@website.com"
set ftpCommand to "curl " & quoted form of ftpURL & " --list-only"
do shell script ftpCommand

Note that you should avoid having the following characters in your username and/or password:
slash /
colon :
at-sign @
single-quote ’
They can confuse the command, since they mean something in the context of a URL, or, for the single-quote, could cause issues running in a shell.

Thanks Krioni,
That makes sense and is working. On to my next part of the code.

Thanks again.

Hi Krioni,
The --list only commands works well except that I really need to have those "\ " where the spaces are so when I use the Curl command to download the file, the correct formatting will be preserved.

for example:

a list only will give me:
John Thompson.mov

for me to upload it using curl, it will have to be:
John\ Thompson.mov

If I use the --list-only, it parses the data with spaces. Is there anyway to add the appropriate "\ " in?

Thank you for your help.

HI Guys,
So basically, I have sort of figured out that problem, but the next part of this is quoted form. I am really not understanding how this parses the data.

For example, my terminal script looks like this:

curl ftp://website.com --user username:password | awk -v nr=9 ‘{ for (x=nr; x<=NF; x++) {printf $x "\ "; }; print “” }’ | sed s/…$//

My applescript is something like this:


--this looks into the ftp site and downloads the files and folders only to a file

set ftpURL to "ftp://website.com"

--This is where the awk setup begins
set awkDelimiter to "\\\\ "
set emptyQuotes to ""
set awkCommand to " | awk -v nr=9 '{ for (x=nr; x<=NF; x++) {printf $x & quoted form of awkDelimiter & "; }; print & quoted for of emptyQuotes & " }' | sed s/..$//"
set ftpCommand to "curl " & quoted form of ftpURL & " --user username:password" 

do shell script ftpCommand


The main issue comes in where the AwkDelimiter sits. No matter what I do, I just cannot seem to get this part to work. Any thoughts? Thank you so much.