Now Playing RSS

hey guys
its been a while since i wrote in apple script, but what i want to do is write an apple script that will run everytime a song is done playing in itunes, and it will then write the now playing song to an rss file. I know how to harvest the variables, just not how to write to an rss file. i would write to an XML file if it would be easier.

Thnx

LordFransie

Hi my lord :wink:

Here is an example to create an RSS (XML) file. Have fun

property LF : ASCII character 10
property xml_item : "<item>"
property xml_noitem : "</item>"
property xml_title : "<title>"
property xml_notitle : "</title>"
property xml_link : "<link>"
property xml_nolink : "</link>"
property xml_description : "<description>"
property xml_nodescription : "</description>"
property xml_nochannel : "</channel>"

property theName : "LordFransie.com"
property theTitle : "LordFransie's RSS feed"
property theDescription : "Watch my played songs in iTunes"

property title1 : "myFirstTitle"
property link1 : "myFirstLink.com"
property description1 : "myFirstDescription"
property title2 : "mySecondTitle"
property link2 : "mySecondLink.com"
property description2 : "mySecondDescription"

-- creates the header
set XMLtext to {"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>", "<rss version=\"2.0\">", indent(2) & "<channel>"}
set end of XMLtext to indent(4) & xml_title & theTitle & xml_notitle
set end of XMLtext to indent(4) & xml_link & theName & xml_nolink
set end of XMLtext to indent(4) & xml_description & theDescription & xml_nodescription
-- optional lines
set end of XMLtext to indent(4) & "<copyright>Copyright 2007, LordFransie.com</copyright>"
set end of XMLtext to indent(4) & "<webMaster>webmaster@LordFransie.com</webMaster>"

-- adds new items
set XMLtext to add_new_item(XMLtext, title1, link1, description1)
set XMLtext to add_new_item(XMLtext, title2, link2, description2)

-- completes the file
set end of XMLtext to (indent(2) & xml_nochannel)
set end of XMLtext to "</rss>"

-- coerces the list to a string
set {TID, text item delimiters} to {text item delimiters, LF}
set XMLtext to XMLtext as string
set text item delimiters to TID

-- writes file to disk
write_to_disk from XMLtext into ((path to desktop as Unicode text) & "rss_test.xml")

-- Subroutines

on add_new_item(t, ti, li, de)
	set end of t to indent(4) & xml_item
	set end of t to indent(6) & xml_title & ti & xml_notitle
	set end of t to indent(6) & xml_link & li & xml_nolink
	set end of t to indent(6) & xml_description & de & xml_nodescription
	set end of t to indent(4) & xml_noitem
	return t
end add_new_item

on indent(x)
	set s to space
	repeat x - 1 times
		set s to s & space
	end repeat
	return s
end indent

on write_to_disk from |data| into target
	set ff to open for access file target with write permission
	write |data| to ff as «class utf8»
	close access ff
end write_to_disk

An xml file is much easier to write. Since your request gave me an idea about a script I could use I wrote one. See if it does what you need.

Note 1: plist files are essentially xml files in MacOSX, so I used the “defaults write” command to create a plist file (i.e. the xml file). In Tiger plist files are in binary format, which means you can’t read them with a normal text editor. As such I added the line "do shell script “plutil -convert xml1 " & posix_xml_path & “.plist”” in the code which converts it from a binary xml file to a text xml file. If you do not need a text xml file then remove that line from the code.

Note 2: I noticed that song names with parenthesis in the name won’t write properly to the xml file, so beware of that.

Note 3: ignore my note #1 above. As StefanK pointed out in the below post I was wrong, plist files are NOT essentially xml files in OSX!

-- this will check iTunes for the currently playing song and write an xml file with the song name and artist information
-- save this code as a "stay open" application, not as a script!
-- iTunes is checked every so many seconds for the song information which is set with the variable "song_check_delay"
-- the xml file is saved to the location set with the variables "xml_folder" and "xml_fileName"


-- variables to change
property xml_folder : (path to desktop) as string
property xml_fileName : "currentSongInfo"
property song_check_delay : 5

property posix_xml_path : POSIX path of xml_folder & xml_fileName
property checkName : ""

on idle
	tell application "System Events" to if not (exists process "iTunes") then return song_check_delay
	try
		tell application "iTunes"
			set current_track_name to name of current track
			set current_track_artist to artist of current track
		end tell
		
		if checkName is "" or checkName is not current_track_name then
			set checkName to current_track_name
			do shell script "defaults write " & quoted form of posix_xml_path & " currentName " & quoted form of current_track_name
			do shell script "defaults write " & quoted form of posix_xml_path & " currentArtist " & quoted form of current_track_artist
			do shell script "plutil -convert xml1 " & posix_xml_path & ".plist"
		end if
	end try
	return song_check_delay
end idle

You can read the xml file with this script or any other way you want

-- you can read your xml file with this script

-- variables to change
set xml_folder to (path to desktop) as string
set xml_fileName to "currentSongInfo"

set posix_xml_path to POSIX path of (xml_folder & xml_fileName)
set songName to do shell script "defaults read " & quoted form of posix_xml_path & " currentName"
set songArtist to do shell script "defaults read " & quoted form of posix_xml_path & " currentArtist"
set frontApp to displayed name of (info for (path to frontmost application))
tell application frontApp to display dialog "The currently playing song is " & return & return & songName & " by " & songArtist buttons {"OK"} default button 1 giving up after 5

Hi regulus,

unfortunately XML is not XML.
have you tried to read the created file with a RSS reader ? :wink:

