]>
Commit | Line | Data |
---|---|---|
1 | import { Job } from 'bullmq' | |
2 | import { extractVideo } from '@server/helpers/video' | |
3 | import { createTorrentAndSetInfoHash, updateTorrentMetadata } from '@server/helpers/webtorrent' | |
4 | import { VideoPathManager } from '@server/lib/video-path-manager' | |
5 | import { VideoModel } from '@server/models/video/video' | |
6 | import { VideoFileModel } from '@server/models/video/video-file' | |
7 | import { VideoStreamingPlaylistModel } from '@server/models/video/video-streaming-playlist' | |
8 | import { ManageVideoTorrentPayload } from '@shared/models' | |
9 | import { logger } from '../../../helpers/logger' | |
10 | ||
11 | async function processManageVideoTorrent (job: Job) { | |
12 | const payload = job.data as ManageVideoTorrentPayload | |
13 | logger.info('Processing torrent in job %s.', job.id) | |
14 | ||
15 | if (payload.action === 'create') return doCreateAction(payload) | |
16 | if (payload.action === 'update-metadata') return doUpdateMetadataAction(payload) | |
17 | } | |
18 | ||
19 | // --------------------------------------------------------------------------- | |
20 | ||
21 | export { | |
22 | processManageVideoTorrent | |
23 | } | |
24 | ||
25 | // --------------------------------------------------------------------------- | |
26 | ||
27 | async function doCreateAction (payload: ManageVideoTorrentPayload & { action: 'create' }) { | |
28 | const [ video, file ] = await Promise.all([ | |
29 | loadVideoOrLog(payload.videoId), | |
30 | loadFileOrLog(payload.videoFileId) | |
31 | ]) | |
32 | ||
33 | if (!video || !file) return | |
34 | ||
35 | const fileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid) | |
36 | ||
37 | try { | |
38 | await video.reload() | |
39 | await file.reload() | |
40 | ||
41 | await createTorrentAndSetInfoHash(video, file) | |
42 | ||
43 | // Refresh videoFile because the createTorrentAndSetInfoHash could be long | |
44 | const refreshedFile = await VideoFileModel.loadWithVideo(file.id) | |
45 | // File does not exist anymore, remove the generated torrent | |
46 | if (!refreshedFile) return file.removeTorrent() | |
47 | ||
48 | refreshedFile.infoHash = file.infoHash | |
49 | refreshedFile.torrentFilename = file.torrentFilename | |
50 | ||
51 | await refreshedFile.save() | |
52 | } finally { | |
53 | fileMutexReleaser() | |
54 | } | |
55 | } | |
56 | ||
57 | async function doUpdateMetadataAction (payload: ManageVideoTorrentPayload & { action: 'update-metadata' }) { | |
58 | const [ video, streamingPlaylist, file ] = await Promise.all([ | |
59 | loadVideoOrLog(payload.videoId), | |
60 | loadStreamingPlaylistOrLog(payload.streamingPlaylistId), | |
61 | loadFileOrLog(payload.videoFileId) | |
62 | ]) | |
63 | ||
64 | if ((!video && !streamingPlaylist) || !file) return | |
65 | ||
66 | const extractedVideo = extractVideo(video || streamingPlaylist) | |
67 | const fileMutexReleaser = await VideoPathManager.Instance.lockFiles(extractedVideo.uuid) | |
68 | ||
69 | try { | |
70 | await updateTorrentMetadata(video || streamingPlaylist, file) | |
71 | ||
72 | await file.save() | |
73 | } finally { | |
74 | fileMutexReleaser() | |
75 | } | |
76 | } | |
77 | ||
78 | async function loadVideoOrLog (videoId: number) { | |
79 | if (!videoId) return undefined | |
80 | ||
81 | const video = await VideoModel.load(videoId) | |
82 | if (!video) { | |
83 | logger.debug('Do not process torrent for video %d: does not exist anymore.', videoId) | |
84 | } | |
85 | ||
86 | return video | |
87 | } | |
88 | ||
89 | async function loadStreamingPlaylistOrLog (streamingPlaylistId: number) { | |
90 | if (!streamingPlaylistId) return undefined | |
91 | ||
92 | const streamingPlaylist = await VideoStreamingPlaylistModel.loadWithVideo(streamingPlaylistId) | |
93 | if (!streamingPlaylist) { | |
94 | logger.debug('Do not process torrent for streaming playlist %d: does not exist anymore.', streamingPlaylistId) | |
95 | } | |
96 | ||
97 | return streamingPlaylist | |
98 | } | |
99 | ||
100 | async function loadFileOrLog (videoFileId: number) { | |
101 | if (!videoFileId) return undefined | |
102 | ||
103 | const file = await VideoFileModel.load(videoFileId) | |
104 | ||
105 | if (!file) { | |
106 | logger.debug('Do not process torrent for file %d: does not exist anymore.', videoFileId) | |
107 | } | |
108 | ||
109 | return file | |
110 | } |