Can You Help?

This script needs perl/sed/awk help. See my notes below the script. Click on the script icon below the listing to load it into your Script Editor. Need "ProgBar"? E-mail me.

 
property blank : ""

global path_to_xml
global the_contents

set path_to_xml to "~/Music/iTunes/iTunes\\ Music\\ Library.xml"

-- choose folder or use Music Folder

set myOpt to button returned of (display dialog "Look for audio files in the designated \"Music\" folder, or choose other folder..." buttons {"Cancel", "Choose Other...", "Music folder"} default button 3)
if myOpt contains "Choose" then
	set musicFolder to (choose folder with prompt "Choose a folder in which to search for audio files...")
	tell application "Finder" to set folder_nom to get name of folder musicFolder
	set musicFolder to POSIX path of (musicFolder as string)
else
	-- get designated Music folder
	set musicFolder to my get_music_folder()
	set folder_nom to "Music"
end if

if button returned of (display dialog "To be extra especially particular, do you want Spotlight to re-index the " & folder_nom & " folder," & return & return & "  " & musicFolder & return & return & "This will take some extra time." buttons {"No", "Yes"} default button 1 with icon 0) is "Yes" then
	with timeout of 60000 seconds
		do shell script "mdimport " & musicFolder
	end timeout
end if

-- just audio files
set the_command to ("mdfind " & "\"kMDItemMediaTypes == 'Sound'\" -onlyin '" & musicFolder & "'") as string

set returned_list to text_to_list((do shell script the_command), return)
set count_of_returned_list to (count items of my returned_list)

-- ***Prepare the progress bar. This 'sets up' the progress bar's state.
prep_Progress((count_of_returned_list) + 1, "alum_prog_window2") of me
-- ***

try
	with timeout of 60000 seconds
		set the_contents to {}
		set t to 0
		repeat with t from 1 to count_of_returned_list
			set this_file_path to item t of my returned_list
			set file_path to POSIX file this_file_path
			log file_path
			set this_file_path to quoted form of this_file_path
			
			if this_file_path contains "Unknown Album" then
				set alb to ""
			else
				set alb to text 2 thru -2 of last item of text_to_list((do shell script "mdls -name 'kMDItemAlbum' " & this_file_path), "kMDItemAlbum = ")
			end if
			
			if this_file_path contains "Unknown Artist" then
				set art to ""
			else
				set art to text 2 thru -2 of last item of text_to_list((do shell script "mdls -name 'kMDItemAuthors' " & this_file_path), "kMDItemAuthors = ")
				if art starts with "\"" then set art to text 2 thru -2 of art
			end if
			
			set nom to text 2 thru -2 of last item of text_to_list((do shell script "mdls -name 'kMDItemTitle' " & this_file_path), "kMDItemTitle = ")
			
			set siz to last item of text_to_list((do shell script "mdls -name 'kMDItemFSSize' " & this_file_path), "kMDItemFSSize = ")
			
			--	we have nom, alb, art & siz
			
			-- ***
			increment_progbar(t + 1, count_of_returned_list, alb, art, nom) of me
			-- ***
			
			(*
			What would be great is a do shell script that does a m// on the XML file
			I have included the essential path to a user's iTunes XML file
			in the variable "path_to_xml"
			You will have to create the matcing string taking into consideration
			that an "Unknown Artist" and "Unknown Album" will NOT be listed
			in the XML
			*)
			
			tell application "iTunes"
				if (exists (some track of library playlist 1 whose album contains (alb as text) and name contains (nom as text) and size is (siz as number))) then
					-- if length of (get every track of library playlist 1 whose album contains (alb as text) and name contains (nom as text) and size is (siz as number)) = 0 then
					-- not found
				else
					set end of the_contents to (file_path & return)
				end if
			end tell
			
		end repeat
		
		-- ***
		end_Progress("alum_prog_window2") of me
		-- ***
		make_text_file()
		
	end timeout
	
on error m number n
	display dialog m & return & n buttons {"OK"}
	make_text_file()
	
	-- ***
	end_Progress("alum_prog_window2") of me
	-- ***
	
end try
-- ===============================================================

