Skip to content

Instantly share code, notes, and snippets.

@nanawel
Created December 18, 2023 20:02
Show Gist options
  • Save nanawel/f93f2b8af51903ce6c19d1fe33ac7eb6 to your computer and use it in GitHub Desktop.
Save nanawel/f93f2b8af51903ce6c19d1fe33ac7eb6 to your computer and use it in GitHub Desktop.
<?php
/**
* MPD Playlist Updater
*
* @version 0.1.0
* @since 2012-03-14
*/
define('MPCPF_VERSION', '0.1.0');
define('MPCPF_MPD_CONF', '/etc/mpd.conf');
define('MPCPF_USER', 'mpd');
/*
* Process script arguments
*/
$usage = 'php -f ' . basename(__FILE__) . " -- \\\n\t"
. "[ -p | --playlist PLAYLIST \\\n\t"
. "[ -u | --skipusercheck \\\n\t";
$longopts = array(
'playlist:',
'skipusercheck'
);
$options = getopt('p:u', $longopts);
// Check current user
$skipUserCheck = isset($options['skipusercheck']) || isset($options['u']);
if (!$skipUserCheck) {
exec('whoami', $out);
if ($out[0] != MPCPF_USER) {
die('This script must be run as user ' . MPCPF_USER . "\n");
}
}
// Process playlist argument
if (!isset($options['playlist']) && !isset($options['p'])) {
die("Missing --playlist argument.\nUsage:\t$usage\n"
. "PLAYLIST: the name of the MPD playlist to process (without .m3u extension)"
. "\n\n");
}
$playlist = isset($options['playlist']) ? $options['playlist'] : $options['p'];
/*
* Load exclude list
*/
$excludeFile = dirname(__FILE__) . '/exclude.conf';
if (!is_readable($excludeFile)) {
die("Cannot read exclude.conf file. (create it first?)\n");
}
$exclude = array_map('trim', file($excludeFile, FILE_SKIP_EMPTY_LINES));
/*
* Retrieve MPD config
*/
$mpdConfig = file_get_contents(MPCPF_MPD_CONF);
//Music dir
if (!preg_match('/music_directory.*?"(.*)"/i', $mpdConfig, $matches)) {
die('Cannot find music_directory config value.\n');
}
$musicDir = $matches[1];
// Playlist dir
if (!preg_match('/playlist_directory.*?"(.*)"/i', $mpdConfig, $matches)) {
die('Cannot find playlist_directory config value.\n');
}
$playlistsDirPath = $matches[1];
///* Search existing playlists */
//$playlists = array();
//$playlistsDir = new DirectoryIterator($playlistsDirPath);
//foreach($playlistsDir as $file) {
// if (substr($file, -3) == 'm3u') {
// $playlists[] = $file->getFilename();
// }
//}
$playlistPath = $playlistsDirPath . '/' . $playlist . '.m3u';
/*
* Update playlist
*/
echo "Updating playlist '$playlist'...\n";
exec('mpc clear');
exec('mpc update --wait');
exec("mpc rm $playlist");
exec('mpc ls | grep -v ".m3u" | mpc add');
exec("mpc save $playlist");
/*
* Prepare filter
*/
foreach($exclude as $i => &$e) {
if ($e === '') {
unset($exclude[$i]);
continue;
}
$e = preg_quote($e, '/');
//$e = str_replace('/', '\\/', $e);
}
$regExp = '/' . implode('|', $exclude) . '/i';
/*
* Apply filter on playlists contents
*/
echo "Filtering playlist '$playlist'...\n";
$totalTracks = 0;
$filteredTracks = 0;
$hPlaylist = fopen($playlistPath, 'r');
if (false === $hPlaylist) {
die("Cannot open playlist $playlist\n");
}
$hTmp = tmpfile();
if (false === $hTmp) {
die("Cannot create temporary file. Aborting.\n");
}
// Filter line by line
while ($line = fgets($hPlaylist)) {
$totalTracks++;
if (!preg_match($regExp, $line)) {
fputs($hTmp, $line);
}
else {
$filteredTracks++;
}
}
fclose($hPlaylist);
//Backup current playlist
$bakPath = $playlistPath . '.bak';
if (file_exists($bakPath)) {
unlink($bakPath);
}
copy($playlistPath, $bakPath);
//Write temp file contents to playlist file
fseek($hTmp, 0);
$hPlaylist = fopen($playlistPath, 'w');
while ($line = fgets($hTmp)) {
fputs($hPlaylist, $line);
}
fclose($hPlaylist);
// Close and destroy temp file
fclose($hTmp);
/*
* Reload playlist and resume playing
*/
echo "$totalTracks tracks found in playlist '$playlist'. Removed: $filteredTracks.\n";
echo "Reloading playlist '$playlist'...\n";
exec('mpc clear');
exec('mpc load ' . $playlist);
exec('mpc play');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment