- Send selected manually, ctd.
The process_this_file() handler
The script has to emulate the tasks we were able to do before with the two rsync and perl routines: check if the selected track's file already exists at the destination, supply a destination file path; perform the file copy to the destination. We have already used a routine that can add a file to a remote iTunes and we'll only need to slightly modify that for this script.
First we need to format some file paths based on the POSIX location path passed to the handler:
-- == handlers = == == == == == == == -- copy to remote iTunes and add to process_this_file(posixLoc) log posixLoc (*/Users/dougadams/Music/iTunes/iTunes Music/Little Feat/Feats Don't Fail Me Now/05 Spanish Moon.m4a*) -- == init some variables -- 1: set fileFolderHeirarchy to text ((length of locMusicLibrary) + 1) thru -1 of (posixLoc as text) (*Little Feat/Feats Don't Fail Me Now/05 Spanish Moon.m4a*) -- 2: set remLoc to (remMusicLibrary & fileFolderHeirarchy) as text (*/Users/cleanuser/Music/iTunes/iTunes Music/Little Feat/Feats Don't Fail Me Now/05 Spanish Moon.m4a*) -- 3: set remContainer to (my list_to_text(items 1 thru -2 of my text_to_list(remLoc, "/"), "/") & "/") as text (*/Users/cleanuser/Music/iTunes/iTunes Music/Little Feat/Feats Don't Fail Me Now/*) -- to be continued... end process_this_file
(I purposely chose a track with an apostrophe in its file path so I could smoke-test the upcoming escaping and quoting routines.)
The handler is passed the POSIX version of a track's location as the variable posixLoc. Here are the file paths we need:
-- 1: the variable fileFolderHeirarchy is set to the artist/album/file path, which is what rsync's dry-run routine would have supplied. It is created by retrieving the rest of the file path that appears after the local iTunes Music folder path (offset of the length of the locMusicLibrary string plus one position to the right through the last character--you made locMusicLibrary a global up top, right?)
-- 2: remLoc is set to the path the file will have after it is copied to the remote machine. It is a concatenation of the remMusicLibrary string (you made it a global, too, right?) and the fileFolderHeirarchy string just obtained. This is the string that the osascript needs to add the file to the remote iTunes.
-- 3: the remContainer variable is the path to the file's (eventual) containing folder. This will be the destination path used when we scp the file.
Next, we need to determine if the selected file already exists on the remote machine. Add this handler with the others:
on rem_file_exists(remF) set testCom to quoted form of ("test -e \"" & remF & "\"") try set x to (do shell script ("ssh " & remAddr & space & testCom)) return (x is "") on error return false end try end rem_file_exists
If the result of the test command is anything but an empty string (technically, it would be the number--not the string--"0", but AppleScript coerces the number 0 to empty string) then return false. We are rooting for a false result so we can copy the file. Otherwise, we will skip this track.
Now include the fix_single_quotes() handler from earlier as well as this additional handler to escape spaces and single quotes:
to escape_for_unix(n) set n1 to my replace_chars(n, " ", "\\ ") return my replace_chars(n1, "'", "\\'") end escape_for_unix
Here is the rest of the process_this_file() handler:
if not my rem_file_exists(remLoc) then -- 4: == containing folder exists? if not, create set mkdirCom to quoted form of ("mkdir -p " & my escape_for_unix(remContainer)) as text -- mkdir will error quietly if the containing folders already exist try set x to do shell script "ssh " & remAddr & space & mkdirCom log x on error m log ("mkdir err: " & m) end try -- 5: == copy the file set scpCom to ("scp -EC" & space & quoted form of posixLoc & space & ¬ remAddr & ":\"" & my escape_for_unix(remContainer) & "\"") as text set rezList to do shell script scpCom log rezList -- this result not needed; observation only -- 6: == add the newly copied file to remote iTunes set fileToAdd to my fix_single_quotes(remLoc) try with timeout of (1 * days) seconds set osaCom to quoted form of ¬ ("osascript -e 'tell application\"iTunes\" to add POSIX file \"" & fileToAdd & "\"'") do shell script ("ssh " & remAddr & space & osaCom) end timeout on error m number n log m log n end try else log "EXISTS - SKIP" end if end process_this_file
-- 4: if the location indicated by remContainer doesn't exist create it with mkdir. The p flag tells mkdir to create any intermediate folders that don't exist yet either, so we'll be certain to have a artist/album folder "receiver" on the remote end. If, however, the folder path already does exist, mkdir will fail silently and exit the try block without attempting to re-create the folder path. (but each time? yes, because tracks may each have different artist and album paths)
-- 5: copy the file with scp. The format for scp is similar to cp where source is the track's file path on the local end and destination is the remContainer folder on the remote end:
scp options source destination
and like rsync the ":" tells scp to use an ssh-type secure login. Figuring out the escapes here was mind-blowing (but you ain't seen nothin' yet). The -E and -C flags handle extended attributes and enable ssh compression, respectively.
-- 6: this is the routine used with the filesToAdd list earlier but without the trackAddedCounter business. (Although you could do something similar to report if files did/didn't get added, you know?)
The full script is listed on the next page.