Applescript help - creating a new folder

Discussion in 'Mac Programming' started by robert-a-hudson, Feb 12, 2007.

  1. macrumors regular

    Joined:
    Apr 11, 2006
    Location:
    Britain
    #1
    Hi,

    I'm trying to write an applescript which will enable me to sync a playlist in itunes with my phone-mp3-player.

    To do this, I am going to need to create some folders within my test directory (startup disk:users:robert:dekstop:Scripts:test folder: ) since my phones jukebox needs to have the files within the "MP3' folder in "artist/album/song.mp3".

    So I am now trying to simply create a folder within my test directory.

    At the moment, what I have is:

    Code:
    property mainFolder : "startup disk:users:robert:dekstop:Scripts:test folder:"
    
    tell application "Finder"
    	set mainFolder to (path_to_folder)
    	make new folder at folder mainFolder with properties {name:"test"}
    end tell
    When I run this I receive an apple script error "Finder got an error: Can't get some object."


    So, please can someone help me.

    Thanks
     
  2. Administrator

    HexMonkey

    Staff Member

    Joined:
    Feb 5, 2004
    Location:
    New Zealand
    #2
    I think the problem is that mainFolder isn't a valid path. Ignoring the first line in your tell block (since path_to_folder isn't defined), I see that "desktop" is spelt incorrectly in the mainFolder definition, and "startup disk" needs to be replaced by the name of your startup disk (unless "startup disk" is its actual name).

    Alternatively you could try something like this, which should work as long as the "Scripts" and "test folder" folders exist:

    Code:
    tell application "Finder"
    	set mainFolder to folder "test folder" of folder "Scripts" of desktop as string
    	make new folder at folder mainFolder with properties {name:"testfile"}
    end tell
     
  3. thread starter macrumors regular

    Joined:
    Apr 11, 2006
    Location:
    Britain
    #3
    Hi and thanks for your fast response.

    I have tried doing what you said for the folder on my phone (when I plug my phone in, it mounts as "NO NAME") as required, and have modified the code as I would have expected:

    Code:
    tell application "Finder"
    	set mainFolder to folder "Test" of folder "MP3" of "no name" as string
    	make new folder at folder mainFolder with properties {name:"testfile"}
    end tell
    
    And I now receive the error : Can't make «class cfol» "Test" of «class cfol» "MP3" of "no name" into type string.

    Any more help please?

    Thanks again.
     
  4. Administrator

    HexMonkey

    Staff Member

    Joined:
    Feb 5, 2004
    Location:
    New Zealand
    #4
    Instead of:
    Code:
    set mainFolder to folder "Test" of folder "MP3" of "no name" as string
    Try this:
    Code:
    set mainFolder to folder "Test" of folder "MP3" of disk "no name" as string
    Note the word "disk" before "no name". A string on its own means nothing to Finder.
     
  5. thread starter macrumors regular

    Joined:
    Apr 11, 2006
    Location:
    Britain
    #5
    Excellent, thanks once again.

    Now, if I may ask another question. This time about the rest of my code below!

    Now the idea that I had was to copy all the tracks from a playlist (in this case "test") into "mainFolder" Now, when I run this script the test folder is created (since you've helped me with that). But nothing further seems to happen. The idea was to just copy a couple of mp3s in a test playlist. But, I can not figure out how to do this. Hope you can help me again!

    Code:
    property playlistused : "test"
    
    tell application "Finder"
    	
    	--set mainFolder to folder "Test" of folder "MP3" of disk "no name" as string
    	set mainFolder to folder "test folder" of folder "iTunes Scripts" of desktop as string
    	make new folder at folder mainFolder with properties {name:"testfile"}
    	
    end tell
    
    tell application "iTunes"
    	--set oldfi to fixed indexing - means tracks go from 1 to x
    	set oldfi to fixed indexing
    	set fixed indexing to true
    	copy (count playlistused's tracks) to ix
    	
    	repeat with i from 1 to ix
    		copy (get name of track i of user playlist playlistused) to trackName
    		copy (get album of track i of user playlist playlistused) to trackAlbum
    		copy (get artist of track i of user playlist playlistused) to trackArtist
    		copy track i of playlistused to thisTrack
    		copy (get thisTrack's location) to track_location_in_finder
    		
    		tell application "Finder"
    			copy (get name of (get info for (location_in_finder as alias))) as string to fixed_filename
    			copy (get container of location_in_finder) as string to source_folder
    		end tell
    		copy (source_folder & fixed_filename) as string to location_in_finder_info_name
    		
    		my set_item_name(location_in_finder_info_name, itunes_track_name)
    		tell application "Finder"
    			duplicate thisTrack to mainFolder
    		end tell
    	end repeat
    	
    	set fixed indexing to oldfi
    end tell
    
    Thanks
     
  6. Administrator

    HexMonkey

    Staff Member

    Joined:
    Feb 5, 2004
    Location:
    New Zealand
    #6
    I had to make a few changes to get it to work, so I'll go through the code bit by bit.

    Code:
    property playlistused : "test"
    
    tell application "Finder"
    	
    	--set mainFolder to folder "Test" of folder "MP3" of disk "no name" as string
    	set mainFolder to folder "test folder" of folder "iTunes Scripts" of desktop as string
    	set mainFolder to (make new folder at folder mainFolder with properties {name:"testfile"})
    end tell
    Here I set mainFolder to the new folder that you created. If I understand you correctly, you want to add the music files to the testfile folder, not test folder, but if this isn't the case you can revert this code back to what you had before.

    Code:
    tell application "iTunes"
    	--set oldfi to fixed indexing - means tracks go from 1 to x
    	set oldfi to fixed indexing
    	set fixed indexing to true
    	copy (count playlist playlistused's tracks) to ix
    In the last line, I changed (count playlistused's tracks) to (count playlist playlistused's tracks). Without the word playlist, it doesn't know that it's a playlist, so it incorrectly sets ix to 0 (which is what caused your original script to do nothing).

    Code:
    	repeat with i from 1 to ix
    		copy (get name of track i of user playlist playlistused) to trackName
    		copy (get album of track i of user playlist playlistused) to trackAlbum
    		copy (get artist of track i of user playlist playlistused) to trackArtist
    		copy track i of playlist playlistused to thisTrack
    		copy (get thisTrack's location) to track_location_in_finder
    Again, I added the word playlist before playlistused on the second to last line.

    Code:
    		tell application "Finder"
    			copy (get name of (get info for (track_location_in_finder as alias))) as string to fixed_filename
    			copy (get container of track_location_in_finder) as string to source_folder
    		end tell
    		copy (source_folder & fixed_filename) as string to location_in_finder_info_name
    Here I changed location_in_finder (which wasn't defined) to track_location_in_finder several times.

    Code:
    		--my set_item_name(location_in_finder_info_name, itunes_track_name)
    		tell application "Finder"
    			set aFile to duplicate (location_in_finder_info_name as alias) to mainFolder
    			set name of aFile to trackName & ".mp3" as string
    		end tell
    I commented out the first line since I don't have your code for set_item_name. I also changed the duplicate line, which gave an error with your code. Finally, I added a line to rename the file to its iTunes track name (rather than its filename), which is what I suspect the purpose of set_item_name might have been.

    The rest of the code is unchanged:
    Code:
    	end repeat
    	
    	set fixed indexing to oldfi
    end tell
    Here's the code in one segment:

    Code:
    property playlistused : "test"
    
    tell application "Finder"
    	
    	--set mainFolder to folder "Test" of folder "MP3" of disk "no name" as string
    	set mainFolder to folder "test folder" of folder "iTunes Scripts" of desktop as string
    	set mainFolder to (make new folder at folder mainFolder with properties {name:"testfile"})
    end tell
    
    tell application "iTunes"
    	--set oldfi to fixed indexing - means tracks go from 1 to x
    	set oldfi to fixed indexing
    	set fixed indexing to true
    	copy (count playlist playlistused's tracks) to ix
    	
    	repeat with i from 1 to ix
    		copy (get name of track i of user playlist playlistused) to trackName
    		copy (get album of track i of user playlist playlistused) to trackAlbum
    		copy (get artist of track i of user playlist playlistused) to trackArtist
    		copy track i of playlist playlistused to thisTrack
    		copy (get thisTrack's location) to track_location_in_finder
    		
    		tell application "Finder"
    			copy (get name of (get info for (track_location_in_finder as alias))) as string to fixed_filename
    			copy (get container of track_location_in_finder) as string to source_folder
    		end tell
    		copy (source_folder & fixed_filename) as string to location_in_finder_info_name
    		
    		--my set_item_name(location_in_finder_info_name, itunes_track_name)
    		tell application "Finder"
    			set aFile to duplicate (location_in_finder_info_name as alias) to mainFolder
    			set name of aFile to trackName & ".mp3" as string
    		end tell
    	end repeat
    	
    	set fixed indexing to oldfi
    end tell
     
  7. thread starter macrumors regular

    Joined:
    Apr 11, 2006
    Location:
    Britain
    #7
    HexMonkey.

    Thanks a lot for all the help!, so far it's working a treat!
    I'm now working on getting the tracks organised into a folder hierarchy, so I may be posting again for help!

    Thanks again.
     
  8. thread starter macrumors regular

    Joined:
    Apr 11, 2006
    Location:
    Britain
    #8
    Okay, so I'm stuck again!

    Now, I'm trying to get the mp3 files to be copied into a folder structure such as:

    mainFolder/trackArtist/trackAlbum/trackName.mp3

    Now, I've basically just added the lines:
    Code:
    
    			make new folder at folder mainFolder with properties {name:"newfolder"}
    			set name of folder "newfolder" of folder mainFolder to trackArtist
    			set artistfolder to folder trackArtist of folder mainFolder
    			
    			make new folder at folder artistfolder with properties {name:"newfolder"}
    			set name of folder "newfolder" of folder artistfolder to trackAlbum
    			set artistalbumfolder to folder trackAlbum of folder mainFolder
    	
    
    and thought I was going to be okay just following the way it it is done right at the start of the code, but apparently that doesnt work.... can you help please!

    ---The entire code:

    Code:
    property playlistused : "test"
    
    tell application "Finder"
    	
    	--set mainFolder to folder "Test" of folder "MP3" of disk "no name" as string
    	set mainFolder to folder "test folder" of folder "iTunes Scripts" of desktop as string
    	set mainFolder to (make new folder at folder mainFolder with properties {name:"testfile"})
    end tell
    
    tell application "iTunes"
    	-- set oldfi to ficed indexing -> means tracks fo from 1 to ix
    	set oldfi to fixed indexing
    	set fixed indexing to true
    	copy (count playlist playlistused's tracks) to ix
    	
    	repeat with i from 1 to ix
    		copy (get name of track i of user playlist playlistused) to trackName
    		copy (get album of track i of user playlist playlistused) as string to trackAlbum
    		copy (get artist of track i of user playlist playlistused) as string to trackArtist
    		copy track i of playlist playlistused to thisTrack
    		copy (get thisTrack's location) to track_location_in_finder
    		
    		tell application "Finder"
    			copy (get name of (get info for (track_location_in_finder as alias))) as string to fixed_filename
    			copy (get container of track_location_in_finder) as string to source_folder
    		end tell
    		copy (source_folder & fixed_filename) as string to location_in_finder_info_name
    		
    		--my set_item_name(location_in_finder_info_name, itunes_track_name)
    		tell application "Finder"
    			
    			make new folder at folder mainFolder with properties {name:"newfolder"}
    			set name of folder "newfolder" of folder mainFolder to trackArtist
    			set artistfolder to folder trackArtist of folder mainFolder
    			
    			make new folder at folder artistfolder with properties {name:"newfolder"}
    			set name of folder "newfolder" of folder artistfolder to trackAlbum
    			set artistalbumfolder to folder trackAlbum of folder mainFolder
    			
    			set aFile to duplicate (location_in_finder_info_name as alias) to artistalbumfolder
    			set name of aFile to trackName & ".mp3" as string
    		end tell
    	end repeat
    	
    	set fixed indexing to oldfi
    end tell
    
     
  9. Administrator

    HexMonkey

    Staff Member

    Joined:
    Feb 5, 2004
    Location:
    New Zealand
    #9
    This code can be simplified a bit because you can set the folder name to trackAlbum when you create it, rather than creating it with the name "newfolder" then immediately renaming it.

    To get the code to work, I had to convert the folder variables to strings. I also wrapped some try blocks around the make new folder commands since they give an error if the folder already exists, and you're likely to have multiple songs in the same album or by the same artist. Finally, I added a couple of lines earlier in the code to set the artist and album to "Unknown Artist" and "Unknown Album" respectively if the artist or album was not specified, since you can't have an empty folder name.

    Here's the code:

    Code:
    property playlistused : "test"
    
    tell application "Finder"
    	
    	--set mainFolder to folder "Test" of folder "MP3" of disk "no name" as string
    	set mainFolder to folder "test folder" of folder "iTunes Scripts" of desktop as string
    	set mainFolder to (make new folder at folder mainFolder with properties {name:"testfile"}) as string
    end tell
    
    tell application "iTunes"
    	-- set oldfi to ficed indexing -> means tracks fo from 1 to ix
    	set oldfi to fixed indexing
    	set fixed indexing to true
    	copy (count playlist playlistused's tracks) to ix
    	
    	repeat with i from 1 to ix
    		copy (get name of track i of user playlist playlistused) to trackName
    		copy (get album of track i of user playlist playlistused) as string to trackAlbum
    		copy (get artist of track i of user playlist playlistused) as string to trackArtist
    		if (trackArtist is "") then set trackArtist to "Unknown Artist"
    		if (trackAlbum is "") then set trackAlbum to "Unknown Album"
    		copy track i of playlist playlistused to thisTrack
    		copy (get thisTrack's location) to track_location_in_finder
    		
    		tell application "Finder"
    			copy (get name of (get info for (track_location_in_finder as alias))) as string to fixed_filename
    			copy (get container of track_location_in_finder) as string to source_folder
    		end tell
    		copy (source_folder & fixed_filename) as string to location_in_finder_info_name
    		
    		--my set_item_name(location_in_finder_info_name, itunes_track_name)
    		tell application "Finder"
    			try
    				make new folder at folder mainFolder with properties {name:trackArtist}
    			end try
    			set artistfolder to folder trackArtist of folder mainFolder as string
    			try
    				make new folder at folder artistfolder with properties {name:trackAlbum}
    			end try
    			set artistalbumfolder to folder trackAlbum of folder artistfolder as string
    			set aFile to duplicate (location_in_finder_info_name as alias) to artistalbumfolder
    			set name of aFile to trackName & ".mp3" as string
    		end tell
    	end repeat
    	
    	set fixed indexing to oldfi
    end tell
     
  10. thread starter macrumors regular

    Joined:
    Apr 11, 2006
    Location:
    Britain
    #10
    Thanks for the help. I now have the code working with my phone, and it all goes wonderfully.

    I do have one remaining question however: On my phone's media player, it sees both the file "song.mp3" but it also sees a ".something" file for each of the songs copied over. Is there anyway to get the apple script to not copy the .something files?
    (I have noticed this when saving documents etc on my SD Card for use with my PDA which then see's all these .whatever files.)

    Hope that makes sense, and you can help again!

    Thanks.

    Code:
    property playlistused : "*Phone"
    
    tell application "Finder"
    	--set mainFolder to folder "MP3" of disk "no name" as string
    	set mainFolder to folder "MP3" of disk "NO NAME" as string
    end tell
    
    tell application "iTunes"
    	-- set oldfi to ficed indexing -> means tracks fo from 1 to ix
    	set oldfi to fixed indexing
    	set fixed indexing to true
    	copy (count playlist playlistused's tracks) to ix
    	
    	repeat with i from 1 to ix
    		copy (get name of track i of user playlist playlistused) to trackName
    		copy (get album of track i of user playlist playlistused) as string to trackAlbum
    		copy (get artist of track i of user playlist playlistused) as string to trackArtist
    		if (trackArtist is "") then set trackArtist to "Unknown Artist"
    		if (trackAlbum is "") then set trackAlbum to "Unknown Album"
    		copy track i of playlist playlistused to thisTrack
    		copy (get thisTrack's location) to track_location_in_finder
    		
    		tell application "Finder"
    			copy (get name of (get info for (track_location_in_finder as alias))) as string to fixed_filename
    			copy (get container of track_location_in_finder) as string to source_folder
    		end tell
    		copy (source_folder & fixed_filename) as string to location_in_finder_info_name
    		
    		--my set_item_name(location_in_finder_info_name, itunes_track_name)
    		if (get thisTrack's kind) is "MPEG audio file" then
    			copy ".mp3" to trackExt
    		else if (get thisTrack's kind) is "MPEG-4 video file" then
    			copy ".mp4" to trackExt
    		else
    			copy "skip" to trackExt
    		end if
    		
    		if (trackExt is not "skip") then
    			tell application "Finder"
    				try
    					make new folder at folder mainFolder with properties {name:trackArtist}
    				end try
    				set artistfolder to folder trackArtist of folder mainFolder as string
    				try
    					make new folder at folder artistfolder with properties {name:trackAlbum}
    				end try
    				set artistalbumfolder to folder trackAlbum of folder artistfolder as string
    				set aFile to duplicate (location_in_finder_info_name as alias) to artistalbumfolder
    				set name of aFile to trackName & trackExt as string
    			end tell
    		end if
    	end repeat
    	
    	set fixed indexing to oldfi
    end tell
    
     
  11. Administrator

    HexMonkey

    Staff Member

    Joined:
    Feb 5, 2004
    Location:
    New Zealand
  12. thread starter macrumors regular

    Joined:
    Apr 11, 2006
    Location:
    Britain
    #12
    Yep
     
  13. Administrator

    HexMonkey

    Staff Member

    Joined:
    Feb 5, 2004
    Location:
    New Zealand
    #13
    The .DS_Store files are created automatically by Mac OS X each time the script creates a new folder (see here for more information on .DS_Store files). To solve your problem, they must be deleted at the end of the script. The easiest way to do this is to run a shell script using the do shell script command.

    Replace the last two lines of your code (set fixed indexing ... end tell) with this:

    Code:
    	--Run a shell script to remove .DS_Store files
    	set dsStoreScript to "find " & my posix_path(mainFolder) & " -name '.DS_Store' -exec rm -rf {} \\;" as string
    	delay 10
    	do shell script dsStoreScript
    	
    	set fixed indexing to oldfi
    end tell
    
    --The following subroutine was written by James Sorenson
    --Source: http://www.macosxhints.com/article.php?story=20011030193449870
    on posix_path(mac_path)
    	set mac_path to (mac_path as text)
    	set root to (offset of ":" in mac_path)
    	set rootdisk to (characters 1 thru (root - 1) of mac_path)
    	tell application "Finder"
    		if (disk (rootdisk as string) is the startup disk) then
    			set unixpath to "/" & (characters (root + 1) thru end of mac_path)
    		else
    			set unixpath to "/Volumes:" & mac_path
    		end if
    	end tell
    	set chars to every character of unixpath
    	repeat with i from 2 to length of chars
    		if item i of chars as text is equal to "/" then
    			set item i of chars to ":"
    		else if item i of chars as text is equal to ":" then
    			set item i of chars to "/"
    		else if item i of chars as text is equal to "'" then
    			set item i of chars to "\\'"
    		else if item i of chars as text is equal to "\"" then
    			set item i of chars to "\\" & "\""
    		else if item i of chars as text is equal to "*" then
    			set item i of chars to "\\*"
    		else if item i of chars as text is equal to "?" then
    			set item i of chars to "\\?"
    		else if item i of chars as text is equal to " " then
    			set item i of chars to "\\ "
    		else if item i of chars as text is equal to "\\" then
    			set item i of chars to "\\\\"
    		end if
    	end repeat
    	return every item of chars as string
    end posix_path
    Note that the .DS_Store aren't created immediately, but on a short cycle of about 5 seconds. Eg if you created a folder each second, five .DS_Store files would be created at once each run of the cycle. For this reason, I needed to put a delay in the script before running the shell script, so that the files wouldn't be created after I'd tried to delete them.

    Also note that the .DS_Store files will be recreated if you open any of the folders in the script, or if you modify their contents.
     
  14. thread starter macrumors regular

    Joined:
    Apr 11, 2006
    Location:
    Britain
    #14
    cheers that has gotten rid of the ds store files fine.

    Thanks again
     
  15. macrumors newbie

    Joined:
    Feb 12, 2009
    #15
    iTune Play Lists Export

    Hi,

    I a trying to export all my playlists as folders on to a hard drive. Have tried to modify your script to use but could not export the playlist to a folder with the same name as the playlist. Can you please help?

    Regards

    J


     

Share This Page