Server: split videos controller
This commit is contained in:
parent
1f0215a908
commit
d33242b047
4 changed files with 339 additions and 264 deletions
112
server/controllers/api/videos/abuse.js
Normal file
112
server/controllers/api/videos/abuse.js
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const express = require('express')
|
||||||
|
const waterfall = require('async/waterfall')
|
||||||
|
|
||||||
|
const db = require('../../../initializers/database')
|
||||||
|
const logger = require('../../../helpers/logger')
|
||||||
|
const friends = require('../../../lib/friends')
|
||||||
|
const middlewares = require('../../../middlewares')
|
||||||
|
const admin = middlewares.admin
|
||||||
|
const oAuth = middlewares.oauth
|
||||||
|
const pagination = middlewares.pagination
|
||||||
|
const validators = middlewares.validators
|
||||||
|
const validatorsPagination = validators.pagination
|
||||||
|
const validatorsSort = validators.sort
|
||||||
|
const validatorsVideos = validators.videos
|
||||||
|
const sort = middlewares.sort
|
||||||
|
const databaseUtils = require('../../../helpers/database-utils')
|
||||||
|
const utils = require('../../../helpers/utils')
|
||||||
|
|
||||||
|
const router = express.Router()
|
||||||
|
|
||||||
|
router.get('/abuse',
|
||||||
|
oAuth.authenticate,
|
||||||
|
admin.ensureIsAdmin,
|
||||||
|
validatorsPagination.pagination,
|
||||||
|
validatorsSort.videoAbusesSort,
|
||||||
|
sort.setVideoAbusesSort,
|
||||||
|
pagination.setPagination,
|
||||||
|
listVideoAbuses
|
||||||
|
)
|
||||||
|
router.post('/:id/abuse',
|
||||||
|
oAuth.authenticate,
|
||||||
|
validatorsVideos.videoAbuseReport,
|
||||||
|
reportVideoAbuseRetryWrapper
|
||||||
|
)
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
module.exports = router
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function listVideoAbuses (req, res, next) {
|
||||||
|
db.VideoAbuse.listForApi(req.query.start, req.query.count, req.query.sort, function (err, abusesList, abusesTotal) {
|
||||||
|
if (err) return next(err)
|
||||||
|
|
||||||
|
res.json(utils.getFormatedObjects(abusesList, abusesTotal))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function reportVideoAbuseRetryWrapper (req, res, next) {
|
||||||
|
const options = {
|
||||||
|
arguments: [ req, res ],
|
||||||
|
errorMessage: 'Cannot report abuse to the video with many retries.'
|
||||||
|
}
|
||||||
|
|
||||||
|
databaseUtils.retryTransactionWrapper(reportVideoAbuse, options, function (err) {
|
||||||
|
if (err) return next(err)
|
||||||
|
|
||||||
|
return res.type('json').status(204).end()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function reportVideoAbuse (req, res, finalCallback) {
|
||||||
|
const videoInstance = res.locals.video
|
||||||
|
const reporterUsername = res.locals.oauth.token.User.username
|
||||||
|
|
||||||
|
const abuse = {
|
||||||
|
reporterUsername,
|
||||||
|
reason: req.body.reason,
|
||||||
|
videoId: videoInstance.id,
|
||||||
|
reporterPodId: null // This is our pod that reported this abuse
|
||||||
|
}
|
||||||
|
|
||||||
|
waterfall([
|
||||||
|
|
||||||
|
databaseUtils.startSerializableTransaction,
|
||||||
|
|
||||||
|
function createAbuse (t, callback) {
|
||||||
|
db.VideoAbuse.create(abuse).asCallback(function (err, abuse) {
|
||||||
|
return callback(err, t, abuse)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
function sendToFriendsIfNeeded (t, abuse, callback) {
|
||||||
|
// We send the information to the destination pod
|
||||||
|
if (videoInstance.isOwned() === false) {
|
||||||
|
const reportData = {
|
||||||
|
reporterUsername,
|
||||||
|
reportReason: abuse.reason,
|
||||||
|
videoRemoteId: videoInstance.remoteId
|
||||||
|
}
|
||||||
|
|
||||||
|
friends.reportAbuseVideoToFriend(reportData, videoInstance)
|
||||||
|
}
|
||||||
|
|
||||||
|
return callback(null, t)
|
||||||
|
},
|
||||||
|
|
||||||
|
databaseUtils.commitTransaction
|
||||||
|
|
||||||
|
], function andFinally (err, t) {
|
||||||
|
if (err) {
|
||||||
|
logger.debug('Cannot update the video.', { error: err })
|
||||||
|
return databaseUtils.rollbackTransaction(err, t, finalCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info('Abuse report for video %s created.', videoInstance.name)
|
||||||
|
return finalCallback(null)
|
||||||
|
})
|
||||||
|
}
|
43
server/controllers/api/videos/blacklist.js
Normal file
43
server/controllers/api/videos/blacklist.js
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const express = require('express')
|
||||||
|
|
||||||
|
const db = require('../../../initializers/database')
|
||||||
|
const logger = require('../../../helpers/logger')
|
||||||
|
const middlewares = require('../../../middlewares')
|
||||||
|
const admin = middlewares.admin
|
||||||
|
const oAuth = middlewares.oauth
|
||||||
|
const validators = middlewares.validators
|
||||||
|
const validatorsVideos = validators.videos
|
||||||
|
|
||||||
|
const router = express.Router()
|
||||||
|
|
||||||
|
router.post('/:id/blacklist',
|
||||||
|
oAuth.authenticate,
|
||||||
|
admin.ensureIsAdmin,
|
||||||
|
validatorsVideos.videosBlacklist,
|
||||||
|
addVideoToBlacklist
|
||||||
|
)
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
module.exports = router
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function addVideoToBlacklist (req, res, next) {
|
||||||
|
const videoInstance = res.locals.video
|
||||||
|
|
||||||
|
const toCreate = {
|
||||||
|
videoId: videoInstance.id
|
||||||
|
}
|
||||||
|
|
||||||
|
db.BlacklistedVideo.create(toCreate).asCallback(function (err) {
|
||||||
|
if (err) {
|
||||||
|
logger.error('Errors when blacklisting video ', { error: err })
|
||||||
|
return next(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.type('json').status(204).end()
|
||||||
|
})
|
||||||
|
}
|
|
@ -6,12 +6,11 @@ const multer = require('multer')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const waterfall = require('async/waterfall')
|
const waterfall = require('async/waterfall')
|
||||||
|
|
||||||
const constants = require('../../initializers/constants')
|
const constants = require('../../../initializers/constants')
|
||||||
const db = require('../../initializers/database')
|
const db = require('../../../initializers/database')
|
||||||
const logger = require('../../helpers/logger')
|
const logger = require('../../../helpers/logger')
|
||||||
const friends = require('../../lib/friends')
|
const friends = require('../../../lib/friends')
|
||||||
const middlewares = require('../../middlewares')
|
const middlewares = require('../../../middlewares')
|
||||||
const admin = middlewares.admin
|
|
||||||
const oAuth = middlewares.oauth
|
const oAuth = middlewares.oauth
|
||||||
const pagination = middlewares.pagination
|
const pagination = middlewares.pagination
|
||||||
const validators = middlewares.validators
|
const validators = middlewares.validators
|
||||||
|
@ -20,8 +19,12 @@ const validatorsSort = validators.sort
|
||||||
const validatorsVideos = validators.videos
|
const validatorsVideos = validators.videos
|
||||||
const search = middlewares.search
|
const search = middlewares.search
|
||||||
const sort = middlewares.sort
|
const sort = middlewares.sort
|
||||||
const databaseUtils = require('../../helpers/database-utils')
|
const databaseUtils = require('../../../helpers/database-utils')
|
||||||
const utils = require('../../helpers/utils')
|
const utils = require('../../../helpers/utils')
|
||||||
|
|
||||||
|
const abuseController = require('./abuse')
|
||||||
|
const blacklistController = require('./blacklist')
|
||||||
|
const rateController = require('./rate')
|
||||||
|
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
|
|
||||||
|
@ -45,31 +48,14 @@ const storage = multer.diskStorage({
|
||||||
|
|
||||||
const reqFiles = multer({ storage: storage }).fields([{ name: 'videofile', maxCount: 1 }])
|
const reqFiles = multer({ storage: storage }).fields([{ name: 'videofile', maxCount: 1 }])
|
||||||
|
|
||||||
|
router.use('/', abuseController)
|
||||||
|
router.use('/', blacklistController)
|
||||||
|
router.use('/', rateController)
|
||||||
|
|
||||||
router.get('/categories', listVideoCategories)
|
router.get('/categories', listVideoCategories)
|
||||||
router.get('/licences', listVideoLicences)
|
router.get('/licences', listVideoLicences)
|
||||||
router.get('/languages', listVideoLanguages)
|
router.get('/languages', listVideoLanguages)
|
||||||
|
|
||||||
router.get('/abuse',
|
|
||||||
oAuth.authenticate,
|
|
||||||
admin.ensureIsAdmin,
|
|
||||||
validatorsPagination.pagination,
|
|
||||||
validatorsSort.videoAbusesSort,
|
|
||||||
sort.setVideoAbusesSort,
|
|
||||||
pagination.setPagination,
|
|
||||||
listVideoAbuses
|
|
||||||
)
|
|
||||||
router.post('/:id/abuse',
|
|
||||||
oAuth.authenticate,
|
|
||||||
validatorsVideos.videoAbuseReport,
|
|
||||||
reportVideoAbuseRetryWrapper
|
|
||||||
)
|
|
||||||
|
|
||||||
router.put('/:id/rate',
|
|
||||||
oAuth.authenticate,
|
|
||||||
validatorsVideos.videoRate,
|
|
||||||
rateVideoRetryWrapper
|
|
||||||
)
|
|
||||||
|
|
||||||
router.get('/',
|
router.get('/',
|
||||||
validatorsPagination.pagination,
|
validatorsPagination.pagination,
|
||||||
validatorsSort.videosSort,
|
validatorsSort.videosSort,
|
||||||
|
@ -110,13 +96,6 @@ router.get('/search/:value',
|
||||||
searchVideos
|
searchVideos
|
||||||
)
|
)
|
||||||
|
|
||||||
router.post('/:id/blacklist',
|
|
||||||
oAuth.authenticate,
|
|
||||||
admin.ensureIsAdmin,
|
|
||||||
validatorsVideos.videosBlacklist,
|
|
||||||
addVideoToBlacklist
|
|
||||||
)
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router
|
||||||
|
@ -135,147 +114,6 @@ function listVideoLanguages (req, res, next) {
|
||||||
res.json(constants.VIDEO_LANGUAGES)
|
res.json(constants.VIDEO_LANGUAGES)
|
||||||
}
|
}
|
||||||
|
|
||||||
function rateVideoRetryWrapper (req, res, next) {
|
|
||||||
const options = {
|
|
||||||
arguments: [ req, res ],
|
|
||||||
errorMessage: 'Cannot update the user video rate.'
|
|
||||||
}
|
|
||||||
|
|
||||||
databaseUtils.retryTransactionWrapper(rateVideo, options, function (err) {
|
|
||||||
if (err) return next(err)
|
|
||||||
|
|
||||||
return res.type('json').status(204).end()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function rateVideo (req, res, finalCallback) {
|
|
||||||
const rateType = req.body.rating
|
|
||||||
const videoInstance = res.locals.video
|
|
||||||
const userInstance = res.locals.oauth.token.User
|
|
||||||
|
|
||||||
waterfall([
|
|
||||||
databaseUtils.startSerializableTransaction,
|
|
||||||
|
|
||||||
function findPreviousRate (t, callback) {
|
|
||||||
db.UserVideoRate.load(userInstance.id, videoInstance.id, t, function (err, previousRate) {
|
|
||||||
return callback(err, t, previousRate)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
function insertUserRateIntoDB (t, previousRate, callback) {
|
|
||||||
const options = { transaction: t }
|
|
||||||
|
|
||||||
let likesToIncrement = 0
|
|
||||||
let dislikesToIncrement = 0
|
|
||||||
|
|
||||||
if (rateType === constants.VIDEO_RATE_TYPES.LIKE) likesToIncrement++
|
|
||||||
else if (rateType === constants.VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++
|
|
||||||
|
|
||||||
// There was a previous rate, update it
|
|
||||||
if (previousRate) {
|
|
||||||
// We will remove the previous rate, so we will need to remove it from the video attribute
|
|
||||||
if (previousRate.type === constants.VIDEO_RATE_TYPES.LIKE) likesToIncrement--
|
|
||||||
else if (previousRate.type === constants.VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement--
|
|
||||||
|
|
||||||
previousRate.type = rateType
|
|
||||||
|
|
||||||
previousRate.save(options).asCallback(function (err) {
|
|
||||||
return callback(err, t, likesToIncrement, dislikesToIncrement)
|
|
||||||
})
|
|
||||||
} else { // There was not a previous rate, insert a new one
|
|
||||||
const query = {
|
|
||||||
userId: userInstance.id,
|
|
||||||
videoId: videoInstance.id,
|
|
||||||
type: rateType
|
|
||||||
}
|
|
||||||
|
|
||||||
db.UserVideoRate.create(query, options).asCallback(function (err) {
|
|
||||||
return callback(err, t, likesToIncrement, dislikesToIncrement)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
function updateVideoAttributeDB (t, likesToIncrement, dislikesToIncrement, callback) {
|
|
||||||
const options = { transaction: t }
|
|
||||||
const incrementQuery = {
|
|
||||||
likes: likesToIncrement,
|
|
||||||
dislikes: dislikesToIncrement
|
|
||||||
}
|
|
||||||
|
|
||||||
// Even if we do not own the video we increment the attributes
|
|
||||||
// It is usefull for the user to have a feedback
|
|
||||||
videoInstance.increment(incrementQuery, options).asCallback(function (err) {
|
|
||||||
return callback(err, t, likesToIncrement, dislikesToIncrement)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
function sendEventsToFriendsIfNeeded (t, likesToIncrement, dislikesToIncrement, callback) {
|
|
||||||
// No need for an event type, we own the video
|
|
||||||
if (videoInstance.isOwned()) return callback(null, t, likesToIncrement, dislikesToIncrement)
|
|
||||||
|
|
||||||
const eventsParams = []
|
|
||||||
|
|
||||||
if (likesToIncrement !== 0) {
|
|
||||||
eventsParams.push({
|
|
||||||
videoId: videoInstance.id,
|
|
||||||
type: constants.REQUEST_VIDEO_EVENT_TYPES.LIKES,
|
|
||||||
count: likesToIncrement
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dislikesToIncrement !== 0) {
|
|
||||||
eventsParams.push({
|
|
||||||
videoId: videoInstance.id,
|
|
||||||
type: constants.REQUEST_VIDEO_EVENT_TYPES.DISLIKES,
|
|
||||||
count: dislikesToIncrement
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
friends.addEventsToRemoteVideo(eventsParams, t, function (err) {
|
|
||||||
return callback(err, t, likesToIncrement, dislikesToIncrement)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
function sendQaduToFriendsIfNeeded (t, likesToIncrement, dislikesToIncrement, callback) {
|
|
||||||
// We do not own the video, there is no need to send a quick and dirty update to friends
|
|
||||||
// Our rate was already sent by the addEvent function
|
|
||||||
if (videoInstance.isOwned() === false) return callback(null, t)
|
|
||||||
|
|
||||||
const qadusParams = []
|
|
||||||
|
|
||||||
if (likesToIncrement !== 0) {
|
|
||||||
qadusParams.push({
|
|
||||||
videoId: videoInstance.id,
|
|
||||||
type: constants.REQUEST_VIDEO_QADU_TYPES.LIKES
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dislikesToIncrement !== 0) {
|
|
||||||
qadusParams.push({
|
|
||||||
videoId: videoInstance.id,
|
|
||||||
type: constants.REQUEST_VIDEO_QADU_TYPES.DISLIKES
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
friends.quickAndDirtyUpdatesVideoToFriends(qadusParams, t, function (err) {
|
|
||||||
return callback(err, t)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
databaseUtils.commitTransaction
|
|
||||||
|
|
||||||
], function (err, t) {
|
|
||||||
if (err) {
|
|
||||||
// This is just a debug because we will retry the insert
|
|
||||||
logger.debug('Cannot add the user video rate.', { error: err })
|
|
||||||
return databaseUtils.rollbackTransaction(err, t, finalCallback)
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info('User video rate for video %s of user %s updated.', videoInstance.name, userInstance.username)
|
|
||||||
return finalCallback(null)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrapper to video add that retry the function if there is a database error
|
// Wrapper to video add that retry the function if there is a database error
|
||||||
// We need this because we run the transaction in SERIALIZABLE isolation that can fail
|
// We need this because we run the transaction in SERIALIZABLE isolation that can fail
|
||||||
function addVideoRetryWrapper (req, res, next) {
|
function addVideoRetryWrapper (req, res, next) {
|
||||||
|
@ -564,90 +402,3 @@ function searchVideos (req, res, next) {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function listVideoAbuses (req, res, next) {
|
|
||||||
db.VideoAbuse.listForApi(req.query.start, req.query.count, req.query.sort, function (err, abusesList, abusesTotal) {
|
|
||||||
if (err) return next(err)
|
|
||||||
|
|
||||||
res.json(utils.getFormatedObjects(abusesList, abusesTotal))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function reportVideoAbuseRetryWrapper (req, res, next) {
|
|
||||||
const options = {
|
|
||||||
arguments: [ req, res ],
|
|
||||||
errorMessage: 'Cannot report abuse to the video with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
databaseUtils.retryTransactionWrapper(reportVideoAbuse, options, function (err) {
|
|
||||||
if (err) return next(err)
|
|
||||||
|
|
||||||
return res.type('json').status(204).end()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function reportVideoAbuse (req, res, finalCallback) {
|
|
||||||
const videoInstance = res.locals.video
|
|
||||||
const reporterUsername = res.locals.oauth.token.User.username
|
|
||||||
|
|
||||||
const abuse = {
|
|
||||||
reporterUsername,
|
|
||||||
reason: req.body.reason,
|
|
||||||
videoId: videoInstance.id,
|
|
||||||
reporterPodId: null // This is our pod that reported this abuse
|
|
||||||
}
|
|
||||||
|
|
||||||
waterfall([
|
|
||||||
|
|
||||||
databaseUtils.startSerializableTransaction,
|
|
||||||
|
|
||||||
function createAbuse (t, callback) {
|
|
||||||
db.VideoAbuse.create(abuse).asCallback(function (err, abuse) {
|
|
||||||
return callback(err, t, abuse)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
function sendToFriendsIfNeeded (t, abuse, callback) {
|
|
||||||
// We send the information to the destination pod
|
|
||||||
if (videoInstance.isOwned() === false) {
|
|
||||||
const reportData = {
|
|
||||||
reporterUsername,
|
|
||||||
reportReason: abuse.reason,
|
|
||||||
videoRemoteId: videoInstance.remoteId
|
|
||||||
}
|
|
||||||
|
|
||||||
friends.reportAbuseVideoToFriend(reportData, videoInstance)
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(null, t)
|
|
||||||
},
|
|
||||||
|
|
||||||
databaseUtils.commitTransaction
|
|
||||||
|
|
||||||
], function andFinally (err, t) {
|
|
||||||
if (err) {
|
|
||||||
logger.debug('Cannot update the video.', { error: err })
|
|
||||||
return databaseUtils.rollbackTransaction(err, t, finalCallback)
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info('Abuse report for video %s created.', videoInstance.name)
|
|
||||||
return finalCallback(null)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function addVideoToBlacklist (req, res, next) {
|
|
||||||
const videoInstance = res.locals.video
|
|
||||||
|
|
||||||
const toCreate = {
|
|
||||||
videoId: videoInstance.id
|
|
||||||
}
|
|
||||||
|
|
||||||
db.BlacklistedVideo.create(toCreate).asCallback(function (err) {
|
|
||||||
if (err) {
|
|
||||||
logger.error('Errors when blacklisting video ', { error: err })
|
|
||||||
return next(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.type('json').status(204).end()
|
|
||||||
})
|
|
||||||
}
|
|
169
server/controllers/api/videos/rate.js
Normal file
169
server/controllers/api/videos/rate.js
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const express = require('express')
|
||||||
|
const waterfall = require('async/waterfall')
|
||||||
|
|
||||||
|
const constants = require('../../../initializers/constants')
|
||||||
|
const db = require('../../../initializers/database')
|
||||||
|
const logger = require('../../../helpers/logger')
|
||||||
|
const friends = require('../../../lib/friends')
|
||||||
|
const middlewares = require('../../../middlewares')
|
||||||
|
const oAuth = middlewares.oauth
|
||||||
|
const validators = middlewares.validators
|
||||||
|
const validatorsVideos = validators.videos
|
||||||
|
const databaseUtils = require('../../../helpers/database-utils')
|
||||||
|
|
||||||
|
const router = express.Router()
|
||||||
|
|
||||||
|
router.put('/:id/rate',
|
||||||
|
oAuth.authenticate,
|
||||||
|
validatorsVideos.videoRate,
|
||||||
|
rateVideoRetryWrapper
|
||||||
|
)
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
module.exports = router
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function rateVideoRetryWrapper (req, res, next) {
|
||||||
|
const options = {
|
||||||
|
arguments: [ req, res ],
|
||||||
|
errorMessage: 'Cannot update the user video rate.'
|
||||||
|
}
|
||||||
|
|
||||||
|
databaseUtils.retryTransactionWrapper(rateVideo, options, function (err) {
|
||||||
|
if (err) return next(err)
|
||||||
|
|
||||||
|
return res.type('json').status(204).end()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function rateVideo (req, res, finalCallback) {
|
||||||
|
const rateType = req.body.rating
|
||||||
|
const videoInstance = res.locals.video
|
||||||
|
const userInstance = res.locals.oauth.token.User
|
||||||
|
|
||||||
|
waterfall([
|
||||||
|
databaseUtils.startSerializableTransaction,
|
||||||
|
|
||||||
|
function findPreviousRate (t, callback) {
|
||||||
|
db.UserVideoRate.load(userInstance.id, videoInstance.id, t, function (err, previousRate) {
|
||||||
|
return callback(err, t, previousRate)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
function insertUserRateIntoDB (t, previousRate, callback) {
|
||||||
|
const options = { transaction: t }
|
||||||
|
|
||||||
|
let likesToIncrement = 0
|
||||||
|
let dislikesToIncrement = 0
|
||||||
|
|
||||||
|
if (rateType === constants.VIDEO_RATE_TYPES.LIKE) likesToIncrement++
|
||||||
|
else if (rateType === constants.VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++
|
||||||
|
|
||||||
|
// There was a previous rate, update it
|
||||||
|
if (previousRate) {
|
||||||
|
// We will remove the previous rate, so we will need to remove it from the video attribute
|
||||||
|
if (previousRate.type === constants.VIDEO_RATE_TYPES.LIKE) likesToIncrement--
|
||||||
|
else if (previousRate.type === constants.VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement--
|
||||||
|
|
||||||
|
previousRate.type = rateType
|
||||||
|
|
||||||
|
previousRate.save(options).asCallback(function (err) {
|
||||||
|
return callback(err, t, likesToIncrement, dislikesToIncrement)
|
||||||
|
})
|
||||||
|
} else { // There was not a previous rate, insert a new one
|
||||||
|
const query = {
|
||||||
|
userId: userInstance.id,
|
||||||
|
videoId: videoInstance.id,
|
||||||
|
type: rateType
|
||||||
|
}
|
||||||
|
|
||||||
|
db.UserVideoRate.create(query, options).asCallback(function (err) {
|
||||||
|
return callback(err, t, likesToIncrement, dislikesToIncrement)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
function updateVideoAttributeDB (t, likesToIncrement, dislikesToIncrement, callback) {
|
||||||
|
const options = { transaction: t }
|
||||||
|
const incrementQuery = {
|
||||||
|
likes: likesToIncrement,
|
||||||
|
dislikes: dislikesToIncrement
|
||||||
|
}
|
||||||
|
|
||||||
|
// Even if we do not own the video we increment the attributes
|
||||||
|
// It is usefull for the user to have a feedback
|
||||||
|
videoInstance.increment(incrementQuery, options).asCallback(function (err) {
|
||||||
|
return callback(err, t, likesToIncrement, dislikesToIncrement)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
function sendEventsToFriendsIfNeeded (t, likesToIncrement, dislikesToIncrement, callback) {
|
||||||
|
// No need for an event type, we own the video
|
||||||
|
if (videoInstance.isOwned()) return callback(null, t, likesToIncrement, dislikesToIncrement)
|
||||||
|
|
||||||
|
const eventsParams = []
|
||||||
|
|
||||||
|
if (likesToIncrement !== 0) {
|
||||||
|
eventsParams.push({
|
||||||
|
videoId: videoInstance.id,
|
||||||
|
type: constants.REQUEST_VIDEO_EVENT_TYPES.LIKES,
|
||||||
|
count: likesToIncrement
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dislikesToIncrement !== 0) {
|
||||||
|
eventsParams.push({
|
||||||
|
videoId: videoInstance.id,
|
||||||
|
type: constants.REQUEST_VIDEO_EVENT_TYPES.DISLIKES,
|
||||||
|
count: dislikesToIncrement
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
friends.addEventsToRemoteVideo(eventsParams, t, function (err) {
|
||||||
|
return callback(err, t, likesToIncrement, dislikesToIncrement)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
function sendQaduToFriendsIfNeeded (t, likesToIncrement, dislikesToIncrement, callback) {
|
||||||
|
// We do not own the video, there is no need to send a quick and dirty update to friends
|
||||||
|
// Our rate was already sent by the addEvent function
|
||||||
|
if (videoInstance.isOwned() === false) return callback(null, t)
|
||||||
|
|
||||||
|
const qadusParams = []
|
||||||
|
|
||||||
|
if (likesToIncrement !== 0) {
|
||||||
|
qadusParams.push({
|
||||||
|
videoId: videoInstance.id,
|
||||||
|
type: constants.REQUEST_VIDEO_QADU_TYPES.LIKES
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dislikesToIncrement !== 0) {
|
||||||
|
qadusParams.push({
|
||||||
|
videoId: videoInstance.id,
|
||||||
|
type: constants.REQUEST_VIDEO_QADU_TYPES.DISLIKES
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
friends.quickAndDirtyUpdatesVideoToFriends(qadusParams, t, function (err) {
|
||||||
|
return callback(err, t)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
databaseUtils.commitTransaction
|
||||||
|
|
||||||
|
], function (err, t) {
|
||||||
|
if (err) {
|
||||||
|
// This is just a debug because we will retry the insert
|
||||||
|
logger.debug('Cannot add the user video rate.', { error: err })
|
||||||
|
return databaseUtils.rollbackTransaction(err, t, finalCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info('User video rate for video %s of user %s updated.', videoInstance.name, userInstance.username)
|
||||||
|
return finalCallback(null)
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in a new issue