From 836d7a6748946c5e82b7af2a84a8f27c148a9dd0 Mon Sep 17 00:00:00 2001 From: smiley Date: Tue, 12 Nov 2024 20:56:43 +0100 Subject: [PATCH] :octocat: Spotify examples moved to https://github.com/codemasher/spotify-client (WIP) --- .../Providers/Spotify/MixesDBTrackSearch.php | 146 --------- examples/Providers/Spotify/SpotifyClient.php | 304 ------------------ .../Providers/Spotify/SpotifyNewReleases.php | 150 --------- examples/Providers/Spotify/cache/.gitignore | 1 - examples/Providers/Spotify/mixesdb-scrape.php | 117 ------- .../Spotify/mixesdb-track-search.php | 36 --- examples/Providers/Spotify/new-releases.php | 45 --- examples/Providers/Spotify/playlist-diff.php | 57 ---- examples/Providers/Spotify/spotify-common.php | 20 -- 9 files changed, 876 deletions(-) delete mode 100644 examples/Providers/Spotify/MixesDBTrackSearch.php delete mode 100644 examples/Providers/Spotify/SpotifyClient.php delete mode 100644 examples/Providers/Spotify/SpotifyNewReleases.php delete mode 100644 examples/Providers/Spotify/cache/.gitignore delete mode 100644 examples/Providers/Spotify/mixesdb-scrape.php delete mode 100644 examples/Providers/Spotify/mixesdb-track-search.php delete mode 100644 examples/Providers/Spotify/new-releases.php delete mode 100644 examples/Providers/Spotify/playlist-diff.php delete mode 100644 examples/Providers/Spotify/spotify-common.php diff --git a/examples/Providers/Spotify/MixesDBTrackSearch.php b/examples/Providers/Spotify/MixesDBTrackSearch.php deleted file mode 100644 index f05cfe8..0000000 --- a/examples/Providers/Spotify/MixesDBTrackSearch.php +++ /dev/null @@ -1,146 +0,0 @@ - - * @copyright 2023 smiley - * @license MIT - */ -declare(strict_types=1); - -use chillerlan\HTTP\Utils\MessageUtil; - -/** - * Track search in a JSON file scraped from MixesDB (RIP) - * - * @see https://gist.github.com/codemasher/8986089773f036a2d4c0f34eab439459 - */ -class MixesDBTrackSearch extends SpotifyClient{ - - /** - * search tracks on spotify from the given mixesdb track lists - * - * @param string[] $find - */ - public function getTracks( - string $clubnightsJSON, - int $since, - int $until, - array $find = [], - int $limit = 5, - bool $playlistPerSet = false, - ):void{ - $clubnights = json_decode(file_get_contents($clubnightsJSON), true); - $tracks = []; - - foreach($clubnights as $date => $sets){ - $date = strtotime($date); - // skip by date - if($date < $since || $date > $until){ - continue; - } - - foreach($sets as $name => $set){ - // skip by inclusion list - if(!$this->setContains($name, $find)){ - continue; - } - - $this->logger->info($name); - $setTracks = []; - - foreach($set as $track){ - $track = $this->cleanTrack($track); - - if(empty($track)){ - continue; - } - - $this->logger->info(sprintf('search: %s', $track)); - - $response = $this->request('/v1/search', [ - 'q' => $this->getSearchTerm($track), - 'type' => 'track', - 'limit' => $limit, - 'market' => $this->market, - ]); - - usleep(self::sleepTimer); - - if($response->getStatusCode() !== 200){ - continue; - } - - $data = MessageUtil::decodeJSON($response); - - foreach($data->tracks->items as $i => $item){ - $setTracks[$item->id] = $item->id; - - $this->logger->info( - sprintf( - 'found: [%s][%s] %s - %s', - ++$i, - $item->id, - implode(', ', array_column($item->artists, 'name')), - $item->name, - ), - ); - } - - } - - if($playlistPerSet){ - $playlistID = $this->createPlaylist($name, ''); - $this->addTracks($playlistID, $setTracks); - } - - $tracks = array_merge($tracks, $setTracks); - } - - } - - if(!$playlistPerSet){ - $playlistID = $this->createPlaylist('mixesdb search result', implode(', ', $find)); - $this->addTracks($playlistID, $tracks); - } - - } - - /** - * check a string for the occurence of any in the given array of needles - * - * @param string[] $needles - */ - protected function setContains(string $haystack, array $needles):bool{ - - if(empty($needles)){ - return true; - } - - $haystack = mb_strtolower($haystack); - - return str_replace(array_map('mb_strtolower', $needles), '', $haystack) !== $haystack; - } - - /** - * clean any unwanted symbols/strings from the track name - */ - protected function cleanTrack(string $track):string{ - // strip time codes [01:23] and record IDs [EYE Q - 001] from name - return trim(preg_replace(['/^\[[\d:?]+\] /', '/ \[[^]]+\]/'], '', $track), ' -?'); - } - - /** - * prepare the spotify search term - */ - protected function getSearchTerm(string $track):string{ - $at = explode(' - ', $track, 2); // artist - track - - return match (count($at)){ - 1 => sprintf('artist:%1$s track:%1$s', $at[0]), - 2 => sprintf('artist:%s track:%s', $at[0], $at[1]), - }; - } - -} diff --git a/examples/Providers/Spotify/SpotifyClient.php b/examples/Providers/Spotify/SpotifyClient.php deleted file mode 100644 index c1b52cc..0000000 --- a/examples/Providers/Spotify/SpotifyClient.php +++ /dev/null @@ -1,304 +0,0 @@ - - * @copyright 2023 smiley - * @license MIT - */ -declare(strict_types=1); - -use chillerlan\HTTP\Utils\MessageUtil; -use chillerlan\OAuth\Providers\Spotify; - -/** - * Extended functionality for the Spotify client - */ -class SpotifyClient extends Spotify{ - - protected const sleepTimer = 250000; // sleep between requests (µs) - - protected object $me; - protected string $id; - protected string $market; - /** @var array */ - protected array $artists = []; - /** @var array> */ - protected array $albums = []; - - protected function construct():void{ - // set the name to the original provider's name so that we use the same tokens - $this->name = 'Spotify'; - $this->getMe(); - } - - /** - * @param string[] $vars - */ - protected function saveToFile(array $vars, string $dir):void{ - - foreach($vars as $var){ - file_put_contents( - sprintf('%s/%s.json', rtrim($dir, '\\/'), $var), - json_encode($this->{$var}, (JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)), - ); - } - - } - - /** - * @param string[] $vars - */ - protected function loadFromFile(array $vars, string $dir):bool{ - - foreach($vars as $var){ - $file = sprintf('%s/%s.json', rtrim($dir, '\\/'), $var); - - if(!file_exists($file)){ - return false; - } - - - $data = json_decode(file_get_contents($file)); - - foreach($data as $k => $v){ - $this->{$var}[$k] = $v; - } - - } - - return true; - } - - /** - * fetch the currently authenticated user - */ - protected function getMe():void{ - $me = $this->request('/v1/me'); - - if($me->getStatusCode() !== 200){ - throw new RuntimeException('could not fetch data from /me endpoint'); - } - - $json = MessageUtil::decodeJSON($me); - - if($json === false || !isset($json->country, $json->id)){ - throw new RuntimeException('invalid response from /me endpoint'); - } - - $this->me = $json; - $this->id = $this->me->id; - $this->market = $this->me->country; - } - - /** - * fetch the artists the user is following - */ - public function getFollowedArtists():array{ - $this->artists = []; - - $params = [ - 'type' => 'artist', - 'limit' => 50, // API max = 50 artists - 'after' => null, - ]; - - do{ - $meFollowing = $this->request('/v1/me/following', $params); - $data = MessageUtil::decodeJSON($meFollowing); - - if($meFollowing->getStatusCode() === 200){ - - foreach($data->artists->items as $artist){ - $this->artists[$artist->id] = $artist; - - $this->logger->info('artist: '.$artist->name); - } - - $params['after'] = ($data->artists->cursors->after ?? ''); - - $this->logger->info(sprintf('next cursor: %s', $params['after'])); - } - // not dealing with this - else{ - - if(isset($data->error)){ - $this->logger->error($data->error->message.' ('.$data->error->status.')'); - } - - break; - } - - usleep(self::sleepTimer); - } - while($params['after'] !== ''); - - $this->logger->info(sprintf('fetched %s artists', count($this->artists))); - - return $this->artists; - } - - /** - * fetch the releases for the followed artists - */ - public function getArtistReleases():array{ - $this->albums = []; - - foreach($this->artists as $artistID => $artist){ - // WTB bulk endpoint /artists/albums?ids=artist_id1,artist_id2,... - $artistAlbums = $this->request(sprintf('/v1/artists/%s/albums', $artistID), ['market' => $this->market]); - - if($artistAlbums->getStatusCode() !== 200){ - $this->logger->warning(sprintf('could not fetch albums for artist "%s"', $artist->name)); - - continue; - } - - $data = MessageUtil::decodeJSON($artistAlbums); - - if(!isset($data->items)){ - $this->logger->warning(sprintf('albums response empty for artist "%s"', $artist->name)); - - continue; - } - - foreach($data->items as $album){ - $this->albums[$artistID][$album->id] = $album; - - $this->logger->info(sprintf('album: %s - %s', $artist->name, $album->name)); - - } - - usleep(self::sleepTimer); - } - - return $this->albums; - } - - /** - * get the tracks from the given playlist - */ - public function getPlaylist(string $playlistID):array{ - - $params = [ - 'fields' => 'total,limit,offset,items(track(id,name,album(id,name),artists(id,name)))', - 'market' => $this->market, - 'offset' => 0, - 'limit' => 100, - ]; - - $playlist = []; - $retry = 0; - - do{ - $response = $this->request(sprintf('/v1/playlists/%s/tracks', $playlistID), $params); - - if($retry > 3){ - throw new RuntimeException('error while retrieving playlist'); - } - - if($response->getStatusCode() !== 200){ - $this->logger->warning(sprintf('playlist endpoint http/%s', $response->getStatusCode())); - - $retry++; - - continue; - } - - $json = MessageUtil::decodeJSON($response); - - if(!isset($json->items)){ - $this->logger->warning('empty playlist response'); - - $retry++; - - continue; - } - - foreach($json->items as $item){ - $playlist[$item->track->id] = $item->track; - } - - $params['offset'] += 100; - $retry = 0; - - } - while($params['offset'] <= $json->total); - - return $playlist; - } - - /** - * create a new playlist - */ - public function createPlaylist(string $name, string $description):string{ - - $createPlaylist = $this->request( - path : sprintf('/v1/users/%s/playlists', $this->id), - method : 'POST', - body : [ - 'name' => $name, - 'description' => $description, - // we'll never create public playlists - that's up to the user to decide - 'public' => false, - 'collaborative' => false, - ], - headers: ['Content-Type' => 'application/json'], - ); - - if($createPlaylist->getStatusCode() !== 201){ - throw new RuntimeException('could not create a new playlist'); - } - - $playlist = MessageUtil::decodeJSON($createPlaylist); - - if(!isset($playlist->id)){ - throw new RuntimeException('invalid create playlist response'); - } - - $this->logger->info(sprintf('created playlist: "%s" ("%s")', $name, $description)); - $this->logger->info(sprintf('spotify:user:%s:playlist:%s', $this->id, $playlist->id)); - $this->logger->info(sprintf('https://open.spotify.com/playlist/%s', $playlist->id)); - - return $playlist->id; - } - - /** - * add the tracks to the given playlist - * - * @param string[] $trackIDs - */ - public function addTracks(string $playlistID, array $trackIDs):static{ - - $uris = array_chunk( - array_map(fn(string $t):string => 'spotify:track:'.$t , array_values($trackIDs)), // why not just ids??? - 100, // API max = 100 track URIs - ); - - foreach($uris as $i => $chunk){ - - $playlistAddTracks = $this->request( - path : sprintf('/v1/playlists/%s/tracks', $playlistID), - method : 'POST', - body : ['uris' => $chunk], - headers: ['Content-Type' => 'application/json'], - ); - - usleep(self::sleepTimer); - - if(in_array($playlistAddTracks->getStatusCode(), [200, 201, 204], true)){ - $json = MessageUtil::decodeJSON($playlistAddTracks); - - $this->logger->info(sprintf('added tracks %s/%s [%s]', ++$i, count($uris), $json->snapshot_id)); - - continue; - } - - $this->logger->warning(sprintf('error adding tracks: http/%s', $playlistAddTracks->getStatusCode())); // idc - } - - return $this; - } - -} diff --git a/examples/Providers/Spotify/SpotifyNewReleases.php b/examples/Providers/Spotify/SpotifyNewReleases.php deleted file mode 100644 index 38bfa3c..0000000 --- a/examples/Providers/Spotify/SpotifyNewReleases.php +++ /dev/null @@ -1,150 +0,0 @@ - - * @copyright 2023 smiley - * @license MIT - */ -declare(strict_types=1); - -use chillerlan\HTTP\Utils\MessageUtil; - -/** - * New releases crawler - */ -class SpotifyNewReleases extends SpotifyClient{ - - /** @var array */ - protected array $newAlbums = []; - - /** - * the script runner - */ - public function getNewReleases( - int $since, - int $until, - int $minTracks, - bool $skipVariousArtist, - bool $skipAppearsOn, - bool $fromCache, - string $cacheDir, - ):void{ - $loaded = $fromCache && $this->loadFromFile(['artists', 'albums'], $cacheDir); - - if(!$loaded){ - $this->getFollowedArtists(); - $this->getArtistReleases(); - $this->saveToFile(['artists', 'albums'], $cacheDir); - } - - $this->filterReleases($since, $until, $minTracks, $skipVariousArtist, $skipAppearsOn); - $this->getNewAlbumTracks($since, $until); - } - - /** - * filters the releases for the followed artists and dumps the release info to the console - */ - public function filterReleases(int $since, int $until, int $minTracks, bool $skipVariousArtist, bool $skipAppearsOn):void{ - $this->newAlbums = []; - $releaseinfo = []; - - foreach($this->albums as $albums){ - - foreach($albums as $album){ - - // skip if the release has fewer than the minimum tracks - if($album->total_tracks < $minTracks){ - continue; - } - - // skip the "Various Artists" samplers - if( - $skipVariousArtist - && !empty($album->artists) - && strtolower($album->artists[0]->name) === 'various artists' - ){ - continue; - } - - // skip "appears on" releases - if($skipAppearsOn && $album->album_group === 'appears_on'){ - continue; - } - - $releaseDate = match($album->release_date_precision){ - 'month' => $album->release_date.'-01', - 'year' => $album->release_date.'-01-01', - default => $album->release_date, - }; - - $rdate = strtotime($releaseDate); - - // skip if the release is outside the date range - if($rdate < $since || $rdate > $until){ - continue; - } - - $this->newAlbums[$album->id] = $album->id; - $releaseinfo[$releaseDate][] = $album; - } - - } - - // sort the $releaseinfo array by release date (descending) - krsort($releaseinfo); - - // dump the new release info to console - foreach($releaseinfo as $date => $releases){ - [$year, $month, $day] = explode('-', $date); - - $this->logger->info(''); - $this->logger->info(date('--- l, jS F Y\: ---', mktime(0, 0, 0, (int)$month, (int)$day, (int)$year))); - $this->logger->info(''); - - foreach($releases as $k => $release){ - $this->logger->info('['.(++$k).'] '.implode(', ', array_column($release->artists, 'name')).' - '.$release->name); - } - - $this->logger->info(''); - } - - } - - /** - * fetches the tracks for the filtered releases and puts the first of each album into a playlist - */ - protected function getNewAlbumTracks(int $since, int $until):void{ - $newtracks = []; - - // fetch the album tracks (why aren't the tracks in the albums response???) - foreach(array_chunk(array_values($this->newAlbums), 20, true) as $chunk){ // API max = 20 albums - $albums = $this->request('/v1/albums', ['ids' => implode(',', $chunk), 'market' => $this->market]); - $data = MessageUtil::decodeJSON($albums); - - if(!isset($data->albums)){ - $this->logger->warning('invalid albums response'); - - continue; - } - - foreach($data->albums as $album){ - $tracks = array_column($album->tracks->items, 'id'); - $id = array_shift($tracks); - - $newtracks[$id] = $id; - } - - usleep(self::sleepTimer); - } - - $playlistID = $this->createPlaylist( - sprintf('new releases %s - %s', date('d.m.Y', $since), date('d.m.Y', $until)), - sprintf('new releases by the artists i\'m following, %s - %s', date('d.m.Y', $since), date('d.m.Y', $until)), - ); - - $this->addTracks($playlistID, $newtracks); - } - -} diff --git a/examples/Providers/Spotify/cache/.gitignore b/examples/Providers/Spotify/cache/.gitignore deleted file mode 100644 index 72e8ffc..0000000 --- a/examples/Providers/Spotify/cache/.gitignore +++ /dev/null @@ -1 +0,0 @@ -* diff --git a/examples/Providers/Spotify/mixesdb-scrape.php b/examples/Providers/Spotify/mixesdb-scrape.php deleted file mode 100644 index cdea6ff..0000000 --- a/examples/Providers/Spotify/mixesdb-scrape.php +++ /dev/null @@ -1,117 +0,0 @@ - - * @copyright 2023 smiley - * @license MIT - * - * @noinspection PhpComposerExtensionStubsInspection - */ -declare(strict_types=1); - -use chillerlan\HTTP\Utils\MessageUtil; - -/** - * @var \OAuthExampleProviderFactory $factory - * @var \chillerlan\OAuth\Providers\Spotify $spotify - * @var \Psr\Log\LoggerInterface $logger - * @var string $file - */ -require_once __DIR__.'/spotify-common.php'; - -$logger = $factory->getLogger(); -$requestFactory = $factory->getRequestFactory(); - -$file ??= __DIR__.'/cache/clubnights.json'; -$baseURL = 'https://www.mixesdb.com'; -$catPath = '/db/index.php?title=Category:Clubnight'; -$tracklist = []; - -// suppress html parse errors -libxml_use_internal_errors(true); - -do{ - $logger->info($catPath); - - // fetch the category page - $catRequest = $requestFactory->createRequest('GET', $baseURL.$catPath); - $catResponse = $spotify->sendRequest($catRequest); - - if($catResponse->getStatusCode() !== 200){ - break; - } - - $catDOM = new DOMDocument('1.0', 'UTF-8'); - $catDOM->loadHTML(MessageUtil::getContents($catResponse)); - - // get the pages from the category list - foreach($catDOM->getElementById('catMixesList')->childNodes as $node){ - - if($node->nodeType !== XML_ELEMENT_NODE){ - continue; - } - - $page = $node->childNodes[0]->attributes->getNamedItem('href')->nodeValue; - - // get the date string - preg_match('#\d{4}-\d{2}-\d{2}#', $page, $match); - - if(!isset($match[0])){ - continue; - } - - // fetch the page - $pageRequest = $requestFactory->createRequest('GET', $baseURL.$page); - $pageResponse = $spotify->sendRequest($pageRequest); - - if($pageResponse->getStatusCode() !== 200){ - continue; - } - - $pageDOM = new DOMDocument('1.0', 'UTF-8'); - $pageDOM->loadHTML(MessageUtil::getContents($pageResponse)); - - $name = $pageDOM->getElementById('firstHeading')->nodeValue; - - if(!empty($name)){ - $logger->info($name); - - // get the tracklist - foreach($pageDOM->getElementsByTagName('ol') as $li){ - foreach($li->childNodes as $e){ - $tracklist[$match[0]][$name][] = trim($e->nodeValue); - } - } - - } - else{ - $logger->warning(sprintf('name empty for page: "%s"', $page)); - } - - // try not to hammer - usleep(500000); - } - - // get the next page from the category navigation - $catPath = null; - - foreach($catDOM->getElementById('catcount')->getElementsByTagName('a') as $node){ - if($node->textContent === 'next 200'){ - $catPath = $node->attributes->getNamedItem('href')->nodeValue; - - break; - } - } - -} -while(!empty($catPath)); - -file_put_contents($file, json_encode($tracklist, (JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE))); diff --git a/examples/Providers/Spotify/mixesdb-track-search.php b/examples/Providers/Spotify/mixesdb-track-search.php deleted file mode 100644 index 0740d67..0000000 --- a/examples/Providers/Spotify/mixesdb-track-search.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2023 smiley - * @license MIT - */ -declare(strict_types=1); - -/** - * @var \OAuthExampleProviderFactory $factory - * @var \chillerlan\OAuth\Providers\Spotify $spotify - */ -require_once __DIR__.'/spotify-common.php'; -require_once __DIR__.'/MixesDBTrackSearch.php'; - -$file = __DIR__.'/cache/clubnights.json'; -$since = strtotime('1990-05-05'); // first clubnight: 1990-05-05 -$until = strtotime('2000-01-01'); // last clubnight: 2014-06-07 (studio), 2014-06-14 (live) -$find = ['Dag', 'Fenslau', 'Pascal' /* F.E.O.S. */, 'Talla', 'Taucher', 'Tom Wax', 'Ulli Brenner', 'Väth']; -$limit = 1; -$playlistPerSet = false; - -if(!file_exists($file)){ - include __DIR__.'/mixesdb-scrape.php'; -} - -$spotify = $factory->getProvider(MixesDBTrackSearch::class, OAuthExampleProviderFactory::STORAGE_FILE); -$spotify->getTracks($file, $since, $until, $find, $limit, $playlistPerSet); - -exit; diff --git a/examples/Providers/Spotify/new-releases.php b/examples/Providers/Spotify/new-releases.php deleted file mode 100644 index 219ac25..0000000 --- a/examples/Providers/Spotify/new-releases.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright 2018 Smiley - * @license MIT - */ -declare(strict_types=1); - -/** - * @var \OAuthExampleProviderFactory $factory - * @var \SpotifyNewReleases $spotify - */ - -require_once __DIR__.'/spotify-common.php'; -require_once __DIR__.'/SpotifyNewReleases.php'; - -$since = strtotime('last Saturday'); // (time() - 7 * 86400); // last week -$until = time(); // adjust to your likes -$minTracks = 1; // minimum number of tracks per album (1 = single releases) -$skipAppearsOn = true; -$skipVariousArtist = true; -$fromCache = false; -$cacheDir = __DIR__.'/cache'; - -$spotify = $factory->getProvider(SpotifyNewReleases::class, OAuthExampleProviderFactory::STORAGE_FILE); -$spotify->getNewReleases($since, $until, $minTracks, $skipVariousArtist, $skipAppearsOn, $fromCache, $cacheDir); - -/* -// crawl for yearly album releases in the given range -foreach(range(1970, 1979) as $year){ - $since = \mktime(0, 0, 0, 1, 1, $year); - $until = \mktime(23, 59, 59, 12, 31, $year); - - $client->getNewReleases($since, $until, 5, false, true, true, $cacheDir); -} -*/ - -exit; diff --git a/examples/Providers/Spotify/playlist-diff.php b/examples/Providers/Spotify/playlist-diff.php deleted file mode 100644 index fac5355..0000000 --- a/examples/Providers/Spotify/playlist-diff.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright 2023 smiley - * @license MIT - */ -declare(strict_types=1); - -require_once __DIR__.'/spotify-common.php'; - -class PlaylistDiff extends SpotifyClient{ - - public function diff(string $playlistID1, string $playlistID2):array{ - $p1 = array_keys($this->getPlaylist($playlistID1)); - $p2 = array_keys($this->getPlaylist($playlistID2)); - $diff = array_diff($p1, $p2); - - $playlistID = $this->createPlaylist( - 'playlist diff', - sprintf('diff between playlists "spotify:playlist:%s" and "spotify:playlist:%s"', $playlistID1, $playlistID2), - ); - - $this->addTracks($playlistID, $diff); - - return $diff; - } - - public function merge(string $targetID, string ...$playlistIDs):array{ - $merged = $this->getPlaylist($targetID); - - foreach($playlistIDs as $playlistID){ - $merged = array_merge($merged, $this->getPlaylist($playlistID)); - } - - $playlistID = $this->createPlaylist( - 'playlist merge', - sprintf('merged playlists "%s" into "spotify:playlist:%s"', implode('", "', $playlistIDs), $targetID), - ); - - $this->addTracks($playlistID, array_keys($merged)); - - return $merged; - } - -} - -/** - * @var \OAuthExampleProviderFactory $factory - * @var \PlaylistDiff $spotify - */ - -$spotify = $factory->getProvider(PlaylistDiff::class, OAuthExampleProviderFactory::STORAGE_FILE); -$spotify->diff('37i9dQZF1DX4UtSsGT1Sbe', '37i9dQZF1DXb57FjYWz00c'); -$spotify->merge('37i9dQZF1DX4UtSsGT1Sbe', '37i9dQZF1DXb57FjYWz00c'); diff --git a/examples/Providers/Spotify/spotify-common.php b/examples/Providers/Spotify/spotify-common.php deleted file mode 100644 index 16601f8..0000000 --- a/examples/Providers/Spotify/spotify-common.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @copyright 2019 smiley - * @license MIT - */ -declare(strict_types=1); - -namespace chillerlan\OAuthExamples\Providers\Spotify; - -use chillerlan\OAuth\Providers\Spotify; - -require_once __DIR__.'/../../provider-example-common.php'; -require_once __DIR__.'/SpotifyClient.php'; - -/** @var \OAuthExampleProviderFactory $factory */ -$spotify = $factory->getProvider(Spotify::class, \OAuthExampleProviderFactory::STORAGE_FILE);