Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

nick_harambee

macrumors regular
Original poster
May 20, 2005
118
0
Hi,

I have written the applescript below to duplicate my Apple Lossless iTunes library as a MP3 Library. I wanted the script to be able to do the following things:

1. For all Apple Lossless tracks in iTunes Library (at the moment the script is just set to work with a selection for testing purposes) check if track already exists in MP3 folder with more recent modification date and:
a If yes, do nothing
b If same track with earlier modification date convert and replace track (so that tag changes are transferred)
c If track doesn't exist convert track.

2. If there are any MP3 files in the target folder that aren't in the source folder (i.e. the iTunes Music Folder), delete these files. This is for the scenario when I delete files from my iTunes Library that I no longer want, and I want the equivalent MP3 file to be deleted as well. So once the script has finished running there should be an exact match between the Apple Lossless library and the MP3 folder.

The script below does everything I want it to do with the following caveats:

1. I am not sure how to go about deleting the MP3 files as in part 2. I guess it would have to be an additional section of script which compares each file by name in the folder/subfolder in the iTunes Music Library with the equivalent folders in the target music folder, deleting any files found in the target music folder that don't exist in the iTunes Music folders, but I'm not sure if this is the best/only method, and how I would go about scripting this.

2. Because I need to specify the conversion twice (once if no file exists in target folder and once if it does but with an older modification date) I am wondering about using a subroutine method here. I tried doing so, but no conversions happened even though some should have happened. I wonder if this is because the relevant variables aren't picked up properly by the script when it's a subroutine. I can leave things as they are, just thought it would be good to make the script neater.

Code:
tell application "iTunes"
	activate
	
	set sel to selection
	set encoderBackup to name of current encoder
	set this_folder to "Macintosh HD:Users:nick:Desktop:music:" as text
	set current encoder to encoder "MP3 Encoder"
	
	
	repeat with this_track in sel
		set trackComposer to this_track's composer
		set trackAlbum to this_track's album
		set trackName to this_track's name
		tell application "Finder"
			
			set path1 to "Macintosh HD:Users:nick:Desktop:music:" & trackComposer as text
			
			if folder path1 exists then
				{}
			else
				make new folder at this_folder with properties {name:trackComposer}
			end if
			
			set path2 to this_folder & trackComposer & ":" & trackAlbum as text
			
			if folder path2 exists then
				{}
			else
				make new folder at path1 with properties {name:trackAlbum}
			end if
			
			if exists file (path2 & ":" & trackName & ".mp3") then
				set file2 to (path2 & ":" & trackName & ".mp3") as alias
				set modDate to modification date of file2
				set modDate2 to this_track's modification date
				if modDate is greater than modDate2 then
					{}
				else
					tell application "iTunes"
						try -- skip on failure
							set new_track to item 1 of (convert this_track)
							set loc to new_track's location
							set dbid to new_track's database ID
							delete artworks of new_track
							
							-- move the file to new location
							do shell script "mv " & (quoted form of POSIX path of loc) & " " & (quoted form of POSIX path of path2 as string)
							
							-- delete the track
							delete new_track
						end try
					end tell
					
				end if
			else
				tell application "iTunes"
					try -- skip on failure
						set new_track to item 1 of (convert this_track)
						set loc to new_track's location
						set dbid to new_track's database ID
						delete artworks of new_track
						
						-- move the file to new location
						do shell script "mv " & (quoted form of POSIX path of loc) & " " & (quoted form of POSIX path of path2 as string)
						
						-- delete the track
						delete new_track
					end try
				end tell
				
			end if
		end tell
		
	end repeat
	
	set current encoder to encoder encoderBackup
	display dialog "done"
end tell

Can anyone help with either points?

Thanks

Nick
 
If you are using variables in functions, that are declared outside the function, you need to define them as global for example:

Code:
global myFirstGlobal
set myFirstGlobal to "2"

In terms of how to script the stuff you want, you have to determine the best method to get those things done.
 
Thanks. I have tried to integrate the global variables as you suggest, but I can't have got it right, because the script is not converting any files when it should be doing so:

Here's the amended script:

Code:
tell application "iTunes"
	activate
	
	set sel to selection
	set encoderBackup to name of current encoder
	set this_folder to "Macintosh HD:Users:nick:Desktop:music:" as text
	set current encoder to encoder "MP3 Encoder"
	
	global this_track
	repeat with this_track in sel
		set trackComposer to this_track's composer
		set trackAlbum to this_track's album
		set trackName to this_track's name
		tell application "Finder"
			
			set path1 to "Macintosh HD:Users:nick:Desktop:music:" & trackComposer as text
			
			if folder path1 exists then
				{}
			else
				make new folder at this_folder with properties {name:trackComposer}
			end if
			
			global path2
			set path2 to this_folder & trackComposer & ":" & trackAlbum as text
			
			if folder path2 exists then
				{}
			else
				make new folder at path1 with properties {name:trackAlbum}
			end if
			
			if exists file (path2 & ":" & trackName & ".mp3") then
				set file2 to (path2 & ":" & trackName & ".mp3") as alias
				set modDate to modification date of file2
				set modDate2 to this_track's modification date
				if modDate is greater than modDate2 then
					{}
				else
					my convertTrack
				end if
			else
				my convertTrack
			end if
		end tell
		
	end repeat
	
	set current encoder to encoder encoderBackup
	display dialog "done"
end tell

