views:

105

answers:

3

I'm having a strange AppleScript issue, and can't seem to figure out the underlying cause, or a solution. I'm trying to download files with a process that mimics the one below. This code fails for me, reporting "URL Access Scripting got an error: Can’t make some data into the expected type." number -1700 to item"

If I remove 3 characters from the local path name (and it doesn't seem to matter which 3), then it runs fine. If I only remove 2 characters, it doesn't throw an error, but the file it downloads is a corrupted JPG. I tried doing the same with curl in a "do shell script" line, and it seemed to fail too for any file name length, albeit silently (returning ""). What's causing this, and what can I do about it?

tell application "URL Access Scripting"
    download "http://interfacelift.com/wallpaper_beta/grab/02331_veiledinclouds_2560x1600.jpg" to "/Users/abc/Downloads/02331_veiledinclouds_2560x1600.jpg"
end tell
+1  A: 

Your biggest problem is you're using a posix-style path (using slashes) when you should be using a mac-style path (with colons). Applescript uses colon delimited paths. We can convert between the two using "posix path" to go from colons to slashes and "posix file" to go from slashes to colons.

And you can't just pass the path as a string. In applescript we use file specifiers... which is why I put the word file in front of the string path. So this works once we fix that.

set posixPath to "/Users/abc/Downloads/02331_veiledinclouds_2560x1600.jpg"
set macPath to (POSIX file posixPath) as text

tell application "URL Access Scripting"
    download "http://interfacelift.com/wallpaper_beta/grab/02331_veiledinclouds_2560x1600.jpg" to file macPath
end tell

However, there must be a filename length issue because when I run it the filename of the downloaded file is shortened to 31 characters.

EDIT: Here's a script to truncate, download, and rename the file if necessary.

set posixPath to "/Users/abc/Downloads/02331_veiledinclouds_2560x1600.jpg"
set baseName to do shell script "/usr/bin/basename " & quoted form of posixPath

set needsRenaming to false
if (count of baseName) is greater than 31 then
    set downloadName to text -31 thru -1 of baseName
    set basePath to do shell script "/usr/bin/dirname " & quoted form of posixPath
    set posixPath to basePath & "/" & downloadName
    set needsRenaming to true
end if

set macPath to (POSIX file posixPath) as text

tell application "URL Access Scripting"
    download "http://interfacelift.com/wallpaper_beta/grab/02331_veiledinclouds_2560x1600.jpg" to file macPath
end tell

if needsRenaming then
    tell application "Finder"
        set name of file macPath to baseName
    end tell
end if
regulus6633
I get an error, telling me that it can't get the POSIX file from the path specified (because the file doesn't exist yet?). I believe that URL Access Scripting does take POSIX paths, as numerous examples I've found online show that. Also, I believe it's a thin wrapper around CURL - does CURL have a 31-character limit? Thanks for the suggestion, though.
Dov
I can put those first 2 lines into a script all by itself and there's no error... and there's no file. So I'm not sure what's happening on your end. Make sure you coerce it to text like I showed and then in the download statement you place the keyword "file" before it to coerce it to a file specification which is what the statement requires.
regulus6633
Okay, trying this again, I see that it does work, but with the truncation issue you updated the post with, I'm no better off. Essentially, this truncates the file name instead of throwing an error.
Dov
I added another script to my answer that handles the truncation issue. It basically detects if the name is too long and if so manually truncates the name, downloads the file, and renames the truncated name to the original name.
regulus6633
+1  A: 

I'm willing to bet that this function still calls some ancient Carbon (or pre-Carbon) API call that only allows 31 characters. Some of the Google links related to this go back to 2003, and as far as Mac OS is concerned, both the year and the specific 31 character limit point to this being an outdated API that was never brought up to date. This is the problem with the darker corners of Applescript. Maybe Satimage or someone has made a Scripting Addition that works around this. I think you are stuck and need to get help from somewhere outside of this addition. I would love to proven wrong on this one because I couldn't get it to work no matter what I tried.

Philip Regan
Thinking about it more though, what's very strange is the effect I noticed when the length is 33 characters instead of 32 or 34 (including period and extension). At 32 all's fine, and at 34 it fails completely - but at 33, it saves, but corrupted. Strange, and I really don't have a clue what it means or implies.
Dov
I think it just means you stumbled on what was a bug then and is simply outright outdated functionality now.
Philip Regan
Is there a better way to download a file? As far as I could tell, this was the plainest, recommended way to do it (without automating an FTP app).
Dov
The last time I had to do this, I actually wrote a little Applescript-able application in Real Studio to help me with the downloading. I'm not recommending that here but I'm willing to bet that there is a shell command or script that can be had from somewhere. I don't have much practical knowledge of the Terminal, but from what I can gather, just about everything you can think of is there. Shell commands can be included in an Applescript with the `do shell script` command.
Philip Regan
+1  A: 

I ultimately decided to download to a temporary, shorter name and then rename it with Finder. The rewritten script is below:

tell application "URL Access Scripting"
    set tempFileName to "abc.jpg"
    set downloadPath to (POSIX path of (path to downloads folder))

    set tempFile to download "http://interfacelift.com/wallpaper_beta/grab/02331_veiledinclouds_2560x1600.jpg" to downloadPath & tempFileName
end tell

tell application "Finder" to set name of file tempFile to "02331_veiledinclouds_2560x1600.jpg"

I prefer the simplicity of this approach to regulus6633's approach, which only renames the file if it needs it.

Dov
Well played. I didn't even think to do that.
Philip Regan