From 150081b2c37737623ae531067fc3aa8c5b0e29d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr> Date: Fri, 3 Jun 2022 11:52:45 +0200 Subject: [PATCH] Add a "mix daily mixes" button --- public/index.php | 20 ++++++++++++++- spotify/lib.php | 66 +++++++++++++++++++++++++++++++++++++++++++----- template.php | 30 ++++++++++++++++++++++ 3 files changed, 108 insertions(+), 8 deletions(-) diff --git a/public/index.php b/public/index.php index 19e7d16..0c64493 100644 --- a/public/index.php +++ b/public/index.php @@ -77,6 +77,7 @@ $templateData = [ $generatePlaylistFromPlaylist = isset($_GET['generate-playlist-from-playlist']); $generatePlaylistFromSelectedTopArtists = isset($_GET['generate-playlist-top-artists']); $generatePlaylistFromRandomTopArtists = isset($_GET['generate-playlist-random-top-artists']); +$generateQuickPlaylistFromDailyMixes = isset($_GET['generate-quick-playlist-from-daily-mixes']); $showPlaylistContent = isset($_GET['show-playlist']); $action = ''; @@ -86,6 +87,8 @@ if ($generatePlaylistFromPlaylist) { $action = 'generate-playlist-from-selected-top-artists'; } elseif ($generatePlaylistFromRandomTopArtists) { $action = 'generate-playlist-from-random-top-artists'; +} elseif ($generateQuickPlaylistFromDailyMixes) { + $action = 'generate-playlist-from-daily-mixes'; } elseif ($showPlaylistContent) { $action = 'show-playlist-content'; } else { @@ -152,6 +155,7 @@ switch ($action) { ); $templateData['infos'][] = getCreatedPlaylistInformationMessage($api, $newPlaylist); break; + case 'generate-playlist-from-selected-top-artists': $selectedArtists = $_GET['selected-artist']; printLog('Will create new playlist with filterted recommendations from artists: '.join(', ', $selectedArtists).'".'); @@ -193,6 +197,7 @@ switch ($action) { ); $templateData['infos'][] = getCreatedPlaylistInformationMessage($api, $newPlaylist); break; + case 'generate-playlist-from-random-top-artists': $countInTopArtists = random_int(4, 6); $countInLessTopArtists = random_int(4, 6); @@ -242,14 +247,27 @@ switch ($action) { ); $templateData['infos'][] = getCreatedPlaylistInformationMessage($api, $newPlaylist); break; + + case 'generate-playlist-from-daily-mixes': + $generateLongPlaylist = isset($_GET['check-quick-create-long-playlist']); + + printLog('Generate playlist from Daily Mixes (long playlist :'.($generateLongPlaylist ? 'yes' : 'no').')'); + + $newPlaylist = createPlaylistFromDailyMixesTracks( + $api, + $generateLongPlaylist ? $tracksCountInLongPlaylist : $tracksCountInShortPlaylist + ); + $templateData['infos'][] = getCreatedPlaylistInformationMessage($api, $newPlaylist); + break; + case 'show-playlist-content': printLog('Get content of playlist'); - $playlistId = $_GET['id']; $playlist = $api->getPlaylist($playlistId); $templateData['infos'][] = getPlaylistInformationMessage($api, $playlist); $templateData['playlist'] = createDisplayablePlaylist($playlist); break; + default: $templateData['topArtists'] = $api->getMyTop('artists', ['limit' => $topArtistsCount, 'time_range' => 'short_term'])->items; $templateData['playlists'] = $api->getUserPlaylists($user['id'], ['limit' => $playlistsCount])->items; diff --git a/spotify/lib.php b/spotify/lib.php index 8844ab4..d2c3386 100644 --- a/spotify/lib.php +++ b/spotify/lib.php @@ -30,18 +30,18 @@ function createEmptyPlaylist($api, $playlistName = 'Auto playlist') return $playlist; } -function pickRandomTracksFromArray($recommendedTrackIds, $count = 0) +function pickRandomTracksFromArray($trackIds, $count = 0) { - $recommendedTrackIds = array_keys($recommendedTrackIds); - printLog('=> Got '.count($recommendedTrackIds).' unique tracks.'); - shuffle($recommendedTrackIds); + $trackIds = \array_keys($trackIds); + printLog('=> Got '.\count($trackIds).' unique tracks.'); + \shuffle($trackIds); if (!$count) { - return $recommendedTrackIds; + return $trackIds; } - $pickedTrackIds = array_slice($recommendedTrackIds, 0, $count); - printLog('Keep '.count($pickedTrackIds).' random tracks.'); + $pickedTrackIds = \array_slice($trackIds, 0, $count); + printLog('Keep '.\count($pickedTrackIds).' random tracks.'); return $pickedTrackIds; } @@ -89,6 +89,37 @@ function createPlaylistWithRandomTracks($api, $trackIds, $count = 50) return $api->getPlaylist($playlist->id); } +function createPlaylistFromDailyMixesTracks($api, $count = 50) +{ + // Get daily mix playlists from user library + $userPlaylists = getAllPlaylistsFromUserId($api, $api->me()->id); + $dailyMixPlaylistIds = []; + foreach ($userPlaylists as $userPlaylist) { + $regex = '/^Daily Mix [1-6]$/'; + if (\preg_match($regex, $userPlaylist->name)) { + $dailyMixPlaylistIds[] = $userPlaylist->id; + } + } + + // Get all tracks in daily mix playlists + $trackIds = []; + foreach ($dailyMixPlaylistIds as $dailyMixPlaylistId) { + $dailyMixPlaylist = $api->getPlaylist($dailyMixPlaylistId); + $tracks = $dailyMixPlaylist->tracks->items; + foreach ($tracks as $track) { + $trackId = $track->track->id; + $trackIds[$trackId] = $trackId; + } + } + + $pickedTrackIds = pickRandomTracksFromArray($trackIds, $count); + + $playlist = createEmptyPlaylist($api, 'Daily Mixes'); + $api->replacePlaylistTracks($playlist->id, $pickedTrackIds); + + return $api->getPlaylist($playlist->id); +} + function getCreatedPlaylistInformationMessage($api, $playlist) { $link = '<a href="'.generateShowPlaylistUrl($playlist->id).'">'.$playlist->name.'</a>'; @@ -138,3 +169,24 @@ function createDisplayablePlaylist($playlist) return $output; } + +function getAllPlaylistsFromUserId($api, $userId) { + $playlists = []; + $batchSize = 50; + $offset = 0; + + while (($offset === 0) or (\count($batch->items) === $batchSize)) { + $batch = $api->getUserPlaylists($userId, [ + 'limit' => $batchSize, + 'offset' => $offset, + ]); + + foreach ($batch->items as $playlist) { + $playlists[] = $playlist; + } + + $offset += $batchSize; + } + + return $playlists; +} diff --git a/template.php b/template.php index 305e5bb..9a6948c 100644 --- a/template.php +++ b/template.php @@ -54,6 +54,36 @@ <?php } ?> <?php if (count($templateData['topArtists'])) { ?> + <form class="clearfix mt-2"> + <div class="row"> + <div class="col-md-12"> + <legend>Quick playlist generator:</legend> + </div> + </div> + <div class="row"> + <div class="col-md-8 col-sm-12"> + <div> + <input + type="checkbox" + class="custom-control-input" + id="check-quick-create-long-playlist" + name="check-quick-create-long-playlist" + value="long-playlist" + checked + > + <label class="custom-control-label" for="check-quick-create-long-playlist"> + Generate a long playlist (x2) + </label> + </div> + </div> + <div class="col-md-4 col-sm-12"> + <div class="btn-group float-end" role="group" aria-label="Action buttons"> + <button name="generate-quick-playlist-from-daily-mixes" type="submit" class="btn btn-primary">🎶 Mix daily mixes!</button> + </div> + </div> + </div> + </form> + <form class="clearfix mt-2"> <div class="row"> <div class="col-md-8 col-sm-12"> -- GitLab