PDA

View Full Version : AppleScript: Know what to do but not how to do it




wrldwzrd89
May 18, 2006, 05:03 PM
I would like to make an iTunes auto-tagging script. Basically, what it does is this:

Loop through all the selected songs
Find each song file on my computer (in the form filename.ext) - the song names in iTunes contain the original extension so I know what to search for
Get the containing folder of the song file and set that to the song's Album tag
Get the containing folder of the containing folder of the song file and set that to the song's Artist tag


Can anyone here point me in the right direction? What I'm struggling with is figuring out how to search for a file on my computer with AppleScript, then do something with the search result (there should only be one result - I could guarantee that by limiting the search to only the folder of interest, but again, I'm not sure how).



HexMonkey
May 19, 2006, 06:18 AM
Is this what you want? Rather than searching for the song file, it just gets the file reference from iTunes.

tell application "iTunes"
--Get current track selection
set theTracks to selection

--Iterate through each track
repeat with nextTrack in theTracks
--Get the track's file path
set trackPath to location of nextTrack
tell application "Finder"
set trackFile to file trackPath

--Get container names
set theContainer to container of trackPath
set albumName to name of theContainer
set artistName to name of container of theContainer
end tell

--Set track information
set album of nextTrack to albumName
set artist of nextTrack to artistName
end repeat
end tell

wrldwzrd89
May 19, 2006, 09:28 AM
Is this what you want? Rather than searching for the song file, it just gets the file reference from iTunes.

tell application "iTunes"
--Get current track selection
set theTracks to selection

--Iterate through each track
repeat with nextTrack in theTracks
--Get the track's file path
set trackPath to location of nextTrack
tell application "Finder"
set trackFile to file trackPath

--Get container names
set theContainer to container of trackPath
set albumName to name of theContainer
set artistName to name of container of theContainer
end tell

--Set track information
set album of nextTrack to albumName
set artist of nextTrack to artistName
end repeat
end tell
This is good. The only problem is this:

Let's say the music files in iTunes are located in ~/Music/iTunes/iTunes Music and the original source files are in ~/Music/Source/Module. The file we're interested in is called Stream.s3m.

What I want is not ~/Music/iTunes/iTunes Music/(artist)/(album)/Stream.s3m but rather ~/Music/Source/Module/(other folders go here)/(artist)/(album)/Stream.s3m - where the names of the second artist and album folders contain the data to add to the iTunes track. I'm not entirely sure if your script retrieves the right file, but I'll have to test it.

wrldwzrd89
May 19, 2006, 01:25 PM
OK, I tested it. It writes the tags correctly, but it's not getting the tag info from the right file. It's getting it from the folder of the iTunes track, which is no help at all (it will always tag it Unknown Artist and Unknown Album).

EDIT: The problem seems to be in the section I've highlighted:

tell application "iTunes"
--Get current track selection
set theTracks to selection

--Iterate through each track
repeat with nextTrack in theTracks
--Get the track's file path
set trackPath to location of nextTrack
tell application "Finder"
set trackFile to file trackPath

--Get container names
set theContainer to container of trackPath
set albumName to name of theContainer
set artistName to name of container of theContainer
end tell

--Set track information
set album of nextTrack to albumName
set artist of nextTrack to artistName
end repeat
end tell
trackPath isn't getting set to the right file.

mduser63
May 19, 2006, 02:36 PM
I really don't think there's a simple way to do what you're asking with AppleScript. You need a script that does a system-wide search (or at least a search within some set of folders) and can determine on it's own which file corresponds to which song, when they're not linked in the iTunes library itself. There are tools out there that will tag files based on the folder hierarchy that they're contained in. You would probably be best off using one of those, and then after all your files are tagged, import them into iTunes.

wrldwzrd89
May 19, 2006, 03:26 PM
I got it to work, sort of:


tell application "iTunes"
--Get current track selection
set theTracks to selection

