X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fcontrollers%2Fapi%2Fvideos%2Fimport.ts;h=f9a24a0c2c7c628af9f70f708593df6735dac956;hb=e8bafea35bc930cb8ac5b2d521a188642a1adffe;hp=b2f73fa48289ea0b7124c725ce91b6e4b18b60fa;hpb=3e17515e2996b79e23f569c296051a91af3fcbe4;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts index b2f73fa48..f9a24a0c2 100644 --- a/server/controllers/api/videos/import.ts +++ b/server/controllers/api/videos/import.ts @@ -1,16 +1,9 @@ import * as express from 'express' import * as magnetUtil from 'magnet-uri' import 'multer' -import { auditLoggerFactory, VideoImportAuditView } from '../../../helpers/audit-logger' +import { auditLoggerFactory, getAuditIdFromRes, VideoImportAuditView } from '../../../helpers/audit-logger' import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoImportAddValidator } from '../../../middlewares' -import { - CONFIG, - IMAGE_MIMETYPE_EXT, - PREVIEWS_SIZE, - sequelizeTypescript, - THUMBNAILS_SIZE, - TORRENT_MIMETYPE_EXT -} from '../../../initializers' +import { MIMETYPES } from '../../../initializers/constants' import { getYoutubeDLInfo, YoutubeDLInfo } from '../../../helpers/youtube-dl' import { createReqFiles } from '../../../helpers/express-utils' import { logger } from '../../../helpers/logger' @@ -20,26 +13,31 @@ import { getVideoActivityPubUrl } from '../../../lib/activitypub' import { TagModel } from '../../../models/video/tag' import { VideoImportModel } from '../../../models/video/video-import' import { JobQueue } from '../../../lib/job-queue/job-queue' -import { processImage } from '../../../helpers/image-utils' import { join } from 'path' import { isArray } from '../../../helpers/custom-validators/misc' import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model' import { VideoChannelModel } from '../../../models/video/video-channel' import * as Bluebird from 'bluebird' import * as parseTorrent from 'parse-torrent' -import { readFileBufferPromise, renamePromise } from '../../../helpers/core-utils' import { getSecureTorrentName } from '../../../helpers/utils' +import { move, readFile } from 'fs-extra' +import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist' +import { CONFIG } from '../../../initializers/config' +import { sequelizeTypescript } from '../../../initializers/database' +import { createVideoThumbnailFromExisting } from '../../../lib/thumbnail' +import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' +import { ThumbnailModel } from '../../../models/video/thumbnail' const auditLogger = auditLoggerFactory('video-imports') const videoImportsRouter = express.Router() const reqVideoFileImport = createReqFiles( [ 'thumbnailfile', 'previewfile', 'torrentfile' ], - Object.assign({}, TORRENT_MIMETYPE_EXT, IMAGE_MIMETYPE_EXT), + Object.assign({}, MIMETYPES.TORRENT.MIMETYPE_EXT, MIMETYPES.IMAGE.MIMETYPE_EXT), { - thumbnailfile: CONFIG.STORAGE.THUMBNAILS_DIR, - previewfile: CONFIG.STORAGE.PREVIEWS_DIR, - torrentfile: CONFIG.STORAGE.TORRENTS_DIR + thumbnailfile: CONFIG.STORAGE.TMP_DIR, + previewfile: CONFIG.STORAGE.TMP_DIR, + torrentfile: CONFIG.STORAGE.TMP_DIR } ) @@ -78,10 +76,10 @@ async function addTorrentImport (req: express.Request, res: express.Response, to // Rename the torrent to a secured name const newTorrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, getSecureTorrentName(torrentName)) - await renamePromise(torrentfile.path, newTorrentPath) + await move(torrentfile.path, newTorrentPath) torrentfile.path = newTorrentPath - const buf = await readFileBufferPromise(torrentfile.path) + const buf = await readFile(torrentfile.path) const parsedTorrent = parseTorrent(buf) videoName = isArray(parsedTorrent.name) ? parsedTorrent.name[ 0 ] : parsedTorrent.name as string @@ -94,8 +92,8 @@ async function addTorrentImport (req: express.Request, res: express.Response, to const video = buildVideo(res.locals.videoChannel.id, body, { name: videoName }) - await processThumbnail(req, video) - await processPreview(req, video) + const thumbnailModel = await processThumbnail(req, video) + const previewModel = await processPreview(req, video) const tags = body.tags || undefined const videoImportAttributes = { @@ -104,7 +102,14 @@ async function addTorrentImport (req: express.Request, res: express.Response, to state: VideoImportState.PENDING, userId: user.id } - const videoImport: VideoImportModel = await insertIntoDB(video, res.locals.videoChannel, tags, videoImportAttributes) + const videoImport = await insertIntoDB({ + video, + thumbnailModel, + previewModel, + videoChannel: res.locals.videoChannel, + tags, + videoImportAttributes + }) // Create job to import the video const payload = { @@ -114,7 +119,7 @@ async function addTorrentImport (req: express.Request, res: express.Response, to } await JobQueue.Instance.createJob({ type: 'video-import', payload }) - auditLogger.create(res.locals.oauth.token.User.Account.Actor.getIdentifier(), new VideoImportAuditView(videoImport.toFormattedJSON())) + auditLogger.create(getAuditIdFromRes(res), new VideoImportAuditView(videoImport.toFormattedJSON())) return res.json(videoImport.toFormattedJSON()).end() } @@ -137,8 +142,8 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response) const video = buildVideo(res.locals.videoChannel.id, body, youtubeDLInfo) - const downloadThumbnail = !await processThumbnail(req, video) - const downloadPreview = !await processPreview(req, video) + const thumbnailModel = await processThumbnail(req, video) + const previewModel = await processPreview(req, video) const tags = body.tags || youtubeDLInfo.tags const videoImportAttributes = { @@ -146,19 +151,26 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response) state: VideoImportState.PENDING, userId: user.id } - const videoImport: VideoImportModel = await insertIntoDB(video, res.locals.videoChannel, tags, videoImportAttributes) + const videoImport = await insertIntoDB({ + video: video, + thumbnailModel, + previewModel, + videoChannel: res.locals.videoChannel, + tags, + videoImportAttributes + }) // Create job to import the video const payload = { type: 'youtube-dl' as 'youtube-dl', videoImportId: videoImport.id, thumbnailUrl: youtubeDLInfo.thumbnailUrl, - downloadThumbnail, - downloadPreview + downloadThumbnail: !thumbnailModel, + downloadPreview: !previewModel } await JobQueue.Instance.createJob({ type: 'video-import', payload }) - auditLogger.create(res.locals.oauth.token.User.Account.Actor.getIdentifier(), new VideoImportAuditView(videoImport.toFormattedJSON())) + auditLogger.create(getAuditIdFromRes(res), new VideoImportAuditView(videoImport.toFormattedJSON())) return res.json(videoImport.toFormattedJSON()).end() } @@ -171,6 +183,7 @@ function buildVideo (channelId: number, body: VideoImportCreate, importData: You licence: body.licence || importData.licence, language: body.language || undefined, commentsEnabled: body.commentsEnabled || true, + downloadEnabled: body.downloadEnabled || true, waitTranscoding: body.waitTranscoding || false, state: VideoState.TO_IMPORT, nsfw: body.nsfw || importData.nsfw || false, @@ -178,7 +191,8 @@ function buildVideo (channelId: number, body: VideoImportCreate, importData: You support: body.support || null, privacy: body.privacy || VideoPrivacy.PRIVATE, duration: 0, // duration will be set by the import job - channelId: channelId + channelId: channelId, + originallyPublishedAt: importData.originallyPublishedAt } const video = new VideoModel(videoData) video.url = getVideoActivityPubUrl(video) @@ -190,32 +204,34 @@ async function processThumbnail (req: express.Request, video: VideoModel) { const thumbnailField = req.files ? req.files['thumbnailfile'] : undefined if (thumbnailField) { const thumbnailPhysicalFile = thumbnailField[ 0 ] - await processImage(thumbnailPhysicalFile, join(CONFIG.STORAGE.THUMBNAILS_DIR, video.getThumbnailName()), THUMBNAILS_SIZE) - return true + return createVideoThumbnailFromExisting(thumbnailPhysicalFile.path, video, ThumbnailType.THUMBNAIL) } - return false + return undefined } async function processPreview (req: express.Request, video: VideoModel) { const previewField = req.files ? req.files['previewfile'] : undefined if (previewField) { const previewPhysicalFile = previewField[0] - await processImage(previewPhysicalFile, join(CONFIG.STORAGE.PREVIEWS_DIR, video.getPreviewName()), PREVIEWS_SIZE) - return true + return createVideoThumbnailFromExisting(previewPhysicalFile.path, video, ThumbnailType.PREVIEW) } - return false + return undefined } -function insertIntoDB ( +function insertIntoDB (parameters: { video: VideoModel, + thumbnailModel: ThumbnailModel, + previewModel: ThumbnailModel, videoChannel: VideoChannelModel, tags: string[], videoImportAttributes: FilteredModelAttributes -): Bluebird { +}): Bluebird { + let { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes } = parameters + return sequelizeTypescript.transaction(async t => { const sequelizeOptions = { transaction: t } @@ -223,6 +239,17 @@ function insertIntoDB ( const videoCreated = await video.save(sequelizeOptions) videoCreated.VideoChannel = videoChannel + if (thumbnailModel) { + thumbnailModel.videoId = videoCreated.id + videoCreated.addThumbnail(await thumbnailModel.save({ transaction: t })) + } + if (previewModel) { + previewModel.videoId = videoCreated.id + videoCreated.addThumbnail(await previewModel.save({ transaction: t })) + } + + await autoBlacklistVideoIfNeeded(video, videoChannel.Account.User, t) + // Set tags to the video if (tags) { const tagInstances = await TagModel.findOrCreateTags(tags, t)