import { extname, join } from 'path'
import { VideoCreate, VideoPrivacy, VideoState, VideoUpdate } from '../../../../shared'
import { renamePromise } from '../../../helpers/core-utils'
-import { retryTransactionWrapper } from '../../../helpers/database-utils'
import { getVideoFileResolution } from '../../../helpers/ffmpeg-utils'
import { processImage } from '../../../helpers/image-utils'
import { logger } from '../../../helpers/logger'
import { Redis } from '../../../lib/redis'
import {
asyncMiddleware,
+ asyncRetryTransactionMiddleware,
authenticate,
optionalAuthenticate,
paginationValidator,
import { VideoFilter } from '../../../../shared/models/videos/video-query.type'
import { VideoSortField } from '../../../../client/src/app/shared/video/sort-field.type'
import { createReqFiles, isNSFWHidden } from '../../../helpers/express-utils'
+import { ScheduleVideoUpdateModel } from '../../../models/video/schedule-video-update'
const videosRouter = express.Router()
authenticate,
reqVideoFileUpdate,
asyncMiddleware(videosUpdateValidator),
- asyncMiddleware(updateVideoRetryWrapper)
+ asyncRetryTransactionMiddleware(updateVideo)
)
videosRouter.post('/upload',
authenticate,
reqVideoFileAdd,
asyncMiddleware(videosAddValidator),
- asyncMiddleware(addVideoRetryWrapper)
+ asyncRetryTransactionMiddleware(addVideo)
)
videosRouter.get('/:id/description',
videosRouter.delete('/:id',
authenticate,
asyncMiddleware(videosRemoveValidator),
- asyncMiddleware(removeVideoRetryWrapper)
+ asyncRetryTransactionMiddleware(removeVideo)
)
// ---------------------------------------------------------------------------
res.json(VIDEO_PRIVACIES)
}
-// 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
-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.'
- }
-
- const video = await retryTransactionWrapper(addVideo, options)
-
- res.json({
- video: {
- id: video.id,
- uuid: video.uuid
- }
- }).end()
-}
-
-async function addVideo (req: express.Request, res: express.Response, videoPhysicalFile: Express.Multer.File) {
+async function addVideo (req: express.Request, res: express.Response) {
+ const videoPhysicalFile = req.files['videofile'][0]
const videoInfo: VideoCreate = req.body
// Prepare data so we don't block the transaction
video.VideoFiles = [ videoFile ]
+ // Create tags
if (videoInfo.tags !== undefined) {
const tagInstances = await TagModel.findOrCreateTags(videoInfo.tags, t)
video.Tags = tagInstances
}
+ // Schedule an update in the future?
+ if (videoInfo.scheduleUpdate) {
+ await ScheduleVideoUpdateModel.create({
+ videoId: video.id,
+ updateAt: videoInfo.scheduleUpdate.updateAt,
+ privacy: videoInfo.scheduleUpdate.privacy || null
+ }, { transaction: t })
+ }
+
await federateVideoIfNeeded(video, true, t)
logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoCreated.uuid)
await JobQueue.Instance.createJob({ type: 'video-file', payload: dataInput })
}
- return videoCreated
-}
-
-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.'
- }
-
- await retryTransactionWrapper(updateVideo, options)
-
- return res.type('json').status(204).end()
+ return res.json({
+ video: {
+ id: videoCreated.id,
+ uuid: videoCreated.uuid
+ }
+ }).end()
}
async function updateVideo (req: express.Request, res: express.Response) {
if (wasPrivateVideo === false) await changeVideoChannelShare(videoInstanceUpdated, oldVideoChannel, t)
}
+ // Schedule an update in the future?
+ if (videoInfoToUpdate.scheduleUpdate) {
+ await ScheduleVideoUpdateModel.upsert({
+ videoId: videoInstanceUpdated.id,
+ updateAt: videoInfoToUpdate.scheduleUpdate.updateAt,
+ privacy: videoInfoToUpdate.scheduleUpdate.privacy || null
+ }, { transaction: t })
+ } else if (videoInfoToUpdate.scheduleUpdate === null) {
+ await ScheduleVideoUpdateModel.deleteByVideoId(videoInstanceUpdated.id, t)
+ }
+
const isNewVideo = wasPrivateVideo && videoInstanceUpdated.privacy !== VideoPrivacy.PRIVATE
- await federateVideoIfNeeded(videoInstanceUpdated, isNewVideo)
+ await federateVideoIfNeeded(videoInstanceUpdated, isNewVideo, t)
})
logger.info('Video with name %s and uuid %s updated.', videoInstance.name, videoInstance.uuid)
throw err
}
+
+ return res.type('json').status(204).end()
}
function getVideo (req: express.Request, res: express.Response) {
return res.json(getFormattedObjects(resultList.data, resultList.total))
}
-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.'
- }
-
- await retryTransactionWrapper(removeVideo, options)
-
- return res.type('json').status(204).end()
-}
-
async function removeVideo (req: express.Request, res: express.Response) {
const videoInstance: VideoModel = res.locals.video
})
logger.info('Video with name %s and uuid %s deleted.', videoInstance.name, videoInstance.uuid)
+
+ return res.type('json').status(204).end()
}
async function searchVideos (req: express.Request, res: express.Response, next: express.NextFunction) {