AppleScript: Know what to do but not how to do it

Discussion in 'Mac Programming' started by wrldwzrd89, May 18, 2006.

  1. macrumors G4

    wrldwzrd89

    Joined:
    Jun 6, 2003
    Location:
    Solon, OH
    #1
    I would like to make an iTunes auto-tagging script. Basically, what it does is this:
    1. Loop through all the selected songs
    2. 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
    3. Get the containing folder of the song file and set that to the song's Album tag
    4. 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).
     
  2. Administrator

    HexMonkey

    Staff Member

    Joined:
    Feb 5, 2004
    Location:
    New Zealand
    #2
    Is this what you want? Rather than searching for the song file, it just gets the file reference from iTunes.

    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 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
     
  3. thread starter macrumors G4

    wrldwzrd89

    Joined:
    Jun 6, 2003
    Location:
    Solon, OH
    #3
    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.
     
  4. thread starter macrumors G4

    wrldwzrd89

    Joined:
    Jun 6, 2003
    Location:
    Solon, OH
    #4
    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:

    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
    		[COLOR="Red"][B]set trackPath to location of nextTrack[/B][/COLOR]
    		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.
     
  5. macrumors 68040

    mduser63

    Joined:
    Nov 9, 2004
    Location:
    Salt Lake City, UT
    #5
    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.
     
  6. thread starter macrumors G4

    wrldwzrd89

    Joined:
    Jun 6, 2003
    Location:
    Solon, OH
    #6
    I got it to work, sort of:

    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 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:
     
  7. thread starter macrumors G4

    wrldwzrd89

    Joined:
    Jun 6, 2003
    Location:
    Solon, OH
    #7
    Found the cause of the above problem and fixed it. However, it still doesn't work.

    Script:

    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)
    		
    		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:
    Code:
    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.
     
  8. macrumors 68040

    mduser63

    Joined:
    Nov 9, 2004
    Location:
    Salt Lake City, UT
    #8
    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.
     
  9. thread starter macrumors G4

    wrldwzrd89

    Joined:
    Jun 6, 2003
    Location:
    Solon, OH
    #9
    Tried that, got the exact same error, but in Finder instead of in iTunes. :confused:
     
  10. macrumors 68040

    mduser63

    Joined:
    Nov 9, 2004
    Location:
    Salt Lake City, UT
    #10
    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.
     
  11. Administrator

    HexMonkey

    Staff Member

    Joined:
    Feb 5, 2004
    Location:
    New Zealand
    #11
    It works for me if I change the 'set trackFile to...' line to:
    Code:
    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:
    Code:
    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:

    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
     
  12. thread starter macrumors G4

    wrldwzrd89

    Joined:
    Jun 6, 2003
    Location:
    Solon, OH

Share This Page