--Iterate through each track
repeat with nextTrack in theTracks
--Get the track's file path
set trackName to name of nextTrack
set trackName to replace_chars(trackName, "'", "\\'")
set the_command to ("mdfind -onlyin ~/Music/Source/Module " & trackName) as string
set returned_list to (do shell script the_command)

if returned_list is not "" then -- we got some results
-- make a list from the string; items are separated by carriage returns
set new_list to text_to_list(returned_list, return)
repeat with trackFile in new_list
set trackFile to POSIX file trackFile
tell application "Finder"
--Get container names
set theContainer to container of trackFile
set albumName to name of theContainer
set artistName to name of container of theContainer
end tell
end repeat
end if

--Set track information
set album of nextTrack to albumName
set artist of nextTrack to artistName
end repeat
end tell

on replace_chars(txt, srch, repl)
set AppleScript's text item delimiters to the srch
set the item_list to every text item of txt
set AppleScript's text item delimiters to the repl
set txt to the item_list as string
set AppleScript's text item delimiters to ""
return txt
end replace_chars

on text_to_list(txt, delim)
set saveD to AppleScript's text item delimiters
try
set AppleScript's text item delimiters to {delim}
set theList to every text item of txt
on error errStr number errNum
set AppleScript's text item delimiters to saveD
error errStr number errNum
end try
set AppleScript's text item delimiters to saveD
return (theList)
end text_to_list


When I run this I get an error: "iTunes got an error: Can't continue replace_chars." I can't figure out why, since it works perfectly in the sample script here: http://www.dougscripts.com/itunes/itinfo/spotlight.php

Scroll down to where it says:

OK, that's fine, but there's a coupla things:

wrldwzrd89
May 19, 2006, 04:48 PM
Found the cause of the above problem and fixed it. However, it still doesn't work.

Script:


tell application "iTunes"
--Get current track selection
set theTracks to selection

--Iterate through each track
repeat with nextTrack in theTracks
--Get the track's file path
set trackName to name of nextTrack
set trackName to my replace_chars(trackName, "'", "\\'")
set the_command to ("mdfind -onlyin ~/Music/Source/Module " & "'kMDItemFSName == " & trackName & "'") as string
set returned_list to (do shell script the_command)

if returned_list is not "" then -- we got some results
-- make a list from the string; items are separated by carriage returns
set new_list to my text_to_list(returned_list, return)
repeat with this_file in new_list
set trackFile to POSIX file this_file
tell application "Finder"

--Get container names
set theContainer to container of trackFile
set albumName to name of theContainer
set artistName to name of container of theContainer
end tell
end repeat
end if

--Set track information
set album of nextTrack to albumName
set artist of nextTrack to artistName
end repeat
end tell

on replace_chars(txt, srch, repl)
set AppleScript's text item delimiters to the srch
set the item_list to every text item of txt
set AppleScript's text item delimiters to the repl
set txt to the item_list as string
set AppleScript's text item delimiters to ""
return txt
end replace_chars

on text_to_list(txt, delim)
set saveD to AppleScript's text item delimiters
try
set AppleScript's text item delimiters to {delim}
set theList to every text item of txt
on error errStr number errNum
set AppleScript's text item delimiters to saveD
error errStr number errNum
end try
set AppleScript's text item delimiters to saveD
return (theList)
end text_to_list


Event Log:

tell application "iTunes"
get selection
{file track id 4483 of folder playlist id 3505 of source id 39}
get name of file track id 4483 of folder playlist id 3505 of source id 39
"Stream.xm"
do shell script "mdfind -onlyin ~/Music/Source/Module 'kMDItemFSName == Stream.xm'"
"/Users/wrldwzrd89/Music/Source/Module/single song/XM/CyberZip/Nebula/Stream.xm"
get POSIX file "/Users/wrldwzrd89/Music/Source/Module/single song/XM/CyberZip/Nebula/Stream.xm"
"iTunes got an error: Can't get POSIX file (item 1 of {\"/Users/wrldwzrd89/Music/Source/Module/single song/XM/CyberZip/Nebula/Stream.xm\"})."


