import express from 'express' ; import { MVideoCaption } from '@server/types/models' ; import { HttpStatusCode } from '../../../../shared/models/http/http-error-codes' ; import { moveAndProcessCaptionFile } from '../../../helpers/captions-utils' ; import { createReqFiles } from '../../../helpers/express-utils' ; import { logger } from '../../../helpers/logger' ; import { getFormattedObjects } from '../../../helpers/utils' ; import { CONFIG } from '../../../initializers/config' ; import { MIMETYPES } from '../../../initializers/constants' ; import { sequelizeTypescript } from '../../../initializers/database' ; import { federateVideoIfNeeded } from '../../../lib/activitypub/videos' ; import { asyncMiddleware , asyncRetryTransactionMiddleware , authenticate } from '../../../middlewares' ; import { addVideoCaptionValidator , deleteVideoCaptionValidator , listVideoCaptionsValidator } from '../../../middlewares/validators' ; import { VideoCaptionModel } from '../../../models/video/video-caption' ; import { Hooks } from '@server/lib/plugins/hooks' ; const reqVideoCaptionAdd = createReqFiles ( [ 'captionfile' ] , MIMETYPES . VIDEO_CAPTIONS . MIMETYPE_EXT , { captionfile : CONFIG . STORAGE . CAPTIONS_DIR } ) ; const videoCaptionsRouter = express . Router ( ) ; videoCaptionsRouter . get ( '/:videoId/captions' , asyncMiddleware ( listVideoCaptionsValidator ) , asyncMiddleware ( listVideoCaptions ) ) ; videoCaptionsRouter . put ( '/:videoId/captions/:captionLanguage' , authenticate , reqVideoCaptionAdd , asyncMiddleware ( addVideoCaptionValidator ) , asyncRetryTransactionMiddleware ( addVideoCaption ) ) ; videoCaptionsRouter . delete ( '/:videoId/captions/:captionLanguage' , authenticate , asyncMiddleware ( deleteVideoCaptionValidator ) , asyncRetryTransactionMiddleware ( deleteVideoCaption ) ) ; export { videoCaptionsRouter } ; async function listVideoCaptions ( req , res ) { const data = await VideoCaptionModel . listVideoCaptions ( res . locals . onlyVideo . id ) ; return res . json ( getFormattedObjects ( data , data . length ) ) ; } async function addVideoCaption ( req , res ) { const videoCaptionPhysicalFile = req . files [ 'captionfile' ] [ 0 ] ; const video = res . locals . videoAll ; const captionLanguage = req . params . captionLanguage ; const videoCaption = new VideoCaptionModel ( { videoId : video . id , filename : VideoCaptionModel . generateCaptionName ( captionLanguage ) , language : captionLanguage } ) as MVideoCaption ; await moveAndProcessCaptionFile ( videoCaptionPhysicalFile , videoCaption ) ; await sequelizeTypescript . transaction ( async ( t ) => { await VideoCaptionModel . insertOrReplaceLanguage ( videoCaption , t ) ; await federateVideoIfNeeded ( video , false , t ) ; } ) ; Hooks . runAction ( 'action:api.video-caption.created' , { caption : videoCaption , req , res } ) ; return res . status ( HttpStatusCode . NO_CONTENT_204 ) . end ( ) ; } async function deleteVideoCaption ( req , res ) { const video = res . locals . videoAll ; const videoCaption = res . locals . videoCaption ; await sequelizeTypescript . transaction ( async ( t ) => { await videoCaption . destroy ( { transaction : t } ) ; await federateVideoIfNeeded ( video , false , t ) ; } ) ; logger . info ( 'Video caption %s of video %s deleted.' , videoCaption . language , video . uuid ) ; Hooks . runAction ( 'action:api.video-caption.deleted' , { caption : videoCaption , req , res } ) ; return res . type ( 'json' ) . status ( HttpStatusCode . NO_CONTENT_204 ) . end ( ) ; }