displays the user's top songs via spotify api, authentication via oauth 2.
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
module cs2440.joshashton.dev/api
|
||||||
|
|
||||||
|
go 1.23.5
|
||||||
|
|
||||||
|
require github.com/joho/godotenv v1.5.1 // indirect
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
|
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"fmt"
|
||||||
|
"github.com/joho/godotenv"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func generateRandomString(length int) string {
|
||||||
|
var b = make([]byte, length)
|
||||||
|
rand.Read(b)
|
||||||
|
return fmt.Sprintf("%x", b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := godotenv.Load("../.env")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error loading .env file: %s", err)
|
||||||
|
}
|
||||||
|
client_id := os.Getenv("SPOTIFY_CLIENT_ID")
|
||||||
|
|
||||||
|
redirect_uri := "http://localhost/music"
|
||||||
|
|
||||||
|
http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
scope := "user-top-read"
|
||||||
|
|
||||||
|
redirectURL := "https://accounts.spotify.com/authorize?" + strings.Join([]string{
|
||||||
|
"response_type=code",
|
||||||
|
"client_id=" + client_id,
|
||||||
|
"scope=" + scope,
|
||||||
|
"redirect_uri=" + redirect_uri,
|
||||||
|
}, "&")
|
||||||
|
|
||||||
|
http.Redirect(w, r, redirectURL, http.StatusFound)
|
||||||
|
})
|
||||||
|
|
||||||
|
http.ListenAndServe(":8080", nil)
|
||||||
|
}
|
||||||
+1
-4
@@ -1,6 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
function get_core()
|
|
||||||
{
|
|
||||||
$albums = [
|
$albums = [
|
||||||
array('name' => 'Abyss', 'artist' => 'Pastel Ghost', 'link' => 'https://open.spotify.com/album/2FQieUp8BxPN7OR8fE76TE'),
|
array('name' => 'Abyss', 'artist' => 'Pastel Ghost', 'link' => 'https://open.spotify.com/album/2FQieUp8BxPN7OR8fE76TE'),
|
||||||
array('name' => 'Golden Age - The 4th Album', 'artist' => 'NCT 127', 'link' => 'https://open.spotify.com/album/5mUo2e4QpUA7NJl2t51uFu'),
|
array('name' => 'Golden Age - The 4th Album', 'artist' => 'NCT 127', 'link' => 'https://open.spotify.com/album/5mUo2e4QpUA7NJl2t51uFu'),
|
||||||
@@ -34,6 +32,5 @@ function get_core()
|
|||||||
</table>
|
</table>
|
||||||
';
|
';
|
||||||
|
|
||||||
return $html;
|
echo $html;
|
||||||
}
|
|
||||||
?>
|
?>
|
||||||
|
|||||||
+99
-6
@@ -7,7 +7,11 @@ $html = '';
|
|||||||
|
|
||||||
$client_id = $_ENV['SPOTIFY_CLIENT_ID'];
|
$client_id = $_ENV['SPOTIFY_CLIENT_ID'];
|
||||||
$client_secret = $_ENV['SPOTIFY_CLIENT_SECRET'];
|
$client_secret = $_ENV['SPOTIFY_CLIENT_SECRET'];
|
||||||
$access_token = get_access_token($client_id, $client_secret);
|
// $auth_code = $_ENV['SPOTIFY_AUTH_CODE'];
|
||||||
|
$auth_code = $_GET['code'];
|
||||||
|
// $auth_state = $_GET['state'];
|
||||||
|
|
||||||
|
$client_credentials = get_client_credentials($client_id, $client_secret);
|
||||||
|
|
||||||
// TODO: Dynamically retrieve top 10 albums from Spotify API
|
// TODO: Dynamically retrieve top 10 albums from Spotify API
|
||||||
// TODO: Implement server-side caching for faster load times.
|
// TODO: Implement server-side caching for faster load times.
|
||||||
@@ -24,9 +28,11 @@ $albums = [
|
|||||||
'2eQMC9nJE3f3hCNKlYYHL1'
|
'2eQMC9nJE3f3hCNKlYYHL1'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
shuffle($albums);
|
||||||
|
|
||||||
$content = '';
|
$content = '';
|
||||||
foreach ($albums as $album_id) {
|
foreach ($albums as $album_id) {
|
||||||
$data = get_album($access_token, $album_id);
|
$data = get_album($client_credentials, $album_id);
|
||||||
$content = $content . '<tr>
|
$content = $content . '<tr>
|
||||||
<td><img src="' . $data['images'][0]['url'] . '" /></td>
|
<td><img src="' . $data['images'][0]['url'] . '" /></td>
|
||||||
<td>' . $data['name'] . '</td>
|
<td>' . $data['name'] . '</td>
|
||||||
@@ -44,7 +50,7 @@ $html = '
|
|||||||
<th>Spotify</th>
|
<th>Spotify</th>
|
||||||
</tr>' . $content . '</table>';
|
</tr>' . $content . '</table>';
|
||||||
|
|
||||||
function get_access_token($client_id, $client_secret)
|
function get_client_credentials($client_id, $client_secret)
|
||||||
{
|
{
|
||||||
$url = 'https://accounts.spotify.com/api/token';
|
$url = 'https://accounts.spotify.com/api/token';
|
||||||
|
|
||||||
@@ -80,7 +86,7 @@ function get_access_token($client_id, $client_secret)
|
|||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_album($access_token, $album_id)
|
function get_album($client_credentials, $album_id)
|
||||||
{
|
{
|
||||||
$url = 'https://api.spotify.com/v1/albums/' . $album_id;
|
$url = 'https://api.spotify.com/v1/albums/' . $album_id;
|
||||||
|
|
||||||
@@ -89,7 +95,7 @@ function get_album($access_token, $album_id)
|
|||||||
curl_setopt_array($ch, array(
|
curl_setopt_array($ch, array(
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
CURLOPT_HTTPHEADER => array(
|
CURLOPT_HTTPHEADER => array(
|
||||||
"Authorization: Bearer $access_token"
|
"Authorization: Bearer $client_credentials"
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -105,5 +111,92 @@ function get_album($access_token, $album_id)
|
|||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
echo $html;
|
function get_access_token($auth_code, $client_id, $client_secret)
|
||||||
|
{
|
||||||
|
$url = 'https://accounts.spotify.com/api/token';
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'grant_type' => 'authorization_code',
|
||||||
|
'code' => $auth_code,
|
||||||
|
'redirect_uri' => 'http://localhost/music'
|
||||||
|
);
|
||||||
|
|
||||||
|
$client_info = base64_encode("$client_id:$client_secret");
|
||||||
|
$post_data = http_build_query($data);
|
||||||
|
|
||||||
|
$ch = curl_init($url);
|
||||||
|
|
||||||
|
curl_setopt_array($ch, array(
|
||||||
|
CURLOPT_POST => true,
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
CURLOPT_HTTPHEADER => array(
|
||||||
|
"Authorization: Basic $client_info",
|
||||||
|
'Content-Type: application/x-www-form-urlencoded'
|
||||||
|
),
|
||||||
|
CURLOPT_POSTFIELDS => $post_data
|
||||||
|
));
|
||||||
|
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
|
||||||
|
if (curl_errno($ch)) {
|
||||||
|
echo curl_error($ch);
|
||||||
|
} else {
|
||||||
|
$data = json_decode($response, true);
|
||||||
|
curl_close($ch);
|
||||||
|
return $data['access_token'];
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_close($ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_albums($auth_code, $client_id, $client_secret)
|
||||||
|
{
|
||||||
|
$access_token = get_access_token($auth_code, $client_id, $client_secret);
|
||||||
|
$url = 'https://api.spotify.com/v1/me/top/tracks';
|
||||||
|
|
||||||
|
$ch = curl_init($url);
|
||||||
|
|
||||||
|
curl_setopt_array($ch, array(
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
CURLOPT_HTTPHEADER => array(
|
||||||
|
"Authorization: Bearer $access_token"
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
|
||||||
|
if (curl_errno($ch)) {
|
||||||
|
echo curl_error($ch);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
$data = json_decode($response, true);
|
||||||
|
$top_songs = $data['items'];
|
||||||
|
}
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
$song_data = [];
|
||||||
|
foreach ($top_songs as $song) {
|
||||||
|
$song_data[] = array(
|
||||||
|
'image' => $song['album']['images'][0]['url'],
|
||||||
|
'song_name' => $song['name'],
|
||||||
|
'song_id' => $song['id'],
|
||||||
|
'album_name' => $song['album']['name'],
|
||||||
|
'album_id' => $song['album']['id'],
|
||||||
|
'artist' => $song['artists'][0]['name'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($song_data as $s) {
|
||||||
|
echo '
|
||||||
|
<img src="' . $s['image'] . '">
|
||||||
|
<h3>Name: ' . $s['song_name'] . ' - ' . $s['artist'] . '</h3>
|
||||||
|
<h4>Album: ' . $s['album_name'] . '</h4>
|
||||||
|
<h6>Song ID: ' . $s['song_id'] . '</h6>
|
||||||
|
<h6>Album ID: ' . $s['album_id'] . '</h6>
|
||||||
|
';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get_albums($auth_code, $client_id, $client_secret);
|
||||||
|
// echo $html;
|
||||||
?>
|
?>
|
||||||
|
|||||||
+3
-5
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
include ('core.php');
|
include ('login.php');
|
||||||
exec('php explore.php &');
|
exec('php explore.php &');
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
@@ -14,12 +14,10 @@ exec('php explore.php &');
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<h1>My Favorite Albums</h1>
|
<h1>My Favorite Albums</h1>
|
||||||
<button onclick=modeSwitch() type="submit">Click me</button>
|
<button id="switcher" onclick=modeSwitch('core')>Core</button>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<?php
|
<?php include ('explore.php'); ?>
|
||||||
echo get_core();
|
|
||||||
?>
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+16
-1
@@ -1,5 +1,7 @@
|
|||||||
async function modeSwitch() {
|
async function modeSwitch(mode) {
|
||||||
const content = document.getElementById("content");
|
const content = document.getElementById("content");
|
||||||
|
console.log(mode);
|
||||||
|
if (mode == 'explore') {
|
||||||
var response = await fetch('explore.php');
|
var response = await fetch('explore.php');
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
@@ -7,4 +9,17 @@ async function modeSwitch() {
|
|||||||
let text = await data();
|
let text = await data();
|
||||||
content.innerHTML = text;
|
content.innerHTML = text;
|
||||||
}
|
}
|
||||||
|
switcher.setAttribute("onclick", "modeSwitch('core')")
|
||||||
|
switcher.innerText = 'Core';
|
||||||
|
} else {
|
||||||
|
var response = await fetch('core.php');
|
||||||
|
|
||||||
|
if (response.status === 200) {
|
||||||
|
let data = async () => { return await response.text() };
|
||||||
|
let text = await data();
|
||||||
|
content.innerHTML = text;
|
||||||
|
}
|
||||||
|
switcher.setAttribute("onclick", "modeSwitch('explore')")
|
||||||
|
switcher.innerText = 'Explore';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
<?php
|
|
||||||
echo 'test';
|
|
||||||
?>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<?php
|
|
||||||
echo '<p>Test</p>';
|
|
||||||
?>
|
|
||||||
Reference in New Issue
Block a user