diff --git a/models/playlist.js b/models/playlist.js new file mode 100644 index 0000000..f985356 --- /dev/null +++ b/models/playlist.js @@ -0,0 +1,13 @@ +const mongoose = require('mongoose'); +const songSchema = require('../models/song').schema; +const userSchema = require('../models/user').schema; + +const playlistSchema = new mongoose.Schema({ + user: userSchema, + songs: [songSchema], +}); + + +var Playlist = mongoose.model('Playlist',playlistSchema); + +module.exports = Playlist; \ No newline at end of file diff --git a/models/song.js b/models/song.js new file mode 100644 index 0000000..a19413a --- /dev/null +++ b/models/song.js @@ -0,0 +1,16 @@ +const mongoose = require('mongoose'); + + +const songSchema = new mongoose.Schema({ + id: String, + title: String, + preview: String, + cover_big: String, + cover_xl: String, + artist: String, +}); + + +var Song= mongoose.model('Song',songSchema); + +module.exports = Song; \ No newline at end of file diff --git a/models/user.js b/models/user.js new file mode 100644 index 0000000..b0d6d14 --- /dev/null +++ b/models/user.js @@ -0,0 +1,15 @@ +const mongoose = require('mongoose'); + + + +const userSchema = new mongoose.Schema({ + googleId: String, + firstName: String, + lastName: String, + profilePhoto: String, +}); + + +var User = mongoose.model('User',userSchema); + +module.exports = User; \ No newline at end of file diff --git a/routes/index.js b/routes/index.js new file mode 100644 index 0000000..9922c5a --- /dev/null +++ b/routes/index.js @@ -0,0 +1,43 @@ +const express = require('express'); +const router = express.Router(); +const passport = require('passport'); + + + + +router.get("/",function(req,res){ + + let user=null; + if (req.isAuthenticated()) { + user = req.user; + } + res.render("home",{ showNavbar: true, user: user}); +}); + +router.get("/login", + passport.authenticate("google", { scope: ["profile"] }) +); + +router.get('/auth/google/musicbuzz', + passport.authenticate('google', { failureRedirect: "/login" }), + function(req, res) { + // Successful authentication, redirect home. + res.redirect("/"); + console.log("Successfully logged in"); +}); + + + +router.use("/songs",require('./songs')); + + +router.use("/:userId",require('./user')); + + +router.use("/search", require('./search')); + + + +router.use("/playlists", require('./playlist')); + +module.exports = router ; \ No newline at end of file diff --git a/routes/playlist.js b/routes/playlist.js new file mode 100644 index 0000000..0b4d70f --- /dev/null +++ b/routes/playlist.js @@ -0,0 +1,78 @@ +const express = require('express'); +const router = express.Router(); +const Song = require('../models/song'); +const Playlist = require('../models/playlist'); + +router.get("/", function (req, res) { + if (req.isAuthenticated()) { + res.redirect("/" + req.user._id + "/playlists"); + } else { + res.send("You need to be logged in to view or create your playlist"); + } +}); + +router.post("/",function (req, res) { + if (!req.isAuthenticated()) { + res.redirect("/login"); + } else { + const currentUser = req.user; + const songInfo = JSON.parse(req.body.songInfo); + console.log(songInfo); + Playlist.findOne({ user: currentUser }, function (err, foundPlaylist) { + if (err) { + console.log(err); + } else { + const songToAdd = new Song({ + id: songInfo.id, + title: songInfo.title, + preview: songInfo.preview, + cover_big: songInfo.cover_big, + cover_xl: songInfo.cover_xl, + artist: songInfo.artist + }); + if (!foundPlaylist) { + // Create a new Playlist + songs = [songToAdd]; + const list = new Playlist({ + user: currentUser, + songs: songs, + }); + list.save(function (err) { + if (!err) { + res.redirect("/"); + console.log("Successfully added song to your favorites"); + } + }); + } else { + + let flag = 1; + // Check if song already exists in the playlist + foundPlaylist.songs.forEach(song => { + if (song.id === songToAdd.id) { + flag = 0; + } + if (flag === 0) { + console.log("Song already exists in your favorites"); + res.redirect("/"); + } else { + // Add Song to existing Playlist + foundPlaylist.songs.push(songToAdd); + foundPlaylist.save(function (err) { + console.log("Successfully added song to your favorites"); + res.redirect("/"); + }); + } + }); + } + } + }); + } +}); + + + + + + + +module.exports = router; \ No newline at end of file diff --git a/routes/search.js b/routes/search.js new file mode 100644 index 0000000..841c8bd --- /dev/null +++ b/routes/search.js @@ -0,0 +1,69 @@ +const express = require('express'); +const router = express.Router(); +const Song = require('../models/song'); +const unirest = require("unirest"); + + + +function search(query,callback){ + + var req = unirest("GET", "https://deezerdevs-deezer.p.rapidapi.com/search"); + + req.query({ + "q": query + }); + + req.headers({ + "x-rapidapi-host": "deezerdevs-deezer.p.rapidapi.com", + "x-rapidapi-key": process.env.API_KEY, + "useQueryString": true + }); + + req.end(function (res) { + if (res.error) throw new Error(res.error); + else{ + // console.log(res.body); + callback(res.body); + } + }); +} + + + + +router.post('/',function(req,res){ + let query = req.body.searchQuery; + res.redirect("/search/" + query); +}); + +router.get("/:name", function(req,res){ + + let user = null; + if (req.isAuthenticated()) { + user = req.user; + } + let query = req.params.name; + + let searchResponse = search(query,function(response){ + + const data = response.data; + let songList = []; + for(const song of data){ + const newSong = new Song({ + id: song.id, + title: song.title, + preview: song.preview, + cover_big: song.album.cover_big, + cover_xl: song.album.cover_xl, + artist: song.artist.name + }); + songList.push(newSong); + } + res.render("songlist",{songs: songList,user: user,showNavbar: true}); + }); +}) + + + + +module.exports = router ; \ No newline at end of file diff --git a/routes/songs.js b/routes/songs.js new file mode 100644 index 0000000..8785544 --- /dev/null +++ b/routes/songs.js @@ -0,0 +1,66 @@ +const express = require('express'); +const router = express.Router(); +const Song = require('../models/song'); +const unirest = require("unirest"); + +function getTrack(songId,callback){ + + var req = unirest("GET", "https://deezerdevs-deezer.p.rapidapi.com/track/" + songId); + + req.headers({ + "x-rapidapi-host": "deezerdevs-deezer.p.rapidapi.com", + "x-rapidapi-key": process.env.API_KEY, + "useQueryString": true + }); + + req.end(function (res) { + if (res.error) throw new Error(res.error); + + else{ + console.log(res.body); + callback(res.body); + } + + }); +} + + + +router.get('/',function(req,res){ + let query = req.body.searchQuery; + res.redirect("/songs/" + query); +}); + + +router.get("/:id",function(req,res){ + + + + let user = null; + if (req.isAuthenticated()) { + user = req.user; + } + const songId = req.params.id; + let trackResponse = getTrack(songId,function(response){ + + const songData = response; + const song = new Song({ + id: songId, + title: songData.title, + preview: songData.preview, + cover_big: songData.album.cover_big, + cover_xl: songData.album.cover_xl, + artist: songData.artist.name, + }); + // const song = {title: songData.title,preview: songData.preview, cover_big: songData.album.cover_big, cover_xl: songData.album.cover_xl, artist: songData.artist.name}; + + res.render("song",{song: song, user: user,showNavbar: false }); + + }); + +}); + + + + +module.exports = router ; \ No newline at end of file diff --git a/routes/user.js b/routes/user.js new file mode 100644 index 0000000..6ec360d --- /dev/null +++ b/routes/user.js @@ -0,0 +1,43 @@ +const express = require('express'); +const router = express.Router(); +const User = require('../models/user'); +const Playlist = require('../models/playlist'); + + +router.get("/logout", function (req, res) { + if (req.isAuthenticated()){ + req.logout(); + res.redirect("/"); + console.log("Successfully logged out"); + } else { + res.redirect("/login") + } +}); + +router.get("/playlists" , function (req, res) { + User.findOne({ _id: req.user.id }, function (err, foundUser) { + if (err) { + console.log(err); + } else { + Playlist.findOne({ user: foundUser}, function (err, foundPlaylist) { + if (err) { + console.log(err); + } else { + if (!foundPlaylist) { + res.send("No Playlists have been created"); + + } else { + res.render("songlist",{songs: foundPlaylist.songs, user: foundPlaylist.user, showNavbar: true}); + } + } + }); + } + }); +}); + + + + + + +module.exports = router ; \ No newline at end of file diff --git a/server.js b/server.js index 59e6413..1aaf29a 100644 --- a/server.js +++ b/server.js @@ -4,13 +4,14 @@ const bodyParser = require("body-parser"); const ejs = require("ejs"); const unirest = require("unirest"); const _ = require("lodash"); +const User = require('./models/user'); const mongoose = require("mongoose"); const session = require("express-session"); const passport = require("passport"); const passportLocalMongoose = require("passport-local-mongoose"); const GoogleStrategy = require("passport-google-oauth20").Strategy; -const findOrCreate = require("mongoose-findorcreate"); + const app = express(); @@ -37,39 +38,13 @@ mongoose.connect("mongodb://localhost:27017/songDB", { mongoose.set("useCreateIndex", true); -// Schema for the user -const userSchema = new mongoose.Schema({ - googleId: String, - firstName: String, - lastName: String, - profilePhoto: String, -}); - -// Schema for the song -const songSchema = new mongoose.Schema({ - id: String, - title: String, - preview: String, - cover_big: String, - cover_xl: String, - artist: String, -}); -// Schema for playlist -const playlistSchema = new mongoose.Schema({ - user: userSchema, - songs: [songSchema], -}); -userSchema.plugin(findOrCreate); -const User = mongoose.model("User", userSchema); -const Playlist = mongoose.model("Playlist", playlistSchema); -const Song = mongoose.model("Song", songSchema); passport.serializeUser(function(user, done) { @@ -89,270 +64,45 @@ passport.use(new GoogleStrategy({ clientSecret: process.env.CLIENT_SECRET, callbackURL: "http://localhost:3000/auth/google/musicbuzz" }, - function(accessToken, refreshToken, profile, cb) { - // console.log(profile); + async function(accessToken, refreshToken, profile, done) { + + try{ + let user = await User.findOne({id: profile.id.value}); + + if(user){ + return done(null,user); + } + // if user is not found in the database the we have to sign up using google + // create the user and set it to req.user + else{ + User.create({ + googleId: profile.id, + firstName: profile.name.givenName, + lastName: profile.name.familyName, + profilePhoto: profile.photos[0].value, - User.findOrCreate( - { - googleId: profile.id, - firstName: profile.name.givenName, - lastName: profile.name.familyName, - profilePhoto: profile.photos[0].value, - }, - function (err, user) { - return cb(err, user); + },function(err,user){ + if(err){console.log(err); return ;} + return done(null,user); + }); + } - ); + }catch(err){ + console.log(err); } -)); + })); // For searching based on the query String. -function search(query,callback){ - - var req = unirest("GET", "https://deezerdevs-deezer.p.rapidapi.com/search"); - req.query({ - "q": query - }); - - req.headers({ - "x-rapidapi-host": "deezerdevs-deezer.p.rapidapi.com", - "x-rapidapi-key": process.env.API_KEY, - "useQueryString": true - }); - - req.end(function (res) { - if (res.error) throw new Error(res.error); - else{ - // console.log(res.body); - callback(res.body); - } - }); -} // For getting a single track based on songId. -function getTrack(songId,callback){ - - var req = unirest("GET", "https://deezerdevs-deezer.p.rapidapi.com/track/" + songId); - - req.headers({ - "x-rapidapi-host": "deezerdevs-deezer.p.rapidapi.com", - "x-rapidapi-key": process.env.API_KEY, - "useQueryString": true - }); - - req.end(function (res) { - if (res.error) throw new Error(res.error); - - else{ - console.log(res.body); - callback(res.body); - } - }); -} // For home page - -app.get("/",function(req,res){ - - let user=null; - if (req.isAuthenticated()) { - user = req.user; - } - res.render("home",{ showNavbar: true, user: user}); -}); - -// For displaying the player. - -app.get("/songs/:id",function(req,res){ - - let user = null; - if (req.isAuthenticated()) { - user = req.user; - } - const songId = req.params.id; - let trackResponse = getTrack(songId,function(response){ - - const songData = response; - const song = new Song({ - id: songId, - title: songData.title, - preview: songData.preview, - cover_big: songData.album.cover_big, - cover_xl: songData.album.cover_xl, - artist: songData.artist.name, - }); - // const song = {title: songData.title,preview: songData.preview, cover_big: songData.album.cover_big, cover_xl: songData.album.cover_xl, artist: songData.artist.name}; - - res.render("song",{song: song, user: user,showNavbar: false }); - - }); - -}); - - -// for logging in the users - -app.get("/login", - passport.authenticate("google", { scope: ["profile"] }) -); - -app.get('/auth/google/musicbuzz', - passport.authenticate('google', { failureRedirect: "/login" }), - function(req, res) { - // Successful authentication, redirect home. - res.redirect("/"); - console.log("Successfully logged in"); -}); - - -// logs out the users - -app.get("/:userId/logout", function (req, res) { - if (req.isAuthenticated()){ - req.logout(); - res.redirect("/"); - console.log("Successfully logged out"); - } else { - res.redirect("/login") - } -}); - -// Posts the query to the search function of the API. - -app.post("/search",function(req,res){ - let query = req.body.searchQuery; - res.redirect("/search/" + query); -}); - - -// Displays the search results based on the name parameter. - -app.get("/search/:name",function(req,res){ - - let user = null; - if (req.isAuthenticated()) { - user = req.user; - } - let query = req.params.name; - - let searchResponse = search(query,function(response){ - - const data = response.data; - let songList = []; - for(const song of data){ - const newSong = new Song({ - id: song.id, - title: song.title, - preview: song.preview, - cover_big: song.album.cover_big, - cover_xl: song.album.cover_xl, - artist: song.artist.name - }); - songList.push(newSong); - } - res.render("songlist",{songs: songList,user: user,showNavbar: true}); - }); -}); - - -// Redirects to the user's playlist. - -app.get("/playlists", function (req, res) { - if (req.isAuthenticated()) { - res.redirect("/" + req.user._id + "/playlists"); - } else { - res.send("You need to be logged in to view or create your playlist"); - } -}); - -// Displays the user's playlist. - -app.get("/:userId/playlists", function (req, res) { - User.findOne({ _id: req.user.id }, function (err, foundUser) { - if (err) { - console.log(err); - } else { - Playlist.findOne({ user: foundUser}, function (err, foundPlaylist) { - if (err) { - console.log(err); - } else { - if (!foundPlaylist) { - res.send("No Playlists have been created"); - - } else { - res.render("songlist",{songs: foundPlaylist.songs, user: foundPlaylist.user, showNavbar: true}); - } - } - }); - } - }); -}); - - -// Adding new songs to user playlist - -app.post("/playlists", function (req, res) { - if (!req.isAuthenticated()) { - res.redirect("/login"); - } else { - const currentUser = req.user; - const songInfo = JSON.parse(req.body.songInfo); - console.log(songInfo); - Playlist.findOne({ user: currentUser }, function (err, foundPlaylist) { - if (err) { - console.log(err); - } else { - const songToAdd = new Song({ - id: songInfo.id, - title: songInfo.title, - preview: songInfo.preview, - cover_big: songInfo.cover_big, - cover_xl: songInfo.cover_xl, - artist: songInfo.artist - }); - if (!foundPlaylist) { - // Create a new Playlist - songs = [songToAdd]; - const list = new Playlist({ - user: currentUser, - songs: songs, - }); - list.save(function (err) { - if (!err) { - res.redirect("/"); - console.log("Successfully added song to your favorites"); - } - }); - } else { - - let flag = 1; - // Check if song already exists in the playlist - foundPlaylist.songs.forEach(song => { - if (song.id === songToAdd.id) { - flag = 0; - } - if (flag === 0) { - console.log("Song already exists in your favorites"); - res.redirect("/"); - } else { - // Add Song to existing Playlist - foundPlaylist.songs.push(songToAdd); - foundPlaylist.save(function (err) { - console.log("Successfully added song to your favorites"); - res.redirect("/"); - }); - } - }); - } - } - }); - } -}); +app.use("/",require('./routes/index'));