Optimizing A Script

Hello,

“amjbrown” over at the iPodlounge forums came up with a couple applescript to set the last played date on iTunes for iPod Shuffle users. The first script is used before the iPod is connected and the second after its been connected. The first script seems to be very fast, but the second is terribly slow.

Is there any way of optimizing either/both of these scripts to run faster?

Script 1…

property ShuffleTrax : “Shuffle Up”

tell application “iTunes”
set myPlaylist to playlist ShuffleTrax
set theFile to open for access file “Shuffle Playlist” with write permission
set eof theFile to 0
repeat with aTrack in (get every track of myPlaylist)
set dbID to database ID of aTrack
set pc to get played count of aTrack
set nm to get name of aTrack as string
write {dbID, pc, nm} to theFile as list
end repeat

close access theFile

end tell

Script 2 (the really slow one)

set theFile to open for access file “Shuffle Playlist” with write permission
set cd to (get current date)
try
repeat
set theData to read theFile as list
set dbID to item 1 of theData
set pc to item 2 of theData
set nm to item 3 of theData
tell application “iTunes”
set thetrack to some track of playlist 1 whose database ID is dbID
set theArtist to the artist of thetrack
set thePlayCount to the played count of thetrack
if thePlayCount is greater than pc then
set played date of thetrack to cd
end if
end tell
end repeat
on error
close access theFile
end try

Thanks.

Benp

I don’t use iTunes enough to have many items in the playlists, so I can’t test the speed of the following versions of your scripts. But they look as though they should be at least a little faster, as they only make one disk access each. They also don’t bother to access data that aren’t used.

-- Script 1:
property ShuffleTrax : "Library"

set fileData to {}
tell application "iTunes"
  set myPlaylist to playlist ShuffleTrax
  repeat with aTrack in (get every track of myPlaylist)
    set end of my fileData to aTrack's {database ID, played count}
  end repeat
end tell

set theFile to open for access file "Shuffle Playlist" with write permission -- creates file at top level of startup disk
try
  set eof theFile to 0
  write fileData to theFile as list
end try
close access theFile


-- Script 2:
set cd to (current date)
try
  set fileData to (read file ((path to startup disk as Unicode text) & "Shuffle Playlist") from 1 as list)
  repeat with theData in fileData
    set {dbID, pc} to theData
    tell application "iTunes"
      tell (first track of playlist 1 whose database ID is dbID and played count > pc)
        if it exists then set played date to cd
      end tell
    end tell
  end repeat
end try

The only fly in the ointment, as far as I can see, is that in my version of iTunes, ‘played date’ is a read-only property — which makes the whole exercise rather a waste of time. :wink:

Nigel,

Thanks for the reply. The second script still takes (on a 867mhz G4 PB, 10.3.8 OSX, 4.7.1 iTunes) around 3-4 mins. to process a playlist of 120 songs. It doesn’t seem that it should take that long at all. Any other thoughts on a better way of analyzing the play count of iTunes tracks and updating Last Played dates. Thanks.

Ben p.

I think there is a bug in Nigel’s script, which may be causing the slow-down:

tell (first track of playlist 1...

Instead of:

tell (first track of playlist ShuffleTrax...

So, if your “ShuffleTrax” library contains 120 songs, but your library contains 8200, Nigel’s script 2 will be processing “playlist 1”, which uses to be the main library.
Here is a bit more optimized version of Nigel’s version which drops around 30 s. for a 371-songs-playlist (not sure, though, if this works or does something at all!):

property ShuffleTrax : "Música de los 60"

tell application "iTunes" to ¬
	set fileData to {database ID, played count} of tracks of playlist ShuffleTrax

set theFile to open for access file "Shuffle Playlist" with write permission -- creates file at top level of startup disk 
try
	set eof theFile to 0
	write fileData to theFile as list
end try
close access theFile

-- Script 2: 
property fileData : {}
set cd to (current date)
try
	set my fileData to (read file ((path to startup disk as Unicode text) & "Shuffle Playlist") from 1 as list)
	repeat with i from 1 to count my fileData's item 1
		tell application "iTunes"
			tell (first track of playlist ShuffleTrax whose database ID is my fileData's item 1's item i and played count > my fileData's item 2's item i)
				if it exists then set played date to cd
			end tell
		end tell
	end repeat
end try

No, Nigel’s “bug” was not the slow-down, since it is iterating only the proper number of times. I think iTunes is specially slow accepting/sending apple-events. Anyway, here is an improved version of the last one:

property ShuffleTrax : "Música de los 60"

tell application "iTunes" to ¬
	set fileData to {database ID, played count} of tracks of playlist ShuffleTrax

set theFile to open for access file "Shuffle Playlist" with write permission -- creates file at top level of startup disk 
try
	set eof theFile to 0
	write fileData to theFile as list
end try
close access theFile

-- Script 2: 
property fileData : {}
set cd to (current date)
try
	set my fileData to (read file ((path to startup disk as Unicode text) & "Shuffle Playlist") from 1 as list)
	
	repeat with i from 1 to count my fileData's item 1
		tell application "iTunes" to ¬
			tell (first track of playlist ShuffleTrax whose database ID is (my fileData's item 1's item i)) to ¬
				if its played count > (my fileData's item 2's item i) then set its played date to cd
	end repeat
end try

It’s now 7.8 sec.

thanks. Ill give it a try when I get off work and let the community know my results.

jj,

I have tried both of the scripts and something doesn’t seem to work. I can’t point to the problem but it seems to be the second script. The only item I altered was "property ShuffleTrax : “Shuffle Up”.

Is there something I’m missing.

benp

Yes. Most probably we should include also the property “ShuffleTrax” in the second script:
Script 2

property ShuffleTrax : "Shuffle Up"
property fileData : {}
set cd to (current date)
try
	set my fileData to (read file ((path to startup disk as Unicode text) & "Shuffle Playlist") from 1 as list)
	repeat with i from 1 to count my fileData's item 1
		tell application "iTunes" to ¬
			tell (first track of playlist ShuffleTrax whose database ID is (my fileData's item 1's item i)) to ¬
				if its played count > (my fileData's item 2's item i) then set its played date to cd
	end repeat
end try

It’s now 18.5 seconds for a 400-songs-playlist, and 1.4 for a 100-songs-playlist (?)

Works perfect. Thanks so much.

ben p