diff --git a/routes/controller.js b/routes/controller.js index 8c16b1a..9c3ccb3 100644 --- a/routes/controller.js +++ b/routes/controller.js @@ -1,247 +1,260 @@ const async = require('async'); const fs = require('fs'); const Queue = require('bull'); const PopupTools = require('popup-tools'); const wikiUpload = require('../models/wikiUploadUtils'); const UserModel = require('../models/User'); const VideoModel = require('../models/Video'); const utils = require('./utils'); const config = require('../config'); const REDIS_CONFIG = { host: config.REDIS_HOST, port: config.REDIS_PORT, password: config.REDIS_PASSWORD } const PROCESS_VIDEO_QUEUE = 'PROCESS_VIDEO_QUEUE'; const PROCESS_VIDEO_PROGRESS_QUEUE = 'PROCESS_VIDEO_PROGRESS_QUEUE'; const PROCESS_VIDEO_FINISH_QUEUE = 'PROCESS_VIDEO_FINISH_QUEUE'; const processVideoQueue = new Queue(PROCESS_VIDEO_QUEUE, { redis: REDIS_CONFIG }); const processVideoProgressQueue = new Queue(PROCESS_VIDEO_PROGRESS_QUEUE, { redis: REDIS_CONFIG }); const processVideoFinishQueue = new Queue(PROCESS_VIDEO_FINISH_QUEUE, { redis: REDIS_CONFIG }); processVideoProgressQueue.process((job, done) => { console.log('progress', job.data); const io = require('../websockets')(); const { videoId, stage, ...rest } = job.data; VideoModel.updateOne({ _id: videoId }, { $set: { stage, status: 'processing' } }) .then((r) => { return VideoModel.findById(videoId).populate('uploadedBy') }) .then((video) => { if (video && video.uploadedBy) { io.to(video.uploadedBy.socketId).emit('progress:update', { stage, status: 'processing', ...rest }); } }) .catch(err => { console.log(err); }) done(); }) function processVideo(data) { processVideoQueue.add(data) } function registerUser(user, callback) { UserModel.update({ mediawikiId: user.mediawikiId }, user, { upsert: true }) .then((r) => { return UserModel.findOne({ mediawikiId: user.mediawikiId }) }) .then(userDoc => { callback(null, userDoc.toObject()) }) .catch(err => { console.log('err', err) callback(err) }) } module.exports = { sendCallback: (req, res) => { console.log('Hit Send') const disableAudio = req.body.disableAudio; var out_width = req.body.out_width; var out_height = req.body.out_height; var x_value = req.body.x_value; var y_value = req.body.y_value; const url = req.body.inputVideoUrl; var mode = req.body.trimMode; var trims = req.body.trims; const trimVideo = req.body.trimVideo; var user = req.body.user; var RotateValue = req.body.RotateValue; const videoName = req.body.videoName; // used for uploads const publicVideos = req.body.videos; // Video Settings let { rotateVideo, trimIntoMultipleVideos, trimIntoSingleVideo, cropVideo, upload, } = req.body; //This is to log the outting video console.log("Your Video Mode is : " + mode); console.log("Your video upload to commons is : " + upload); console.log("You Video Audio Disablity is : " + disableAudio); console.log("Video Rotation : " + rotateVideo); console.log("Video Crop : " + cropVideo); console.log("Video trim into multiple videos : " + trimIntoMultipleVideos); console.log("Video trim in to single video : " + trimIntoSingleVideo); console.log("Rotate Video : " + RotateValue); // console.log('downloading video ' + url) // This fetches the video into the server. // Params: videoURL -> videoPath if (!upload) { const videoData = { url, status: 'queued', videoName, uploadedBy: user ? user._id : null, settings: { trimVideo, trims, mode, cropVideo, out_width, out_height, x_value, y_value, rotateVideo, rotateValue: RotateValue, disableAudio, } } VideoModel.create(videoData) .then((videoDoc) => { console.log('vidoe doc', videoDoc) processVideo(videoDoc); return res.json({ queued: true, video: videoDoc }); }).catch(err => { console.log(err); return res.status(400).send('Something went wrong'); }) } else { let responses = []; UserModel .findOne({ mediawikiId: user.mediawikiId }) .select('+mediawikiToken +mediawikiTokenSecret') .then((userData) => { if (!userData) throw new Error('Invalid user mediawiki id'); const uploadFileArray = []; publicVideos.forEach(video => { uploadFileArray.push((cb) => { // This modules supports to upload the result of the operations to the Commons wikiUpload.uploadFileToMediawiki( userData.mediawikiToken, userData.mediawikiTokenSecret, fs.createReadStream(video.path), { filename: video.title, text: video.text, comment: video.comment }, (err, response) => { if (err) { console.log(err); return cb(err); } responses.push(response); cb() } ) }) }); async.series(uploadFileArray, (err, result) => { if (err) { console.log(err); return res.status(400).send('Something went wrong while uploading video'); } res.send(responses); }) }) .catch(err => { console.log(err); return res.status(400).send('Something when wrong while uploading'); }) } }, uploadFileSendCallback: (req, res) => { console.log('Upload sent') if ('video' in req.files) { let data; try { data = JSON.parse(req.body.data); } catch (SyntaxError) { console.log("There was an issue with the data sent."); console.log(req.body.data); return res.status(500).send('Something has gone wrong with the video you uploaded. Please try again.') } for (let key in data) { req.body[key] = data[key] } req.body.inputVideoUrl = req.files.video.tempFilePath req.body.videoName = req.files.video.name utils.moveVideosToPublic([{path: `../${req.body.inputVideoUrl}`, name: req.body.videoName}], (err, results) => { if (err) { console.log(err); return res.status(400).send('Something went wrong'); } req.body.inputVideoUrl = `https://videocuttool.wmflabs.org/video-cut-tool-back-end/public/${results[0].split('public/').pop()}`; module.exports.sendCallback(req, res) }) } else { return res.status(400).send('There was no video specified.') } }, - + onVideoProgress: (req, res) => { + const { video_id, progress_info } = req.body; + const io = require('../websockets')(); + VideoModel.findById(video_id).populate('uploadedBy') + .then((video) => { + if (video && video.uploadedBy) { + io.to(video.uploadedBy.socketId).emit('progress:updateBar', { progress_info }); + } + }) + .catch(err => { + console.log(err); + }); + res.send('done'); + }, onVideoProcessed: (req, res) => { const { videoId } = req.body; const videos = Array.isArray(req.files.videos) ? req.files.videos : [req.files.videos]; utils.moveVideosToPublic(videos.map(v => ({...v, path: `../${v.tempFilePath}`})), (err, results) => { VideoModel.updateOne({ _id: videoId }, { $set: { outputs: results.map(p => `public/${p.split('public/').pop()}`), status: 'done' } }, (err) => { if (err) { console.log(err); } let video; VideoModel.findById(videoId) .populate('uploadedBy') .then(video => { if (video.uploadedBy) { processVideoProgressQueue.add({ videoId: video._id, status: 'done', ...video.toObject(), videos: video.outputs }) } }) .catch(err => { console.log(err); }) }) }) res.send('done') }, downloadFile: function (req, res) { const file = 'public/' + req.params.videopath; res.download(file); // Set disposition and send it. }, authCallback: (req, res) => { const user = JSON.parse(JSON.stringify(req.user)); registerUser(user, (err, user) => { res.end(PopupTools.popupResponse({ user })); }) } } \ No newline at end of file diff --git a/routes/index.js b/routes/index.js index bbc7771..5bac96f 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,82 +1,84 @@ var express = require("express"), session = require("express-session"), passport = require("passport"), app = express(), router = express.Router(); const controller = require('./controller') app.set("views", __dirname + "/public/views"); app.set("view engine", "ejs"); app.use('/routes', express.static(__dirname + '/routes')); app.use(passport.initialize()); app.use(passport.session()); app.use(session({ secret: "OAuth Session", saveUninitialized: true, resave: true })); passport.serializeUser(function (user, done) { done(null, user); }); passport.deserializeUser(function (obj, done) { done(null, obj); }); /* GET home page. */ router.get('/video-cut-tool-back-end', function (req, res) { res.render('index'); }); router.post('/send', controller.sendCallback); router.post('/video-cut-tool-back-end/send', controller.sendCallback); router.post('/video-cut-tool-back-end/video-cut-tool-back-end/send', controller.sendCallback); router.post('/send/upload', controller.uploadFileSendCallback); router.post('/video-cut-tool-back-end/send/upload', controller.uploadFileSendCallback) router.post('/video-cut-tool-back-end/video-cut-tool-back-end/send/upload', controller.uploadFileSendCallback); router.post('/video-cut-tool-back-end/video_processed', controller.onVideoProcessed); router.post('/video_processed', controller.onVideoProcessed); +router.post('/video-cut-tool-back-end/video_progress', controller.onVideoProgress); +router.post('/video_progress', controller.onVideoProgress); router.get('/download/public/:videopath', function(req, res){ const file = 'public/'+req.params.videopath; res.download(file); // Set disposition and send it. }); router.get('/video-cut-tool-back-end/download/public/:videopath', controller.downloadFile); router.get('/insert', function (req, res) { res.render('index'); }); router.get('/video-cut-tool-back-end/insert', function (req, res) { res.render('index'); }); router.get(['/video-cut-tool-back-end/video-cut-tool-back-end/login', '/video-cut-tool-back-end/login'], passport.authenticate('mediawiki'), () => {}); router.get("/", function (req, res) { res.redirect(req.baseUrl + '/video-cut-tool-back-end/'); }); router.get('/video-cut-tool-back-end/video-cut-tool-back-end/auth/mediawiki/callback', passport.authenticate('mediawiki', { failureRedirect: '/login', }), controller.authCallback) router.get('/video-cut-tool-back-end/auth/mediawiki/callback', passport.authenticate('mediawiki', { failureRedirect: '/login', }), controller.authCallback) router.get('/auth/mediawiki/callback', passport.authenticate('mediawiki', { failureRedirect: '/login', }), controller.authCallback) module.exports = router;