Extract all iTunes artwork (file exists "do shell script" kills it)

I’m working on a PHP script to use on Opera for the Nintendo DS. Everything is working decent enough (given having to not run Apache as the www user and the “request” call to osascript for this task behaving erratically). I decided to include an AppleScript/AS.app to extract all album artwork in one pass. Which is fine because the PHP scripts react quicker using this technique.

Anyway, one cycles saving “should have” feature of the AppleScript is to check if the artwork file has already been extracted before proceeding. Adding this ends the repeat at that point. Judging by the event log, the shell commands react as expected, but AS doesn’t. So I’m hoping some kind soul can see what I can’t.

I ran the AS from Script Editor without the shell commands and it saves all available artwork. I tested the shell inclusion by adding artwork to a couple of tracks that didn’t have any when running the AS the previous time. Though egrep doesn’t find a corresponding file, AS does nothing about it and gets the next tracks’ album name.

property my_path : ((path to sites folder) as text) & "iTunesDS:images:albums:"
property my_x_path : POSIX path of my_path
property last_album : ""

tell application "iTunes"
	set the_tracks to (every file track of library playlist 1)
	repeat with i from 1 to number of items in the_tracks
		set the_track to item i of the_tracks
		try
			tell the_track
				set album_name to my removeChars(album)
				if album_name is not last_album then
					set last_album to album_name
					if (do shell script "ls " & quoted form of my_x_path & " | egrep -xs " & quoted form of (my slashChars(album_name) & ".jpg")) is "" then -- Also tried as 'missing value' and without the 's' flag
						set artwork_data to data of artwork 1
						set artwork_image to (open for access my_path & "temp_img" with write permission)
						set eof artwork_image to 512
						write artwork_data to artwork_image starting at 513
						close access artwork_image
						set artwork_data to ""
						tell application "Image Events"
							set this_image to open (my_path & "temp_img") as string
							scale this_image to size 110
							set new_item to (my_path & album_name & ".jpg") as string
							save this_image in new_item as JPEG
							close this_image
						end tell
					end if
				end if
			end tell
		end try
	end repeat
end tell

on removeChars(this_text)
	set the illegalChars to "\"\"'\\:?" -- 2nd escaped dbl quote added for BBS legibility
	set the character_list to {}
	repeat with this_char in this_text
		set this_char to the contents of this_char
		if this_char is in the illegalChars then
			set the end of the character_list to ""
		else
			set the end of the character_list to this_char
		end if
	end repeat
	return (the character_list) as string
end removeChars

on slashChars(this_text)
	set the illegalChars to "\\/$^*()+.?[]{}|"
	set the character_list to {}
	repeat with this_char in this_text
		set this_char to the contents of this_char
		if this_char is in the illegalChars then
			set the end of the character_list to "\\" & this_char
		else
			set the end of the character_list to this_char
		end if
	end repeat
	return (the character_list) as string
end slashChars

I’ve tried setting the do shell script as a variable before the if. Also tried that as string. Tried exiting the tell the_track set album_name before calling the shell and using another tell the_track to get the artwork data.

Sorry to double post. One problem down, new problem up…

Here is an updated script using a Finder routine to check if file exists. It finds the files then goes to the step of open for access, then repeats without running the Image Events tell block.

property my_path : ((path to sites folder) as text) & "iTunesDS:images:albums:"
property my_x_path : POSIX path of my_path
property last_album : ""

tell application "iTunes"
	set the_tracks to (every file track of library playlist 1)
	repeat with i from 1 to number of items in the_tracks
		set the_track to item i of the_tracks
		try
			tell the_track
				set album_name to my removeChars(album)
				if album_name is not last_album then
					set last_album to album_name
					if (my fileExists(album_name)) is "false" then
						set artwork_data to data of artwork 1
						set artwork_image to (open for access my_path & "temp_img" with write permission)
						set eof artwork_image to 512
						write artwork_data to artwork_image starting at 513
						close access artwork_image
						set artwork_data to ""
						tell application "Image Events"
							set this_image to open (my_path & "temp_img") as string
							scale this_image to size 110
							set new_item to (my_path & album_name & ".jpg") as string
							save this_image in new_item as JPEG
							close this_image
						end tell
					end if
				end if
			end tell
		end try
	end repeat
end tell

on removeChars(this_text)
	set the illegalChars to "\"\\:?/"
	set the character_list to {}
	repeat with this_char in this_text
		set this_char to the contents of this_char
		if this_char is in the illegalChars then
			set the end of the character_list to ""
		else
			set the end of the character_list to this_char
		end if
	end repeat
	return (the character_list) as string
end removeChars

on fileExists(the_file)
	tell application "Finder"
		if file (my_path & the_file & ".jpg") exists then
			return "true"
		else
			return "false"
		end if
	end tell
end fileExists

Anyone?

