Script to save iTunes lyrics as text files - help please!

Hi, I’ve been to the excellent Doug’s Scripts for iTunes (http://dougscripts.com/itunes/) site to get a script to extract the lyrics from my library and paste in a text file.

That bit works absolutely fine (cos it’s not the bit I wrote!). However, what I’d like to do is automate the saving of each of these text files, using the name in the header of the document. This bit I can’t get to work. It saves the first one only, but doesn’t loop. It’s probably something really silly I’ve omitted, but looking at various sites, I can’t see what it is!

This is the script:

tell application "iTunes"
if player state is playing then
set sel to current track as list
else if selection is not {} then
set sel to selection
end if

repeat with this_track in sel
set the_lyrics to this_track's lyrics
set {art, nom} to {this_track's artist, this_track's name}
if the_lyrics is not "" then
tell application "TextEdit"
activate
make new document at front with properties {text:the_lyrics}
set name of front window to (art & " - " & nom)
set documentName to {art & " - " & nom}
end tell
else
beep
end if
end repeat
end tell

tell application "Finder"
set theDocumentPath to ("/users/myname/documents/music/lyrics/" as text) & (documentName as text) & ".txt" as text
if item (theDocumentPath) exists then -- check if document already exists, avoid overwriting it!
display alert "Document already exists!"
else
try
tell application "TextEdit" to save document 1 in theDocumentPath
on error
display alert "Cannot save " & theDocumentPath as text
end try
end if
tell application "TextEdit" to activate
end tell

Thanks in advance!

Model: MacBook Pro
AppleScript: 2.0.1
Browser: Firefox 3.0.5
Operating System: Mac OS X (10.5)

Think about what is going on in the repeat loop below.
It loops through all the sel making new documents in
TextEdit. When it is finished going through all the items
it then writes the last one to file.

Try moving the save to file to inside the repeat loop.
And better yet. Search for ‘write to file’ and
experiment with writing directly to files instead
of opening them in TextEdit. You will have no problem
locating a ‘write to file’ handler. Don’t worry if you
do not understand all that it does.

Let us know your progress.

Regards,

Craig

Thanks so much for the pointer! I may have not written it particularly elegantly, but I’ve put the save element in the loop as you suggested and it is now working.

Now that’s done, I will try the ‘write to file’ handler!

Thanks again (and for replying so quickly!)

Your welcome.

In case you did not know it we have a tutorial section here called
Unscripted. Lots of very useful information.

Here is one on File read/write.

I think that it would be more efficient if you just wrote the text file directly in the Finder and bypass using Text Edit.

Hi, I think you’re undoubtedly correct, but I’m unsure how to make the document itself from Finder. Obviously with the TextEdit application, “make new document” works fine, but what is the Finder equivalent?

I have abbreviated things, but the script as below gives a “can’t make class document” error:

tell application "iTunes"
	set sel to selection
	
	repeat with this_track in sel
		set the_lyrics to this_track's lyrics
		set {art, alb, nom} to {this_track's artist, this_track's album, this_track's name}
		if the_lyrics is not "" then
			tell application "Finder"
				make new document at front with properties {text:the_lyrics}
				set name of front window to (art & " - " & alb & " - " & nom)
				set documentName to {art & " - " & alb & " - " & nom}
				set theDocumentPath to ("/users/myname/documents/music/lyrics/" as text) & (documentName as text) & ".txt" as text
				write 1 to theDocumentPath
			end tell
		else
			beep
		end if
	end repeat
end tell

You can use shell script like below or you can use write to file as I suggested earlier.
You will need to read the tutorial to understand how it works and how to implement
it. There are example handlers in that tutorial that you can copy and paste into your
script that require no additional work.

Regards,

Craig


tell application "iTunes"
	set sel to selection
	
	repeat with this_track in sel
		set the_lyrics to this_track's lyrics
		set {art, alb, nom} to {this_track's artist, this_track's album, this_track's name}
		if the_lyrics is not "" then
			set theName to (art & " - " & alb & " - " & nom)
			set theDocumentPath to ((path to music folder) & "lyrics:" & theName & ".txt") as string
			log the_lyrics
			set theCommand to "echo " & quoted form of the_lyrics & " > " & quoted form of POSIX path of theDocumentPath
			do shell script theCommand
		else
			beep
		end if
	end repeat
end tell

Thanks! I will give it a try and also get to grips with the tutorial!

Hi,

try this


set lyricsFolder to ((path to documents folder as text) & "music:lyrics:")
tell application "iTunes" to set sel to selection

repeat with this_track in sel
	tell application "iTunes"
		tell contents of this_track to set {the_lyrics, art, alb, nom} to {lyrics, artist, album, name}
	end tell
	if the_lyrics is not "" then
		set theFile to lyricsFolder & art & " - " & alb & " - " & nom & ".txt"
		try
			set ff to open for access file theFile with write permission
			write the_lyrics to ff
			close access ff
		on error
			try
				close access file theFile
			end try
		end try
	else
		beep
	end if
end repeat

Well if your interested this script attempts to searche an online lyrics database and puts them in a text file.

property choseCurrent : false
on edittext(someText)
	-- Remove anything that is not alphanumeric or a space
	return do shell script "echo " & quoted form of someText & " | /usr/bin/ruby -ne 'print $_.delete(\"^a-z\", \"^A-Z\", \"^0-9\", \"^ \")'"
end edittext

display dialog "Please specify the type of lyric search:" buttons {"Song being played on iTunes", "Specify song"} default button "Song being played on iTunes"
if the button returned of the result is "Song being played on iTunes" then
	set choseCurrent to true
	tell application "iTunes"
		try
			set theSong to the name of the current track as string
			set theArtist to the artist of the current track as string
		on error
			display dialog "There is no song currently playing. Please play a song and restart this application."
			return -128
		end try
		display dialog "Lyrics Snagger will now attempt to fetch the lyrics for " & theSong & " by " & theArtist & "."
		
	end tell
else
	set theSong to the text returned of (display dialog "What is the song called?" default answer "") as string
	
	
	set theArtist to text returned of (display dialog "Who is the artist?" default answer "") as string
end if


set theSong to edittext(theSong)
set theArtist to edittext(theArtist)


set ASTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to {" "}
set theSong to text items of theSong
set theArtist to text items of theArtist

set AppleScript's text item delimiters to {"_"}
set theSong to theSong as Unicode text
set theArtist to theArtist as Unicode text
set AppleScript's text item delimiters to {""}

do shell script "/usr/bin/curl 'http://lyricwiki.org/api.php?func=getSong&artist=" & theArtist & "&song=" & theSong & "&fmt=text'"
set theLyrics to result
set AppleScript's text item delimiters to {return}
set theLyrics to text 1 thru -1 of (theLyrics as Unicode text)
set AppleScript's text item delimiters to ASTID
if choseCurrent is true then
	tell application "iTunes"
		set the lyrics of the current track to theLyrics
	end tell
end if

set user_text to theLyrics
set file_name to (choose file name with prompt "Please type a file name" default name theSong & ".txt")
if file_name as string does not end with ".txt" then set file_name to ((file_name as string) & ".txt")
my make_report(file_name, user_text)

set dMes to return & return & "Would you like to open the  file now?"
set opts to (display dialog "Done!" & dMes buttons {"Yes", "No Thanks"} default button 1 with icon 1 giving up after 30)
if button returned of opts is "Yes" or gave up of opts is true then
	tell application "TextEdit"
		activate
		try
			open (file_name as alias)
		on error errMs
			display dialog errMs buttons {"Cancel"}
		end try
	end tell
end if -- button is "Done"

to make_report(file_name, user_text)
	try
		do shell script "rm " & quoted form of POSIX path of file_name
	end try
	
	try
		set fileRefr to (a reference to (open for access file_name with write permission))
		write user_text to fileRefr
		close access fileRefr
	on error errx number errNum from badObj
		try
			close access fileRefr
		end try
		log errNum
		if (errNum is equal to -48) then
			do shell script "rm " & quoted form of POSIX path of file_name
			my make_report()
		else
			display dialog "There has been an error creating the file:" & return & return & (badObj as string) & errx & return & "error number: " & errNum buttons {"Cancel"}
		end if
	end try
end make_report
on error_and_cancel(ms)
	if gave up of (display dialog ms with icon 2 buttons {"Cancel"} default button 1 giving up after 15) then error number -128
end error_and_cancel