aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers/api/videos
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-02-25 13:56:07 +0100
committerChocobozzz <chocobozzz@cpy.re>2021-02-25 15:01:07 +0100
commitd61893f7236abbed30c25b1823e6ecad93a8e8dd (patch)
tree9cf1d47598d9a99f390c6754d289d2573788451d /server/controllers/api/videos
parentd7df188f23bb3c4773ac26e6fa8b3d82b1229e6d (diff)
downloadPeerTube-d61893f7236abbed30c25b1823e6ecad93a8e8dd.tar.gz
PeerTube-d61893f7236abbed30c25b1823e6ecad93a8e8dd.tar.zst
PeerTube-d61893f7236abbed30c25b1823e6ecad93a8e8dd.zip
Async torrent creation
Diffstat (limited to 'server/controllers/api/videos')
-rw-r--r--server/controllers/api/videos/index.ts38
1 files changed, 31 insertions, 7 deletions
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts
index e89315930..58ab72370 100644
--- a/server/controllers/api/videos/index.ts
+++ b/server/controllers/api/videos/index.ts
@@ -9,12 +9,12 @@ import { LiveManager } from '@server/lib/live-manager'
9import { addOptimizeOrMergeAudioJob, buildLocalVideoFromReq, buildVideoThumbnailsFromReq, setVideoTags } from '@server/lib/video' 9import { addOptimizeOrMergeAudioJob, buildLocalVideoFromReq, buildVideoThumbnailsFromReq, setVideoTags } from '@server/lib/video'
10import { generateVideoFilename, getVideoFilePath } from '@server/lib/video-paths' 10import { generateVideoFilename, getVideoFilePath } from '@server/lib/video-paths'
11import { getServerActor } from '@server/models/application/application' 11import { getServerActor } from '@server/models/application/application'
12import { MVideoFullLight } from '@server/types/models' 12import { MVideo, MVideoFile, MVideoFullLight } from '@server/types/models'
13import { VideoCreate, VideoState, VideoUpdate } from '../../../../shared' 13import { VideoCreate, VideoState, VideoUpdate } from '../../../../shared'
14import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' 14import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
15import { VideoFilter } from '../../../../shared/models/videos/video-query.type' 15import { VideoFilter } from '../../../../shared/models/videos/video-query.type'
16import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger' 16import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger'
17import { resetSequelizeInstance } from '../../../helpers/database-utils' 17import { resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers/database-utils'
18import { buildNSFWFilter, createReqFiles, getCountVideos } from '../../../helpers/express-utils' 18import { buildNSFWFilter, createReqFiles, getCountVideos } from '../../../helpers/express-utils'
19import { getMetadataFromFile, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffprobe-utils' 19import { getMetadataFromFile, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffprobe-utils'
20import { logger } from '../../../helpers/logger' 20import { logger } from '../../../helpers/logger'
@@ -221,9 +221,6 @@ async function addVideo (req: express.Request, res: express.Response) {
221 fallback: type => generateVideoMiniature({ video, videoFile, type }) 221 fallback: type => generateVideoMiniature({ video, videoFile, type })
222 }) 222 })
223 223
224 // Create the torrent file
225 await createTorrentAndSetInfoHash(video, videoFile)
226
227 const { videoCreated } = await sequelizeTypescript.transaction(async t => { 224 const { videoCreated } = await sequelizeTypescript.transaction(async t => {
228 const sequelizeOptions = { transaction: t } 225 const sequelizeOptions = { transaction: t }
229 226
@@ -258,7 +255,6 @@ async function addVideo (req: express.Request, res: express.Response) {
258 isNew: true, 255 isNew: true,
259 transaction: t 256 transaction: t
260 }) 257 })
261 await federateVideoIfNeeded(video, true, t)
262 258
263 auditLogger.create(getAuditIdFromRes(res), new VideoAuditView(videoCreated.toFormattedDetailsJSON())) 259 auditLogger.create(getAuditIdFromRes(res), new VideoAuditView(videoCreated.toFormattedDetailsJSON()))
264 logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoCreated.uuid) 260 logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoCreated.uuid)
@@ -266,7 +262,21 @@ async function addVideo (req: express.Request, res: express.Response) {
266 return { videoCreated } 262 return { videoCreated }
267 }) 263 })
268 264
269 Notifier.Instance.notifyOnNewVideoIfNeeded(videoCreated) 265 // Create the torrent file in async way because it could be long
266 createTorrentAndSetInfoHashAsync(video, videoFile)
267 .catch(err => logger.error('Cannot create torrent file for video %s', video.url, { err }))
268 .then(() => VideoModel.loadAndPopulateAccountAndServerAndTags(video.id))
269 .then(refreshedVideo => {
270 if (!refreshedVideo) return
271
272 // Only federate and notify after the torrent creation
273 Notifier.Instance.notifyOnNewVideoIfNeeded(refreshedVideo)
274
275 return retryTransactionWrapper(() => {
276 return sequelizeTypescript.transaction(t => federateVideoIfNeeded(refreshedVideo, true, t))
277 })
278 })
279 .catch(err => logger.error('Cannot federate or notify video creation %s', video.url, { err }))
270 280
271 if (video.state === VideoState.TO_TRANSCODE) { 281 if (video.state === VideoState.TO_TRANSCODE) {
272 await addOptimizeOrMergeAudioJob(videoCreated, videoFile, res.locals.oauth.token.User) 282 await addOptimizeOrMergeAudioJob(videoCreated, videoFile, res.locals.oauth.token.User)
@@ -526,3 +536,17 @@ async function removeVideo (req: express.Request, res: express.Response) {
526 .status(HttpStatusCode.NO_CONTENT_204) 536 .status(HttpStatusCode.NO_CONTENT_204)
527 .end() 537 .end()
528} 538}
539
540async function createTorrentAndSetInfoHashAsync (video: MVideo, fileArg: MVideoFile) {
541 await createTorrentAndSetInfoHash(video, fileArg)
542
543 // Refresh videoFile because the createTorrentAndSetInfoHash could be long
544 const refreshedFile = await VideoFileModel.loadWithVideo(fileArg.id)
545 // File does not exist anymore, remove the generated torrent
546 if (!refreshedFile) return fileArg.removeTorrent()
547
548 refreshedFile.infoHash = fileArg.infoHash
549 refreshedFile.torrentFilename = fileArg.torrentFilename
550
551 return refreshedFile.save()
552}