From 6722c737b8dbc61cf1894da5cf5ff7fbcd623094 Mon Sep 17 00:00:00 2001 From: Yujiro Akihiro Date: Thu, 4 Jul 2024 03:56:46 +0200 Subject: [PATCH 1/2] #1 Create Account and set up API --- app.js | 15 +++++++++++++++ package.json | 8 +++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/app.js b/app.js index 5ea8eb4db..decfdbedc 100644 --- a/app.js +++ b/app.js @@ -4,6 +4,8 @@ const express = require('express'); const hbs = require('hbs'); // require spotify-web-api-node package here: +const SpotifyWebApi = require('spotify-web-api-node'); + const app = express(); @@ -12,7 +14,20 @@ app.set('views', __dirname + '/views'); app.use(express.static(__dirname + '/public')); // setting the spotify-api goes here: +const spotifyApi = new SpotifyWebApi({ + clientId: process.env.CLIENT_ID, + clientSecret: process.env.CLIENT_SECRET + }); + + spotifyApi + .clientCredentialsGrant() + .then(data => spotifyApi.setAccessToken(data.body['access_token'])) + .catch(error => console.log('Something went wrong when retrieving an access token', error)); + // Our routes go here: +app.get('/', (req, res) => { + res.render('index'); + }); app.listen(3000, () => console.log('My Spotify project running on port 3000 🎧 đŸĨ 🎸 🔊')); diff --git a/package.json b/package.json index c9f4085ba..bed238e08 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,12 @@ "author": "", "license": "ISC", "devDependencies": { - "nodemon": "^2.0.2" + "nodemon": "^2.0.22" + }, + "dependencies": { + "dotenv": "^16.4.5", + "express": "^4.19.2", + "hbs": "^4.2.0", + "spotify-web-api-node": "^5.0.2" } } From fcef3b6cde09f2cfe3c6bace303eb7955252461e Mon Sep 17 00:00:00 2001 From: Yujiro Akihiro Date: Thu, 4 Jul 2024 05:14:15 +0200 Subject: [PATCH 2/2] #Done* --- app.js | 64 ++++++++++--- public/styles/style.css | 162 ++++++++++++++++++++++++++++++++ views/albums.hbs | 27 ++++++ views/artist-search-results.hbs | 25 +++++ views/index.hbs | 19 ++++ views/layout.hbs | 12 +++ views/tracks.hbs | 43 +++++++++ 7 files changed, 340 insertions(+), 12 deletions(-) create mode 100644 views/albums.hbs create mode 100644 views/artist-search-results.hbs create mode 100644 views/index.hbs create mode 100644 views/layout.hbs create mode 100644 views/tracks.hbs diff --git a/app.js b/app.js index decfdbedc..e66c3131a 100644 --- a/app.js +++ b/app.js @@ -2,32 +2,72 @@ require('dotenv').config(); const express = require('express'); const hbs = require('hbs'); - -// require spotify-web-api-node package here: const SpotifyWebApi = require('spotify-web-api-node'); - const app = express(); app.set('view engine', 'hbs'); app.set('views', __dirname + '/views'); app.use(express.static(__dirname + '/public')); -// setting the spotify-api goes here: +// Spotify API setup const spotifyApi = new SpotifyWebApi({ - clientId: process.env.CLIENT_ID, - clientSecret: process.env.CLIENT_SECRET - }); + clientId: process.env.CLIENT_ID, + clientSecret: process.env.CLIENT_SECRET +}); - spotifyApi +// Retrieve an access token +spotifyApi .clientCredentialsGrant() .then(data => spotifyApi.setAccessToken(data.body['access_token'])) .catch(error => console.log('Something went wrong when retrieving an access token', error)); - -// Our routes go here: +// Home route app.get('/', (req, res) => { - res.render('index'); - }); + res.render('index'); +}); + +// Artist search route +app.get('/artist-search', (req, res) => { + const { artist } = req.query; + + spotifyApi + .searchArtists(artist) + .then(data => { + console.log('The received data from the API: ', data.body); + res.render('artist-search-results', { artists: data.body.artists.items }); + }) + .catch(err => console.log('The error while searching artists occurred: ', err)); +}); + +// Albums route +app.get('/albums/:artistId', (req, res) => { + const { artistId } = req.params; + + spotifyApi + .getArtistAlbums(artistId) + .then(data => { + console.log('Artist albums', data.body); + spotifyApi.getArtist(artistId).then(artistData => { + res.render('albums', { albums: data.body.items, artistName: artistData.body.name }); + }); + }) + .catch(err => console.log('The error while searching albums occurred: ', err)); +}); + +// Tracks route +app.get('/tracks/:albumId', (req, res) => { + const { albumId } = req.params; + + spotifyApi + .getAlbumTracks(albumId) + .then(data => { + console.log('Album tracks', data.body); + spotifyApi.getAlbum(albumId).then(albumData => { + res.render('tracks', { tracks: data.body.items, albumName: albumData.body.name }); + }); + }) + .catch(err => console.log('The error while searching tracks occurred: ', err)); +}); app.listen(3000, () => console.log('My Spotify project running on port 3000 🎧 đŸĨ 🎸 🔊')); diff --git a/public/styles/style.css b/public/styles/style.css index e69de29bb..c74e92f3c 100644 --- a/public/styles/style.css +++ b/public/styles/style.css @@ -0,0 +1,162 @@ +body, html { + height: 100%; + margin: 0; + font-family: Arial, Helvetica, sans-serif; + } + + .background { + background-image: url('/images/spotify-background.jpeg'); + height: 100%; + background-position: center; + background-repeat: no-repeat; + background-size: cover; + display: flex; + justify-content: center; + align-items: center; + } + + .search-container { + background-color: rgba(255, 255, 255, 0.8); /* 透明åēĻãŽã‚ã‚‹čƒŒæ™¯ */ + padding: 20px; + border-radius: 10px; + } + + .search-container input[type="text"] { + padding: 10px; + margin-right: 10px; + border: 1px solid #ccc; + border-radius: 5px; + } + + .search-container button { + padding: 10px 20px; + background-color: #f44336; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; + } + + .search-container button:hover { + background-color: #d32f2f; + } + + h1 { + text-align: center; + margin-top: 20px; + } + + .artists-container, .albums-container { + display: flex; + justify-content: center; + flex-wrap: wrap; + margin-top: 20px; + } + + .artist, .album { + display: flex; + flex-direction: column; + justify-content: space-between; + margin: 20px; + border: 1px solid #ddd; + border-radius: 5px; + overflow: hidden; + width: 200px; + height: 400px; /* å›ē厚ぎéĢ˜ã•ã‚’č¨­åŽš */ + text-align: center; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + } + + .artist img, .album img, .artist .no-image, .album .no-image { + width: 100%; + height: auto; + max-height: 300px; /* į”ģ像ぎ最大éĢ˜ã•ã‚’č¨­åŽš */ + } + + .artist .no-image, .album .no-image { + display: flex; + justify-content: center; + align-items: center; + height: 300px; /* į”ģ像がãĒい場合ぎéĢ˜ã•ã‚’č¨­åŽš */ + background-color: #f0f0f0; + color: #888; + } + + .artist h2, .album h2 { + font-size: 16px; + margin: 10px 0; + } + + .btn { + display: block; + padding: 10px 20px; + background-color: #f44336; + color: white; + text-decoration: none; + border-radius: 5px; + margin: 10px auto 0; + transition: background-color 0.3s; + } + + .btn:hover { + background-color: #d32f2f; + } + + .tracks-table { + width: 80%; + margin: 20px auto; + border-collapse: collapse; + } + + .tracks-table th, .tracks-table td { + border: 1px solid #ddd; + padding: 10px; + } + + .tracks-table .title-header { + text-align: left; + } + + .tracks-table .listen-header { + text-align: center; + } + + .tracks-table .title-cell { + text-align: left; + } + + .tracks-table .listen-cell { + text-align: right; + } + + .tracks-table th { + background-color: #333; + color: white; + } + + .tracks-table td { + background-color: #f9f9f9; + } + + .audio-container { + display: flex; + justify-content: flex-end; + align-items: center; + } + + .audio-container audio { + margin-right: 10px; + } + + .download-btn { + color: #f44336; + text-decoration: none; + padding: 5px; + border-radius: 5px; + transition: color 0.3s; + } + + .download-btn:hover { + color: #d32f2f; + } + \ No newline at end of file diff --git a/views/albums.hbs b/views/albums.hbs new file mode 100644 index 000000000..6738c2aa2 --- /dev/null +++ b/views/albums.hbs @@ -0,0 +1,27 @@ + + + + + + Spotify Albums + + + +