on convertTrack()
	tell application "iTunes"
		try -- skip on failure
			global path2
			global this_track
			set new_track to item 1 of (convert this_track)
			set loc to new_track's location
			set dbid to new_track's database ID
			delete artworks of new_track
			
			-- move the file to new location
			do shell script "mv " & (quoted form of POSIX path of loc) & " " & (quoted form of POSIX path of path2 as string)
			
			-- delete the track
			delete new_track
		end try
	end tell
end convertTrack

I worked out there are two variables which are not declared within the function, path2 and this_track, so I added a line to define them as global above the line where they are declared, and also in the handler (not sure if this second step is necessary). I then simply used 'my convertTrack' in the script. But as I said, it's not working as it stands.

Regarding point 1 in my original post, I presume that the best method would be to work folder by folder comparing folders and subfolders of the main destination folder 'music' with their equivalent folders and subfolders in the iTunes music library, removing any file (checked by filename) in the destination folder that is not found in the source folder. But I am not sure how to go about this.

Nick
 
Just to say that I have worked out the second issue, so that I can use a handler to specify the conversion and call it in the script when necessary. I am not sure where to start though with the first issue, i.e. how to delete any MP3 files in the destination folders/subfolders, that don't exist as m4a files in the source (iTunes) folders/subfolders (presumably this would have to be by generating a list of files of in each folder and comparing file names, but I am not sure how to go about this - would I do it folder by folder, or just generate one long list of all the files in the folders/subfolders?). Here's the revised script:

Code:
tell application "iTunes"
	activate
	
	set sel to selection
	set encoderBackup to name of current encoder
	set this_folder to "Macintosh HD:Users:nick:Desktop:music:" as text
	set current encoder to encoder "MP3 Encoder"
	
	repeat with this_track in sel
		set trackComposer to this_track's composer
		set trackAlbum to this_track's album
		set trackName to this_track's name
		tell application "Finder"
			
			set path1 to "Macintosh HD:Users:nick:Desktop:music:" & trackComposer as text
			
			if not (folder path1 exists) then
				make new folder at this_folder with properties {name:trackComposer}
			end if
			
			local path2
			set path2 to this_folder & trackComposer & ":" & trackAlbum as text
			
			if not (folder path2 exists) then
				make new folder at path1 with properties {name:trackAlbum}
			end if
			
			if exists file (path2 & ":" & trackName & ".mp3") then
				set file2 to (path2 & ":" & trackName & ".mp3") as alias
				set modDate to modification date of file2
				set modDate2 to this_track's modification date
				if not (modDate is greater than modDate2) then
					my convertTrack(this_track, path2)
				end if
			else
				my convertTrack(this_track, path2)
			end if
		end tell
		
	end repeat
	
	set current encoder to encoder encoderBackup
	display dialog "done"
end tell

on convertTrack(this_track, path2)
	tell application "iTunes"
		try -- skip on failure
			set new_track to item 1 of (convert this_track)
			set loc to new_track's location
			set dbid to new_track's database ID
			delete artworks of new_track
			-- move the file to new location
			do shell script "mv " & (quoted form of POSIX path of loc) & " " & (quoted form of POSIX path of path2 as string)
			
			-- delete the track
			delete new_track
		end try
	end tell
end convertTrack
 
Thanks.

I now have a script that does everything I want, including deleting superfluous tracks from the destination folder, except where there are characters in the track name in iTunes that aren't supported in filenames in Finder (i.e. ? / :). This means that all tracks which contain these characters in the name are re-converted every time I run the script.

Is there a way I wonder of adapting the script so that when it is checking to see if the track already exists in the destination folder, it replaces these characters in the track name with an _ (which is what happens in Finder) for the purposes of the comparison?

Nick

Code:
tell application "iTunes"
	activate
	
	set sel to every track of playlist "1 music library"
	set encoderBackup to name of current encoder
	set this_folder to "Macintosh HD:Users:nick:Desktop:music:" as text
	set current encoder to encoder "MP3 Encoder"
	
	repeat with this_track in sel
		set trackComposer to this_track's composer
		set trackAlbum to this_track's album
		set trackName to this_track's name
		tell application "Finder"
			
			set path1 to "Macintosh HD:Users:nick:Desktop:music:" & trackComposer as text
			
			if not (folder path1 exists) then
				make new folder at this_folder with properties {name:trackComposer}
			end if
			
			local path2
			set path2 to this_folder & trackComposer & ":" & trackAlbum as text
			
			if not (folder path2 exists) then
				make new folder at path1 with properties {name:trackAlbum}
			end if
			
			if exists file (path2 & ":" & trackName & ".mp3") then
				set file2 to (path2 & ":" & trackName & ".mp3") as alias
				set modDate to modification date of file2
				set modDate2 to this_track's modification date
				if not (modDate is greater than modDate2) then
					my convertTrack(this_track, path2)
				end if
			else
				my convertTrack(this_track, path2)
			end if
		end tell
		
	end repeat
	
	set current encoder to encoder encoderBackup
	display dialog "done"
end tell

on convertTrack(this_track, path2)
	tell application "iTunes"
		try -- skip on failure
			set new_track to item 1 of (convert this_track)
			set loc to new_track's location
			-- move the file to new location
			do shell script "mv " & (quoted form of POSIX path of loc) & " " & (quoted form of POSIX path of path2 as string)
			
			-- delete the track
			delete new_track
		end try
	end tell
end convertTrack
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.