Note that this Wiki is a work in progress, items may not be updated or may disappear entirely as the pages are updated.
Select Oldest Song Played PAL
From SpacialAudio
I developed this PAL when I discovered that I had tracks that had not been played for 8 months. It simply finds the oldest played track, checks the queue and SAM's Artist/Album Repeat rules and then queues it up. It does not look at categories or anything else. If you need that type of ability, put your coding hat on.
I've been using it for the last 4 months and it has now reduced my oldest non played song to 3 months old. It has a variable chance to run at the top of each hour more than once. Let me know if you experience any problems with it. My thanks to FesterHead for publicly sharing his PAL's because his PAL's helped me solve a few issues I had.
You may download the script here. http://spacialnet.com/knowledge/attachment.php?attId=150 (see below) Also available here: http://fm5280.com/nuke/modules.php?name=Forums&file=viewtopic&t=296
Please note using the selection method of "Least recently Played" in your clockwheel rotation will give you the same results with error checking.
{ Created by DJ Cassio - FM5280.COM 10/31/05 - PLEASE LEAVE THIS COMMENT INTACT
This PAL selects the OLDEST played song in the database. It follows SAM's
Artist/Album repeat rules. I don't want it to run ALL the time, so it randomly waits at the top
of each hour. It does not run on Tuesdays during Twofers but that is configurable. This PAL is not
intended to be your sole selection PAL, it is designed to augment your normal clockwheel
What's configurable?
- Toggle for FesterHeads Twofer for Tuesday }
///////////////////////////////////////////////////////////////
// Configure these
// Set this to false if you do not use FesterHeads Twofers Script
var twofers : Boolean = true;
// If you use Twofers What is the ID you use, if not ignore this set previous to false
var twofersID : Integer = 1;
// Fail Safe Count this is the maximum number of selections it will try before giving up and waiting for the next try. Don't set this to high or SAM may lock up.
var failSafe : Integer = 50;
// Do Not edit below this line unless you know what you are doing
///////////////////////////////////////////////////////////////
// Let's keep it running continously
PAL.Loop := True;
// Set the global variables used in the script
var D, D1, D2 : TDataSet;
var QFlag : Boolean = false;
var CFlag : Boolean = false;
var randomInteger : Integer = 0;
var count : Integer = 0;
// SAM's Playlist Rotation Rules for Artist & Album only
var artisthourRestriction : Float = Round(Int(PlaylistRules.MinArtistTime / 60));
var artistminRestriction : Float = Round(PlaylistRules.MinArtistTime - (artisthourRestriction * 60));
var albumhourRestriction : Float = Round(Int(PlaylistRules.MinAlbumTime / 60));
var albumminRestriction : Float = Round(PlaylistRules.MinAlbumTime - (albumhourRestriction * 60));
// This PAL has a 70/30 chance of runnning again
Randomize;
randomInteger := RandomInt(100) + 1;
if (randomInteger <= 30) then
begin
{Wait for next hour}
PAL.WaitForTime('XX:30:00');
end;
// The PAL waits for the next day if Twofers PAL is running if configured above is true.
if (twofers) then
begin
D := Query('SELECT * from currentshow', [], True);
if (D['id'] = twofersID) then
begin
D.Free;
PAL.WaitForTime(T['00:15:00']+1); // I give it 15 minutes to get normal rotation started
end;
end;
D.free;
// Let's make it execute as fast as possible
Pal.LockExecution;
WriteLn('Choosing Oldest played song...');
// Let's grab the oldest songs sorted by date played
D := Query('SELECT ID, filename, album, artist FROM songlist where songtype = ''S'' ORDER by date_played LIMIT :=failsafe',[failSafe], True);
D.First;
// We need to make sure the song selected is not already in the queue
While ((not QFlag) AND (count < failSafe)) Do
begin
WriteLn('Chosen Song: ' + D['filename']);
D1 := Query('SELECT songID from queuelist WHERE songID = :songID', [D['ID']], True);
if D1.IsEmpty then
begin
CFlag := true;
WriteLn('selected song is not in queue...checking history for artist next');
end
else
begin
CFlag := false;
count := (count + 1);
WriteLn('selected song is in the queue...selecting next song');
end;
// Done with queue checking moving on to history checking
// Check for artist rule - Has this artist played within SAM's No Repeat Rule?
if CFlag then
begin
D1 := Query('SELECT date_played, artist from historylist WHERE artist = :artist AND date_played > ' + QuotedStr(FormatDateTime('yyyy-mm-dd hh:mm:ss', T['-'+FloatToStr(artisthourRestriction)+':'+FloatToStr(artistminRestriction)+':00'])) + ' ' +
'AND songtype = ''S''', [D['artist']], True);
if D1.IsEmpty then
begin
CFlag := true;
WriteLn('selected artist not in history...checking history for album next');
end
else
begin
CFlag := false;
count := (count + 1);
WriteLn('selected artist is in history...selecting next song');
end;
end;
// Check for album rule - Has this album played within SAM's No Repeat Rule?
if CFlag then
begin
D1.Free;
D1 := Query('SELECT date_played, album from historylist WHERE album = :album AND date_played > ' + QuotedStr(FormatDateTime('yyyy-mm-dd hh:mm:ss', T['-'+FloatToStr(albumhourRestriction)+':'+FloatToStr(albumminRestriction)+':00'])) + ' ' +
'AND songtype = ''S''', [D['artist']], True);
if D1.IsEmpty then
begin
CFlag := true;
WriteLn('selected album not in history...checking queue next');
end
else
begin
CFlag := false;
count := (count + 1);
WriteLn('selected album is in history...selecting next song');
end;
end;
// Query the queue list to check for artist & album
if CFLag then
begin
D2 := Query('Select queuelist.songID, songlist.artist, songlist.album, songlist.ID from queuelist, songlist where songtype = ''S'' and queuelist.songID = songlist.ID', [], True);
D2.First;
while ((CFLAG) AND (not D2.EOF)) Do
begin
If (D2['album'] = D['album']) or (D2['artist'] = D['artist']) then
begin
CFlag := false;
count := (count + 1);
WriteLn('the selected album or artist is already in the queue...selecting next song');
end;
D2.Next;
end;
if CFlag then
WriteLn('the selected album or artist is not in queue...');
end;
// Query the requeslist list to check for artist & album
if CFLag then
begin
D2.Free;
D2 := Query('Select requestlist.songID, songlist.artist, songlist.album, songlist.ID from requestlist, songlist where (requestlist.status=''new'' or requestlist.status=''pending'') and songlist.songtype = ''S'' and requestlist.songID = songlist.ID', [], True);
D2.First;
while ((CFLAG) AND (not D2.EOF)) Do
begin
If (D2['album'] = D['album']) or (D2['artist'] = D['artist']) then
begin
CFlag := false;
count := (count + 1);
WriteLn('the selected album or artist is in the request queue...selecting next song');
end;
D2.Next;
end;
if CFlag then
WriteLn('the selected album or artist is not in the request queue...');
end;
if CFlag then
begin
QFlag := true;
end
else
begin
WriteLn('Count: ' + IntToStr(count));
D.Next;
end;
end;
if (count < failSafe) then
begin
// Check if file actually exists and queue up selected song
if FileExists(D['filename']) then
begin
Queue.AddFile(D['filename'],ipBottom);
WriteLn('Adding: ' + D['filename'] + ' to queue.')
end
else
WriteLn('file does not exist not Adding: ' + D['filename'] + ' to queue.');
end
else
WriteLn('Could not find a selection in ' + intToStr(failsafe) + ' attempts...no song added');
// Free up data structures and release the PAL
D.Free;
D1.Free;
D2.Free;
PAL.UnlockExecution;
PAL.WaitForTime('+00:00:30');
