v0.2:
[Marketplaylister.git] / callback.php
1 <?php
2 declare(strict_types = 1);
3
4 require 'secrets.php';
5 require 'mpfuncs.php';
6
7 const BASE_URL = 'https://api.spotify.com/v1/';
8 const AUTH_URL = 'https://accounts.spotify.com/';
9 const DATE_FILE = 'prev_date.txt';
10 const DATE_FORM = 'm/d/Y';
11 const MONTHS = [
12 '01' => 'January',
13 '02' => 'February',
14 '03' => 'March',
15 '04' => 'April',
16 '05' => 'May',
17 '06' => 'June',
18 '07' => 'July',
19 '08' => 'August',
20 '09' => 'September',
21 '10' => 'October',
22 '11' => 'November',
23 '12' => 'December',
24 ];
25
26 $code = $_GET['code'];
27
28 if (!$code) {
29 exit(1);
30 }
31
32 $today = new DateTime;
33
34 #print_r($today);
35
36 $prevDTTxt = file_get_contents(DATE_FILE);
37
38 $prevDT = $prevDTTxt ? DateTime::createFromFormat(DATE_FORM, $prevDTTxt) : DateTime::createFromFormat(DATE_FORM, $today->format('m/') . '01' . $today->format('/Y'));
39
40 if (strcmp($prevDT->format('m'), $today->format('m')) < 0) {
41 $prevDT = DateTime::createFromFormat(DATE_FORM, $today->format('m/') . '01' . $today->format('/Y'));
42 }
43
44
45 #Handle Spotify Token Authorization
46
47 $token_data = [
48 'grant_type' => 'authorization_code',
49 'code' => $code,
50 'redirect_uri' => REDIRECT_URI
51 ];
52 $token_data = http_build_query($token_data);
53
54 $token_opts = [
55 'http' => [
56 'method' => 'POST',
57 /*'header' => "Content-type: application/x-www-form-urlencoded\r\n"
58 . "Content-Length: " . strlen($token_data) . "\r\n"
59 . "Authorization: Basic " . base64_encode('868e2cba00de4819900dd8a647a7ba7d:' . CLIENT_SECRET) . "\r\n",*/
60 'header' => "Authorization: Basic " . base64_encode('868e2cba00de4819900dd8a647a7ba7d:' . CLIENT_SECRET) . " \r\n",
61 'content' => $token_data
62 ]
63 ];
64
65 $token_context = stream_context_create($token_opts);
66
67 $spot_req = file_get_contents(AUTH_URL . 'api/token', false, $token_context);
68
69 #echo $spot_req;
70 $spot_json = json_decode($spot_req, true);
71
72 $spot_token = $spot_json['access_token'];
73
74 $me_opts = [
75 'http' => [
76 'method' => 'GET',
77 'header' => 'Authorization: Bearer ' . $spot_token . "\r\n"
78 ]
79 ];
80
81 $me_context = stream_context_create($me_opts);
82
83 $me_resp = file_get_contents(BASE_URL . 'me', false, $me_context);
84 $me_json = json_decode($me_resp, true);
85 $me_id = $me_json['id'];
86
87 echo '<br />';
88 #print_r($me_resp);
89
90 $page = 1;
91 $html = file_get_contents('https://www.marketplace.org/latest-music');
92 $DOM = new DOMDocument;
93 $DOM->loadHTML($html);
94 $headers = $DOM->getElementsByTagName('h2');
95 $divs = $DOM->getElementsByTagName('div');
96
97 $recentEpDT;
98 $episodePages = [];
99
100 foreach ($headers as $header) {
101 if ($header->hasAttribute('class') && $header->getAttribute('class') === 'river--hed') {
102 $recentEpDT = DateTime::createFromFormat(DATE_FORM, explode(':', $header->nodeValue)[0]);
103 break;
104 }
105 }
106
107 $prevDate = (int) $prevDT->format('d');
108 $recentEpDate = (int) $recentEpDT->format('d');
109 $daysToGet = ($prevDate === 1) ? $recentEpDate : $recentEpDate - $prevDate;
110 $daysToGet = $daysToGet - 2 * (int) ($daysToGet / 7);
111
112 if ($daysToGet === 0) {
113 echo 'No new episodes since last check.';
114 exit(0);
115 }
116
117
118 do {
119 $episodePages[] = parseEpisodePage($divs, $daysToGet);
120 } while ($daysToGet > 0 && ($DOM->loadHTML(file_get_contents('https://www.marketplace.org/latest-music?page=' . ++$page))) && ($divs = $DOM->getElementsByTagName('div')) );
121
122 /*
123 echo '<br />';
124
125 print_r($date_headers);
126
127 echo '<br />';
128 print_r($episodes);
129 */
130
131 print_r($episodePages);
132
133 # Check if this month's playlist exists
134
135 $playlistName = MONTHS[$today->format('m')] . ' Marketplace Tracks';
136
137 $checkPlaylistOpts = [
138 'http' => [
139 'method' => 'GET',
140 'header' => 'Authorization: Bearer ' . $spot_token . "\r\n"
141 ]
142 ];
143
144 $checkPlaylistContext = stream_context_create($checkPlaylistOpts);
145
146 $checkPlaylistReq = file_get_contents(BASE_URL . 'me/playlists', false, $checkPlaylistContext);
147
148 $checkPlaylistJson = json_decode($checkPlaylistReq, true);
149
150 foreach ($checkPlaylistJson['items'] as $playlist) {
151 #TODO should check if $user owns playlist
152 if (!strcmp($playlistName, $playlist['name'])) {
153 $playlistID = $playlist['id'];
154 }
155 }
156
157 #echo 'playlistID' . $playlistID;
158
159 # Create new playlist if one does not exist
160 # DEVELOPMENT TEMP ALWAYS CREATE NEW PLAYLIST
161 #if (!$playlistID) {
162 if (true) {
163
164 $playlist_data = [
165 'name' => $playlistName,
166 ];
167
168 $playlist_opts = [
169 'http' => [
170 'method' => 'POST',
171 'header' => 'Authorization: Bearer ' . $spot_token . "\r\n"
172 . 'Content-Type application/json \r\n',
173 'content' => json_encode($playlist_data)
174 ]
175 ];
176
177 $playlist_context = stream_context_create($playlist_opts);
178 $playlist_req = file_get_contents(BASE_URL . 'users/' . $me_id . '/playlists', false, $playlist_context);
179 $playlist_json = json_decode($playlist_req, true);
180 $playlistID = $playlist_json['id'];
181
182 #echo '<br />' . $playlistID;
183
184 }
185
186 $uris = [];
187
188 foreach ( array_reverse($episodePages) as $episodes) {
189 foreach ( array_reverse($episodes) as $episode) {
190
191 $track_opts = [
192 'http' => [
193 'method' => 'GET',
194 'header' => 'Authorization: Bearer ' . $spot_token . "\r\n"
195 ]
196 ];
197
198 $track_context = stream_context_create($track_opts);
199
200 foreach ($episode as $song_info) {
201
202 $track_search_url = BASE_URL . 'search?q=track:' . urlencode($song_info['title'])
203 . '+artist:' . urlencode($song_info['artist']) . '&type=track';
204
205 #echo '<br />' . $track_search_url;
206 #echo '<br />';
207
208 $trackReq = file_get_contents($track_search_url, false, $track_context);
209 if ($trackReq) {
210 $trackJSON = json_decode($trackReq, true);
211 $trackJSON = $trackJSON['tracks'];
212
213 print_r($trackJSON);
214
215 if ($trackJSON['total'] === 0) {
216 continue;
217 }
218
219 $uris[] = $trackJSON['items'][0]['uri'];
220
221 #rate limit
222 sleep(1);
223
224 }
225 }
226 }
227 }
228
229 $update_data = [
230 'uris' => $uris,
231 ];
232
233 echo '<br /> update_data <br />';
234 #print_r($update_data);
235
236 $update_opts = [
237 'http' => [
238 'method' => 'POST',
239 'header' => 'Authorization: Bearer ' . $spot_token . "\r\n"
240 . 'Content-Type application/json \r\n',
241 'content' => json_encode($update_data)
242 ]
243 ];
244
245 $update_context = stream_context_create($update_opts);
246 $update_url = BASE_URL . 'users/' . $me_id . '/playlists/' . $playlistID . '/tracks';
247 echo '<br />' . $update_url;
248 echo '<br />';
249 echo '<br />' . count($uris);
250 echo '<br />';
251 print_r(json_encode($update_data));
252 $update_req = file_get_contents(BASE_URL . 'users/' . $me_id . '/playlists/' . $playlistID . '/tracks', false, $update_context);
253 print_r($update_req);
254
255 file_put_contents(DATE_FILE, $recentEpDT->format(DATE_FORM));
256