Albums for: {{artistName}}

+
+ {{#each albums}} +
+ {{#if this.images.[0]}} + {{this.name}} + {{else}} +
No Image Available
+ {{/if}} +
+

{{this.name}}

+ View Tracks +
+
+ {{/each}} +
+ + diff --git a/views/artist-search-results.hbs b/views/artist-search-results.hbs new file mode 100644 index 000000000..b35ab8d98 --- /dev/null +++ b/views/artist-search-results.hbs @@ -0,0 +1,25 @@ + + + + + + Spotify Search Results + + + +

Artist Search Results

+
+ {{#each artists}} +
+

{{this.name}}

+ {{#if this.images.[0]}} + {{this.name}} + {{else}} +
No Image Available
+ {{/if}} + View Albums +
+ {{/each}} +
+ + diff --git a/views/index.hbs b/views/index.hbs new file mode 100644 index 000000000..4a9102cf3 --- /dev/null +++ b/views/index.hbs @@ -0,0 +1,19 @@ + + + + + + Spotify Search + + + +
+
+
+ + +
+
+
+ + diff --git a/views/layout.hbs b/views/layout.hbs new file mode 100644 index 000000000..4df70fd68 --- /dev/null +++ b/views/layout.hbs @@ -0,0 +1,12 @@ + + + + + + Spotify Search + + + + {{{body}}} + + diff --git a/views/tracks.hbs b/views/tracks.hbs new file mode 100644 index 000000000..9ec3f77b2 --- /dev/null +++ b/views/tracks.hbs @@ -0,0 +1,43 @@ + + + + + + Spotify Tracks + + + + +

Tracks for: {{albumName}}

+ + + + + + + + + {{#each tracks}} + + + + + {{/each}} + +
TitleListen
{{this.name}} + {{#if this.preview_url}} +
+ + + + +
+ {{else}} + No preview available + {{/if}} +
+ +