From: Joey Schulze Date: Tue, 25 Dec 2018 00:29:03 +0000 (+0100) Subject: Support playlist management X-Git-Url: https://git.infodrom.org/?p=infodrom%2Fmusiikki-web.git;a=commitdiff_plain;h=4c2b109c43c6d90dfc3f621f1cfed1dae838e687 Support playlist management --- diff --git a/class/ajax.class.php b/class/ajax.class.php index 8d11ee5..ec34f5e 100644 --- a/class/ajax.class.php +++ b/class/ajax.class.php @@ -148,7 +148,8 @@ class AJAX { $list = $cache->findTitles($_POST['keyword']); - return $list; + return ['results' => $list, + 'playlist' => $_SESSION['playlist']]; } public static function getresultsAction() @@ -156,4 +157,44 @@ class AJAX { return array(); } + public static function playlistSelectAction() + { + $_SESSION['playlist'] = $_POST['name']; + } + + public static function getplaylistsAction() + { + $playlists = new Playlists(); + $selected = null; + if (array_key_exists('playlist', $_SESSION)) + $selected = $_SESSION['playlist']; + + return ['list' => $playlists->getList(), + 'selected' => $selected]; + } + + public static function playlistAction() + { + $playlists = new Playlists(); + + return ['title' => $_POST['name'], + 'list' => $playlists->getContents($_POST['name'])]; + } + + public function playlistNewAction() + { + $playlists = new Playlists(); + $playlists->create($_POST['name']); + } + + public function playlistAddAction() + { + $cache = new Cache(); + $playlists = new Playlists(); + + if (!array_key_exists('playlist', $_SESSION)) + return; + + $playlists->add($_SESSION['playlist'], $cache->getRelativePath($_POST['id'])); + } } diff --git a/class/cache.class.php b/class/cache.class.php index 9cd885a..89b3ca8 100644 --- a/class/cache.class.php +++ b/class/cache.class.php @@ -11,11 +11,24 @@ class Cache { $this->db = new PDO('sqlite:/'.$cache); } + public function getRelativePath($id) + { + $media_dir = Config::main()->get('media_dir_A'); + + $sql = sprintf("SELECT path FROM details WHERE id = %d", $id); + $sth = $this->db->query($sql); + if ($sth === false) return null; + + $row = $sth->fetchObject(); + $path = substr($row->PATH, strlen($media_dir)+1); + return $path; + } + public function findTitles($keyword) { $media_dir = Config::main()->get('media_dir_A'); $results = array('count' => 0, 'list' => []); - $sql = sprintf("SELECT path, title, timestamp, size FROM details WHERE path LIKE %s AND mime IS NOT NULL", + $sql = sprintf("SELECT id, path, title, timestamp, size FROM details WHERE path LIKE %s AND mime IS NOT NULL", $this->db->quote('%'.$keyword.'%')); $sth = $this->db->query($sql); @@ -41,7 +54,14 @@ class Cache { if (!array_key_exists($section, $results['list'])) $results['list'][$section] = []; - $results['list'][$section][] = ['path' => dirname($path), 'name' => basename($path), 'title' => $row->TITLE]; + + $item = ['path' => dirname($path), 'name' => basename($path), 'title' => $row->TITLE]; + if (array_key_exists('playlist', $_SESSION)) + $item['id'] = $row->ID; + else + $item['id'] = ''; + + $results['list'][$section][] = $item; } return $results; diff --git a/class/playlists.class.php b/class/playlists.class.php new file mode 100644 index 0000000..2c0d329 --- /dev/null +++ b/class/playlists.class.php @@ -0,0 +1,90 @@ +get('media_dir_A') . '/playlists'; + $list = []; + + foreach (new DirectoryIterator($dir) as $fileInfo) { + if ($fileInfo->isDot()) continue; + if ($fileInfo->isDir()) continue; + if ($fileInfo->getExtension() != 'm3u') continue; + + $lines = preg_split('/\r?\n/', file_get_contents($fileInfo->getPathname())); + if ($lines[0] == static::EMPTYSTRING) { + $count = 0; + } else { + $count = count($lines) - 1; + } + + $list[] = ['name' => $fileInfo->getBasename('.m3u'), 'count' => $count]; + } + + usort($list, function($a, $b){return strcmp($a['name'], $b['name']);}); + return $list; + } + + public function getContents($name) + { + $dir = Config::main()->get('media_dir_A') . '/playlists'; + $list = []; + + $path = $dir . '/' . $name . '.m3u'; + if (file_exists($path)) { + $content = explode("\n", file_get_contents($path)); + foreach ($content as $path) { + if (empty(trim($path))) continue; + if ($path == static::EMPTYSTRING) continue; + + $fname = basename($path); + + if (($pos = strrpos($fname, '.')) > strlen($fname)-10) + $fname = substr($fname, 0, $pos); + $list[] = $fname; + } + } + + return $list; + } + + public function add($name, $path) + { + $playlist = Config::main()->get('media_dir_A') . '/playlists/' . $name . '.m3u'; + if (!file_exists($playlist)) return; + + $content = explode("\n", file_get_contents($playlist)); + $found = false; + foreach ($content as $line) + if ($line == $path) + $found = true; + + if (!$found) + $content[] = $path; + + if (($f = fopen($playlist.'.new', 'w')) !== false) { + foreach ($content as $line) { + if (empty(trim($line))) continue; + if ($line == static::EMPTYSTRING) continue; + fwrite($f, $line . "\n"); + } + fclose($f); + rename($playlist.'.new', $playlist); + } + + } + + public function create($name) + { + $playlist = Config::main()->get('media_dir_A') . '/playlists/' . $name . '.m3u'; + if (file_exists($playlist)) return; + + if (($f = fopen($playlist, 'w')) !== false) { + fwrite($f, static::EMPTYSTRING . "\n"); + + fclose($f); + } + } +} diff --git a/html/index.php b/html/index.php index 694096a..4fb9fbb 100644 --- a/html/index.php +++ b/html/index.php @@ -1,6 +1,9 @@ render([]); diff --git a/html/main.js b/html/main.js index fc57f28..25d2cb5 100644 --- a/html/main.js +++ b/html/main.js @@ -42,9 +42,23 @@ function results_waiting() } setTimeout(results_waiting_stop,20000); -function submit_search() +function search_addto_playlist(event) { - if (!$('input#search_keyword').val().length) + var btn = $(this); + console.log($(this).attr('data-id')); + + $.post('index.php', + {action: 'playlistAdd', + id: $(this).attr('data-id')}, + function(data){ + btn.hide(); + }); +} + +function submit_search(e) +{ + var input = $(e).parent().find('#search_keyword'); + if (!input.val().length) return false; $('div#results h1').text('Results.'); @@ -53,25 +67,39 @@ function submit_search() results_waiting(); $.post('index.php', - 'action=search&' + $('div.w3-container#search form').serialize(), + 'action=search&keyword=' + encodeURI(input.val()), function(data){ if (data) { - $('div#results h1').text(data.count+' matches.'); + input.val(''); + if (data.playlist != null && data.playlist.length) { + $('#results #playlist').find('b').text(data.playlist); + $('#results #playlist').show(); + } else { + $('#results #playlist').hide(); + } + $('div#results h1').text(data.results.count+' matches.'); var result = $('