diff --git a/app-backend/controllers/video.controller.js b/app-backend/controllers/video.controller.js index a3ee7b9..0741a87 100644 --- a/app-backend/controllers/video.controller.js +++ b/app-backend/controllers/video.controller.js @@ -4,25 +4,138 @@ const {sendError, sendMessage} = require ("../config/response.config"); const {checkLogin} = require("../config/sessionJWT.config"); const {youtube, dailymotion} = require("../config/host.config"); const VideoCategories = require("../models/objects/video.categories.model"); +const ObjectId = require('mongoose').Types.ObjectId; const Video = db.videos; +function asyncRequest(uri, option){ + return new Promise(function(resolve){ + request(uri, option,function (error, response, body){ + resolve({response: response, body: JSON.parse(body)}); + }); + }); +} + +function asyncInterest(interest, source){ + return new Promise(function(resolve){ + for(const i in VideoCategories){ + for(const j in VideoCategories[i].categories){ + if((VideoCategories[i].categories[j].name === interest || VideoCategories[i].categories[j].id === interest) + && VideoCategories[i].categories[j].source === source){ + resolve(VideoCategories[i].interest); + } + } + } + resolve(null); + }); +} + // Search Videos -exports.search = (req, res) => { +exports.search = async (req, res) => { const token = checkLogin(req, res); - if(token){ - return sendError(res, 501, -1, "Video.search not Implemented", token); + if(token && typeof req.query.q !== 'undefined'){ + const query = req.query.q; + const sources = req.query.sources ? req.query.sources : ["yt", "dm"]; + const maxResults = req.query.maxResults ? req.query.maxResults : 45; + const pageToken = req.query.pageToken ? req.query.pageToken : undefined; + + let yt_results; + let dm_results; + for(const i in sources){ + if(sources[i] === youtube.shortname){ + if(youtube.YOUTUBE_API_KEY !== 'undefined' && youtube.YOUTUBE_API_KEY !== ''){ + let uri; + if(typeof pageToken !== 'undefined'){ + uri = youtube.baseAPIUrl+'/search'+'?part=snippet&maxResults='+maxResults+'&q='+query+'&pageToken='+pageToken+'&key='+youtube.YOUTUBE_API_KEY; + } else{ + uri = youtube.baseAPIUrl+'/search'+'?part=snippet&maxResults='+maxResults+'&q='+query+'&key='+youtube.YOUTUBE_API_KEY; + } + const dataIds = await asyncRequest(uri, {}); + if(dataIds.response.statusCode === 200 && dataIds.body.items.length > 0){ + let yt_videoIds = ""; + dataIds.body.items.forEach(item => yt_videoIds = yt_videoIds+item.id.videoId+","); + uri = youtube.baseAPIUrl+'/videos'+'?part=snippet&part=statistics&id='+yt_videoIds.slice(0, -1)+'&key='+youtube.YOUTUBE_API_KEY; + const dataVideos = await asyncRequest(uri, {}); + if(dataVideos.response.statusCode === 200 && dataVideos.body.items.length > 0){ + yt_results = dataVideos.body.items; + } + } + } else{ + return sendError(res, 500, -1, `Error Env Variable DAILYMOTION_API_KEY missing, please contact the admin.`, token); + } + } else if(sources[i] === dailymotion.shortname){ + if(dailymotion.DAILYMOTION_API_KEY !== 'undefined' && dailymotion.DAILYMOTION_API_KEY !== '') { + const uri = dailymotion.baseAPIUrl + '/videos?limit='+maxResults+'&search='+query+'&fields=created_time%2Cdescription%2Cthumbnail_480_url%2Clikes_total%2Ctitle%2Cid%2Cembed_url%2Cviews_total%2Cowner.username%2Cowner.id%2Cchannel.name'; + const data = await asyncRequest(uri, {}); + const response = data.response; + const jsonBody = data.body; + if(response.statusCode === 200){ + dm_results = jsonBody.list; + } + } else{ + return sendError(res, 500, -1, `Error Env Variable DAILYMOTION_API_KEY missing, please contact the admin.`, token); + } + } + } + + let results = []; + for(let i = 0; i < Math.max(dm_results.length, yt_results.length); i++){ + + // Youtube + if(yt_results.length > i){ + const yt_data = { + videoId: yt_results[i].id, + source: youtube.name, + imageUrl: yt_results[i].snippet.thumbnails.medium.url ? yt_results[i].snippet.thumbnails.medium.url : null, + title: yt_results[i].snippet.title ? yt_results[i].snippet.title : null, + channelTitle: yt_results[i].snippet.channelTitle ? yt_results[i].snippet.channelTitle : null, + channelUrl: youtube.baseChannelUrl+yt_results[i].snippet.channelId ? yt_results[i].snippet.channelId : null, + description: yt_results[i].snippet.description ? yt_results[i].snippet.description : null, + embedUrl: 'https://www.youtube.com/embed/'+yt_results[i].id, + interest: await asyncInterest(yt_results[i].snippet.categoryId, youtube.name), + views: yt_results[i].statistics.viewCount ? parseInt(yt_results[i].statistics.viewCount) : null, + likes: yt_results[i].statistics.likeCount ? parseInt(yt_results[i].statistics.likeCount) : null, + dislikes: yt_results[i].statistics.dislikeCount ? parseInt(yt_results[i].statistics.dislikeCount) : null, + publishedAt: yt_results[i].snippet.publishedAt ? yt_results[i].snippet.publishedAt : null + }; + results.push(yt_data); + } + + // Dailymotion + if(dm_results.length > i) { + const channelTitle = dm_results[i]['owner.username'] ? dm_results[i]['owner.username'] : null; + const dm_data = { + videoId: dm_results[i].id ? dm_results[i].id : null, + source: dailymotion.name, + imageUrl: dm_results[i].thumbnail_480_url ? dm_results[i].thumbnail_480_url : null, + title: dm_results[i].title ? dm_results[i].title : null, + channelTitle: channelTitle.charAt(0).toUpperCase() + channelTitle.slice(1), + channelUrl: dailymotion.baseChannelUrl + channelTitle, + description: dm_results[i].description ? dm_results[i].description : null, + embedUrl: dm_results[i].embed_url ? dm_results[i].embed_url : null, + interest: await asyncInterest(dm_results[i]['channel.name'], dailymotion.name), + views: dm_results[i].views_total ? parseInt(dm_results[i].views_total) : null, + likes: dm_results[i].likes_total ? parseInt(dm_results[i].likes_total) : null, + dislikes: null, + publishedAt: dm_results[i].created_time ? new Date(dm_results[i].created_time * 1000) : null + }; + results.push(dm_data); + } + } + return sendMessage(res, 31, results, token); + } else{ + return sendError(res, 500, -1, `No q given`, token); } }; // Get Video with id of source -exports.get = (req, res) => { +exports.get = (req, res) => { if(typeof req.query.source !== 'undefined' && typeof req.params.id !== 'undefined'){ const source = req.query.source; const id = req.params.id; if(source === youtube.shortname){ if(youtube.YOUTUBE_API_KEY !== 'undefined' && youtube.YOUTUBE_API_KEY !== ''){ const uri = youtube.baseAPIUrl+'/videos'+'?part=snippet&part=statistics&id='+id+'&key='+youtube.YOUTUBE_API_KEY; - request(uri,{},function (error, response, body){ + request(uri,{},async function (error, response, body){ if(typeof body !== 'undefined'){ const jsonBody = JSON.parse(body); if(jsonBody.items.length !== 0 && @@ -36,9 +149,7 @@ exports.get = (req, res) => { const description = jsonBody.items[0].snippet.description ? jsonBody.items[0].snippet.description : null; //const embedUrl = jsonBody.embed_url ? jsonBody.embed_url : null; const publishedAt = jsonBody.items[0].snippet.publishedAt ? jsonBody.items[0].snippet.publishedAt : null; - const interest = jsonBody.items[0].snippet.categoryId ? VideoCategories - .filter(obj => Object.values(obj.categories[1]) - .some(val => val.includes(jsonBody.items[0].snippet.categoryId)))[0].interest : null; + const interest = jsonBody.items[0].snippet.categoryId ? await asyncInterest(jsonBody.items[0].snippet.categoryId, youtube.name): null; const views = jsonBody.items[0].statistics.viewCount ? parseInt(jsonBody.items[0].statistics.viewCount) : null; const likes = jsonBody.items[0].statistics.likeCount ? parseInt(jsonBody.items[0].statistics.likeCount) : null; const dislikes = jsonBody.items[0].statistics.dislikeCount ? parseInt(jsonBody.items[0].statistics.dislikeCount) : null; @@ -71,7 +182,7 @@ exports.get = (req, res) => { } else if(source === dailymotion.shortname){ if(dailymotion.DAILYMOTION_API_KEY !== 'undefined' && dailymotion.DAILYMOTION_API_KEY !== ''){ const uri = dailymotion.baseAPIUrl+'/video/'+id+'?fields=created_time%2Cdescription%2Cthumbnail_480_url%2Clikes_total%2Ctitle%2Cid%2Cembed_url%2Cviews_total%2Cowner.username%2Cowner.id%2Cchannel.name'; - request(uri,{},function (error, response, body) { + request(uri,{},async function (error, response, body) { if (typeof body !== 'undefined') { const jsonBody = JSON.parse(body); if(response.statusCode === 200 && @@ -84,9 +195,7 @@ exports.get = (req, res) => { const description = jsonBody.description ? jsonBody.description : null; const embedUrl = jsonBody.embed_url ? jsonBody.embed_url : null; const publishedAt = jsonBody.created_time ? new Date(jsonBody.created_time * 1000) : null; - const interest = jsonBody['channel.name'] ? VideoCategories - .filter(obj => Object.values(obj.categories[0]) - .some(val => val.includes(jsonBody['channel.name'])))[0].interest : null; + const interest = jsonBody['channel.name'] ? await asyncInterest(jsonBody['channel.name'], dailymotion.name) : null; const views = jsonBody.views_total ? parseInt(jsonBody.views_total) : null; const likes = jsonBody.likes_total ? parseInt(jsonBody.likes_total) : null; const dislikes = null; @@ -130,7 +239,7 @@ exports.create = (req, res) => { typeof req.body.interest !== 'undefined' && typeof req.params.id !== 'undefined'){ const id = req.params.id; - Video.exists({userId: token.id, videoId: id, source: req.body.source}, function (err, docs){ + Video.exists({userId: token.id, videoId: id, source: req.body.source, isActive: true}, function (err, docs){ if(err){ sendError(res, 500,100,err.message || "Some error occurred while checking if the Video already exists.", token); } else{ @@ -202,15 +311,40 @@ exports.update = (req, res) => { // Delete Video with id exports.delete = (req, res) => { const token = checkLogin(req, res); - if(token){ - return sendError(res, 501, -1, "Video.delete not Implemented", token); + if(token && typeof req.params.id !== 'undefined') { + const id = req.params.id; + if(id && ObjectId.isValid(id)){ + Video.updateOne({_id: id, userId: token.id, isActive: true}, {isActive: false}, {useFindAndModify: false}) + .then(data => { + if(data) { + return sendMessage(res, 37, {message: `Video ${id} was successfully deleted.`}, token); + } else { + return sendError(res, 404, 105, `Video not found with id=${id}`, token); + } + }) + .catch(err => { + return sendError(res, 500, 100, err.message || `Some error occurred while deleting the Video with id=${id}`, token); + }); + } else { + return sendError(res, 500, -1, `Error id is not valid`, token); + } + } else { + return sendError(res, 500, -1, `No id given`, token); } }; // Delete all Videos exports.deleteAll = (req, res) => { const token = checkLogin(req, res); - if(token){ - return sendError(res, 501, -1, "Video.deleteAll not Implemented", token); + if(token) { + Video.deleteMany({userId: {$eq: token.id}}) + .then(data => { + return sendMessage(res, 38, { + message: `${data.deletedCount} Videos were deleted successfully.` + }); + }) + .catch(err => { + return sendError(res, 500, 100, err.message || "Some error occurred while removing all Videos."); + }); } };