to make_text_file()
	-- make text file
	
	if the_contents is {} then return
	set the_contents to the_contents as string
	set file_name to ((path to desktop as string) & "Music Folder Files Not Added.txt") as string
	try
		copy (a reference to (open for access file_name with write permission)) to fileRef
		write the_contents to fileRef
		close access fileRef
	on error errx number errNum
		close access fileRef
		display dialog "There has been an error creating the file:" & return & return & errx & return & "error number: " & errNum buttons {"Cancel"}
	end try
end make_text_file

on quit
	continue quit
end quit

to get_music_folder()
	set musicFolder to ""
	try -- get the XML file, which contains the location of the Music folder
		-- thanks to Sal Soghoian for pointing me in the right direction here
		set these_paths to do shell script "defaults read com.apple.iapps iTunesRecentDatabases"
		set the data_file to the text 19 thru ((the offset of "\")" in these_paths) - 1) of these_paths
		set musicFolder to parse_xml_file((my replace_chars(data_file, "%20", " ")))
	end try
	return musicFolder
end get_music_folder

to parse_xml_file(thePath)
	-- this grep routine is lifted and modified from "Wicked Cool Shell Scripts" by Dave Taylor, published by No Starch Press
	return (do shell script "grep '>Music Folder<' " & (quoted form of thePath) & " | cut -d/ -f5- | cut -d\\< -f1 | sed 's/%20/ /g'")
end parse_xml_file

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

on replace_chars(txt, srch, repl)
	set saveD to AppleScript's text item delimiters
	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 saveD
	return txt
end replace_chars

-- Prepare progress bar subroutine.
on prep_Progress(someMaxCount, windowName)
	tell application "ProgBar"
		set title of window "alum_prog_window2" to "Music Folder Files Not Added"
		show window "alum_prog_window2"
		
		activate
		tell text field "field_one" of window windowName to set contents to "Working..."
		tell text field "field_two" of window windowName to set contents to blank
		tell progress indicator "prog_one" of window windowName
			set content to 0
			set uses threaded animation to true
			start
			set minimum value to 0
			set maximum value to someMaxCount
		end tell
	end tell
end prep_Progress

-- Increment progress bar subroutine. DA added n parameter, the name of the current trak being checked
on increment_progbar(item_number, count_of_returned_list, alb, art, nom)
	tell application "ProgBar"
		tell text field "field_one" of window "alum_prog_window2" to set contents to ((item_number - 1) & "/" & count_of_returned_list) as string
		tell progress indicator "prog_one" of window "alum_prog_window2" to set content to item_number
		if art is "" then set art to "Unknown Artist"
		if alb is "" then set alb to "Unknown Album"
		tell text field "field_two" of window "alum_prog_window2" to set contents to ((nom as text) & " by " & (art as text))
	end tell
end increment_progbar

-- End progress bar subroutine.
on end_Progress(windowName)
	tell application "ProgBar"
		tell progress indicator "prog_one" of window windowName to stop
		tell progress indicator "prog_one" of window windowName to set content to 0
		try
			quit
		end try
	end tell
end end_Progress


Notes:

- I got a few false positive results. You may want to include "artist contains (art as text)" in the iTunes filter command.

- If you are running the script as an application: to stop it select it in the Dock and hold the "esc" key, which will generate an error and quit the app.

- The sort of perl script I'm looking for would take nom, art, alb, and siz and insert them into a m// routine. This is the sort of thing I've been playing with:

set rez to do shell script "perl -n -e '<>=~m:<key>Size</key><integer>" & (siz as text) & "</integer>:sg; print $&;' " & path_to_xml

Then you would check the variable "rez" for whatever result from the do shell script. The problem I run up against is getting the AppleScript variables into the command. The siz variable works because there's no chance of getting "bad" characters. But the other text variables--art, nom, and alb--need to be in "quoted form of". I got errors when I did this using the sort of syntax above.

- ProgBar is available from T.J. Mahaffey's Spork Software site. However, it appears to be unavailable. I have written to T.J. to inquire about the availablity of ProgBar.

Site contents © 2001 - 2012 Doug Adams and weblished by Doug Adams, dougscripts AT mac DOT com.
All rights reserved. Legal.
AppleScript, iTunes, iPod, iPad, and iPhone are registered trademarks of Apple Inc.