Hi there,
I wrote a simple AppleScript that gets a random line from a song playing in iTunes, then outputs that line as well as the next four. I linked it up to Adium through use of AdiumScripts, but it memory leaks like nobody's business, and completely unpredictably. Sometimes I can go a whole day with ~4MB usage (good!), sometimes it takes all of five seconds to use two to three GIGABYTES of RAM.
Should be noted that I just modified someone elses code; which, as it explicitly says, they were fine with.
Any advice?
I wrote a simple AppleScript that gets a random line from a song playing in iTunes, then outputs that line as well as the next four. I linked it up to Adium through use of AdiumScripts, but it memory leaks like nobody's business, and completely unpredictably. Sometimes I can go a whole day with ~4MB usage (good!), sometimes it takes all of five seconds to use two to three GIGABYTES of RAM.
Should be noted that I just modified someone elses code; which, as it explicitly says, they were fine with.
Any advice?
Code:
-- **** by quis
-- **** www.quis.cc
-- **** this is a script for use with adium
-- **** version 1.0
-- **** do whatever you want with this code
-- **** see
-- **** http://adiumxtras.com/index.php?a=xtras&xtra_id=2187
-- **** for more
substitute()
on substitute()
--You can configure the variables below without changing the logic of the script.
--If iTunes is either paused or closed, this is displayed:
set quiet to "Silence."
--If you'd like a suffix to be displayed (for example, an ellipsis), set it below:
set suffix to ""
--If you want a comma, if present, at the end of the lyric line itself to be removed, keep this true.
--Otherwise, set it to false.
--As an example of what this does: if the lyric chosen is "The lookout has parked the car," (from Kate Bush's song "There Goes a Tenner"), the resulting lyric displayed becomes "The lookout has parked the car" and whatever suffix you've specified, if you've done so. Note that if your suffix itself is a comma, it will be removed if this option is set to true.
--Remember that you can override what's displayed for any song (for example, if it's instrumental and thus has no lyrics) by adding "display lyric as ", followed by whatever you want to display, to the end of the song's comment.
--For example, if you wanted a certain classical track to display as "Interlude while I run and get something", append "display lyric as Interlude while I run and get something" to that track's comment.
set removeendcomma to true
--If there are no lyrics for a song, what do you want to be displayed? Set it below:
set returnifnolyric to "No Lyrics"
--Changing things below this may change the logic of the script.
--check if iTunes is running...
tell application "System Events"
set iTunes to ((application processes whose (name is equal to "iTunes")) count)
end tell
if iTunes is greater than 0 then
tell application "iTunes"
--...and playing
if player state is playing then
--grab handler for current track
set song to current track
--are there lyrics in the comment section?
if comment of song contains "display lyric as " then
--return comment of song
set _chars to characters of ((get comment of song) & "") as list
set todisplay to ""
repeat with i from ((offset of "display lyric as " in (get comment of song)) + 17) to (length of _chars)
set todisplay to todisplay & (get item i of _chars)
end repeat
return todisplay
end if
--do lyrics exist?
if lyrics of song is equal to "" then
return returnifnolyric
end if
--if neither, fetch current lyrics
set final to ""
set tuid to database ID of song
--get tuid of song that was playing last time this script ran
set oldtuid to do shell script "/bin/cat ~/Library/Application\\ Support/Adium\\ 2.0/Scripts/ParaLyrical.AdiumScripts/Contents/Resources/cache.dat"
--pass track unique identifier to cache file
if tuid as integer is not equal to oldtuid as integer then
-- repeat until (final is not "")
--get lyrics
set lyric to lyrics of song
--count lines
set paracount to count paragraphs of lyric
--set paracount to paracount - 5
set boolvalid to false
repeat until boolvalid is true
--choose a random line
set randomnumber to random number from 1 to paracount as integer
set randomnumber2 to randomnumber + 1 as integer
set randomnumber3 to randomnumber + 2 as integer
set randomnumber4 to randomnumber + 3 as integer
set randomnumber5 to randomnumber + 4 as integer
if randomnumber5 is greater than paracount then
set boolvalid to false
else
set boolvalid to true
end if
end repeat
--ORIGINAL CODE
set randomline to paragraph randomnumber of lyric
set randomline2 to paragraph randomnumber2 of lyric
set randomline3 to paragraph randomnumber3 of lyric
set randomline4 to paragraph randomnumber4 of lyric
set randomline5 to paragraph randomnumber5 of lyric
--work some array + for loop magic here?
(*
set randompara to paragraph randomnumber of lyric & paragraph randomnumber2 of lyric & paragraph randomnumber3 of lyric & paragraph randomnumber4 of lyric & paragraph randomnumber5 of lyric as list
repeat with i from 1 to ((length of randompara) + 5)
if (length of item i of randompara) is equal to 0 then
set item i of randompara to item (i + 1)
set item (i + 1) of randompara to item (i + 2)
set item (i + 2) of randompara to item (i + 3)
set item (i + 3) of randompara to item (i + 4)
set item (i + 4) of randompara to item (i + 5)
set item (i + 5) of randompara to item (i + 6)
end if
end repeat
*)
--see if you can fix this to have no blank lines!
set lyriclength to count characters of (randomline & randomline2 & randomline3 & randomline4 & randomline5)
set lyric to randomline & return & randomline2 & return & randomline3 & return & randomline4 & return & randomline5 & suffix
--set lyric to randompara
set _chars to characters of lyric as list
repeat with i from 1 to (length of _chars)
if (get item i of _chars) is "'" then
set item i of _chars to "\\'"
end if
end repeat
if removeendcomma is true and ((get item (length of _chars) of _chars) is ",") then
set item (length of _chars) of _chars to ""
end if
-- end repeat
--store lyric to linecache.dat
do shell script "/bin/echo " & tuid & " > ~/Library/Application\\ Support/Adium\\ 2.0/Scripts/ParaLyrical.AdiumScripts/Contents/Resources/cache.dat"
do shell script "/bin/echo " & (items of _chars as string) & " > ~/Library/Application\\ Support/Adium\\ 2.0/Scripts/ParaLyrical.AdiumScripts/Contents/Resources/linecache.dat"
--send it over to adium
final is equal to items of _chars as string
return final
else if tuid as integer is equal to oldtuid as integer then
--get current song lyric from linecache.dat
set existingLyric to do shell script "/bin/cat ~/Library/Application\\ Support/Adium\\ 2.0/Scripts/ParaLyrical.AdiumScripts/Contents/Resources/linecache.dat"
set _chars to characters of existingLyric as list
--if removeendcomma is true and ((get item (length of _chars) of _chars) is ",") then
-- set item (length of _chars) of _chars to ""
--end if
return items of _chars as string
end if
else
return quiet
end if
end tell
else
return quiet
end if
end substitute