This has me completely baffled.

mduser63
May 19, 2006, 06:09 PM
tell application "iTunes"
get selection
{file track id 4483 of folder playlist id 3505 of source id 39}
get name of file track id 4483 of folder playlist id 3505 of source id 39
"Stream.xm"
do shell script "mdfind -onlyin ~/Music/Source/Module 'kMDItemFSName == Stream.xm'"
"/Users/wrldwzrd89/Music/Source/Module/single song/XM/CyberZip/Nebula/Stream.xm"
get POSIX file "/Users/wrldwzrd89/Music/Source/Module/single song/XM/CyberZip/Nebula/Stream.xm"
"iTunes got an error: Can't get POSIX file (item 1 of {\"/Users/wrldwzrd89/Music/Source/Module/single song/XM/CyberZip/Nebula/Stream.xm\"})."


This has me completely baffled.

Try taking the 'set trackFile to POSIX file this_file' line and putting it inside the Finder tell. BTW, I'm impressed that you've gotten as far as you have using AppleScript. I had forgotten that Spotlight could be accessed via the command line.

wrldwzrd89
May 19, 2006, 07:29 PM
Try taking the 'set trackFile to POSIX file this_file' line and putting it inside the Finder tell. BTW, I'm impressed that you've gotten as far as you have using AppleScript. I had forgotten that Spotlight could be accessed via the command line.
Tried that, got the exact same error, but in Finder instead of in iTunes. :confused:

mduser63
May 19, 2006, 10:58 PM
Tried that, got the exact same error, but in Finder instead of in iTunes. :confused:

I'm a little curious about the escaped quotes around the file path. I'm not an AppleScript expert, but that just jumped out at me as something that could possibly cause a problem.

HexMonkey
May 20, 2006, 01:49 AM
It works for me if I change the 'set trackFile to...' line to:
set trackFile to this_file as POSIX file

I also moved the 'set album...' and 'set artist...' lines so that the script wouldn't give an error if the search returned no results, and changed the 'set the_command to...' line to:
set the_command to ("mdfind -onlyin ~/Music/Source/Module " & "\"kMDItemFSName == '" & trackName & "*'\"") as string
which allows for multiple words in a filename and some text to follow the track name (eg the extension).

The modified code:

tell application "iTunes"
--Get current track selection
set theTracks to selection

--Iterate through each track
repeat with nextTrack in theTracks
--Get the track's file path
set trackName to name of nextTrack
set trackName to my replace_chars(trackName, "'", "\\'")
set the_command to ("mdfind -onlyin ~/Music/Source/Module " & "\"kMDItemFSName == '" & trackName & "*'\"") as string
set returned_list to (do shell script the_command)
--return returned_list
if returned_list is not "" then -- we got some results
-- make a list from the string; items are separated by carriage returns
set new_list to my text_to_list(returned_list, return)
repeat with this_file in new_list
set trackFile to this_file as POSIX file
tell application "Finder"

--Get container names
set theContainer to container of trackFile
set albumName to name of theContainer
set artistName to name of container of theContainer
end tell

end repeat
--Set track information
set album of nextTrack to albumName
set artist of nextTrack to artistName
end if
end repeat
end tell

on replace_chars(txt, srch, repl)
set AppleScript's text item delimiters to the srch
set the item_list to every text item of txt
set AppleScript's text item delimiters to the repl
set txt to the item_list as string
set AppleScript's text item delimiters to ""
return txt
end replace_chars

on text_to_list(txt, delim)
set saveD to AppleScript's text item delimiters
try
set AppleScript's text item delimiters to {delim}
set theList to every text item of txt
on error errStr number errNum
set AppleScript's text item delimiters to saveD
error errStr number errNum
end try
set AppleScript's text item delimiters to saveD
return (theList)
end text_to_list

wrldwzrd89
May 20, 2006, 10:33 AM
Yay, it works now! Thanks, everyone :D