diff options
Diffstat (limited to 'server/controllers/api/videos')
-rw-r--r-- | server/controllers/api/videos/import.ts | 57 |
1 files changed, 45 insertions, 12 deletions
diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts index c16a254d2..df151e79d 100644 --- a/server/controllers/api/videos/import.ts +++ b/server/controllers/api/videos/import.ts | |||
@@ -1,8 +1,16 @@ | |||
1 | import * as magnetUtil from 'magnet-uri' | ||
2 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import * as magnetUtil from 'magnet-uri' | ||
3 | import 'multer' | ||
3 | import { auditLoggerFactory, VideoImportAuditView } from '../../../helpers/audit-logger' | 4 | import { auditLoggerFactory, VideoImportAuditView } from '../../../helpers/audit-logger' |
4 | import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoImportAddValidator } from '../../../middlewares' | 5 | import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoImportAddValidator } from '../../../middlewares' |
5 | import { CONFIG, IMAGE_MIMETYPE_EXT, PREVIEWS_SIZE, sequelizeTypescript, THUMBNAILS_SIZE } from '../../../initializers' | 6 | import { |
7 | CONFIG, | ||
8 | IMAGE_MIMETYPE_EXT, | ||
9 | PREVIEWS_SIZE, | ||
10 | sequelizeTypescript, | ||
11 | THUMBNAILS_SIZE, | ||
12 | TORRENT_MIMETYPE_EXT | ||
13 | } from '../../../initializers' | ||
6 | import { getYoutubeDLInfo, YoutubeDLInfo } from '../../../helpers/youtube-dl' | 14 | import { getYoutubeDLInfo, YoutubeDLInfo } from '../../../helpers/youtube-dl' |
7 | import { createReqFiles } from '../../../helpers/express-utils' | 15 | import { createReqFiles } from '../../../helpers/express-utils' |
8 | import { logger } from '../../../helpers/logger' | 16 | import { logger } from '../../../helpers/logger' |
@@ -18,16 +26,20 @@ import { isArray } from '../../../helpers/custom-validators/misc' | |||
18 | import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model' | 26 | import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model' |
19 | import { VideoChannelModel } from '../../../models/video/video-channel' | 27 | import { VideoChannelModel } from '../../../models/video/video-channel' |
20 | import * as Bluebird from 'bluebird' | 28 | import * as Bluebird from 'bluebird' |
29 | import * as parseTorrent from 'parse-torrent' | ||
30 | import { readFileBufferPromise, renamePromise } from '../../../helpers/core-utils' | ||
31 | import { getSecureTorrentName } from '../../../helpers/utils' | ||
21 | 32 | ||
22 | const auditLogger = auditLoggerFactory('video-imports') | 33 | const auditLogger = auditLoggerFactory('video-imports') |
23 | const videoImportsRouter = express.Router() | 34 | const videoImportsRouter = express.Router() |
24 | 35 | ||
25 | const reqVideoFileImport = createReqFiles( | 36 | const reqVideoFileImport = createReqFiles( |
26 | [ 'thumbnailfile', 'previewfile' ], | 37 | [ 'thumbnailfile', 'previewfile', 'torrentfile' ], |
27 | IMAGE_MIMETYPE_EXT, | 38 | Object.assign({}, TORRENT_MIMETYPE_EXT, IMAGE_MIMETYPE_EXT), |
28 | { | 39 | { |
29 | thumbnailfile: CONFIG.STORAGE.THUMBNAILS_DIR, | 40 | thumbnailfile: CONFIG.STORAGE.THUMBNAILS_DIR, |
30 | previewfile: CONFIG.STORAGE.PREVIEWS_DIR | 41 | previewfile: CONFIG.STORAGE.PREVIEWS_DIR, |
42 | torrentfile: CONFIG.STORAGE.TORRENTS_DIR | ||
31 | } | 43 | } |
32 | ) | 44 | ) |
33 | 45 | ||
@@ -49,17 +61,37 @@ export { | |||
49 | function addVideoImport (req: express.Request, res: express.Response) { | 61 | function addVideoImport (req: express.Request, res: express.Response) { |
50 | if (req.body.targetUrl) return addYoutubeDLImport(req, res) | 62 | if (req.body.targetUrl) return addYoutubeDLImport(req, res) |
51 | 63 | ||
52 | if (req.body.magnetUri) return addTorrentImport(req, res) | 64 | const file = req.files['torrentfile'][0] |
65 | if (req.body.magnetUri || file) return addTorrentImport(req, res, file) | ||
53 | } | 66 | } |
54 | 67 | ||
55 | async function addTorrentImport (req: express.Request, res: express.Response) { | 68 | async function addTorrentImport (req: express.Request, res: express.Response, torrentfile: Express.Multer.File) { |
56 | const body: VideoImportCreate = req.body | 69 | const body: VideoImportCreate = req.body |
57 | const magnetUri = body.magnetUri | ||
58 | 70 | ||
59 | const parsed = magnetUtil.decode(magnetUri) | 71 | let videoName: string |
60 | const magnetName = isArray(parsed.name) ? parsed.name[0] : parsed.name as string | 72 | let torrentName: string |
73 | let magnetUri: string | ||
74 | |||
75 | if (torrentfile) { | ||
76 | torrentName = torrentfile.originalname | ||
77 | |||
78 | // Rename the torrent to a secured name | ||
79 | const newTorrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, getSecureTorrentName(torrentName)) | ||
80 | await renamePromise(torrentfile.path, newTorrentPath) | ||
81 | torrentfile.path = newTorrentPath | ||
82 | |||
83 | const buf = await readFileBufferPromise(torrentfile.path) | ||
84 | const parsedTorrent = parseTorrent(buf) | ||
85 | |||
86 | videoName = isArray(parsedTorrent.name) ? parsedTorrent.name[ 0 ] : parsedTorrent.name as string | ||
87 | } else { | ||
88 | magnetUri = body.magnetUri | ||
89 | |||
90 | const parsed = magnetUtil.decode(magnetUri) | ||
91 | videoName = isArray(parsed.name) ? parsed.name[ 0 ] : parsed.name as string | ||
92 | } | ||
61 | 93 | ||
62 | const video = buildVideo(res.locals.videoChannel.id, body, { name: magnetName }) | 94 | const video = buildVideo(res.locals.videoChannel.id, body, { name: videoName }) |
63 | 95 | ||
64 | await processThumbnail(req, video) | 96 | await processThumbnail(req, video) |
65 | await processPreview(req, video) | 97 | await processPreview(req, video) |
@@ -67,13 +99,14 @@ async function addTorrentImport (req: express.Request, res: express.Response) { | |||
67 | const tags = null | 99 | const tags = null |
68 | const videoImportAttributes = { | 100 | const videoImportAttributes = { |
69 | magnetUri, | 101 | magnetUri, |
102 | torrentName, | ||
70 | state: VideoImportState.PENDING | 103 | state: VideoImportState.PENDING |
71 | } | 104 | } |
72 | const videoImport: VideoImportModel = await insertIntoDB(video, res.locals.videoChannel, tags, videoImportAttributes) | 105 | const videoImport: VideoImportModel = await insertIntoDB(video, res.locals.videoChannel, tags, videoImportAttributes) |
73 | 106 | ||
74 | // Create job to import the video | 107 | // Create job to import the video |
75 | const payload = { | 108 | const payload = { |
76 | type: 'magnet-uri' as 'magnet-uri', | 109 | type: torrentfile ? 'torrent-file' as 'torrent-file' : 'magnet-uri' as 'magnet-uri', |
77 | videoImportId: videoImport.id, | 110 | videoImportId: videoImport.id, |
78 | magnetUri | 111 | magnetUri |
79 | } | 112 | } |