import { isSignupAllowed } from '../../helpers'
import { CONFIG } from '../../initializers'
+import { asyncMiddleware } from '../../middlewares'
import { ServerConfig } from '../../../shared'
const configRouter = express.Router()
-configRouter.get('/', getConfig)
+configRouter.get('/',
+ asyncMiddleware(getConfig)
+)
-function getConfig (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function getConfig (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const allowed = await isSignupAllowed()
- isSignupAllowed().then(allowed => {
- const enabledResolutions = Object.keys(CONFIG.TRANSCODING.RESOLUTIONS)
- .filter(key => CONFIG.TRANSCODING.RESOLUTIONS[key] === true)
- .map(r => parseInt(r, 10))
+ const enabledResolutions = Object.keys(CONFIG.TRANSCODING.RESOLUTIONS)
+ .filter(key => CONFIG.TRANSCODING.RESOLUTIONS[key] === true)
+ .map(r => parseInt(r, 10))
- const json: ServerConfig = {
- signup: {
- allowed
- },
- transcoding: {
- enabledResolutions
- }
+ const json: ServerConfig = {
+ signup: {
+ allowed
+ },
+ transcoding: {
+ enabledResolutions
}
+ }
- res.json(json)
- })
+ return res.json(json)
}
// ---------------------------------------------------------------------------
import { CONFIG } from '../../initializers'
import { logger } from '../../helpers'
+import { asyncMiddleware } from '../../middlewares'
import { database as db } from '../../initializers/database'
import { OAuthClientLocal } from '../../../shared'
const oauthClientsRouter = express.Router()
-oauthClientsRouter.get('/local', getLocalClient)
+oauthClientsRouter.get('/local',
+ asyncMiddleware(getLocalClient)
+)
// Get the client credentials for the PeerTube front end
-function getLocalClient (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function getLocalClient (req: express.Request, res: express.Response, next: express.NextFunction) {
const serverHostname = CONFIG.WEBSERVER.HOSTNAME
const serverPort = CONFIG.WEBSERVER.PORT
let headerHostShouldBe = serverHostname
return res.type('json').status(403).end()
}
- db.OAuthClient.loadFirstClient()
- .then(client => {
- if (!client) throw new Error('No client available.')
-
- const json: OAuthClientLocal = {
- client_id: client.clientId,
- client_secret: client.clientSecret
- }
- res.json(json)
- })
- .catch(err => next(err))
+ const client = await db.OAuthClient.loadFirstClient()
+ if (!client) throw new Error('No client available.')
+
+ const json: OAuthClientLocal = {
+ client_id: client.clientId,
+ client_secret: client.clientSecret
+ }
+ return res.json(json)
}
// ---------------------------------------------------------------------------
paginationValidator,
setPagination,
setPodsSort,
- podsSortValidator
+ podsSortValidator,
+ asyncMiddleware
} from '../../middlewares'
import { PodInstance } from '../../models'
podsSortValidator,
setPodsSort,
setPagination,
- listPods
+ asyncMiddleware(listPods)
)
podsRouter.post('/make-friends',
authenticate,
ensureIsAdmin,
makeFriendsValidator,
setBodyHostsPort,
- makeFriendsController
+ asyncMiddleware(makeFriendsController)
)
podsRouter.get('/quit-friends',
authenticate,
ensureIsAdmin,
- quitFriendsController
+ asyncMiddleware(quitFriendsController)
)
podsRouter.delete('/:id',
authenticate,
ensureIsAdmin,
podRemoveValidator,
- removeFriendController
+ asyncMiddleware(removeFriendController)
)
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
-function listPods (req: express.Request, res: express.Response, next: express.NextFunction) {
- db.Pod.listForApi(req.query.start, req.query.count, req.query.sort)
- .then(resultList => res.json(getFormattedObjects(resultList.data, resultList.total)))
- .catch(err => next(err))
+async function listPods (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const resultList = await db.Pod.listForApi(req.query.start, req.query.count, req.query.sort)
+
+ return res.json(getFormattedObjects(resultList.data, resultList.total))
}
-function makeFriendsController (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function makeFriendsController (req: express.Request, res: express.Response, next: express.NextFunction) {
const hosts = req.body.hosts as string[]
+ // Don't wait the process that could be long
makeFriends(hosts)
.then(() => logger.info('Made friends!'))
.catch(err => logger.error('Could not make friends.', err))
- // Don't wait the process that could be long
- res.type('json').status(204).end()
+ return res.type('json').status(204).end()
}
-function quitFriendsController (req: express.Request, res: express.Response, next: express.NextFunction) {
- quitFriends()
- .then(() => res.type('json').status(204).end())
- .catch(err => next(err))
+async function quitFriendsController (req: express.Request, res: express.Response, next: express.NextFunction) {
+ await quitFriends()
+
+ return res.type('json').status(204).end()
}
-function removeFriendController (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function removeFriendController (req: express.Request, res: express.Response, next: express.NextFunction) {
const pod = res.locals.pod as PodInstance
- removeFriend(pod)
- .then(() => res.type('json').status(204).end())
- .catch(err => next(err))
+ await removeFriend(pod)
+
+ return res.type('json').status(204).end()
}
checkSignature,
signatureValidator,
setBodyHostPort,
- remotePodsAddValidator
+ remotePodsAddValidator,
+ asyncMiddleware
} from '../../../middlewares'
import { sendOwnedDataToPod } from '../../../lib'
import { getMyPublicCert, getFormattedObjects } from '../../../helpers'
remotePodsRouter.post('/remove',
signatureValidator,
checkSignature,
- removePods
+ asyncMiddleware(removePods)
)
-remotePodsRouter.post('/list', remotePodsList)
+remotePodsRouter.post('/list',
+ asyncMiddleware(remotePodsList)
+)
remotePodsRouter.post('/add',
setBodyHostPort, // We need to modify the host before running the validator!
remotePodsAddValidator,
- addPods
+ asyncMiddleware(addPods)
)
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
-function addPods (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function addPods (req: express.Request, res: express.Response, next: express.NextFunction) {
const information = req.body
const pod = db.Pod.build(information)
- pod.save()
- .then(podCreated => {
- return sendOwnedDataToPod(podCreated.id)
- })
- .then(() => {
- return getMyPublicCert()
- })
- .then(cert => {
- return res.json({ cert: cert, email: CONFIG.ADMIN.EMAIL })
- })
- .catch(err => next(err))
+ const podCreated = await pod.save()
+
+ await sendOwnedDataToPod(podCreated.id)
+
+ const cert = await getMyPublicCert()
+ return res.json({ cert, email: CONFIG.ADMIN.EMAIL })
}
-function remotePodsList (req: express.Request, res: express.Response, next: express.NextFunction) {
- db.Pod.list()
- .then(podsList => res.json(getFormattedObjects<FormattedPod, PodInstance>(podsList, podsList.length)))
- .catch(err => next(err))
+async function remotePodsList (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const pods = await db.Pod.list()
+
+ return res.json(getFormattedObjects<FormattedPod, PodInstance>(pods, pods.length))
}
-function removePods (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function removePods (req: express.Request, res: express.Response, next: express.NextFunction) {
const signature: PodSignature = req.body.signature
const host = signature.host
- db.Pod.loadByHost(host)
- .then(pod => pod.destroy())
- .then(() => res.type('json').status(204).end())
- .catch(err => next(err))
+ const pod = await db.Pod.loadByHost(host)
+ await pod.destroy()
+
+ return res.type('json').status(204).end()
}
import * as express from 'express'
-import * as Promise from 'bluebird'
+import * as Bluebird from 'bluebird'
import * as Sequelize from 'sequelize'
import { database as db } from '../../../initializers/database'
remoteEventsVideosValidator
} from '../../../middlewares'
import { logger, retryTransactionWrapper } from '../../../helpers'
-import { quickAndDirtyUpdatesVideoToFriends } from '../../../lib'
+import { quickAndDirtyUpdatesVideoToFriends, fetchVideoChannelByHostAndUUID } from '../../../lib'
import { PodInstance, VideoFileInstance } from '../../../models'
import {
RemoteVideoRequest,
const fromPod = res.locals.secure.pod
// We need to process in the same order to keep consistency
- Promise.each(requests, request => {
+ Bluebird.each(requests, request => {
const data = request.data
// Get the function we need to call in order to process the request
const requests: RemoteQaduVideoRequest[] = req.body.data
const fromPod = res.locals.secure.pod
- Promise.each(requests, request => {
+ Bluebird.each(requests, request => {
const videoData = request.data
return quickAndDirtyUpdateVideoRetryWrapper(videoData, fromPod)
const requests: RemoteVideoEventRequest[] = req.body.data
const fromPod = res.locals.secure.pod
- Promise.each(requests, request => {
+ Bluebird.each(requests, request => {
const eventData = request.data
return processVideosEventsRetryWrapper(eventData, fromPod)
return res.type('json').status(204).end()
}
-function processVideosEventsRetryWrapper (eventData: RemoteVideoEventData, fromPod: PodInstance) {
+async function processVideosEventsRetryWrapper (eventData: RemoteVideoEventData, fromPod: PodInstance) {
const options = {
arguments: [ eventData, fromPod ],
errorMessage: 'Cannot process videos events with many retries.'
}
- return retryTransactionWrapper(processVideosEvents, options)
+ await retryTransactionWrapper(processVideosEvents, options)
}
-function processVideosEvents (eventData: RemoteVideoEventData, fromPod: PodInstance) {
+async function processVideosEvents (eventData: RemoteVideoEventData, fromPod: PodInstance) {
+ await db.sequelize.transaction(async t => {
+ const sequelizeOptions = { transaction: t }
+ const videoInstance = await fetchVideoByUUID(eventData.uuid, t)
- return db.sequelize.transaction(t => {
- return fetchVideoByUUID(eventData.uuid, t)
- .then(videoInstance => {
- const options = { transaction: t }
+ let columnToUpdate
+ let qaduType
- let columnToUpdate
- let qaduType
+ switch (eventData.eventType) {
+ case REQUEST_VIDEO_EVENT_TYPES.VIEWS:
+ columnToUpdate = 'views'
+ qaduType = REQUEST_VIDEO_QADU_TYPES.VIEWS
+ break
- switch (eventData.eventType) {
- case REQUEST_VIDEO_EVENT_TYPES.VIEWS:
- columnToUpdate = 'views'
- qaduType = REQUEST_VIDEO_QADU_TYPES.VIEWS
- break
+ case REQUEST_VIDEO_EVENT_TYPES.LIKES:
+ columnToUpdate = 'likes'
+ qaduType = REQUEST_VIDEO_QADU_TYPES.LIKES
+ break
- case REQUEST_VIDEO_EVENT_TYPES.LIKES:
- columnToUpdate = 'likes'
- qaduType = REQUEST_VIDEO_QADU_TYPES.LIKES
- break
+ case REQUEST_VIDEO_EVENT_TYPES.DISLIKES:
+ columnToUpdate = 'dislikes'
+ qaduType = REQUEST_VIDEO_QADU_TYPES.DISLIKES
+ break
- case REQUEST_VIDEO_EVENT_TYPES.DISLIKES:
- columnToUpdate = 'dislikes'
- qaduType = REQUEST_VIDEO_QADU_TYPES.DISLIKES
- break
+ default:
+ throw new Error('Unknown video event type.')
+ }
- default:
- throw new Error('Unknown video event type.')
- }
+ const query = {}
+ query[columnToUpdate] = eventData.count
- const query = {}
- query[columnToUpdate] = eventData.count
+ await videoInstance.increment(query, sequelizeOptions)
- return videoInstance.increment(query, options).then(() => ({ videoInstance, qaduType }))
- })
- .then(({ videoInstance, qaduType }) => {
- const qadusParams = [
- {
- videoId: videoInstance.id,
- type: qaduType
- }
- ]
-
- return quickAndDirtyUpdatesVideoToFriends(qadusParams, t)
- })
- })
- .then(() => logger.info('Remote video event processed for video with uuid %s.', eventData.uuid))
- .catch(err => {
- logger.debug('Cannot process a video event.', err)
- throw err
+ const qadusParams = [
+ {
+ videoId: videoInstance.id,
+ type: qaduType
+ }
+ ]
+ await quickAndDirtyUpdatesVideoToFriends(qadusParams, t)
})
+
+ logger.info('Remote video event processed for video with uuid %s.', eventData.uuid)
}
-function quickAndDirtyUpdateVideoRetryWrapper (videoData: RemoteQaduVideoData, fromPod: PodInstance) {
+async function quickAndDirtyUpdateVideoRetryWrapper (videoData: RemoteQaduVideoData, fromPod: PodInstance) {
const options = {
arguments: [ videoData, fromPod ],
errorMessage: 'Cannot update quick and dirty the remote video with many retries.'
}
- return retryTransactionWrapper(quickAndDirtyUpdateVideo, options)
+ await retryTransactionWrapper(quickAndDirtyUpdateVideo, options)
}
-function quickAndDirtyUpdateVideo (videoData: RemoteQaduVideoData, fromPod: PodInstance) {
+async function quickAndDirtyUpdateVideo (videoData: RemoteQaduVideoData, fromPod: PodInstance) {
let videoUUID = ''
- return db.sequelize.transaction(t => {
- return fetchVideoByHostAndUUID(fromPod.host, videoData.uuid, t)
- .then(videoInstance => {
- const options = { transaction: t }
+ await db.sequelize.transaction(async t => {
+ const videoInstance = await fetchVideoByHostAndUUID(fromPod.host, videoData.uuid, t)
+ const sequelizeOptions = { transaction: t }
- videoUUID = videoInstance.uuid
+ videoUUID = videoInstance.uuid
- if (videoData.views) {
- videoInstance.set('views', videoData.views)
- }
+ if (videoData.views) {
+ videoInstance.set('views', videoData.views)
+ }
- if (videoData.likes) {
- videoInstance.set('likes', videoData.likes)
- }
+ if (videoData.likes) {
+ videoInstance.set('likes', videoData.likes)
+ }
- if (videoData.dislikes) {
- videoInstance.set('dislikes', videoData.dislikes)
- }
+ if (videoData.dislikes) {
+ videoInstance.set('dislikes', videoData.dislikes)
+ }
- return videoInstance.save(options)
- })
+ await videoInstance.save(sequelizeOptions)
})
- .then(() => logger.info('Remote video with uuid %s quick and dirty updated', videoUUID))
- .catch(err => logger.debug('Cannot quick and dirty update the remote video.', err))
+
+ logger.info('Remote video with uuid %s quick and dirty updated', videoUUID)
}
// Handle retries on fail
-function addRemoteVideoRetryWrapper (videoToCreateData: RemoteVideoCreateData, fromPod: PodInstance) {
+async function addRemoteVideoRetryWrapper (videoToCreateData: RemoteVideoCreateData, fromPod: PodInstance) {
const options = {
arguments: [ videoToCreateData, fromPod ],
errorMessage: 'Cannot insert the remote video with many retries.'
}
- return retryTransactionWrapper(addRemoteVideo, options)
+ await retryTransactionWrapper(addRemoteVideo, options)
}
-function addRemoteVideo (videoToCreateData: RemoteVideoCreateData, fromPod: PodInstance) {
+async function addRemoteVideo (videoToCreateData: RemoteVideoCreateData, fromPod: PodInstance) {
logger.debug('Adding remote video "%s".', videoToCreateData.uuid)
- return db.sequelize.transaction(t => {
- return db.Video.loadByUUID(videoToCreateData.uuid)
- .then(video => {
- if (video) throw new Error('UUID already exists.')
-
- return db.VideoChannel.loadByHostAndUUID(fromPod.host, videoToCreateData.channelUUID, t)
- })
- .then(videoChannel => {
- if (!videoChannel) throw new Error('Video channel ' + videoToCreateData.channelUUID + ' not found.')
+ await db.sequelize.transaction(async t => {
+ const sequelizeOptions = {
+ transaction: t
+ }
- const tags = videoToCreateData.tags
+ const videoFromDatabase = await db.Video.loadByUUID(videoToCreateData.uuid)
+ if (videoFromDatabase) throw new Error('UUID already exists.')
+
+ const videoChannel = await db.VideoChannel.loadByHostAndUUID(fromPod.host, videoToCreateData.channelUUID, t)
+ if (!videoChannel) throw new Error('Video channel ' + videoToCreateData.channelUUID + ' not found.')
+
+ const tags = videoToCreateData.tags
+ const tagInstances = await db.Tag.findOrCreateTags(tags, t)
+
+ const videoData = {
+ name: videoToCreateData.name,
+ uuid: videoToCreateData.uuid,
+ category: videoToCreateData.category,
+ licence: videoToCreateData.licence,
+ language: videoToCreateData.language,
+ nsfw: videoToCreateData.nsfw,
+ description: videoToCreateData.description,
+ channelId: videoChannel.id,
+ duration: videoToCreateData.duration,
+ createdAt: videoToCreateData.createdAt,
+ // FIXME: updatedAt does not seems to be considered by Sequelize
+ updatedAt: videoToCreateData.updatedAt,
+ views: videoToCreateData.views,
+ likes: videoToCreateData.likes,
+ dislikes: videoToCreateData.dislikes,
+ remote: true
+ }
- return db.Tag.findOrCreateTags(tags, t).then(tagInstances => ({ videoChannel, tagInstances }))
- })
- .then(({ videoChannel, tagInstances }) => {
- const videoData = {
- name: videoToCreateData.name,
- uuid: videoToCreateData.uuid,
- category: videoToCreateData.category,
- licence: videoToCreateData.licence,
- language: videoToCreateData.language,
- nsfw: videoToCreateData.nsfw,
- description: videoToCreateData.description,
- channelId: videoChannel.id,
- duration: videoToCreateData.duration,
- createdAt: videoToCreateData.createdAt,
- // FIXME: updatedAt does not seems to be considered by Sequelize
- updatedAt: videoToCreateData.updatedAt,
- views: videoToCreateData.views,
- likes: videoToCreateData.likes,
- dislikes: videoToCreateData.dislikes,
- remote: true
- }
-
- const video = db.Video.build(videoData)
- return { tagInstances, video }
- })
- .then(({ tagInstances, video }) => {
- return db.Video.generateThumbnailFromData(video, videoToCreateData.thumbnailData).then(() => ({ tagInstances, video }))
+ const video = db.Video.build(videoData)
+ await db.Video.generateThumbnailFromData(video, videoToCreateData.thumbnailData)
+ const videoCreated = await video.save(sequelizeOptions)
+
+ const tasks = []
+ for (const fileData of videoToCreateData.files) {
+ const videoFileInstance = db.VideoFile.build({
+ extname: fileData.extname,
+ infoHash: fileData.infoHash,
+ resolution: fileData.resolution,
+ size: fileData.size,
+ videoId: videoCreated.id
})
- .then(({ tagInstances, video }) => {
- const options = {
- transaction: t
- }
- return video.save(options).then(videoCreated => ({ tagInstances, videoCreated }))
- })
- .then(({ tagInstances, videoCreated }) => {
- const tasks = []
- const options = {
- transaction: t
- }
-
- videoToCreateData.files.forEach(fileData => {
- const videoFileInstance = db.VideoFile.build({
- extname: fileData.extname,
- infoHash: fileData.infoHash,
- resolution: fileData.resolution,
- size: fileData.size,
- videoId: videoCreated.id
- })
-
- tasks.push(videoFileInstance.save(options))
- })
+ tasks.push(videoFileInstance.save(sequelizeOptions))
+ }
- return Promise.all(tasks).then(() => ({ tagInstances, videoCreated }))
- })
- .then(({ tagInstances, videoCreated }) => {
- const options = {
- transaction: t
- }
+ await Promise.all(tasks)
- return videoCreated.setTags(tagInstances, options)
- })
- })
- .then(() => logger.info('Remote video with uuid %s inserted.', videoToCreateData.uuid))
- .catch(err => {
- logger.debug('Cannot insert the remote video.', err)
- throw err
+ await videoCreated.setTags(tagInstances, sequelizeOptions)
})
+
+ logger.info('Remote video with uuid %s inserted.', videoToCreateData.uuid)
}
// Handle retries on fail
-function updateRemoteVideoRetryWrapper (videoAttributesToUpdate: RemoteVideoUpdateData, fromPod: PodInstance) {
+async function updateRemoteVideoRetryWrapper (videoAttributesToUpdate: RemoteVideoUpdateData, fromPod: PodInstance) {
const options = {
arguments: [ videoAttributesToUpdate, fromPod ],
errorMessage: 'Cannot update the remote video with many retries'
}
- return retryTransactionWrapper(updateRemoteVideo, options)
+ await retryTransactionWrapper(updateRemoteVideo, options)
}
-function updateRemoteVideo (videoAttributesToUpdate: RemoteVideoUpdateData, fromPod: PodInstance) {
+async function updateRemoteVideo (videoAttributesToUpdate: RemoteVideoUpdateData, fromPod: PodInstance) {
logger.debug('Updating remote video "%s".', videoAttributesToUpdate.uuid)
- return db.sequelize.transaction(t => {
- return fetchVideoByHostAndUUID(fromPod.host, videoAttributesToUpdate.uuid, t)
- .then(videoInstance => {
- const tags = videoAttributesToUpdate.tags
-
- return db.Tag.findOrCreateTags(tags, t).then(tagInstances => ({ videoInstance, tagInstances }))
- })
- .then(({ videoInstance, tagInstances }) => {
- const options = { transaction: t }
-
- videoInstance.set('name', videoAttributesToUpdate.name)
- videoInstance.set('category', videoAttributesToUpdate.category)
- videoInstance.set('licence', videoAttributesToUpdate.licence)
- videoInstance.set('language', videoAttributesToUpdate.language)
- videoInstance.set('nsfw', videoAttributesToUpdate.nsfw)
- videoInstance.set('description', videoAttributesToUpdate.description)
- videoInstance.set('duration', videoAttributesToUpdate.duration)
- videoInstance.set('createdAt', videoAttributesToUpdate.createdAt)
- videoInstance.set('updatedAt', videoAttributesToUpdate.updatedAt)
- videoInstance.set('views', videoAttributesToUpdate.views)
- videoInstance.set('likes', videoAttributesToUpdate.likes)
- videoInstance.set('dislikes', videoAttributesToUpdate.dislikes)
-
- return videoInstance.save(options).then(() => ({ videoInstance, tagInstances }))
- })
- .then(({ tagInstances, videoInstance }) => {
- const tasks: Promise<void>[] = []
-
- // Remove old video files
- videoInstance.VideoFiles.forEach(videoFile => {
- tasks.push(videoFile.destroy({ transaction: t }))
+ try {
+ await db.sequelize.transaction(async t => {
+ const sequelizeOptions = {
+ transaction: t
+ }
+
+ const videoInstance = await fetchVideoByHostAndUUID(fromPod.host, videoAttributesToUpdate.uuid, t)
+ const tags = videoAttributesToUpdate.tags
+
+ const tagInstances = await db.Tag.findOrCreateTags(tags, t)
+
+ videoInstance.set('name', videoAttributesToUpdate.name)
+ videoInstance.set('category', videoAttributesToUpdate.category)
+ videoInstance.set('licence', videoAttributesToUpdate.licence)
+ videoInstance.set('language', videoAttributesToUpdate.language)
+ videoInstance.set('nsfw', videoAttributesToUpdate.nsfw)
+ videoInstance.set('description', videoAttributesToUpdate.description)
+ videoInstance.set('duration', videoAttributesToUpdate.duration)
+ videoInstance.set('createdAt', videoAttributesToUpdate.createdAt)
+ videoInstance.set('updatedAt', videoAttributesToUpdate.updatedAt)
+ videoInstance.set('views', videoAttributesToUpdate.views)
+ videoInstance.set('likes', videoAttributesToUpdate.likes)
+ videoInstance.set('dislikes', videoAttributesToUpdate.dislikes)
+
+ await videoInstance.save(sequelizeOptions)
+
+ // Remove old video files
+ const videoFileDestroyTasks: Bluebird<void>[] = []
+ for (const videoFile of videoInstance.VideoFiles) {
+ videoFileDestroyTasks.push(videoFile.destroy(sequelizeOptions))
+ }
+ await Promise.all(videoFileDestroyTasks)
+
+ const videoFileCreateTasks: Bluebird<VideoFileInstance>[] = []
+ for (const fileData of videoAttributesToUpdate.files) {
+ const videoFileInstance = db.VideoFile.build({
+ extname: fileData.extname,
+ infoHash: fileData.infoHash,
+ resolution: fileData.resolution,
+ size: fileData.size,
+ videoId: videoInstance.id
})
- return Promise.all(tasks).then(() => ({ tagInstances, videoInstance }))
- })
- .then(({ tagInstances, videoInstance }) => {
- const tasks: Promise<VideoFileInstance>[] = []
- const options = {
- transaction: t
- }
-
- videoAttributesToUpdate.files.forEach(fileData => {
- const videoFileInstance = db.VideoFile.build({
- extname: fileData.extname,
- infoHash: fileData.infoHash,
- resolution: fileData.resolution,
- size: fileData.size,
- videoId: videoInstance.id
- })
-
- tasks.push(videoFileInstance.save(options))
- })
+ videoFileCreateTasks.push(videoFileInstance.save(sequelizeOptions))
+ }
- return Promise.all(tasks).then(() => ({ tagInstances, videoInstance }))
- })
- .then(({ videoInstance, tagInstances }) => {
- const options = { transaction: t }
+ await Promise.all(videoFileCreateTasks)
- return videoInstance.setTags(tagInstances, options)
- })
- })
- .then(() => logger.info('Remote video with uuid %s updated', videoAttributesToUpdate.uuid))
- .catch(err => {
+ await videoInstance.setTags(tagInstances, sequelizeOptions)
+ })
+
+ logger.info('Remote video with uuid %s updated', videoAttributesToUpdate.uuid)
+ } catch (err) {
// This is just a debug because we will retry the insert
logger.debug('Cannot update the remote video.', err)
throw err
- })
+ }
}
-function removeRemoteVideoRetryWrapper (videoToRemoveData: RemoteVideoRemoveData, fromPod: PodInstance) {
+async function removeRemoteVideoRetryWrapper (videoToRemoveData: RemoteVideoRemoveData, fromPod: PodInstance) {
const options = {
arguments: [ videoToRemoveData, fromPod ],
errorMessage: 'Cannot remove the remote video channel with many retries.'
}
- return retryTransactionWrapper(removeRemoteVideo, options)
+ await retryTransactionWrapper(removeRemoteVideo, options)
}
-function removeRemoteVideo (videoToRemoveData: RemoteVideoRemoveData, fromPod: PodInstance) {
+async function removeRemoteVideo (videoToRemoveData: RemoteVideoRemoveData, fromPod: PodInstance) {
logger.debug('Removing remote video "%s".', videoToRemoveData.uuid)
- return db.sequelize.transaction(t => {
+ await db.sequelize.transaction(async t => {
// We need the instance because we have to remove some other stuffs (thumbnail etc)
- return fetchVideoByHostAndUUID(fromPod.host, videoToRemoveData.uuid, t)
- .then(video => video.destroy({ transaction: t }))
- })
- .then(() => logger.info('Remote video with uuid %s removed.', videoToRemoveData.uuid))
- .catch(err => {
- logger.debug('Cannot remove the remote video.', err)
- throw err
+ const videoInstance = await fetchVideoByHostAndUUID(fromPod.host, videoToRemoveData.uuid, t)
+ await videoInstance.destroy({ transaction: t })
})
+
+ logger.info('Remote video with uuid %s removed.', videoToRemoveData.uuid)
}
-function addRemoteVideoAuthorRetryWrapper (authorToCreateData: RemoteVideoAuthorCreateData, fromPod: PodInstance) {
+async function addRemoteVideoAuthorRetryWrapper (authorToCreateData: RemoteVideoAuthorCreateData, fromPod: PodInstance) {
const options = {
arguments: [ authorToCreateData, fromPod ],
errorMessage: 'Cannot insert the remote video author with many retries.'
}
- return retryTransactionWrapper(addRemoteVideoAuthor, options)
+ await retryTransactionWrapper(addRemoteVideoAuthor, options)
}
-function addRemoteVideoAuthor (authorToCreateData: RemoteVideoAuthorCreateData, fromPod: PodInstance) {
+async function addRemoteVideoAuthor (authorToCreateData: RemoteVideoAuthorCreateData, fromPod: PodInstance) {
logger.debug('Adding remote video author "%s".', authorToCreateData.uuid)
- return db.sequelize.transaction(t => {
- return db.Author.loadAuthorByPodAndUUID(authorToCreateData.uuid, fromPod.id, t)
- .then(author => {
- if (author) throw new Error('UUID already exists.')
+ await db.sequelize.transaction(async t => {
+ const authorInDatabase = await db.Author.loadAuthorByPodAndUUID(authorToCreateData.uuid, fromPod.id, t)
+ if (authorInDatabase) throw new Error('Author with UUID ' + authorToCreateData.uuid + ' already exists.')
- return undefined
- })
- .then(() => {
- const videoAuthorData = {
- name: authorToCreateData.name,
- uuid: authorToCreateData.uuid,
- userId: null, // Not on our pod
- podId: fromPod.id
- }
-
- const author = db.Author.build(videoAuthorData)
- return author.save({ transaction: t })
- })
+ const videoAuthorData = {
+ name: authorToCreateData.name,
+ uuid: authorToCreateData.uuid,
+ userId: null, // Not on our pod
+ podId: fromPod.id
+ }
+
+ const author = db.Author.build(videoAuthorData)
+ await author.save({ transaction: t })
})
- .then(() => logger.info('Remote video author with uuid %s inserted.', authorToCreateData.uuid))
- .catch(err => {
- logger.debug('Cannot insert the remote video author.', err)
- throw err
- })
+
+ logger.info('Remote video author with uuid %s inserted.', authorToCreateData.uuid)
}
-function removeRemoteVideoAuthorRetryWrapper (authorAttributesToRemove: RemoteVideoAuthorRemoveData, fromPod: PodInstance) {
+async function removeRemoteVideoAuthorRetryWrapper (authorAttributesToRemove: RemoteVideoAuthorRemoveData, fromPod: PodInstance) {
const options = {
arguments: [ authorAttributesToRemove, fromPod ],
errorMessage: 'Cannot remove the remote video author with many retries.'
}
- return retryTransactionWrapper(removeRemoteVideoAuthor, options)
+ await retryTransactionWrapper(removeRemoteVideoAuthor, options)
}
-function removeRemoteVideoAuthor (authorAttributesToRemove: RemoteVideoAuthorRemoveData, fromPod: PodInstance) {
+async function removeRemoteVideoAuthor (authorAttributesToRemove: RemoteVideoAuthorRemoveData, fromPod: PodInstance) {
logger.debug('Removing remote video author "%s".', authorAttributesToRemove.uuid)
- return db.sequelize.transaction(t => {
- return db.Author.loadAuthorByPodAndUUID(authorAttributesToRemove.uuid, fromPod.id, t)
- .then(videoAuthor => videoAuthor.destroy({ transaction: t }))
- })
- .then(() => logger.info('Remote video author with uuid %s removed.', authorAttributesToRemove.uuid))
- .catch(err => {
- logger.debug('Cannot remove the remote video author.', err)
- throw err
+ await db.sequelize.transaction(async t => {
+ const videoAuthor = await db.Author.loadAuthorByPodAndUUID(authorAttributesToRemove.uuid, fromPod.id, t)
+ await videoAuthor.destroy({ transaction: t })
})
+
+ logger.info('Remote video author with uuid %s removed.', authorAttributesToRemove.uuid)
}
-function addRemoteVideoChannelRetryWrapper (videoChannelToCreateData: RemoteVideoChannelCreateData, fromPod: PodInstance) {
+async function addRemoteVideoChannelRetryWrapper (videoChannelToCreateData: RemoteVideoChannelCreateData, fromPod: PodInstance) {
const options = {
arguments: [ videoChannelToCreateData, fromPod ],
errorMessage: 'Cannot insert the remote video channel with many retries.'
}
- return retryTransactionWrapper(addRemoteVideoChannel, options)
+ await retryTransactionWrapper(addRemoteVideoChannel, options)
}
-function addRemoteVideoChannel (videoChannelToCreateData: RemoteVideoChannelCreateData, fromPod: PodInstance) {
+async function addRemoteVideoChannel (videoChannelToCreateData: RemoteVideoChannelCreateData, fromPod: PodInstance) {
logger.debug('Adding remote video channel "%s".', videoChannelToCreateData.uuid)
- return db.sequelize.transaction(t => {
- return db.VideoChannel.loadByUUID(videoChannelToCreateData.uuid)
- .then(videoChannel => {
- if (videoChannel) throw new Error('UUID already exists.')
+ await db.sequelize.transaction(async t => {
+ const videoChannelInDatabase = await db.VideoChannel.loadByUUID(videoChannelToCreateData.uuid)
+ if (videoChannelInDatabase) {
+ throw new Error('Video channel with UUID ' + videoChannelToCreateData.uuid + ' already exists.')
+ }
- return undefined
- })
- .then(() => {
- const authorUUID = videoChannelToCreateData.ownerUUID
- const podId = fromPod.id
+ const authorUUID = videoChannelToCreateData.ownerUUID
+ const podId = fromPod.id
- return db.Author.loadAuthorByPodAndUUID(authorUUID, podId, t)
- })
- .then(author => {
- if (!author) throw new Error('Unknown author UUID.')
-
- const videoChannelData = {
- name: videoChannelToCreateData.name,
- description: videoChannelToCreateData.description,
- uuid: videoChannelToCreateData.uuid,
- createdAt: videoChannelToCreateData.createdAt,
- updatedAt: videoChannelToCreateData.updatedAt,
- remote: true,
- authorId: author.id
- }
-
- const videoChannel = db.VideoChannel.build(videoChannelData)
- return videoChannel.save({ transaction: t })
- })
- })
- .then(() => logger.info('Remote video channel with uuid %s inserted.', videoChannelToCreateData.uuid))
- .catch(err => {
- logger.debug('Cannot insert the remote video channel.', err)
- throw err
+ const author = await db.Author.loadAuthorByPodAndUUID(authorUUID, podId, t)
+ if (!author) throw new Error('Unknown author UUID' + authorUUID + '.')
+
+ const videoChannelData = {
+ name: videoChannelToCreateData.name,
+ description: videoChannelToCreateData.description,
+ uuid: videoChannelToCreateData.uuid,
+ createdAt: videoChannelToCreateData.createdAt,
+ updatedAt: videoChannelToCreateData.updatedAt,
+ remote: true,
+ authorId: author.id
+ }
+
+ const videoChannel = db.VideoChannel.build(videoChannelData)
+ await videoChannel.save({ transaction: t })
})
+
+ logger.info('Remote video channel with uuid %s inserted.', videoChannelToCreateData.uuid)
}
-function updateRemoteVideoChannelRetryWrapper (videoChannelAttributesToUpdate: RemoteVideoChannelUpdateData, fromPod: PodInstance) {
+async function updateRemoteVideoChannelRetryWrapper (videoChannelAttributesToUpdate: RemoteVideoChannelUpdateData, fromPod: PodInstance) {
const options = {
arguments: [ videoChannelAttributesToUpdate, fromPod ],
errorMessage: 'Cannot update the remote video channel with many retries.'
}
- return retryTransactionWrapper(updateRemoteVideoChannel, options)
+ await retryTransactionWrapper(updateRemoteVideoChannel, options)
}
-function updateRemoteVideoChannel (videoChannelAttributesToUpdate: RemoteVideoChannelUpdateData, fromPod: PodInstance) {
+async function updateRemoteVideoChannel (videoChannelAttributesToUpdate: RemoteVideoChannelUpdateData, fromPod: PodInstance) {
logger.debug('Updating remote video channel "%s".', videoChannelAttributesToUpdate.uuid)
- return db.sequelize.transaction(t => {
- return fetchVideoChannelByHostAndUUID(fromPod.host, videoChannelAttributesToUpdate.uuid, t)
- .then(videoChannelInstance => {
- const options = { transaction: t }
+ await db.sequelize.transaction(async t => {
+ const sequelizeOptions = { transaction: t }
- videoChannelInstance.set('name', videoChannelAttributesToUpdate.name)
- videoChannelInstance.set('description', videoChannelAttributesToUpdate.description)
- videoChannelInstance.set('createdAt', videoChannelAttributesToUpdate.createdAt)
- videoChannelInstance.set('updatedAt', videoChannelAttributesToUpdate.updatedAt)
+ const videoChannelInstance = await fetchVideoChannelByHostAndUUID(fromPod.host, videoChannelAttributesToUpdate.uuid, t)
+ videoChannelInstance.set('name', videoChannelAttributesToUpdate.name)
+ videoChannelInstance.set('description', videoChannelAttributesToUpdate.description)
+ videoChannelInstance.set('createdAt', videoChannelAttributesToUpdate.createdAt)
+ videoChannelInstance.set('updatedAt', videoChannelAttributesToUpdate.updatedAt)
- return videoChannelInstance.save(options)
- })
- })
- .then(() => logger.info('Remote video channel with uuid %s updated', videoChannelAttributesToUpdate.uuid))
- .catch(err => {
- // This is just a debug because we will retry the insert
- logger.debug('Cannot update the remote video channel.', err)
- throw err
+ await videoChannelInstance.save(sequelizeOptions)
})
+
+ logger.info('Remote video channel with uuid %s updated', videoChannelAttributesToUpdate.uuid)
}
-function removeRemoteVideoChannelRetryWrapper (videoChannelAttributesToRemove: RemoteVideoChannelRemoveData, fromPod: PodInstance) {
+async function removeRemoteVideoChannelRetryWrapper (videoChannelAttributesToRemove: RemoteVideoChannelRemoveData, fromPod: PodInstance) {
const options = {
arguments: [ videoChannelAttributesToRemove, fromPod ],
errorMessage: 'Cannot remove the remote video channel with many retries.'
}
- return retryTransactionWrapper(removeRemoteVideoChannel, options)
+ await retryTransactionWrapper(removeRemoteVideoChannel, options)
}
-function removeRemoteVideoChannel (videoChannelAttributesToRemove: RemoteVideoChannelRemoveData, fromPod: PodInstance) {
+async function removeRemoteVideoChannel (videoChannelAttributesToRemove: RemoteVideoChannelRemoveData, fromPod: PodInstance) {
logger.debug('Removing remote video channel "%s".', videoChannelAttributesToRemove.uuid)
- return db.sequelize.transaction(t => {
- return fetchVideoChannelByHostAndUUID(fromPod.host, videoChannelAttributesToRemove.uuid, t)
- .then(videoChannel => videoChannel.destroy({ transaction: t }))
- })
- .then(() => logger.info('Remote video channel with uuid %s removed.', videoChannelAttributesToRemove.uuid))
- .catch(err => {
- logger.debug('Cannot remove the remote video channel.', err)
- throw err
+ await db.sequelize.transaction(async t => {
+ const videoChannel = await fetchVideoChannelByHostAndUUID(fromPod.host, videoChannelAttributesToRemove.uuid, t)
+ await videoChannel.destroy({ transaction: t })
})
+
+ logger.info('Remote video channel with uuid %s removed.', videoChannelAttributesToRemove.uuid)
}
-function reportAbuseRemoteVideoRetryWrapper (reportData: RemoteVideoReportAbuseData, fromPod: PodInstance) {
+async function reportAbuseRemoteVideoRetryWrapper (reportData: RemoteVideoReportAbuseData, fromPod: PodInstance) {
const options = {
arguments: [ reportData, fromPod ],
errorMessage: 'Cannot create remote abuse video with many retries.'
}
- return retryTransactionWrapper(reportAbuseRemoteVideo, options)
+ await retryTransactionWrapper(reportAbuseRemoteVideo, options)
}
-function reportAbuseRemoteVideo (reportData: RemoteVideoReportAbuseData, fromPod: PodInstance) {
+async function reportAbuseRemoteVideo (reportData: RemoteVideoReportAbuseData, fromPod: PodInstance) {
logger.debug('Reporting remote abuse for video %s.', reportData.videoUUID)
- return db.sequelize.transaction(t => {
- return fetchVideoByUUID(reportData.videoUUID, t)
- .then(video => {
- const videoAbuseData = {
- reporterUsername: reportData.reporterUsername,
- reason: reportData.reportReason,
- reporterPodId: fromPod.id,
- videoId: video.id
- }
-
- return db.VideoAbuse.create(videoAbuseData)
- })
- })
- .then(() => logger.info('Remote abuse for video uuid %s created', reportData.videoUUID))
- .catch(err => {
- // This is just a debug because we will retry the insert
- logger.debug('Cannot create remote abuse video', err)
- throw err
- })
-}
+ await db.sequelize.transaction(async t => {
+ const videoInstance = await fetchVideoByUUID(reportData.videoUUID, t)
+ const videoAbuseData = {
+ reporterUsername: reportData.reporterUsername,
+ reason: reportData.reportReason,
+ reporterPodId: fromPod.id,
+ videoId: videoInstance.id
+ }
-function fetchVideoByUUID (id: string, t: Sequelize.Transaction) {
- return db.Video.loadByUUID(id, t)
- .then(video => {
- if (!video) throw new Error('Video not found')
+ await db.VideoAbuse.create(videoAbuseData)
- return video
- })
- .catch(err => {
- logger.error('Cannot load owned video from id.', { error: err.stack, id })
- throw err
- })
+ })
+
+ logger.info('Remote abuse for video uuid %s created', reportData.videoUUID)
}
-function fetchVideoByHostAndUUID (podHost: string, uuid: string, t: Sequelize.Transaction) {
- return db.Video.loadByHostAndUUID(podHost, uuid, t)
- .then(video => {
- if (!video) throw new Error('Video not found')
+async function fetchVideoByUUID (id: string, t: Sequelize.Transaction) {
+ try {
+ const video = await db.Video.loadByUUID(id, t)
- return video
- })
- .catch(err => {
- logger.error('Cannot load video from host and uuid.', { error: err.stack, podHost, uuid })
- throw err
- })
+ if (!video) throw new Error('Video ' + id + ' not found')
+
+ return video
+ } catch (err) {
+ logger.error('Cannot load owned video from id.', { error: err.stack, id })
+ throw err
+ }
}
-function fetchVideoChannelByHostAndUUID (podHost: string, uuid: string, t: Sequelize.Transaction) {
- return db.VideoChannel.loadByHostAndUUID(podHost, uuid, t)
- .then(videoChannel => {
- if (!videoChannel) throw new Error('Video channel not found')
+async function fetchVideoByHostAndUUID (podHost: string, uuid: string, t: Sequelize.Transaction) {
+ try {
+ const video = await db.Video.loadByHostAndUUID(podHost, uuid, t)
+ if (!video) throw new Error('Video not found')
- return videoChannel
- })
- .catch(err => {
- logger.error('Cannot load video channel from host and uuid.', { error: err.stack, podHost, uuid })
- throw err
- })
+ return video
+ } catch (err) {
+ logger.error('Cannot load video from host and uuid.', { error: err.stack, podHost, uuid })
+ throw err
+ }
}
import * as express from 'express'
-import * as Promise from 'bluebird'
+import * as Bluebird from 'bluebird'
import {
AbstractRequestScheduler,
getRequestVideoQaduScheduler,
getRequestVideoEventScheduler
} from '../../lib'
-import { authenticate, ensureIsAdmin } from '../../middlewares'
+import { authenticate, ensureIsAdmin, asyncMiddleware } from '../../middlewares'
import { RequestSchedulerStatsAttributes } from '../../../shared'
const requestSchedulerRouter = express.Router()
requestSchedulerRouter.get('/stats',
authenticate,
ensureIsAdmin,
- getRequestSchedulersStats
+ asyncMiddleware(getRequestSchedulersStats)
)
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
-function getRequestSchedulersStats (req: express.Request, res: express.Response, next: express.NextFunction) {
- Promise.props({
+async function getRequestSchedulersStats (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const result = await Bluebird.props({
requestScheduler: buildRequestSchedulerStats(getRequestScheduler()),
requestVideoQaduScheduler: buildRequestSchedulerStats(getRequestVideoQaduScheduler()),
requestVideoEventScheduler: buildRequestSchedulerStats(getRequestVideoEventScheduler())
})
- .then(result => res.json(result))
- .catch(err => next(err))
+
+ return res.json(result)
}
// ---------------------------------------------------------------------------
-function buildRequestSchedulerStats (requestScheduler: AbstractRequestScheduler<any>) {
- return requestScheduler.remainingRequestsCount().then(count => {
- const result: RequestSchedulerStatsAttributes = {
- totalRequests: count,
- requestsLimitPods: requestScheduler.limitPods,
- requestsLimitPerPod: requestScheduler.limitPerPod,
- remainingMilliSeconds: requestScheduler.remainingMilliSeconds(),
- milliSecondsInterval: requestScheduler.requestInterval
- }
-
- return result
- })
+async function buildRequestSchedulerStats (requestScheduler: AbstractRequestScheduler<any>) {
+ const count = await requestScheduler.remainingRequestsCount()
+
+ const result: RequestSchedulerStatsAttributes = {
+ totalRequests: count,
+ requestsLimitPods: requestScheduler.limitPods,
+ requestsLimitPerPod: requestScheduler.limitPerPod,
+ remainingMilliSeconds: requestScheduler.remainingMilliSeconds(),
+ milliSecondsInterval: requestScheduler.requestInterval
+ }
+
+ return result
}
setPagination,
usersSortValidator,
setUsersSort,
- token
+ token,
+ asyncMiddleware
} from '../../middlewares'
import {
UserVideoRate as FormattedUserVideoRate,
usersRouter.get('/me',
authenticate,
- getUserInformation
+ asyncMiddleware(getUserInformation)
)
usersRouter.get('/me/videos/:videoId/rating',
authenticate,
usersVideoRatingValidator,
- getUserVideoRating
+ asyncMiddleware(getUserVideoRating)
)
usersRouter.get('/',
usersSortValidator,
setUsersSort,
setPagination,
- listUsers
+ asyncMiddleware(listUsers)
)
usersRouter.get('/:id',
usersRouter.post('/register',
ensureUserRegistrationAllowed,
usersRegisterValidator,
- registerUser
+ asyncMiddleware(registerUser)
)
usersRouter.put('/me',
authenticate,
usersUpdateMeValidator,
- updateMe
+ asyncMiddleware(updateMe)
)
usersRouter.put('/:id',
authenticate,
ensureIsAdmin,
usersUpdateValidator,
- updateUser
+ asyncMiddleware(updateUser)
)
usersRouter.delete('/:id',
authenticate,
ensureIsAdmin,
usersRemoveValidator,
- removeUser
+ asyncMiddleware(removeUser)
)
usersRouter.post('/token', token, success)
// ---------------------------------------------------------------------------
-function createUserRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function createUserRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
const options = {
arguments: [ req, res ],
errorMessage: 'Cannot insert the user with many retries.'
}
- retryTransactionWrapper(createUser, options)
- .then(() => {
- // TODO : include Location of the new user -> 201
- res.type('json').status(204).end()
- })
- .catch(err => next(err))
+ await retryTransactionWrapper(createUser, options)
+
+ // TODO : include Location of the new user -> 201
+ return res.type('json').status(204).end()
}
-function createUser (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function createUser (req: express.Request, res: express.Response, next: express.NextFunction) {
const body: UserCreate = req.body
const user = db.User.build({
username: body.username,
videoQuota: body.videoQuota
})
- return createUserAuthorAndChannel(user)
- .then(() => logger.info('User %s with its channel and author created.', body.username))
- .catch((err: Error) => {
- logger.debug('Cannot insert the user.', err)
- throw err
- })
+ await createUserAuthorAndChannel(user)
+
+ logger.info('User %s with its channel and author created.', body.username)
}
-function registerUser (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function registerUser (req: express.Request, res: express.Response, next: express.NextFunction) {
const body: UserCreate = req.body
const user = db.User.build({
videoQuota: CONFIG.USER.VIDEO_QUOTA
})
- return createUserAuthorAndChannel(user)
- .then(() => res.type('json').status(204).end())
- .catch(err => next(err))
+ await createUserAuthorAndChannel(user)
+ return res.type('json').status(204).end()
}
-function getUserInformation (req: express.Request, res: express.Response, next: express.NextFunction) {
- db.User.loadByUsernameAndPopulateChannels(res.locals.oauth.token.user.username)
- .then(user => res.json(user.toFormattedJSON()))
- .catch(err => next(err))
+async function getUserInformation (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const user = await db.User.loadByUsernameAndPopulateChannels(res.locals.oauth.token.user.username)
+
+ return res.json(user.toFormattedJSON())
}
function getUser (req: express.Request, res: express.Response, next: express.NextFunction) {
return res.json(res.locals.user.toFormattedJSON())
}
-function getUserVideoRating (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function getUserVideoRating (req: express.Request, res: express.Response, next: express.NextFunction) {
const videoId = +req.params.videoId
const userId = +res.locals.oauth.token.User.id
.catch(err => next(err))
}
-function listUsers (req: express.Request, res: express.Response, next: express.NextFunction) {
- db.User.listForApi(req.query.start, req.query.count, req.query.sort)
- .then(resultList => {
- res.json(getFormattedObjects(resultList.data, resultList.total))
- })
- .catch(err => next(err))
+async function listUsers (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const resultList = await db.User.listForApi(req.query.start, req.query.count, req.query.sort)
+
+ return res.json(getFormattedObjects(resultList.data, resultList.total))
}
-function removeUser (req: express.Request, res: express.Response, next: express.NextFunction) {
- db.User.loadById(req.params.id)
- .then(user => user.destroy())
- .then(() => res.sendStatus(204))
- .catch(err => {
- logger.error('Errors when removed the user.', err)
- return next(err)
- })
+async function removeUser (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const user = await db.User.loadById(req.params.id)
+
+ await user.destroy()
+
+ return res.sendStatus(204)
}
-function updateMe (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function updateMe (req: express.Request, res: express.Response, next: express.NextFunction) {
const body: UserUpdateMe = req.body
// FIXME: user is not already a Sequelize instance?
- db.User.loadByUsername(res.locals.oauth.token.user.username)
- .then(user => {
- if (body.password !== undefined) user.password = body.password
- if (body.email !== undefined) user.email = body.email
- if (body.displayNSFW !== undefined) user.displayNSFW = body.displayNSFW
+ const user = res.locals.oauth.token.user
- return user.save()
- })
- .then(() => res.sendStatus(204))
- .catch(err => next(err))
+ if (body.password !== undefined) user.password = body.password
+ if (body.email !== undefined) user.email = body.email
+ if (body.displayNSFW !== undefined) user.displayNSFW = body.displayNSFW
+
+ await user.save()
+
+ return await res.sendStatus(204)
}
-function updateUser (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function updateUser (req: express.Request, res: express.Response, next: express.NextFunction) {
const body: UserUpdate = req.body
const user: UserInstance = res.locals.user
if (body.email !== undefined) user.email = body.email
if (body.videoQuota !== undefined) user.videoQuota = body.videoQuota
- return user.save()
- .then(() => res.sendStatus(204))
- .catch(err => next(err))
+ await user.save()
+
+ return res.sendStatus(204)
}
function success (req: express.Request, res: express.Response, next: express.NextFunction) {
videoAbuseReportValidator,
videoAbusesSortValidator,
setVideoAbusesSort,
- setPagination
+ setPagination,
+ asyncMiddleware
} from '../../../middlewares'
import { VideoInstance } from '../../../models'
import { VideoAbuseCreate } from '../../../../shared'
videoAbusesSortValidator,
setVideoAbusesSort,
setPagination,
- listVideoAbuses
+ asyncMiddleware(listVideoAbuses)
)
abuseVideoRouter.post('/:id/abuse',
authenticate,
videoAbuseReportValidator,
- reportVideoAbuseRetryWrapper
+ asyncMiddleware(reportVideoAbuseRetryWrapper)
)
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
-function listVideoAbuses (req: express.Request, res: express.Response, next: express.NextFunction) {
- db.VideoAbuse.listForApi(req.query.start, req.query.count, req.query.sort)
- .then(result => res.json(getFormattedObjects(result.data, result.total)))
- .catch(err => next(err))
+async function listVideoAbuses (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const resultList = await db.VideoAbuse.listForApi(req.query.start, req.query.count, req.query.sort)
+
+ return res.json(getFormattedObjects(resultList.data, resultList.total))
}
-function reportVideoAbuseRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function reportVideoAbuseRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
const options = {
arguments: [ req, res ],
errorMessage: 'Cannot report abuse to the video with many retries.'
}
- retryTransactionWrapper(reportVideoAbuse, options)
- .then(() => res.type('json').status(204).end())
- .catch(err => next(err))
+ await retryTransactionWrapper(reportVideoAbuse, options)
+
+ return res.type('json').status(204).end()
}
-function reportVideoAbuse (req: express.Request, res: express.Response) {
+async function reportVideoAbuse (req: express.Request, res: express.Response) {
const videoInstance = res.locals.video as VideoInstance
const reporterUsername = res.locals.oauth.token.User.username
const body: VideoAbuseCreate = req.body
- const abuse = {
+ const abuseToCreate = {
reporterUsername,
reason: body.reason,
videoId: videoInstance.id,
reporterPodId: null // This is our pod that reported this abuse
}
- return db.sequelize.transaction(t => {
- return db.VideoAbuse.create(abuse, { transaction: t })
- .then(abuse => {
- // We send the information to the destination pod
- if (videoInstance.isOwned() === false) {
- const reportData = {
- reporterUsername,
- reportReason: abuse.reason,
- videoUUID: videoInstance.uuid
- }
-
- return friends.reportAbuseVideoToFriend(reportData, videoInstance, t).then(() => videoInstance)
- }
-
- return videoInstance
- })
- })
- .then((videoInstance: VideoInstance) => logger.info('Abuse report for video %s created.', videoInstance.name))
- .catch(err => {
- logger.debug('Cannot update the video.', err)
- throw err
+ await db.sequelize.transaction(async t => {
+ const abuse = await db.VideoAbuse.create(abuseToCreate, { transaction: t })
+ // We send the information to the destination pod
+ if (videoInstance.isOwned() === false) {
+ const reportData = {
+ reporterUsername,
+ reportReason: abuse.reason,
+ videoUUID: videoInstance.uuid
+ }
+
+ await friends.reportAbuseVideoToFriend(reportData, videoInstance, t)
+ }
})
+
+ logger.info('Abuse report for video %s created.', videoInstance.name)
}
paginationValidator,
blacklistSortValidator,
setBlacklistSort,
- setPagination
+ setPagination,
+ asyncMiddleware
} from '../../../middlewares'
import { BlacklistedVideoInstance } from '../../../models'
import { BlacklistedVideo } from '../../../../shared'
authenticate,
ensureIsAdmin,
videosBlacklistAddValidator,
- addVideoToBlacklist
+ asyncMiddleware(addVideoToBlacklist)
)
blacklistRouter.get('/blacklist',
blacklistSortValidator,
setBlacklistSort,
setPagination,
- listBlacklist
+ asyncMiddleware(listBlacklist)
)
blacklistRouter.delete('/:videoId/blacklist',
authenticate,
ensureIsAdmin,
videosBlacklistRemoveValidator,
- removeVideoFromBlacklistController
+ asyncMiddleware(removeVideoFromBlacklistController)
)
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
-function addVideoToBlacklist (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function addVideoToBlacklist (req: express.Request, res: express.Response, next: express.NextFunction) {
const videoInstance = res.locals.video
const toCreate = {
videoId: videoInstance.id
}
- db.BlacklistedVideo.create(toCreate)
- .then(() => res.type('json').status(204).end())
- .catch(err => {
- logger.error('Errors when blacklisting video ', err)
- return next(err)
- })
+ await db.BlacklistedVideo.create(toCreate)
+ return res.type('json').status(204).end()
}
-function listBlacklist (req: express.Request, res: express.Response, next: express.NextFunction) {
- db.BlacklistedVideo.listForApi(req.query.start, req.query.count, req.query.sort)
- .then(resultList => res.json(getFormattedObjects<BlacklistedVideo, BlacklistedVideoInstance>(resultList.data, resultList.total)))
- .catch(err => next(err))
+async function listBlacklist (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const resultList = await db.BlacklistedVideo.listForApi(req.query.start, req.query.count, req.query.sort)
+
+ return res.json(getFormattedObjects<BlacklistedVideo, BlacklistedVideoInstance>(resultList.data, resultList.total))
}
-function removeVideoFromBlacklistController (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function removeVideoFromBlacklistController (req: express.Request, res: express.Response, next: express.NextFunction) {
const blacklistedVideo = res.locals.blacklistedVideo as BlacklistedVideoInstance
- blacklistedVideo.destroy()
- .then(() => {
- logger.info('Video %s removed from blacklist.', res.locals.video.uuid)
- res.sendStatus(204)
- })
- .catch(err => {
- logger.error('Some error while removing video %s from blacklist.', res.locals.video.uuid, err)
- next(err)
- })
+ try {
+ await blacklistedVideo.destroy()
+
+ logger.info('Video %s removed from blacklist.', res.locals.video.uuid)
+
+ return res.sendStatus(204)
+ } catch (err) {
+ logger.error('Some error while removing video %s from blacklist.', res.locals.video.uuid, err)
+ throw err
+ }
}
import {
logger,
getFormattedObjects,
- retryTransactionWrapper
+ retryTransactionWrapper,
+ resetSequelizeInstance
} from '../../../helpers'
import {
authenticate,
videoChannelsRemoveValidator,
videoChannelGetValidator,
videoChannelsUpdateValidator,
- listVideoAuthorChannelsValidator
+ listVideoAuthorChannelsValidator,
+ asyncMiddleware
} from '../../../middlewares'
import {
createVideoChannel,
videoChannelsSortValidator,
setVideoChannelsSort,
setPagination,
- listVideoChannels
+ asyncMiddleware(listVideoChannels)
)
videoChannelRouter.get('/authors/:authorId/channels',
listVideoAuthorChannelsValidator,
- listVideoAuthorChannels
+ asyncMiddleware(listVideoAuthorChannels)
)
videoChannelRouter.post('/channels',
authenticate,
videoChannelsAddValidator,
- addVideoChannelRetryWrapper
+ asyncMiddleware(addVideoChannelRetryWrapper)
)
videoChannelRouter.put('/channels/:id',
videoChannelRouter.delete('/channels/:id',
authenticate,
videoChannelsRemoveValidator,
- removeVideoChannelRetryWrapper
+ asyncMiddleware(removeVideoChannelRetryWrapper)
)
videoChannelRouter.get('/channels/:id',
videoChannelGetValidator,
- getVideoChannel
+ asyncMiddleware(getVideoChannel)
)
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
-function listVideoChannels (req: express.Request, res: express.Response, next: express.NextFunction) {
- db.VideoChannel.listForApi(req.query.start, req.query.count, req.query.sort)
- .then(result => res.json(getFormattedObjects(result.data, result.total)))
- .catch(err => next(err))
+async function listVideoChannels (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const resultList = await db.VideoChannel.listForApi(req.query.start, req.query.count, req.query.sort)
+
+ return res.json(getFormattedObjects(resultList.data, resultList.total))
}
-function listVideoAuthorChannels (req: express.Request, res: express.Response, next: express.NextFunction) {
- db.VideoChannel.listByAuthor(res.locals.author.id)
- .then(result => res.json(getFormattedObjects(result.data, result.total)))
- .catch(err => next(err))
+async function listVideoAuthorChannels (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const resultList = await db.VideoChannel.listByAuthor(res.locals.author.id)
+
+ return res.json(getFormattedObjects(resultList.data, resultList.total))
}
-// Wrapper to video channel add that retry the function if there is a database error
+// Wrapper to video channel add that retry the async function if there is a database error
// We need this because we run the transaction in SERIALIZABLE isolation that can fail
-function addVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function addVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
const options = {
arguments: [ req, res ],
errorMessage: 'Cannot insert the video video channel with many retries.'
}
- retryTransactionWrapper(addVideoChannel, options)
- .then(() => {
- // TODO : include Location of the new video channel -> 201
- res.type('json').status(204).end()
- })
- .catch(err => next(err))
+ await retryTransactionWrapper(addVideoChannel, options)
+
+ // TODO : include Location of the new video channel -> 201
+ return res.type('json').status(204).end()
}
-function addVideoChannel (req: express.Request, res: express.Response) {
+async function addVideoChannel (req: express.Request, res: express.Response) {
const videoChannelInfo: VideoChannelCreate = req.body
const author: AuthorInstance = res.locals.oauth.token.User.Author
+ let videoChannelCreated: VideoChannelInstance
- return db.sequelize.transaction(t => {
- return createVideoChannel(videoChannelInfo, author, t)
- })
- .then(videoChannelUUID => logger.info('Video channel with uuid %s created.', videoChannelUUID))
- .catch((err: Error) => {
- logger.debug('Cannot insert the video channel.', err)
- throw err
+ await db.sequelize.transaction(async t => {
+ videoChannelCreated = await createVideoChannel(videoChannelInfo, author, t)
})
+
+ logger.info('Video channel with uuid %s created.', videoChannelCreated.uuid)
}
-function updateVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function updateVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
const options = {
arguments: [ req, res ],
errorMessage: 'Cannot update the video with many retries.'
}
- retryTransactionWrapper(updateVideoChannel, options)
- .then(() => res.type('json').status(204).end())
- .catch(err => next(err))
+ await retryTransactionWrapper(updateVideoChannel, options)
+
+ return res.type('json').status(204).end()
}
-function updateVideoChannel (req: express.Request, res: express.Response) {
+async function updateVideoChannel (req: express.Request, res: express.Response) {
const videoChannelInstance: VideoChannelInstance = res.locals.videoChannel
const videoChannelFieldsSave = videoChannelInstance.toJSON()
const videoChannelInfoToUpdate: VideoChannelUpdate = req.body
- return db.sequelize.transaction(t => {
- const options = {
- transaction: t
- }
+ try {
+ await db.sequelize.transaction(async t => {
+ const sequelizeOptions = {
+ transaction: t
+ }
- if (videoChannelInfoToUpdate.name !== undefined) videoChannelInstance.set('name', videoChannelInfoToUpdate.name)
- if (videoChannelInfoToUpdate.description !== undefined) videoChannelInstance.set('description', videoChannelInfoToUpdate.description)
+ if (videoChannelInfoToUpdate.name !== undefined) videoChannelInstance.set('name', videoChannelInfoToUpdate.name)
+ if (videoChannelInfoToUpdate.description !== undefined) videoChannelInstance.set('description', videoChannelInfoToUpdate.description)
- return videoChannelInstance.save(options)
- .then(() => {
- const json = videoChannelInstance.toUpdateRemoteJSON()
+ await videoChannelInstance.save(sequelizeOptions)
+ const json = videoChannelInstance.toUpdateRemoteJSON()
+
+ // Now we'll update the video channel's meta data to our friends
+ return updateVideoChannelToFriends(json, t)
- // Now we'll update the video channel's meta data to our friends
- return updateVideoChannelToFriends(json, t)
- })
- })
- .then(() => {
- logger.info('Video channel with name %s and uuid %s updated.', videoChannelInstance.name, videoChannelInstance.uuid)
- })
- .catch(err => {
- logger.debug('Cannot update the video channel.', err)
-
- // Force fields we want to update
- // If the transaction is retried, sequelize will think the object has not changed
- // So it will skip the SQL request, even if the last one was ROLLBACKed!
- Object.keys(videoChannelFieldsSave).forEach(key => {
- const value = videoChannelFieldsSave[key]
- videoChannelInstance.set(key, value)
- })
-
- throw err
})
+
+ logger.info('Video channel with name %s and uuid %s updated.', videoChannelInstance.name, videoChannelInstance.uuid)
+ } catch (err) {
+ logger.debug('Cannot update the video channel.', err)
+
+ // Force fields we want to update
+ // If the transaction is retried, sequelize will think the object has not changed
+ // So it will skip the SQL request, even if the last one was ROLLBACKed!
+ resetSequelizeInstance(videoChannelInstance, videoChannelFieldsSave)
+
+ throw err
+ }
}
-function removeVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function removeVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
const options = {
arguments: [ req, res ],
errorMessage: 'Cannot remove the video channel with many retries.'
}
- retryTransactionWrapper(removeVideoChannel, options)
- .then(() => res.type('json').status(204).end())
- .catch(err => next(err))
+ await retryTransactionWrapper(removeVideoChannel, options)
+
+ return res.type('json').status(204).end()
}
-function removeVideoChannel (req: express.Request, res: express.Response) {
+async function removeVideoChannel (req: express.Request, res: express.Response) {
const videoChannelInstance: VideoChannelInstance = res.locals.videoChannel
- return db.sequelize.transaction(t => {
- return videoChannelInstance.destroy({ transaction: t })
- })
- .then(() => {
- logger.info('Video channel with name %s and uuid %s deleted.', videoChannelInstance.name, videoChannelInstance.uuid)
- })
- .catch(err => {
- logger.error('Errors when removed the video channel.', err)
- throw err
+ await db.sequelize.transaction(async t => {
+ await videoChannelInstance.destroy({ transaction: t })
})
+
+ logger.info('Video channel with name %s and uuid %s deleted.', videoChannelInstance.name, videoChannelInstance.uuid)
}
-function getVideoChannel (req: express.Request, res: express.Response, next: express.NextFunction) {
- db.VideoChannel.loadAndPopulateAuthorAndVideos(res.locals.videoChannel.id)
- .then(videoChannelWithVideos => res.json(videoChannelWithVideos.toFormattedJSON()))
- .catch(err => next(err))
+async function getVideoChannel (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const videoChannelWithVideos = await db.VideoChannel.loadAndPopulateAuthorAndVideos(res.locals.videoChannel.id)
+
+ return res.json(videoChannelWithVideos.toFormattedJSON())
}
import * as express from 'express'
-import * as Promise from 'bluebird'
import * as multer from 'multer'
import { extname, join } from 'path'
videosSearchValidator,
videosAddValidator,
videosGetValidator,
- videosRemoveValidator
+ videosRemoveValidator,
+ asyncMiddleware
} from '../../../middlewares'
import {
logger,
generateRandomString,
getFormattedObjects,
renamePromise,
- getVideoFileHeight
+ getVideoFileHeight,
+ resetSequelizeInstance
} from '../../../helpers'
import { TagInstance, VideoInstance } from '../../../models'
import { VideoCreate, VideoUpdate } from '../../../../shared'
videosSortValidator,
setVideosSort,
setPagination,
- listVideos
+ asyncMiddleware(listVideos)
)
videosRouter.put('/:id',
authenticate,
videosUpdateValidator,
- updateVideoRetryWrapper
+ asyncMiddleware(updateVideoRetryWrapper)
)
videosRouter.post('/upload',
authenticate,
reqFiles,
videosAddValidator,
- addVideoRetryWrapper
+ asyncMiddleware(addVideoRetryWrapper)
)
videosRouter.get('/:id',
videosGetValidator,
videosRouter.delete('/:id',
authenticate,
videosRemoveValidator,
- removeVideoRetryWrapper
+ asyncMiddleware(removeVideoRetryWrapper)
)
videosRouter.get('/search/:value',
setVideosSort,
setPagination,
setVideosSearch,
- searchVideos
+ asyncMiddleware(searchVideos)
)
// ---------------------------------------------------------------------------
// 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
-function addVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function addVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
const options = {
arguments: [ req, res, req.files['videofile'][0] ],
errorMessage: 'Cannot insert the video with many retries.'
}
- retryTransactionWrapper(addVideo, options)
- .then(() => {
- // TODO : include Location of the new video -> 201
- res.type('json').status(204).end()
- })
- .catch(err => next(err))
+ await retryTransactionWrapper(addVideo, options)
+
+ // TODO : include Location of the new video -> 201
+ res.type('json').status(204).end()
}
-function addVideo (req: express.Request, res: express.Response, videoPhysicalFile: Express.Multer.File) {
+async function addVideo (req: express.Request, res: express.Response, videoPhysicalFile: Express.Multer.File) {
const videoInfo: VideoCreate = req.body
let videoUUID = ''
- return db.sequelize.transaction(t => {
- let p: Promise<TagInstance[]>
-
- if (!videoInfo.tags) p = Promise.resolve(undefined)
- else p = db.Tag.findOrCreateTags(videoInfo.tags, t)
-
- return p
- .then(tagInstances => {
- const videoData = {
- name: videoInfo.name,
- remote: false,
- extname: extname(videoPhysicalFile.filename),
- category: videoInfo.category,
- licence: videoInfo.licence,
- language: videoInfo.language,
- nsfw: videoInfo.nsfw,
- description: videoInfo.description,
- duration: videoPhysicalFile['duration'], // duration was added by a previous middleware
- channelId: res.locals.videoChannel.id
- }
+ await db.sequelize.transaction(async t => {
+ const sequelizeOptions = { transaction: t }
+
+ const videoData = {
+ name: videoInfo.name,
+ remote: false,
+ extname: extname(videoPhysicalFile.filename),
+ category: videoInfo.category,
+ licence: videoInfo.licence,
+ language: videoInfo.language,
+ nsfw: videoInfo.nsfw,
+ description: videoInfo.description,
+ duration: videoPhysicalFile['duration'], // duration was added by a previous middleware
+ channelId: res.locals.videoChannel.id
+ }
+ const video = db.Video.build(videoData)
- const video = db.Video.build(videoData)
- return { tagInstances, video }
- })
- .then(({ tagInstances, video }) => {
- const videoFilePath = join(CONFIG.STORAGE.VIDEOS_DIR, videoPhysicalFile.filename)
- return getVideoFileHeight(videoFilePath)
- .then(height => ({ tagInstances, video, videoFileHeight: height }))
- })
- .then(({ tagInstances, video, videoFileHeight }) => {
- const videoFileData = {
- extname: extname(videoPhysicalFile.filename),
- resolution: videoFileHeight,
- size: videoPhysicalFile.size
- }
+ const videoFilePath = join(CONFIG.STORAGE.VIDEOS_DIR, videoPhysicalFile.filename)
+ const videoFileHeight = await getVideoFileHeight(videoFilePath)
- const videoFile = db.VideoFile.build(videoFileData)
- return { tagInstances, video, videoFile }
- })
- .then(({ tagInstances, video, videoFile }) => {
- const videoDir = CONFIG.STORAGE.VIDEOS_DIR
- const source = join(videoDir, videoPhysicalFile.filename)
- const destination = join(videoDir, video.getVideoFilename(videoFile))
-
- return renamePromise(source, destination)
- .then(() => {
- // This is important in case if there is another attempt in the retry process
- videoPhysicalFile.filename = video.getVideoFilename(videoFile)
- return { tagInstances, video, videoFile }
- })
- })
- .then(({ tagInstances, video, videoFile }) => {
- const tasks = []
-
- tasks.push(
- video.createTorrentAndSetInfoHash(videoFile),
- video.createThumbnail(videoFile),
- video.createPreview(videoFile)
- )
-
- if (CONFIG.TRANSCODING.ENABLED === true) {
- // Put uuid because we don't have id auto incremented for now
- const dataInput = {
- videoUUID: video.uuid
- }
-
- tasks.push(
- JobScheduler.Instance.createJob(t, 'videoFileOptimizer', dataInput)
- )
- }
+ const videoFileData = {
+ extname: extname(videoPhysicalFile.filename),
+ resolution: videoFileHeight,
+ size: videoPhysicalFile.size
+ }
+ const videoFile = db.VideoFile.build(videoFileData)
+ const videoDir = CONFIG.STORAGE.VIDEOS_DIR
+ const source = join(videoDir, videoPhysicalFile.filename)
+ const destination = join(videoDir, video.getVideoFilename(videoFile))
+
+ await renamePromise(source, destination)
+ // This is important in case if there is another attempt in the retry process
+ videoPhysicalFile.filename = video.getVideoFilename(videoFile)
+
+ const tasks = []
+
+ tasks.push(
+ video.createTorrentAndSetInfoHash(videoFile),
+ video.createThumbnail(videoFile),
+ video.createPreview(videoFile)
+ )
+
+ if (CONFIG.TRANSCODING.ENABLED === true) {
+ // Put uuid because we don't have id auto incremented for now
+ const dataInput = {
+ videoUUID: video.uuid
+ }
+
+ tasks.push(
+ JobScheduler.Instance.createJob(t, 'videoFileOptimizer', dataInput)
+ )
+ }
+ await Promise.all(tasks)
- return Promise.all(tasks).then(() => ({ tagInstances, video, videoFile }))
- })
- .then(({ tagInstances, video, videoFile }) => {
- const options = { transaction: t }
+ const videoCreated = await video.save(sequelizeOptions)
+ // Do not forget to add video channel information to the created video
+ videoCreated.VideoChannel = res.locals.videoChannel
+ videoUUID = videoCreated.uuid
- return video.save(options)
- .then(videoCreated => {
- // Do not forget to add video channel information to the created video
- videoCreated.VideoChannel = res.locals.videoChannel
- videoUUID = videoCreated.uuid
+ videoFile.videoId = video.id
- return { tagInstances, video: videoCreated, videoFile }
- })
- })
- .then(({ tagInstances, video, videoFile }) => {
- const options = { transaction: t }
- videoFile.videoId = video.id
+ await videoFile.save(sequelizeOptions)
+ video.VideoFiles = [videoFile]
- return videoFile.save(options)
- .then(() => video.VideoFiles = [ videoFile ])
- .then(() => ({ tagInstances, video }))
- })
- .then(({ tagInstances, video }) => {
- if (!tagInstances) return video
-
- const options = { transaction: t }
- return video.setTags(tagInstances, options)
- .then(() => {
- video.Tags = tagInstances
- return video
- })
- })
- .then(video => {
- // Let transcoding job send the video to friends because the video file extension might change
- if (CONFIG.TRANSCODING.ENABLED === true) return undefined
-
- return video.toAddRemoteJSON()
- .then(remoteVideo => {
- // Now we'll add the video's meta data to our friends
- return addVideoToFriends(remoteVideo, t)
- })
- })
- })
- .then(() => logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoUUID))
- .catch((err: Error) => {
- logger.debug('Cannot insert the video.', err)
- throw err
+ if (videoInfo.tags) {
+ const tagInstances = await db.Tag.findOrCreateTags(videoInfo.tags, t)
+
+ await video.setTags(tagInstances, sequelizeOptions)
+ video.Tags = tagInstances
+ }
+
+ // Let transcoding job send the video to friends because the video file extension might change
+ if (CONFIG.TRANSCODING.ENABLED === true) return undefined
+
+ const remoteVideo = await video.toAddRemoteJSON()
+ // Now we'll add the video's meta data to our friends
+ return addVideoToFriends(remoteVideo, t)
})
+
+ logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoUUID)
}
-function updateVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function updateVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
const options = {
arguments: [ req, res ],
errorMessage: 'Cannot update the video with many retries.'
}
- retryTransactionWrapper(updateVideo, options)
- .then(() => {
- return res.type('json').status(204).end()
- })
- .catch(err => next(err))
+ await retryTransactionWrapper(updateVideo, options)
+
+ return res.type('json').status(204).end()
}
-function updateVideo (req: express.Request, res: express.Response) {
+async function updateVideo (req: express.Request, res: express.Response) {
const videoInstance = res.locals.video
const videoFieldsSave = videoInstance.toJSON()
const videoInfoToUpdate: VideoUpdate = req.body
- return db.sequelize.transaction(t => {
- let tagsPromise: Promise<TagInstance[]>
- if (!videoInfoToUpdate.tags) {
- tagsPromise = Promise.resolve(null)
- } else {
- tagsPromise = db.Tag.findOrCreateTags(videoInfoToUpdate.tags, t)
- }
+ try {
+ await db.sequelize.transaction(async t => {
+ const sequelizeOptions = {
+ transaction: t
+ }
- return tagsPromise
- .then(tagInstances => {
- const options = {
- transaction: t
- }
+ if (videoInfoToUpdate.name !== undefined) videoInstance.set('name', videoInfoToUpdate.name)
+ if (videoInfoToUpdate.category !== undefined) videoInstance.set('category', videoInfoToUpdate.category)
+ if (videoInfoToUpdate.licence !== undefined) videoInstance.set('licence', videoInfoToUpdate.licence)
+ if (videoInfoToUpdate.language !== undefined) videoInstance.set('language', videoInfoToUpdate.language)
+ if (videoInfoToUpdate.nsfw !== undefined) videoInstance.set('nsfw', videoInfoToUpdate.nsfw)
+ if (videoInfoToUpdate.description !== undefined) videoInstance.set('description', videoInfoToUpdate.description)
- if (videoInfoToUpdate.name !== undefined) videoInstance.set('name', videoInfoToUpdate.name)
- if (videoInfoToUpdate.category !== undefined) videoInstance.set('category', videoInfoToUpdate.category)
- if (videoInfoToUpdate.licence !== undefined) videoInstance.set('licence', videoInfoToUpdate.licence)
- if (videoInfoToUpdate.language !== undefined) videoInstance.set('language', videoInfoToUpdate.language)
- if (videoInfoToUpdate.nsfw !== undefined) videoInstance.set('nsfw', videoInfoToUpdate.nsfw)
- if (videoInfoToUpdate.description !== undefined) videoInstance.set('description', videoInfoToUpdate.description)
+ await videoInstance.save(sequelizeOptions)
- return videoInstance.save(options).then(() => tagInstances)
- })
- .then(tagInstances => {
- if (!tagInstances) return
+ if (videoInfoToUpdate.tags) {
+ const tagInstances = await db.Tag.findOrCreateTags(videoInfoToUpdate.tags, t)
- const options = { transaction: t }
- return videoInstance.setTags(tagInstances, options)
- .then(() => {
- videoInstance.Tags = tagInstances
+ await videoInstance.setTags(tagInstances, sequelizeOptions)
+ videoInstance.Tags = tagInstances
+ }
- return
- })
- })
- .then(() => {
- const json = videoInstance.toUpdateRemoteJSON()
+ const json = videoInstance.toUpdateRemoteJSON()
- // Now we'll update the video's meta data to our friends
- return updateVideoToFriends(json, t)
- })
- })
- .then(() => {
- logger.info('Video with name %s and uuid %s updated.', videoInstance.name, videoInstance.uuid)
- })
- .catch(err => {
- logger.debug('Cannot update the video.', err)
+ // Now we'll update the video's meta data to our friends
+ return updateVideoToFriends(json, t)
+ })
+ logger.info('Video with name %s and uuid %s updated.', videoInstance.name, videoInstance.uuid)
+ } catch (err) {
// Force fields we want to update
// If the transaction is retried, sequelize will think the object has not changed
// So it will skip the SQL request, even if the last one was ROLLBACKed!
- Object.keys(videoFieldsSave).forEach(key => {
- const value = videoFieldsSave[key]
- videoInstance.set(key, value)
- })
+ resetSequelizeInstance(videoInstance, videoFieldsSave)
throw err
- })
+ }
}
function getVideo (req: express.Request, res: express.Response) {
if (videoInstance.isOwned()) {
// The increment is done directly in the database, not using the instance value
+ // FIXME: make a real view system
+ // For example, only add a view when a user watch a video during 30s etc
videoInstance.increment('views')
.then(() => {
- // FIXME: make a real view system
- // For example, only add a view when a user watch a video during 30s etc
const qaduParams = {
videoId: videoInstance.id,
type: REQUEST_VIDEO_QADU_TYPES.VIEWS
}
return quickAndDirtyUpdateVideoToFriends(qaduParams)
})
- .catch(err => logger.error('Cannot add view to video %d.', videoInstance.id, err))
+ .catch(err => logger.error('Cannot add view to video %s.', videoInstance.uuid, err))
} else {
// Just send the event to our friends
const eventParams = {
type: REQUEST_VIDEO_EVENT_TYPES.VIEWS
}
addEventToRemoteVideo(eventParams)
+ .catch(err => logger.error('Cannot add event to remote video %s.', videoInstance.uuid, err))
}
// Do not wait the view system
- res.json(videoInstance.toFormattedDetailsJSON())
+ return res.json(videoInstance.toFormattedDetailsJSON())
}
-function listVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
- db.Video.listForApi(req.query.start, req.query.count, req.query.sort)
- .then(result => res.json(getFormattedObjects(result.data, result.total)))
- .catch(err => next(err))
+async function listVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const resultList = await db.Video.listForApi(req.query.start, req.query.count, req.query.sort)
+
+ return res.json(getFormattedObjects(resultList.data, resultList.total))
}
-function removeVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function removeVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
const options = {
arguments: [ req, res ],
errorMessage: 'Cannot remove the video with many retries.'
}
- retryTransactionWrapper(removeVideo, options)
- .then(() => {
- return res.type('json').status(204).end()
- })
- .catch(err => next(err))
+ await retryTransactionWrapper(removeVideo, options)
+
+ return res.type('json').status(204).end()
}
-function removeVideo (req: express.Request, res: express.Response) {
+async function removeVideo (req: express.Request, res: express.Response) {
const videoInstance: VideoInstance = res.locals.video
- return db.sequelize.transaction(t => {
- return videoInstance.destroy({ transaction: t })
- })
- .then(() => {
- logger.info('Video with name %s and uuid %s deleted.', videoInstance.name, videoInstance.uuid)
- })
- .catch(err => {
- logger.error('Errors when removed the video.', err)
- throw err
+ await db.sequelize.transaction(async t => {
+ await videoInstance.destroy({ transaction: t })
})
+
+ logger.info('Video with name %s and uuid %s deleted.', videoInstance.name, videoInstance.uuid)
}
-function searchVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
- db.Video.searchAndPopulateAuthorAndPodAndTags(req.params.value, req.query.field, req.query.start, req.query.count, req.query.sort)
- .then(result => res.json(getFormattedObjects(result.data, result.total)))
- .catch(err => next(err))
+async function searchVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const resultList = await db.Video.searchAndPopulateAuthorAndPodAndTags(
+ req.params.value,
+ req.query.field,
+ req.query.start,
+ req.query.count,
+ req.query.sort
+ )
+
+ return res.json(getFormattedObjects(resultList.data, resultList.total))
}
import * as express from 'express'
-import * as Promise from 'bluebird'
import { database as db } from '../../../initializers/database'
import {
} from '../../../lib'
import {
authenticate,
- videoRateValidator
+ videoRateValidator,
+ asyncMiddleware
} from '../../../middlewares'
import { UserVideoRateUpdate, VideoRateType } from '../../../../shared'
rateVideoRouter.put('/:id/rate',
authenticate,
videoRateValidator,
- rateVideoRetryWrapper
+ asyncMiddleware(rateVideoRetryWrapper)
)
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
-function rateVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function rateVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
const options = {
arguments: [ req, res ],
errorMessage: 'Cannot update the user video rate.'
}
- retryTransactionWrapper(rateVideo, options)
- .then(() => res.type('json').status(204).end())
- .catch(err => next(err))
+ await retryTransactionWrapper(rateVideo, options)
+
+ return res.type('json').status(204).end()
}
-function rateVideo (req: express.Request, res: express.Response) {
+async function rateVideo (req: express.Request, res: express.Response) {
const body: UserVideoRateUpdate = req.body
const rateType = body.rating
const videoInstance = res.locals.video
const userInstance = res.locals.oauth.token.User
- return db.sequelize.transaction(t => {
- return db.UserVideoRate.load(userInstance.id, videoInstance.id, t)
- .then(previousRate => {
- const options = { transaction: t }
-
- let likesToIncrement = 0
- let dislikesToIncrement = 0
-
- if (rateType === VIDEO_RATE_TYPES.LIKE) likesToIncrement++
- else if (rateType === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++
-
- let promise: Promise<any>
-
- // There was a previous rate, update it
- if (previousRate) {
- // We will remove the previous rate, so we will need to update the video count attribute
- if (previousRate.type === VIDEO_RATE_TYPES.LIKE) likesToIncrement--
- else if (previousRate.type === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement--
-
- if (rateType === 'none') { // Destroy previous rate
- promise = previousRate.destroy()
- } else { // Update previous rate
- previousRate.type = rateType as VideoRateType
-
- promise = previousRate.save()
- }
- } else if (rateType !== 'none') { // There was not a previous rate, insert a new one if there is a rate
- const query = {
- userId: userInstance.id,
- videoId: videoInstance.id,
- type: rateType
- }
-
- promise = db.UserVideoRate.create(query, options)
- } else {
- promise = Promise.resolve()
- }
-
- return promise.then(() => ({ likesToIncrement, dislikesToIncrement }))
- })
- .then(({ likesToIncrement, dislikesToIncrement }) => {
- 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
- return videoInstance.increment(incrementQuery, options).then(() => ({ likesToIncrement, dislikesToIncrement }))
- })
- .then(({ likesToIncrement, dislikesToIncrement }) => {
- // No need for an event type, we own the video
- if (videoInstance.isOwned()) return { likesToIncrement, dislikesToIncrement }
-
- const eventsParams = []
-
- if (likesToIncrement !== 0) {
- eventsParams.push({
- videoId: videoInstance.id,
- type: REQUEST_VIDEO_EVENT_TYPES.LIKES,
- count: likesToIncrement
- })
- }
-
- if (dislikesToIncrement !== 0) {
- eventsParams.push({
- videoId: videoInstance.id,
- type: REQUEST_VIDEO_EVENT_TYPES.DISLIKES,
- count: dislikesToIncrement
- })
- }
-
- return addEventsToRemoteVideo(eventsParams, t).then(() => ({ likesToIncrement, dislikesToIncrement }))
- })
- .then(({ likesToIncrement, dislikesToIncrement }) => {
- // 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 undefined
-
- const qadusParams = []
-
- if (likesToIncrement !== 0) {
- qadusParams.push({
- videoId: videoInstance.id,
- type: REQUEST_VIDEO_QADU_TYPES.LIKES
- })
- }
-
- if (dislikesToIncrement !== 0) {
- qadusParams.push({
- videoId: videoInstance.id,
- type: REQUEST_VIDEO_QADU_TYPES.DISLIKES
- })
- }
-
- return quickAndDirtyUpdatesVideoToFriends(qadusParams, t)
- })
- })
- .then(() => logger.info('User video rate for video %s of user %s updated.', videoInstance.name, userInstance.username))
- .catch(err => {
- // This is just a debug because we will retry the insert
- logger.debug('Cannot add the user video rate.', err)
- throw err
+ await db.sequelize.transaction(async t => {
+ const sequelizeOptions = { transaction: t }
+ const previousRate = await db.UserVideoRate.load(userInstance.id, videoInstance.id, t)
+
+ let likesToIncrement = 0
+ let dislikesToIncrement = 0
+
+ if (rateType === VIDEO_RATE_TYPES.LIKE) likesToIncrement++
+ else if (rateType === 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 update the video count attribute
+ if (previousRate.type === VIDEO_RATE_TYPES.LIKE) likesToIncrement--
+ else if (previousRate.type === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement--
+
+ if (rateType === 'none') { // Destroy previous rate
+ await previousRate.destroy()
+ } else { // Update previous rate
+ previousRate.type = rateType as VideoRateType
+
+ await previousRate.save()
+ }
+ } else if (rateType !== 'none') { // There was not a previous rate, insert a new one if there is a rate
+ const query = {
+ userId: userInstance.id,
+ videoId: videoInstance.id,
+ type: rateType
+ }
+
+ await db.UserVideoRate.create(query, sequelizeOptions)
+ }
+
+ const incrementQuery = {
+ likes: likesToIncrement,
+ dislikes: dislikesToIncrement
+ }
+
+ // Even if we do not own the video we increment the attributes
+ // It is useful for the user to have a feedback
+ await videoInstance.increment(incrementQuery, sequelizeOptions)
+
+ // Send a event to original pod
+ if (videoInstance.isOwned() === false) {
+
+ const eventsParams = []
+
+ if (likesToIncrement !== 0) {
+ eventsParams.push({
+ videoId: videoInstance.id,
+ type: REQUEST_VIDEO_EVENT_TYPES.LIKES,
+ count: likesToIncrement
+ })
+ }
+
+ if (dislikesToIncrement !== 0) {
+ eventsParams.push({
+ videoId: videoInstance.id,
+ type: REQUEST_VIDEO_EVENT_TYPES.DISLIKES,
+ count: dislikesToIncrement
+ })
+ }
+
+ await addEventsToRemoteVideo(eventsParams, t)
+ } else { // We own the video, we need to send a quick and dirty update to friends to notify the counts changed
+ const qadusParams = []
+
+ if (likesToIncrement !== 0) {
+ qadusParams.push({
+ videoId: videoInstance.id,
+ type: REQUEST_VIDEO_QADU_TYPES.LIKES
+ })
+ }
+
+ if (dislikesToIncrement !== 0) {
+ qadusParams.push({
+ videoId: videoInstance.id,
+ type: REQUEST_VIDEO_QADU_TYPES.DISLIKES
+ })
+ }
+
+ await quickAndDirtyUpdatesVideoToFriends(qadusParams, t)
+ }
})
+
+ logger.info('User video rate for video %s of user %s updated.', videoInstance.name, userInstance.username)
}
import * as express from 'express'
import { join } from 'path'
import * as validator from 'validator'
-import * as Promise from 'bluebird'
+import * as Bluebird from 'bluebird'
import { database as db } from '../initializers/database'
import {
OPENGRAPH_AND_OEMBED_COMMENT
} from '../initializers'
import { root, readFileBufferPromise, escapeHTML } from '../helpers'
+import { asyncMiddleware } from '../middlewares'
import { VideoInstance } from '../models'
const clientsRouter = express.Router()
// Special route that add OpenGraph and oEmbed tags
// Do not use a template engine for a so little thing
-clientsRouter.use('/videos/watch/:id', generateWatchHtmlPage)
+clientsRouter.use('/videos/watch/:id',
+ asyncMiddleware(generateWatchHtmlPage)
+)
clientsRouter.use('/videos/embed', (req: express.Request, res: express.Response, next: express.NextFunction) => {
res.sendFile(embedPath)
return htmlStringPage.replace(OPENGRAPH_AND_OEMBED_COMMENT, tagsString)
}
-function generateWatchHtmlPage (req: express.Request, res: express.Response, next: express.NextFunction) {
+async function generateWatchHtmlPage (req: express.Request, res: express.Response, next: express.NextFunction) {
const videoId = '' + req.params.id
- let videoPromise: Promise<VideoInstance>
+ let videoPromise: Bluebird<VideoInstance>
// Let Angular application handle errors
if (validator.isUUID(videoId, 4)) {
return res.sendFile(indexPath)
}
- Promise.all([
+ let [ file, video ] = await Promise.all([
readFileBufferPromise(indexPath),
videoPromise
])
- .then(([ file, video ]) => {
- file = file as Buffer
- video = video as VideoInstance
- const html = file.toString()
+ file = file as Buffer
+ video = video as VideoInstance
- // Let Angular application handle errors
- if (!video) return res.sendFile(indexPath)
+ const html = file.toString()
- const htmlStringPageWithTags = addOpenGraphAndOEmbedTags(html, video)
- res.set('Content-Type', 'text/html; charset=UTF-8').send(htmlStringPageWithTags)
- })
- .catch(err => next(err))
+ // Let Angular application handle errors
+ if (!video) return res.sendFile(indexPath)
+
+ const htmlStringPageWithTags = addOpenGraphAndOEmbedTags(html, video)
+ res.set('Content-Type', 'text/html; charset=UTF-8').send(htmlStringPageWithTags)
}
STATIC_PATHS
} from '../initializers'
import { VideosPreviewCache } from '../lib'
+import { asyncMiddleware } from '../middlewares'
const staticRouter = express.Router()
// Video previews path for express
staticRouter.use(
STATIC_PATHS.PREVIEWS + ':uuid.jpg',
- getPreview
+ asyncMiddleware(getPreview)
)
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
-function getPreview (req: express.Request, res: express.Response, next: express.NextFunction) {
- VideosPreviewCache.Instance.getPreviewPath(req.params.uuid)
- .then(path => {
- if (!path) return res.sendStatus(404)
+async function getPreview (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const path = await VideosPreviewCache.Instance.getPreviewPath(req.params.uuid)
+ if (!path) return res.sendStatus(404)
- return res.sendFile(path, { maxAge: STATIC_MAX_AGE })
- })
+ return res.sendFile(path, { maxAge: STATIC_MAX_AGE })
}
// TODO: import from ES6 when retry typing file will include errorFilter function
import * as retry from 'async/retry'
-import * as Promise from 'bluebird'
import { logger } from './logger'
import * as express from 'express'
+import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
import { pseudoRandomBytesPromise } from './core-utils'
return resolutionsEnabled
}
+function resetSequelizeInstance (instance: Sequelize.Instance<any>, savedFields: object) {
+ Object.keys(savedFields).forEach(key => {
+ const value = savedFields[key]
+ instance.set(key, value)
+ })
+}
+
type SortType = { sortModel: any, sortValue: string }
// ---------------------------------------------------------------------------
getFormattedObjects,
isSignupAllowed,
computeResolutionsToTranscode,
+ resetSequelizeInstance,
SortType
}
host: CONFIG.DATABASE.HOSTNAME,
port: CONFIG.DATABASE.PORT,
benchmark: isTestInstance(),
+ isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE,
logging: (message: string, benchmark: number) => {
let newMessage = message
import { addVideoChannelToFriends } from './friends'
import { database as db } from '../initializers'
+import { logger } from '../helpers'
import { AuthorInstance } from '../models'
import { VideoChannelCreate } from '../../shared/models'
-function createVideoChannel (videoChannelInfo: VideoChannelCreate, author: AuthorInstance, t: Sequelize.Transaction) {
- let videoChannelUUID = ''
-
+async function createVideoChannel (videoChannelInfo: VideoChannelCreate, author: AuthorInstance, t: Sequelize.Transaction) {
const videoChannelData = {
name: videoChannelInfo.name,
description: videoChannelInfo.description,
const videoChannel = db.VideoChannel.build(videoChannelData)
const options = { transaction: t }
- return videoChannel.save(options)
- .then(videoChannelCreated => {
- // Do not forget to add Author information to the created video channel
- videoChannelCreated.Author = author
- videoChannelUUID = videoChannelCreated.uuid
-
- return videoChannelCreated
- })
- .then(videoChannel => {
- const remoteVideoChannel = videoChannel.toAddRemoteJSON()
-
- // Now we'll add the video channel's meta data to our friends
- return addVideoChannelToFriends(remoteVideoChannel, t)
- })
- .then(() => videoChannelUUID) // Return video channel UUID
+ const videoChannelCreated = await videoChannel.save(options)
+
+ // Do not forget to add Author information to the created video channel
+ videoChannelCreated.Author = author
+
+ const remoteVideoChannel = videoChannelCreated.toAddRemoteJSON()
+
+ // Now we'll add the video channel's meta data to our friends
+ await addVideoChannelToFriends(remoteVideoChannel, t)
+
+ return videoChannelCreated
+}
+
+async function fetchVideoChannelByHostAndUUID (podHost: string, uuid: string, t: Sequelize.Transaction) {
+ try {
+ const videoChannel = await db.VideoChannel.loadByHostAndUUID(podHost, uuid, t)
+ if (!videoChannel) throw new Error('Video channel not found')
+
+ return videoChannel
+ } catch (err) {
+ logger.error('Cannot load video channel from host and uuid.', { error: err.stack, podHost, uuid })
+ throw err
+ }
}
// ---------------------------------------------------------------------------
export {
- createVideoChannel
+ createVideoChannel,
+ fetchVideoChannelByHostAndUUID
}
--- /dev/null
+import { Request, Response, NextFunction } from 'express'
+
+// Syntactic sugar to avoid try/catch in express controllers
+// Thanks: https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016
+function asyncMiddleware (fn: (req: Request, res: Response, next: NextFunction) => Promise<any>) {
+ return (req: Request, res: Response, next: NextFunction) => {
+ return Promise.resolve(fn(req, res, next))
+ .catch(next)
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ asyncMiddleware
+}
export * from './validators'
export * from './admin'
+export * from './async'
export * from './oauth'
export * from './pagination'
export * from './pods'