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