aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers/api/videos/import.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/controllers/api/videos/import.ts')
-rw-r--r--server/controllers/api/videos/import.ts70
1 files changed, 48 insertions, 22 deletions
diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts
index a72b8c72e..f9a24a0c2 100644
--- a/server/controllers/api/videos/import.ts
+++ b/server/controllers/api/videos/import.ts
@@ -3,7 +3,7 @@ import * as magnetUtil from 'magnet-uri'
3import 'multer' 3import 'multer'
4import { auditLoggerFactory, getAuditIdFromRes, VideoImportAuditView } from '../../../helpers/audit-logger' 4import { auditLoggerFactory, getAuditIdFromRes, VideoImportAuditView } from '../../../helpers/audit-logger'
5import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoImportAddValidator } from '../../../middlewares' 5import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoImportAddValidator } from '../../../middlewares'
6import { MIMETYPES, PREVIEWS_SIZE, THUMBNAILS_SIZE } from '../../../initializers/constants' 6import { MIMETYPES } from '../../../initializers/constants'
7import { getYoutubeDLInfo, YoutubeDLInfo } from '../../../helpers/youtube-dl' 7import { getYoutubeDLInfo, YoutubeDLInfo } from '../../../helpers/youtube-dl'
8import { createReqFiles } from '../../../helpers/express-utils' 8import { createReqFiles } from '../../../helpers/express-utils'
9import { logger } from '../../../helpers/logger' 9import { logger } from '../../../helpers/logger'
@@ -13,12 +13,10 @@ import { getVideoActivityPubUrl } from '../../../lib/activitypub'
13import { TagModel } from '../../../models/video/tag' 13import { TagModel } from '../../../models/video/tag'
14import { VideoImportModel } from '../../../models/video/video-import' 14import { VideoImportModel } from '../../../models/video/video-import'
15import { JobQueue } from '../../../lib/job-queue/job-queue' 15import { JobQueue } from '../../../lib/job-queue/job-queue'
16import { processImage } from '../../../helpers/image-utils'
17import { join } from 'path' 16import { join } from 'path'
18import { isArray } from '../../../helpers/custom-validators/misc' 17import { isArray } from '../../../helpers/custom-validators/misc'
19import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model' 18import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model'
20import { VideoChannelModel } from '../../../models/video/video-channel' 19import { VideoChannelModel } from '../../../models/video/video-channel'
21import { UserModel } from '../../../models/account/user'
22import * as Bluebird from 'bluebird' 20import * as Bluebird from 'bluebird'
23import * as parseTorrent from 'parse-torrent' 21import * as parseTorrent from 'parse-torrent'
24import { getSecureTorrentName } from '../../../helpers/utils' 22import { getSecureTorrentName } from '../../../helpers/utils'
@@ -26,6 +24,9 @@ import { move, readFile } from 'fs-extra'
26import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist' 24import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist'
27import { CONFIG } from '../../../initializers/config' 25import { CONFIG } from '../../../initializers/config'
28import { sequelizeTypescript } from '../../../initializers/database' 26import { sequelizeTypescript } from '../../../initializers/database'
27import { createVideoThumbnailFromExisting } from '../../../lib/thumbnail'
28import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type'
29import { ThumbnailModel } from '../../../models/video/thumbnail'
29 30
30const auditLogger = auditLoggerFactory('video-imports') 31const auditLogger = auditLoggerFactory('video-imports')
31const videoImportsRouter = express.Router() 32const videoImportsRouter = express.Router()
@@ -89,10 +90,10 @@ async function addTorrentImport (req: express.Request, res: express.Response, to
89 videoName = isArray(parsed.name) ? parsed.name[ 0 ] : parsed.name as string 90 videoName = isArray(parsed.name) ? parsed.name[ 0 ] : parsed.name as string
90 } 91 }
91 92
92 const video = buildVideo(res.locals.videoChannel.id, body, { name: videoName }, user) 93 const video = buildVideo(res.locals.videoChannel.id, body, { name: videoName })
93 94
94 await processThumbnail(req, video) 95 const thumbnailModel = await processThumbnail(req, video)
95 await processPreview(req, video) 96 const previewModel = await processPreview(req, video)
96 97
97 const tags = body.tags || undefined 98 const tags = body.tags || undefined
98 const videoImportAttributes = { 99 const videoImportAttributes = {
@@ -101,7 +102,14 @@ async function addTorrentImport (req: express.Request, res: express.Response, to
101 state: VideoImportState.PENDING, 102 state: VideoImportState.PENDING,
102 userId: user.id 103 userId: user.id
103 } 104 }
104 const videoImport = await insertIntoDB(video, res.locals.videoChannel, tags, videoImportAttributes) 105 const videoImport = await insertIntoDB({
106 video,
107 thumbnailModel,
108 previewModel,
109 videoChannel: res.locals.videoChannel,
110 tags,
111 videoImportAttributes
112 })
105 113
106 // Create job to import the video 114 // Create job to import the video
107 const payload = { 115 const payload = {
@@ -132,10 +140,10 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response)
132 }).end() 140 }).end()
133 } 141 }
134 142
135 const video = buildVideo(res.locals.videoChannel.id, body, youtubeDLInfo, user) 143 const video = buildVideo(res.locals.videoChannel.id, body, youtubeDLInfo)
136 144
137 const downloadThumbnail = !await processThumbnail(req, video) 145 const thumbnailModel = await processThumbnail(req, video)
138 const downloadPreview = !await processPreview(req, video) 146 const previewModel = await processPreview(req, video)
139 147
140 const tags = body.tags || youtubeDLInfo.tags 148 const tags = body.tags || youtubeDLInfo.tags
141 const videoImportAttributes = { 149 const videoImportAttributes = {
@@ -143,15 +151,22 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response)
143 state: VideoImportState.PENDING, 151 state: VideoImportState.PENDING,
144 userId: user.id 152 userId: user.id
145 } 153 }
146 const videoImport = await insertIntoDB(video, res.locals.videoChannel, tags, videoImportAttributes) 154 const videoImport = await insertIntoDB({
155 video: video,
156 thumbnailModel,
157 previewModel,
158 videoChannel: res.locals.videoChannel,
159 tags,
160 videoImportAttributes
161 })
147 162
148 // Create job to import the video 163 // Create job to import the video
149 const payload = { 164 const payload = {
150 type: 'youtube-dl' as 'youtube-dl', 165 type: 'youtube-dl' as 'youtube-dl',
151 videoImportId: videoImport.id, 166 videoImportId: videoImport.id,
152 thumbnailUrl: youtubeDLInfo.thumbnailUrl, 167 thumbnailUrl: youtubeDLInfo.thumbnailUrl,
153 downloadThumbnail, 168 downloadThumbnail: !thumbnailModel,
154 downloadPreview 169 downloadPreview: !previewModel
155 } 170 }
156 await JobQueue.Instance.createJob({ type: 'video-import', payload }) 171 await JobQueue.Instance.createJob({ type: 'video-import', payload })
157 172
@@ -160,7 +175,7 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response)
160 return res.json(videoImport.toFormattedJSON()).end() 175 return res.json(videoImport.toFormattedJSON()).end()
161} 176}
162 177
163function buildVideo (channelId: number, body: VideoImportCreate, importData: YoutubeDLInfo, user: UserModel) { 178function buildVideo (channelId: number, body: VideoImportCreate, importData: YoutubeDLInfo) {
164 const videoData = { 179 const videoData = {
165 name: body.name || importData.name || 'Unknown name', 180 name: body.name || importData.name || 'Unknown name',
166 remote: false, 181 remote: false,
@@ -189,32 +204,34 @@ async function processThumbnail (req: express.Request, video: VideoModel) {
189 const thumbnailField = req.files ? req.files['thumbnailfile'] : undefined 204 const thumbnailField = req.files ? req.files['thumbnailfile'] : undefined
190 if (thumbnailField) { 205 if (thumbnailField) {
191 const thumbnailPhysicalFile = thumbnailField[ 0 ] 206 const thumbnailPhysicalFile = thumbnailField[ 0 ]
192 await processImage(thumbnailPhysicalFile, join(CONFIG.STORAGE.THUMBNAILS_DIR, video.getThumbnailName()), THUMBNAILS_SIZE)
193 207
194 return true 208 return createVideoThumbnailFromExisting(thumbnailPhysicalFile.path, video, ThumbnailType.THUMBNAIL)
195 } 209 }
196 210
197 return false 211 return undefined
198} 212}
199 213
200async function processPreview (req: express.Request, video: VideoModel) { 214async function processPreview (req: express.Request, video: VideoModel) {
201 const previewField = req.files ? req.files['previewfile'] : undefined 215 const previewField = req.files ? req.files['previewfile'] : undefined
202 if (previewField) { 216 if (previewField) {
203 const previewPhysicalFile = previewField[0] 217 const previewPhysicalFile = previewField[0]
204 await processImage(previewPhysicalFile, join(CONFIG.STORAGE.PREVIEWS_DIR, video.getPreviewName()), PREVIEWS_SIZE)
205 218
206 return true 219 return createVideoThumbnailFromExisting(previewPhysicalFile.path, video, ThumbnailType.PREVIEW)
207 } 220 }
208 221
209 return false 222 return undefined
210} 223}
211 224
212function insertIntoDB ( 225function insertIntoDB (parameters: {
213 video: VideoModel, 226 video: VideoModel,
227 thumbnailModel: ThumbnailModel,
228 previewModel: ThumbnailModel,
214 videoChannel: VideoChannelModel, 229 videoChannel: VideoChannelModel,
215 tags: string[], 230 tags: string[],
216 videoImportAttributes: FilteredModelAttributes<VideoImportModel> 231 videoImportAttributes: FilteredModelAttributes<VideoImportModel>
217): Bluebird<VideoImportModel> { 232}): Bluebird<VideoImportModel> {
233 let { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes } = parameters
234
218 return sequelizeTypescript.transaction(async t => { 235 return sequelizeTypescript.transaction(async t => {
219 const sequelizeOptions = { transaction: t } 236 const sequelizeOptions = { transaction: t }
220 237
@@ -222,6 +239,15 @@ function insertIntoDB (
222 const videoCreated = await video.save(sequelizeOptions) 239 const videoCreated = await video.save(sequelizeOptions)
223 videoCreated.VideoChannel = videoChannel 240 videoCreated.VideoChannel = videoChannel
224 241
242 if (thumbnailModel) {
243 thumbnailModel.videoId = videoCreated.id
244 videoCreated.addThumbnail(await thumbnailModel.save({ transaction: t }))
245 }
246 if (previewModel) {
247 previewModel.videoId = videoCreated.id
248 videoCreated.addThumbnail(await previewModel.save({ transaction: t }))
249 }
250
225 await autoBlacklistVideoIfNeeded(video, videoChannel.Account.User, t) 251 await autoBlacklistVideoIfNeeded(video, videoChannel.Account.User, t)
226 252
227 // Set tags to the video 253 // Set tags to the video