temp_img was already open, but without an error handler I missed it! :lol:

Sorry, guys.

Glad you solved it.
I was actually playing with it off and on over the last couple of days and just finished it.
So I will post it any way so the time spent will not be a complete wast. :rolleyes:

I think it may process a bit faster than yours. Let me know what you think…
thanks :wink:

property my_path : (path to sites folder) & "iTunesDS:images:albums:" as string
property last_album : ""

tell application "iTunes"
	set the_albums to album of tracks of library playlist 1
	repeat with i from 1 to number of items in the_albums
		set album_name to item i of the_albums as string
		if album_name is not last_album then
			set last_album to album_name
			set the_track to (track 1 whose album is album_name) of library playlist 1
			tell application "Finder"
				set my_x_path to alias my_path
				set album_name to my removeChars(album_name)
				set the_file to (album_name & ".jpg") as string
				if not (exists file the_file of my_x_path) then
					my _make(the_track, album_name)
				end if
			end tell
		end if
	end repeat
end tell

on _make(the_track, album_name)
	try
		tell application "iTunes"
			set artwork_data to data of artwork 1 of the_track
			set artwork_image to (open for access my_path & "temp_img" with write permission)
			set eof artwork_image to 512
			write artwork_data to artwork_image starting at 513
			close access artwork_image
			set artwork_data to ""
			tell application "Image Events"
				set this_image to open (my_path & "temp_img") as string
				scale this_image to size 110
				set new_item to (my_path & (album_name) & ".jpg") as string
				save this_image in new_item as JPEG
				close this_image
			end tell
		end tell
	end try
end _make
on removeChars(this_text)
	set the illegalChars to "\"\\:?/"
	set the character_list to {}
	repeat with this_char in this_text
		set this_char to the contents of this_char
		if this_char is in the illegalChars then
			set the end of the character_list to ""
		else
			set the end of the character_list to this_char
		end if
	end repeat
	return (the character_list) as string
end removeChars


PS.
I Just noticed you changed the ( on removeChars(this_text) )
and have changed it here to the new one


Reason for edit… Too much Tequila last night.

Wow. That’s tons faster. Thanks a lot. :slight_smile:

In case anyone’s interested, here’s the final app version.

global my_path, num_tracks, last_album

property my_path : (path to sites folder) & "iTunesDSr:images:albums:" as string
property num_tracks : 0
property last_album : ""

on run
	tell application "Finder"
		if exists {((path to preferences folder) as text), "iTunesDSr.plist"} then
			set my_alert to "I see you haven't run iTunesDSr Artwork before." & return & "This will probably take a while. So relax. I'll let you know when I'm done. =)"
			do shell script "defaults write iTunesDSr hasRun 'true'"
		else
			set my_alert to "iTunesDSr Artwork will now export album art added since the last time you ran it."
		end if
	end tell
	tell application "iTunes"
		if the button returned of (display alert my_alert buttons {"Cancel", "Proceed"}) is "Proceed" then
			set the_albums to album of tracks of library playlist 1
			repeat with i from 1 to number of items in the_albums
				set album_name to item i of the_albums as string
				if album_name is not last_album then
					set last_album to album_name
					set the_track to (track 1 whose album is album_name) of library playlist 1
					tell application "Finder"
						set my_x_path to alias my_path
						set album_name to my removeChars(album_name)
						set the_file to (album_name & ".jpg") as string
						if not (exists file the_file of my_x_path) then
							my _make(the_track, album_name)
						end if
					end tell
				end if
			end repeat
			beep
			display alert "iTunesDSr Artwork finished!" & return & return & num_tracks & " album artworks exported." buttons {"Ok"} default button 1
		end if
	end tell
end run

on removeChars(this_text)
	set the illegalChars to "\"'\\:?/"
	set the character_list to {}
	repeat with this_char in this_text
		set this_char to the contents of this_char
		if this_char is in the illegalChars then
			set the end of the character_list to ""
		else
			set the end of the character_list to this_char
		end if
	end repeat
	return (the character_list) as string
end removeChars
on _make(the_track, album_name)
	try
		tell application "iTunes"
			set artwork_data to data of artwork 1 of the_track
			if artwork_data is not "" then
				set artwork_image to (open for access my_path & "temp_img" with write permission)
				set eof artwork_image to 512
				write artwork_data to artwork_image starting at 513
				close access artwork_image
				set artwork_data to ""
				tell application "Image Events"
					set this_image to open (my_path & "temp_img") as string
					scale this_image to size 110
					set new_item to (my_path & (album_name) & ".jpg") as string
					save this_image in new_item as JPEG
					close this_image
				end tell
				set num_tracks to num_tracks + 1
			end if
		end tell
	end try
end _make

And, if anyone’s interested in the whole package, it’s at The Opera Blog - News | Opera

Oops! Forgot to add the processed items alert increment.