captions.ts 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import express from 'express'
  2. import { MVideoCaption } from '@server/types/models'
  3. import { HttpStatusCode } from '../../../../shared/models/http/http-error-codes'
  4. import { moveAndProcessCaptionFile } from '../../../helpers/captions-utils'
  5. import { createReqFiles } from '../../../helpers/express-utils'
  6. import { logger } from '../../../helpers/logger'
  7. import { getFormattedObjects } from '../../../helpers/utils'
  8. import { CONFIG } from '../../../initializers/config'
  9. import { MIMETYPES } from '../../../initializers/constants'
  10. import { sequelizeTypescript } from '../../../initializers/database'
  11. import { federateVideoIfNeeded } from '../../../lib/activitypub/videos'
  12. import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate } from '../../../middlewares'
  13. import { addVideoCaptionValidator, deleteVideoCaptionValidator, listVideoCaptionsValidator } from '../../../middlewares/validators'
  14. import { VideoCaptionModel } from '../../../models/video/video-caption'
  15. const reqVideoCaptionAdd = createReqFiles(
  16. [ 'captionfile' ],
  17. MIMETYPES.VIDEO_CAPTIONS.MIMETYPE_EXT,
  18. {
  19. captionfile: CONFIG.STORAGE.CAPTIONS_DIR
  20. }
  21. )
  22. const videoCaptionsRouter = express.Router()
  23. videoCaptionsRouter.get('/:videoId/captions',
  24. asyncMiddleware(listVideoCaptionsValidator),
  25. asyncMiddleware(listVideoCaptions)
  26. )
  27. videoCaptionsRouter.put('/:videoId/captions/:captionLanguage',
  28. authenticate,
  29. reqVideoCaptionAdd,
  30. asyncMiddleware(addVideoCaptionValidator),
  31. asyncRetryTransactionMiddleware(addVideoCaption)
  32. )
  33. videoCaptionsRouter.delete('/:videoId/captions/:captionLanguage',
  34. authenticate,
  35. asyncMiddleware(deleteVideoCaptionValidator),
  36. asyncRetryTransactionMiddleware(deleteVideoCaption)
  37. )
  38. // ---------------------------------------------------------------------------
  39. export {
  40. videoCaptionsRouter
  41. }
  42. // ---------------------------------------------------------------------------
  43. async function listVideoCaptions (req: express.Request, res: express.Response) {
  44. const data = await VideoCaptionModel.listVideoCaptions(res.locals.videoId.id)
  45. return res.json(getFormattedObjects(data, data.length))
  46. }
  47. async function addVideoCaption (req: express.Request, res: express.Response) {
  48. const videoCaptionPhysicalFile = req.files['captionfile'][0]
  49. const video = res.locals.videoAll
  50. const captionLanguage = req.params.captionLanguage
  51. const videoCaption = new VideoCaptionModel({
  52. videoId: video.id,
  53. filename: VideoCaptionModel.generateCaptionName(captionLanguage),
  54. language: captionLanguage
  55. }) as MVideoCaption
  56. // Move physical file
  57. await moveAndProcessCaptionFile(videoCaptionPhysicalFile, videoCaption)
  58. await sequelizeTypescript.transaction(async t => {
  59. await VideoCaptionModel.insertOrReplaceLanguage(videoCaption, t)
  60. // Update video update
  61. await federateVideoIfNeeded(video, false, t)
  62. })
  63. return res.status(HttpStatusCode.NO_CONTENT_204).end()
  64. }
  65. async function deleteVideoCaption (req: express.Request, res: express.Response) {
  66. const video = res.locals.videoAll
  67. const videoCaption = res.locals.videoCaption
  68. await sequelizeTypescript.transaction(async t => {
  69. await videoCaption.destroy({ transaction: t })
  70. // Send video update
  71. await federateVideoIfNeeded(video, false, t)
  72. })
  73. logger.info('Video caption %s of video %s deleted.', videoCaption.language, video.uuid)
  74. return res.type('json').status(HttpStatusCode.NO_CONTENT_204).end()
  75. }