Skip to content

Commit

Permalink
Merge resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
AnoldGH committed Nov 7, 2024
2 parents 103a3e3 + 8492316 commit 8b3d23c
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 53 deletions.
12 changes: 12 additions & 0 deletions backend/models/songModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const mongoose = require("mongoose");

// WE DONT USE THIS YET (GOTTA FIGURE OUT DB CONFIG)
const songSchema = new mongoose.Schema({
title: { type: String, required: true },
artist: { type: String, required: true },
album: { type: String },
duration: { type: Number },
preview_url: { type: String },
});

module.exports = mongoose.model("Song", songSchema);
28 changes: 0 additions & 28 deletions backend/routes/spotifyRoute.js

This file was deleted.

66 changes: 66 additions & 0 deletions backend/routes/spotifyRouter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
const express = require("express");
const router = express.Router();
const axios = require("axios");
const { getAccessToken } = require("../utility/tokenManager");

// Get spotify access token with client credentials flow
// see https://developer.spotify.com/documentation/web-api/tutorials/client-credentials-flow
router.get('/token', async (req, res) => {
try {
const accessToken = await getAccessToken()
res.json({
success: true,
access_token: accessToken
})
} catch (error) {
res.status(500).json({
success: false,
message: "Failed to retrieve access token",
details: error.message
})
}
})

// Get track from track ID
router.get("/track/:id", async (req, res) => {
const trackId = req.params.id;

try {
const accessToken = await getAccessToken();
const response = await axios.get(
`https://api.spotify.com/v1/tracks/${trackId}`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
);
res.json(response.data);
} catch (error) {
res.status(500).json({ error: "Failed to fetch track data" });
}
});

// Get recommendation from genre
router.get("/recommendations", async (req, res) => {
const { genres, limit = 10 } = req.query; // Default to "pop" if genres is not provided
const accessToken = await getAccessToken();

try {
const response = await axios.get(
`https://api.spotify.com/v1/recommendations?seed_genres=${genres}&limit=${limit}`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
);
res.json(response.data);

} catch (error) {
console.error("Error fetching recommendations:", error);
res.status(500).json({ error: "Failed to fetch recommendations" });
}
});

module.exports = router;
8 changes: 5 additions & 3 deletions backend/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const validator = require('validator');
const http = require('http');
const socketIo = require('socket.io');
const cron = require('node-cron');
const spotifyRoute = require('./routes/spotifyRoute.js')
const spotifyRouter = require('./routes/spotifyRouter.js')

const app = express();
app.use(cors());
Expand All @@ -17,8 +17,10 @@ const server = http.createServer(app);
const db = require('./db.js');

// Routes
// --- Spotify route
app.use('/api/spotify', spotifyRoute)
// --- Spotify access token
app.use('/api/spotify', spotifyRouter)
// spotify song routes
app.use('/songModel', spotifyRouter)

server.listen(port, () => {
console.log(`Server running on port ${port}`);
Expand Down
76 changes: 54 additions & 22 deletions frontend/src/App.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,64 @@
import logo from './logo.svg';
import React, {useState, useEffect} from 'react'
import './App.css';
import logo from "./logo.svg";
import React, { useState, useEffect } from "react";
import "./App.css";

function App() {
const [token, setToken] = useState('')
// state for genre
const [selectedGenre, setSelectedGenre] = useState("");

useEffect(() => {
fetch(`${process.env.REACT_APP_API_URL}/api/spotify/token`)
.then(response => response.json())
.then(data => setToken(data.access_token))
.catch(error => console.error("Error fetching token: ", error))
}, [])
// play random previewurl
const playRandomPreview = async () => {
try {
const response = await fetch(
`http://localhost:5000/songModel/recommendations?genres=${selectedGenre}&limit=10`
);
const data = await response.json();

// only get tracks with previewurls
const tracksWithPreview = data.tracks.filter(
(track) => track.preview_url
);

// set random previewurl
if (tracksWithPreview.length > 0) {
const randomTrack =
tracksWithPreview[
Math.floor(Math.random() * tracksWithPreview.length)
];
const previewUrl = randomTrack.preview_url;

// set audio and play
const audio = new Audio(previewUrl);
audio.play();
} else {
alert("No previews available for this genre.");
}
} catch (error) {
console.error("Error fetching recommendations:", error);
}
};

return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
{token ? <p> Token: {token} </p> : <p>No token fetched</p>}
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
<label>
Select Genre:
<select
value={selectedGenre}
onChange={(e) => setSelectedGenre(e.target.value)}
>
<option value=""
disabled>Choose Genre
</option>
<option value="pop">Pop</option>
<option value="rock">Rock</option>
<option value="hip-hop">Hip-Hop</option>
<option value="jazz">Jazz</option>

</select>
</label>

<button onClick={playRandomPreview}>Get Random Preview</button>
</header>
</div>
);
Expand Down

0 comments on commit 8b3d23c

Please sign in to comment.