#!/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();