HomeAudio/scripts/homeaudio_auditqueues.pl

127 lines
5.0 KiB
Perl
Executable File

#!/usr/bin/perl
use DBI;
use DBD::mysql;
use Config::INI::Reader;
sub ltrim { my $s = shift; $s =~ s/^\s+//; return $s };
sub rtrim { my $s = shift; $s =~ s/\s+$//; return $s };
sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
my $confcontents = Config::INI::Reader->read_file('/etc/homeaudio.ini');
my $Config = $confcontents->{_};
$dsn = "DBI:mysql:" . $Config->{DBNAME} . ":" . $Config->{DBHOST};
$dbh = DBI->connect($dsn, $Config->{DBUSER}, $Config->{DBPASS}, {RaiseError=>1});
$mp3dir = $Config->{MP3DIR};
# Check for the existence of SAFETYFILES from the config file before proceeding
my @safetyfiles = split(/,/, trim($Config->{SAFETYFILES}));
for ( my $i=0; $i<@safetyfiles; $i++ ) {
if ( ! -e $Config->{MP3DIR} . $safetyfiles[$i] ) {
print "Missing safety file \"$safetyfiles[$i]\"! Exiting...\n";
exit(1);
}
}
# Get the current default list (if there is one);
$activelist = "";
$sth = $dbh->prepare("SELECT id FROM queues WHERE active='true'");
$sth->execute();
if ( $sth->rows > 0 ) {
@result = $sth->fetchrow_array();
}
$activelist = $result[0];
$sth->finish();
# Create the year queues from the list in the config file if they don't already exist
# Must be at least one year!!!
@years = split(/,/, trim($Config->{YEARDECADES}));
for ( my $i=0; $i<@years; $i++ ) {
$years[$i] = trim($years[$i]);
$sth = $dbh->prepare("INSERT IGNORE INTO queues (name, type) VALUES(?, 'year')");
$queuename = $years[$i] . "'s";
$sth->execute($queuename);
$sth->finish();
}
# Populate and prune the "year" queues (i.e. 1990's)
# First we get all the "year" queues
my %yearqueues; # This will be populated from the database
$sth = $dbh->prepare("SELECT id, name FROM queues WHERE type='year'");
$sth->execute();
while ( @row = $sth->fetchrow_array ) {
$yearqueues{$row[0]} = substr($row[1], 0, 4);
}
$sth->finish();
# First we remove any songs which don't have the correct year
while ( ($yqid, $year) = each %yearqueues ) {
$yearend = $year + 10;
$sth = $dbh->prepare("DELETE FROM queuecontents WHERE qid=$yqid AND songid NOT IN (SELECT id FROM songs WHERE year >= $year AND year < $yearend)");
$sth->execute();
}
$sth->finish();
# Push any song genres which don't already exist into queues.
$sth = $dbh->prepare("INSERT INTO queues (name, type) SELECT DISTINCT(genre) AS genre, 'auto' FROM songs WHERE genre NOT IN (SELECT name FROM queues) AND genre NOT IN (SELECT genre FROM excludes)");
$sth->execute();
$sth->finish();
# Remove any auto queues which don't have corresponding genres in songs.
$sth = $dbh->prepare("DELETE FROM queues WHERE name NOT IN (SELECT DISTINCT(genre) FROM songs) AND type='auto'");
$sth->execute();
$sth->finish();
# Now we insert all the songs for each year into the appropriate queue, ignoring duplicates
# We want to restrict it to a subset of the queues so we'll make an array of queue IDs for the ones we want.
# The config parameter QUEUESINYEARS must have a comma separated list of queue names to include in the years. Must be at least 1!!
# First we get the queue names from the config into a database query friendly string for use with "IN"
my @dbqueuenames = split(/,/, trim($Config->{QUEUESINYEARS}));
my $wantedqueuenames = "";
for ( my $i=0; $i<@dbqueuenames; $i++ ) {
$wantedqueuenames .= "\"" . trim($dbqueuenames[$i]) . "\",";
}
$wantedqueuenames = substr($wantedqueuenames, 0, -1);
# Then we get the list of IDs based on that friendly string and build a new friendly string for the queue IDs
$sth = $dbh->prepare("SELECT id FROM queues WHERE name IN ($wantedqueuenames)");
$sth->execute();
my $wantedqueuesquery = "";
while ( @row = $sth->fetchrow_array ) {
$wantedqueuesquery .= $row[0] . ",";
}
$sth->finish();
$wantedqueuesquery = substr($wantedqueuesquery, 0, -1);
while ( ($yqid, $year) = each %yearqueues ) {
$yearend = $year + 10;
$sth = $dbh->prepare("INSERT IGNORE INTO queuecontents (qid, songid) SELECT $yqid, s.id FROM queuecontents AS qc LEFT JOIN songs AS s on qc.songid=s.id WHERE qc.qid IN ($wantedqueuesquery) AND year >= $year AND year < $yearend");
$sth->execute();
}
$sth->finish();
# Add any missing songs from distinct genres into the appropriate queue.
$sth = $dbh->prepare("INSERT IGNORE INTO queuecontents (qid, songid, timesplayed) SELECT q.id, s.id, 0 FROM songs AS s LEFT JOIN queues AS q ON s.genre=q.name WHERE q.id IS NOT NULL");
$sth->execute();
$sth->finish();
# Remove any queue contents for which the song is missing.
$sth = $dbh->prepare("DELETE FROM queuecontents WHERE songid NOT IN (SELECT id FROM songs)");
$sth->execute();
$sth->finish();
# Since it is possible for the active queue to have been removed (unlikely)
# the lowest indexed queue ID will be made active if no queue is active.
$sth = $dbh->prepare("SELECT id FROM queues WHERE active='true'");
$sth->execute();
if ( $sth->rows == 0 ) {
$sth = $dbh->prepare("SELECT MIN(id) FROM queues");
$sth->execute();
@result = $sth->fetchrow_array();
$sth = $dbh->prepare("UPDATE queues SET active='true' WHERE id=?");
$sth->execute($result[0]);
}
# Close the DB connection
$sth->finish();
$dbh->disconnect();