Code: Selecteer alles
{
Don't be a loser. Leave this here.
Top ten requests for all time script by FesterHead (aka Steve Kunitzer)
$Id: top-ten-requests-all-time-v1.PAL,v 1.1 2007/12/01 21:49:12 FesterHead Exp $
What this PAL does:
* Plays top ten requests for all time
What is configurable:
* Toggle debug mode
* Toggle memory leak warning
* Show updating title, description, and resets
* PAL id for automated schedule highlighting
Schedule this PAL with SAMs Event Scheduler (ES):
* Switch to a desktop with the ES visible
OR
Make the ES visible by clicking the 'Window' menu item and selecting 'Event Scheduler'
* Click '+' (Add new scheduled event)
* Enter a name such as 'Top Ten Requests All Time'
* 'Event action' tab:
* Under 'Action' click 'Execute PAL script'
* In the 'PAL Script' section, click the folder icon and navigate to this script
* 'Scheduled times' tab:
* For a one time event:
* Select the 'Execute one' button
* Adjust the date/time
* Click '+ Add'
* Repeat as necessary for extra one time events
* For recurring events:
* Select the 'Execute every' button
* Adjust date/time
* Click '+ Add'
* Save settings by clicking the 'File' menu item and selecting 'Save Configuration'
WARNING!
IF YOU DON'T CONFIGURE THE SCRIPT, DON'T EXPECT IT TO WORK PROPERLY!
I built this PAL for my station using my station configuration
Your results and mileage may vary
I suggest running the PAL in debugOn mode for a couple days to see if it needs tweaking
}
// Make the PAL run fast!
PAL.LockExecution;
{
**************************
* START OF CONFIGURABLES *
**************************
}
{
Run in debug mode?
This will write to the screen without any queue interaction
Useful for testing the script settings
Turns on memory leak warning
}
var debugOn : Boolean = false;
{
Enable memory leak warning?
Automatically enabled if debugOn is true
Stoping then starting a running script will give false memory leak warnings.
To stop/start do one of the following:
1.
a. Add some spaces to the end of a line
b. Save the script
c. Compile the script
d. Run the script
2.
a. Remove the script
b. Add the script
c. Compile the script
d. Run the script
}
var memoryLeakAlwaysOn : Boolean = false;
{
Define automatic show updating values
text1Update gets countdown stuff added to it
}
var text1Update : String = 'Now Playing: Top ten requests countdown';
var text2Update : String = 'Counting down the top ten requests for all time';
var text1Reset : String = 'Now Playing: Regular schedule';
var text2Reset : String = 'Normal rotation and listener requests';
{
Database table name for logging show history
Debug table automatically appended with '_debug'
}
var tableName : String = 'top_ten_requests_all_time';
{
Define the PAL ids for automated schedule page highlighting
Leave this alone if you don't have automated schedule page highlighting
}
var idThisPAL : Integer = 7;
var idResetPAL : Integer = 0;
{
Define ditty file strings
dittyDirectory needs to contain the count down files 10.mp3, 9.mp3, ...
}
var dittyDirectory : String = 'E:\FesterHead\';
var dittyStart : String = 'Top ten requests of all time start.mp3';
var dittyEnd : String = 'Top ten requests of all time end.mp3';
{
Is this cool or what?
var cool : Boolean = true;
}
{
************************
* END OF CONFIGURABLES *
************************
}
// IF YOU EDIT BELOW HERE, MAKE DARN SURE YOU KNOW WHAT'S GOING ON
// Declare data sets
var theTopTenSongs, currentShow : TDataSet;
// Count the actual songs returned. Not guaranteed to actually have ten songs
var theActualCount : Integer = 0;
// Initialize song count for countdown mp3 use and history column updating
var songCount : Integer = 0;
// Initialize for loop counter
var counter : Integer = 0;
// Initialize selections gatherer
var selections : String = '';
// selection pipe
var selectionsPipe : Boolean = false;
// Initialize the counts
var theCounts : Array of Integer = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
// Initialize error checker
var hasErrors : Boolean = false;
// Check for intro ditty
if (not FileExists(dittyDirectory + dittyStart)) then
begin
ErrorDlg('dittyStart does not exist!');
hasErrors := true;
end;
// Check for outro ditty
if (not FileExists(dittyDirectory + dittyEnd)) then
begin
ErrorDlg('dittyEnd does not exist!');
hasErrors := true;
end;
// Check for countdown ditties
for counter := 1 to 10 do
begin
if (not FileExists(dittyDirectory + IntToStr(counter) + '.mp3')) then
begin
ErrorDlg(IntToStr(counter) + '.mp3 does not exist!');
hasErrors := true;
end;
end;
PAL.UnlockExecution;
while (not hasErrors) do
begin
PAL.LockExecution;
WriteLn('Generating top ten requests for all time:');
WriteLn('');
// Turn on memory leak?
if (debugOn or memoryLeakAlwaysOn) then
begin
PAL.MemoryLeakWarning := true;
WriteLn('Memory leak warning is ON');
WriteLn('');
end;
// Add end ditty and increment the count
if (not debugOn) then
begin
Queue.AddFile(dittyDirectory + dittyEnd, ipTop);
end;
theActualCount := theActualCount + 1;
// Build query
theTopTenSongs := Query('SELECT songlist.filename, songlist.artist, songlist.title, songlist.id, count(*) AS cnt ' +
'FROM songlist, requestlist ' +
'WHERE songlist.ID = requestlist.songID ' +
'AND songlist.songtype = ''S'' ' +
'AND (requestlist.status = ''played'' or requestlist.status = ''ignored'') ' +
'GROUP BY songlist.ID ' +
'ORDER BY cnt DESC, requestlist.t_stamp ASC ' +
'LIMIT 10', [], true);
// Move pointer to the first record
theTopTenSongs.First;
// Add to top of queue in reverse order. That is add #1 first, then #2, then ...
// This will play the top song last
while not theTopTenSongs.EOF do
begin
// Add the song to the top of the queue
if (FileExists(theTopTenSongs['filename'])) then
begin
if (not debugOn) then
begin
Queue.AddFile(theTopTenSongs['filename'], ipTop);
end;
theActualCount := theActualCount + 1;
// Increment song count
songCount := songCount + 1;
// Does selections gatherer need a pipe?
if (selectionsPipe) then
begin
selections := selections + '|';
end;
// Build selections gatherer
selections := selections + IntToStr(theTopTenSongs['id']);
selectionsPipe := true;
// Add the requests count to the array
theCounts[songCount - 1] := theTopTenSongs['cnt'];
// Feedback is cool
WriteLn('#' + IntToStr(songCount) + ': ' +
'(' + IntToStr(theTopTenSongs['cnt']) + ') ' +
theTopTenSongs['artist'] + ' - ' +
theTopTenSongs['title']);
end;
// Add the number ditty to the top of the queue
if (not debugOn) then
begin
Queue.AddFile(dittyDirectory + IntToStr(songCount) + '.mp3', ipTop);
end;
theActualCount := theActualCount + 1;
// Move pointer to next song data
theTopTenSongs.Next;
end;
// Add start ditty and increment the count
if (not debugOn) then
begin
Queue.AddFile(dittyDirectory + dittyStart, ipTop);
end;
theActualCount := theActualCount + 1;
// Log to the database
if (debugOn) then
begin
// Create the table if it doesn't already exist
ExecSQL('CREATE TABLE IF NOT EXISTS ' + tableName + '_debug ' +
'(id MEDIUMINT(9) AUTO_INCREMENT PRIMARY KEY, ' +
'date DATETIME, ' +
'selections TEXT)', []);
ExecSQL('INSERT INTO ' + tableName + '_debug (date, selections) VALUES (''' +
FormatDateTime('yyyy-mm-dd hh:mm:ss', Now) + ''', ' +
QuotedStr(selections) + ')', []);
end
else
begin
// Create the table if it doesn't already exist
ExecSQL('CREATE TABLE IF NOT EXISTS ' + tableName + ' ' +
'(id MEDIUMINT(9) AUTO_INCREMENT PRIMARY KEY, ' +
'date DATETIME, ' +
'selections TEXT)', []);
ExecSQL('INSERT INTO ' + tableName + ' (date, selections) VALUES (''' +
FormatDateTime('yyyy-mm-dd hh:mm:ss', Now) + ''', ' +
QuotedStr(selections) + ')', []);
end;
WriteLn('');
WriteLn('Added ' + IntToStr(theActualCount) + ' songs');
WriteLn('');
PAL.UnlockExecution;
// Wait for 1 song to play before starting the show
WriteLn('Waiting for one song to play...');
WriteLn('');
if (not debugOn) then
begin
PAL.WaitForPlayCount(1);
end;
PAL.LockExecution;
if (not debugOn) then
begin
// Create the table if it doesn't already exist
ExecSQL('CREATE TABLE IF NOT EXISTS currentshow ' +
'(id MEDIUMINT(9), text1 VARCHAR(255), text2 VARCHAR(255))', []);
currentShow := Query('SELECT COUNT(*) AS cnt FROM currentshow', [], true);
// If no rows in currentshow, do an insert
// Else, do an update
if (currentShow['cnt'] = 0) then
begin
ExecSQL('INSERT INTO currentshow (id, text1, text2) ' +
'VALUES (' + IntToStr(idThisPAL) + ', ' + QuotedStr(text1Update) + ', ' +
QuotedStr(text2Update) + ')', []);
end
else
begin
ExecSQL('UPDATE currentshow SET id = ' + IntToStr(idThisPAL), []);
ExecSQL('UPDATE currentshow SET text1 = ' + QuotedStr(text1Update), []);
ExecSQL('UPDATE currentshow SET text2 = ' + QuotedStr(text2Update), []);
end;
end;
// Wait for the show to end
WriteLn('Waiting for ' + IntToStr(theActualCount) + ' songs to play before ending the show.');
WriteLn('Update text1Update as we go along.');
WriteLn('');
PAL.UnlockExecution;
// Wait for the intro to play
if (not debugOn) then
begin
PAL.WaitForPlayCount(1);
end;
PAL.LockExecution;
// Update text1 on the fly as songs change
for counter := songCount to 1 do
begin
WriteLn('UPDATE currentshow SET text1 = ''' + text1Update + ' #' + IntToStr(counter) + ' with ' + IntToStr(theCounts[counter - 1]) + ' requests ''');
if (not debugOn) then
begin
ExecSQL('UPDATE currentshow SET text1 = ''' + text1Update + ' #' + IntToStr(counter) + ' with ' + IntToStr(theCounts[counter - 1]) + ' requests ''', []);
PAL.WaitForPlayCount(2);
end;
end;
if (not debugOn) then
begin
ExecSQL('UPDATE currentshow SET id = ' + IntToStr(idResetPAL), []);
ExecSQL('UPDATE currentshow SET text1 = ' + QuotedStr(text1Reset), []);
ExecSQL('UPDATE currentshow SET text2 = ' + QuotedStr(text2Reset), []);
end;
// Not really an error, but we're pau with the show
hasErrors := true;
PAL.UnlockExecution;
end;
WriteLn('');
WriteLn('Show pau');
// Free up data structures
theTopTenSongs.Free;
currentShow.Free;
Queue.Free;