Skip to content
Snippets Groups Projects
Select Git revision
  • 2e3af5bb0fa93d0fc22adcd13d487af350720f61
  • master default protected
  • 60-display-last-tracks-and-some-dump-metadata
  • 58-create-api-for-main-routes
  • 40-add-more-default-playlists-in-quick-create-feature
  • 37-batch-update-recently-played-tracks
  • 11-improve-new-playlist-name-and-description
  • 15-add-a-play-now-button-on-created-playlist-message
  • 20-rename-playlist-with-artists-names
  • 30-save-spotify-personal-token-for-external-use
10 results

PlaylistController.php

Blame
  • PlaylistController.php 14.39 KiB
    <?php
    
    namespace App\Controller;
    
    use App\Service\SpotifyApiService;
    use App\Service\SpotifyPlaylistService;
    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use Symfony\Component\HttpFoundation\JsonResponse;
    use Symfony\Component\HttpFoundation\RedirectResponse;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\Routing\Annotation\Route;
    
    class PlaylistController extends AbstractController
    {
        /** @var SpotifyWebAPI */
        private $spotifyApi;
    
        /** @var SpotifyPlaylistService */
        private $spotifyPlaylistService;
    
        public function __construct(SpotifyApiService $spotifyApiService, SpotifyPlaylistService $spotifyPlaylistService)
        {
            // increase timeout limit
            set_time_limit(60);
    
            $this->spotifyApi = $spotifyApiService->createApi();
            $this->spotifyPlaylistService = $spotifyPlaylistService;
        }
    
        /**
         * @Route("/playlist-generator", name="playlist-generator")
         *
         * @return Response
         */
        public function playlistGeneratorIndex(): Response
        {
            $me = $this->spotifyApi->me();
    
            return $this->render('playlist-generator/index.html.twig', [
                'user' => $me,
            ]);
        }
    
        /**
         * @Route("/playlists/user", name="get-user-playlists")
         *
         * @return Response
         */
        public function getPlaylists(): Response
        {
            $me = $this->spotifyApi->me();
            $rawPlaylists = $this->spotifyApi->getUserPlaylists(
                $me->id,
                [
                    'limit' => SpotifyPlaylistService::PLAYLISTS_COUNT,
                ]
            )->items;
    
            $playlists = [];
            foreach ($rawPlaylists as $playlist) {
                $playlists[] = [
                    'id' => $playlist->id,
                    'name' => $playlist->name,
                    'imageUrl' => $playlist->images[\count($playlist->images) - 1]->url,
                ];
            }
    
            return new JsonResponse($playlists);
        }
    
        /**
         * @Route("/show-playlist-content/{playlistId}", name="show-playlist-content")
         *e
         * @return Response
         */
        public function showPlaylistContent(string $playlistId): Response
        {
            $this->spotifyPlaylistService->printLog('Get content of playlist');
            $playlist = $this->spotifyApi->getPlaylist($playlistId);
    
            return $this->render('playlist-generator/view.html.twig', [
                'user' => $this->spotifyApi->me(),
                'infos' => $this->spotifyPlaylistService->getPlaylistInformationMessage($playlist),
                'playlist' => $this->spotifyPlaylistService->createDisplayablePlaylist($playlist),
            ]);
        }
    
        /**
         * @Route("/generate-playlist-from-playlists", name="generate-playlist-from-playlists")
         *
         * @return Response
         */
        public function generatePlaylistFromPlaylists(Request $request): Response
        {
            /** @var array */
            $selectedPlaylists = $request->query->get('selected-playlist');
    
            $this->spotifyPlaylistService->printLog('Will create new playlist with recommendations from playlists: ' . join(', ', $selectedPlaylists) . '".');
            $recommendedTrackIds = [];
    
            $shouldFilterByArtists = (null !== $request->query->get('check-playlist-filter-artists'));
            $this->spotifyPlaylistService->printLog('Filter by artists in source playlists: ' . ($shouldFilterByArtists ? 'yes' : 'no'));
    
            $generateLongPlaylist = (null !== $request->query->get('check-playlist-long-playlist'));
            $this->spotifyPlaylistService->printLog('Generate long playlist: ' . ($generateLongPlaylist ? 'yes' : 'no'));
    
            $artistsInSourcePlaylists = [];
    
            foreach ($selectedPlaylists as $selectedPlaylistId) {
                $playlist = $this->spotifyApi->getPlaylist($selectedPlaylistId);
                $this->spotifyPlaylistService->printLog('Will get recommendations from tracks in playlist "' . $playlist->name . '".');
                $playlistTracks = $playlist->tracks->items;
                $this->spotifyPlaylistService->printLog('Found ' . count($playlistTracks) . ' tracks.');
                foreach ($playlistTracks as $track) {
                    $artists = [];
                    foreach ($track->track->artists as $artist) {
                        $artists[] = $artist->name;
                        $artistsInSourcePlaylists[$artist->id] = 1;
                    }
                    $this->spotifyPlaylistService->printLog('Track "' . $track->track->name . '" (' . join(', ', $artists) . ')');
    
                    $recommendations = $this->spotifyApi->getRecommendations([
                        'seed_tracks' => [$track->track->id],
                        'limit' => ($generateLongPlaylist ? 50 : 30)
                    ]);
                    $this->spotifyPlaylistService->printLog(' -> Got ' . count($recommendations->tracks) . ' recommendatations.');
                    foreach ($recommendations->tracks as $recommendedTrack) {
                        $recommendedTrackIds[$recommendedTrack->id] = $recommendedTrack;
                    }
                }
            }
    
            if ($shouldFilterByArtists) {
                $artistsInSourcePlaylists = array_keys($artistsInSourcePlaylists);
                $this->spotifyPlaylistService->printLog('Filter by artists found in source playlists (' . count($artistsInSourcePlaylists) . ')');
    
                $filteredTrackIds = [];
                foreach ($recommendedTrackIds as $track) {
                    foreach ($track->artists as $trackArtist) {
                        if (\in_array($trackArtist->id, $artistsInSourcePlaylists)) {
                            $filteredTrackIds[$track->id] = 1;
                        }
                    }
                }
                $recommendedTrackIds = $filteredTrackIds;
            }
    
            $newPlaylist = $this->spotifyPlaylistService->createPlaylistWithRandomTracks(
                $this->spotifyApi,
                $recommendedTrackIds,
                $generateLongPlaylist ? SpotifyPlaylistService::TRACKS_COUNT_IN_LONG_PLAYLIST : SpotifyPlaylistService::TRACKS_COUNT_IN_SHORT_PLAYLIST
            );
    
            $this->addFlash('infos', $this->spotifyPlaylistService->getCreatedPlaylistInformationMessage($newPlaylist));
    
            return new RedirectResponse($this->generateUrl('show-playlist-content', ['playlistId' => $newPlaylist->id]));
        }
    
        /**
         * @Route("/generate-playlist-from-top-artists", name="generate-playlist-from-top-artists")
         *
         * @return Response
         */
        public function generatePlaylistFromTopArtists(Request $request): Response
        {
            // Swith "random" or "selected"
            if (null !== $request->query->get('generate-playlist-random-top-artists')) {
                return $this->generatePlaylistFromRandomTopArtists($request);
            } elseif (null !== $request->query->get('generate-playlist-top-artists')) {
                return $this->generatePlaylistFromSelectedTopArtists($request);
            }
    
            return new RedirectResponse($this->generateUrl('playlist-generator'));
        }
    
        /**
         *
         * @return Response
         */
        private function generatePlaylistFromSelectedTopArtists(Request $request): Response
        {
            /** @var array */
            $selectedArtists = $request->query->get('selected-artist');
    
            $this->spotifyPlaylistService->printLog('Will create new playlist with filterted recommendations from artists: ' . join(', ', $selectedArtists) . '".');
            $recommendedTrackIds = [];
    
            $shouldFilterByArtists = (null !== $request->query->get('check-top-artist-filter-artists'));
            $this->spotifyPlaylistService->printLog('Filter by artists in selection: ' . ($shouldFilterByArtists ? 'yes' : 'no'));
    
            $generateLongPlaylist = (null !== $request->query->get('check-top-artist-long-playlist'));
            $this->spotifyPlaylistService->printLog('Generate long playlist: ' . ($generateLongPlaylist ? 'yes' : 'no'));
    
            foreach ($selectedArtists as $selectedArtist) {
                $this->spotifyPlaylistService->printLog('Get recommendations for artist ' . $selectedArtist . '');
                $recommendations = $this->spotifyApi->getRecommendations([
                    'seed_artists' => $selectedArtist,
                    'limit' => 100
                ]);
                $this->spotifyPlaylistService->printLog(' -> Got ' . count($recommendations->tracks) . ' recommendatations.');
    
                // Filter by artist if requested, remove duplicates
                foreach ($recommendations->tracks as $recommendedTrack) {
                    if ($shouldFilterByArtists) {
                        foreach ($recommendedTrack->artists as $trackArtist) {
                            if (\in_array($trackArtist->id, $selectedArtists)) {
                                $recommendedTrackIds[$recommendedTrack->id] = 1;
                            }
                        }
                    } else {
                        $recommendedTrackIds[$recommendedTrack->id] = 1;
                    }
                }
            }
    
            $newPlaylist = $this->spotifyPlaylistService->createPlaylistWithRandomTracks(
                $this->spotifyApi,
                $recommendedTrackIds,
                $generateLongPlaylist ? SpotifyPlaylistService::TRACKS_COUNT_IN_LONG_PLAYLIST : SpotifyPlaylistService::TRACKS_COUNT_IN_SHORT_PLAYLIST
            );
    
            $this->addFlash('infos', $this->spotifyPlaylistService->getCreatedPlaylistInformationMessage($newPlaylist));
    
            return new RedirectResponse($this->generateUrl('show-playlist-content', ['playlistId' => $newPlaylist->id]));
        }
    
        /**
         *
         * @return Response
         */
        private function generatePlaylistFromRandomTopArtists(Request $request): Response
        {
            $countInTopArtists = random_int(4, 6);
            $countInLessTopArtists = random_int(4, 6);
            $limitBetweenTopAndLessTop = SpotifyPlaylistService::TOP_ARTISTS_COUNT;
            $selectedArtists = $this->spotifyPlaylistService->getRandomArtistsFromTopArtists(
                $this->spotifyApi,
                $countInTopArtists,
                $countInLessTopArtists,
                $limitBetweenTopAndLessTop
            );
            $this->spotifyPlaylistService->printLog('Will create new playlist with filterted recommendations from random artists: ' . join(', ', $selectedArtists) . '".');
            $recommendedTrackIds = [];
    
            $shouldFilterByArtists = (null !== $request->query->get('check-top-artist-filter-artists'));
            $this->spotifyPlaylistService->printLog('Filter by artists in selection: ' . ($shouldFilterByArtists ? 'yes' : 'no'));
    
            $generateLongPlaylist = (null !== $request->query->get('check-top-artist-long-playlist'));
            $this->spotifyPlaylistService->printLog('Generate long playlist: ' . ($generateLongPlaylist ? 'yes' : 'no'));
    
            foreach ($selectedArtists as $selectedArtist) {
                $this->spotifyPlaylistService->printLog('Get recommendations for artist ' . $selectedArtist . '');
                $recommendations = $this->spotifyApi->getRecommendations([
                    'seed_artists' => $selectedArtist,
                    'limit' => 100
                ]);
                $this->spotifyPlaylistService->printLog(' -> Got ' . count($recommendations->tracks) . ' recommendations.');
    
                // Filter by artist if requested, remove duplicates
                foreach ($recommendations->tracks as $recommendedTrack) {
                    if ($shouldFilterByArtists) {
                        foreach ($recommendedTrack->artists as $trackArtist) {
                            if (\in_array($trackArtist->id, $selectedArtists)) {
                                $recommendedTrackIds[$recommendedTrack->id] = 1;
                            }
                        }
                    } else {
                        $recommendedTrackIds[$recommendedTrack->id] = 1;
                    }
                }
            }
    
            $newPlaylist = $this->spotifyPlaylistService->createPlaylistWithRandomTracks(
                $this->spotifyApi,
                $recommendedTrackIds,
                $generateLongPlaylist ? SpotifyPlaylistService::TRACKS_COUNT_IN_LONG_PLAYLIST : SpotifyPlaylistService::TRACKS_COUNT_IN_SHORT_PLAYLIST
            );
    
            $this->addFlash('infos', $this->spotifyPlaylistService->getCreatedPlaylistInformationMessage($newPlaylist));
    
            return new RedirectResponse($this->generateUrl('show-playlist-content', ['playlistId' => $newPlaylist->id]));
        }
    
        /**
         * @Route("/generate-quick-playlist", name="generate-quick-playlist")
         *
         * @return Response
         */
        public function generateQuickPlaylist(Request $request): Response
        {
            // Swith between "daily mixes" or "tambouille"
            if (null !== $request->query->get('generate-quick-playlist-from-daily-mixes')) {
                return $this->generatePlaylistFromDailyMixes($request);
            } elseif (null !== $request->query->get('generate-quick-playlist-tambouille-mix')) {
                return $this->generateplaylistTambouilleMix($request);
            }
    
            return new RedirectResponse($this->generateUrl('playlist-generator'));
        }
    
        /**
         *
         * @return Response
         */
        private function generatePlaylistFromDailyMixes(Request $request): Response
        {
            $generateLongPlaylist = (null !== $request->query->get('check-quick-create-long-playlist'));
    
            $this->spotifyPlaylistService->printLog('Generate playlist from Daily Mixes (long playlist :' . ($generateLongPlaylist ? 'yes' : 'no') . ')');
    
            $newPlaylist = $this->spotifyPlaylistService->createPlaylistFromDailyMixesTracks(
                $this->spotifyApi,
                $generateLongPlaylist ? SpotifyPlaylistService::TRACKS_COUNT_IN_LONG_PLAYLIST : SpotifyPlaylistService::TRACKS_COUNT_IN_SHORT_PLAYLIST
            );
    
            $this->addFlash('infos', $this->spotifyPlaylistService->getCreatedPlaylistInformationMessage($newPlaylist));
    
            return new RedirectResponse($this->generateUrl('show-playlist-content', ['playlistId' => $newPlaylist->id]));
        }
    
        /**
         *
         * @return Response
         */
        private function generateplaylistTambouilleMix(Request $request): Response
        {
            $generateLongPlaylist = (null !== $request->query->get('check-quick-create-long-playlist'));
    
            $this->spotifyPlaylistService->printLog('Generate tambouille mix playlist (long playlist :' . ($generateLongPlaylist ? 'yes' : 'no') . ')');
    
            $newPlaylist = $this->spotifyPlaylistService->createPlaylistTambouilleMix(
                $this->spotifyApi,
                $generateLongPlaylist ? SpotifyPlaylistService::TRACKS_COUNT_IN_LONG_PLAYLIST : SpotifyPlaylistService::TRACKS_COUNT_IN_SHORT_PLAYLIST
            );
    
            $this->addFlash('infos', $this->spotifyPlaylistService->getCreatedPlaylistInformationMessage($newPlaylist));
    
            return new RedirectResponse($this->generateUrl('show-playlist-content', ['playlistId' => $newPlaylist->id]));
        }
    }