Hi StefanK! Are you kidding? I didn’t realize that. I only read rss with Safari so I haven’t tried to read it with anything other than applescript and the “defaults read” command. Is it because of the file name extension or is it because of all the “plist” wording in the header of the file… I suspect the second thing.

Anyway, lucky for me it works for my purposes! :smiley:

There are certain specifications to create a RSS file e.g. here

Emphasis added…

Well guys i know have the framework for the program i was aiming for(see below)


property LF : ASCII character 10
property xml_item : "<item>"
property xml_noitem : "</item>"
property xml_song : "<song>"
property xml_nosong : "</song>"
property xml_artist : "<artist>"
property xml_noartist : "</artist>"
property xml_album : "<album>"
property xml_noalbum : "</album>"
property xml_nochannel : "</channel>"

--property theName : "LordFransie.com"
--property theTitle : "LordFransie's RSS feed"
--property thealbum : "Watch my played songs in iTunes"

property title1 : "jo"
property artist1 : "jo"
property album1 : "das"
property title2 : "ffdsa"
property artist2 : "fd"
property album2 : "dsd"
property song1 : ""
property song2 : ""
--ideally this would be user inputed
property directory : (path to desktop as Unicode text)
property filename : "rss_test.xml"

--gathers the new variables

tell application "iTunes"
	copy name of current track to title1
	copy album of current track to album1
	copy artist of current track to artist1
	
end tell
--ideally this would be used to have a song1 and song2  song1 being the now playing and song2 the previous.  and even more idealy the user could set how many songs they wanted to go back and a for loop would then finish it up.
--sets the previous songs
--tell application "System Events"
--	set x to (directory & filename)
--	if file x exists then
--		set song1 to value of XML element 1 of third XML element of first XML element of first XML element of XML file x
--		if title1 is equal to value of XML element 1 of third XML element of first XML element of first XML element of XML file x then

--			set title2 to value of XML element 1 of third XML element of first XML element of first XML element of XML file x
--			set artist2 to value of XML element 2 of third XML element of first XML element of first XML element of XML file x
--			set album2 to value of XML element 3 of third XML element of first XML element of first XML element of XML file x
--		end if
--	else


--	end if
--end tell

--fixes a possible null

if title1 is "" then set title1 to "Unknown Song"
if album1 is "" then set album1 to "Unknown Album"
if artist1 is "" then set artist1 to "Unknown Artist"
if title2 is "" then set title2 to "Unknown Song"
if album2 is "" then set album2 to "Unknown Album"
if artist2 is "" then set artist2 to "Unknown Artist"
-- creates the header
set XMLtext to {"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>", "<rss version=\"2.0\">"}
--set end of XMLtext to indent(4) & xml_song & theTitle & xml_nosong
--set end of XMLtext to indent(4) & xml_artist & theName & xml_noartist
--set end of XMLtext to indent(4) & xml_album & thealbum & xml_noalbum
-- optional lines
--set end of XMLtext to indent(4) & "<copyright>Copyright 2007, LordFransie.com</copyright>"
--set end of XMLtext to indent(4) & "<webMaster>webmaster@LordFransie.com</webMaster>"

-- adds new items
set XMLtext to add_new_item(XMLtext, title1, artist1, album1)
--set XMLtext to add_new_item(XMLtext, title2, artist2, album2)

-- completes the file
--set end of XMLtext to (indent(2) & xml_nochannel)
set end of XMLtext to "</rss>"

-- coerces the list to a string
set {TID, text item delimiters} to {text item delimiters, LF}
set XMLtext to XMLtext as string
set text item delimiters to TID

-- writes file to disk

write_to_disk from XMLtext into (directory & filename)
-- Subroutines

on add_new_item(t, ti, li, de)
	--	set end of t to indent(4) & xml_item
	set end of t to indent(2) & xml_song & ti & xml_nosong
	set end of t to indent(2) & xml_artist & li & xml_noartist
	set end of t to indent(2) & xml_album & de & xml_noalbum
	--	set end of t to indent(4) & xml_noitem
	return t
end add_new_item

on indent(x)
	set s to space
	repeat x - 1 times
		set s to s & space
	end repeat
	return s
end indent
--i would love to get this to be able to write to an ftp server of w/e
on write_to_disk from |data| into target
	set ff to open for access file target with write permission
	write |data| to ff as «class utf8»
	close access ff
end write_to_disk

thank you guys so much, i’m sorry about the butchering of code.

Hi,

with this routine you can do this

property ftpserverPath : "[url=ftp://ftp.mydomain.com/path/]ftp.mydomain.com/path/[/url]"
property user_name : "user"
property pass_word : "¢¢¢¢"

curl_upload("Hello World", "curltest.txt")
if result is false then display dialog "Couldn't upload file"

on curl_upload(theData, fName)
	try
		set tempFile to ((path to temporary items as Unicode text) & "curl_tempfile.txt")
		set ff to open for access file tempFile with write permission
		write theData to ff as «class utf8»
		close access ff
		if ftpserverPath does not end with "/" then set ftpserverPath to ftpserverPath & "/"
		do shell script "curl " & quoted form of (ftpserverPath & fName) & " -u " & user_name & ":" & pass_word & " -T " & quoted form of POSIX path of tempFile
		do shell script "rm " & quoted form of POSIX path of tempFile
		return true
	on error
		try
			close file tempFile
			do shell script "rm " & quoted form of POSIX path of tempFile
		end try
		return false
	end try
end curl_upload