diff options
author | Chocobozzz <me@florianbigard.com> | 2018-08-06 17:13:39 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-08-08 09:30:31 +0200 |
commit | ce33919c24e7402d92d81f3cd8e545df52d98240 (patch) | |
tree | 7e131a2f8df649899d0a71294665cf386ffb50d4 /server/helpers | |
parent | 788487140c500abeb69ca44daf3a9e26efa8d36f (diff) | |
download | PeerTube-ce33919c24e7402d92d81f3cd8e545df52d98240.tar.gz PeerTube-ce33919c24e7402d92d81f3cd8e545df52d98240.tar.zst PeerTube-ce33919c24e7402d92d81f3cd8e545df52d98240.zip |
Import magnets with webtorrent
Diffstat (limited to 'server/helpers')
-rw-r--r-- | server/helpers/custom-validators/videos.ts | 9 | ||||
-rw-r--r-- | server/helpers/utils.ts | 11 | ||||
-rw-r--r-- | server/helpers/webtorrent.ts | 31 | ||||
-rw-r--r-- | server/helpers/youtube-dl.ts | 24 |
4 files changed, 61 insertions, 14 deletions
diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts index 338c96582..f4c1c8b07 100644 --- a/server/helpers/custom-validators/videos.ts +++ b/server/helpers/custom-validators/videos.ts | |||
@@ -17,6 +17,7 @@ import { VideoModel } from '../../models/video/video' | |||
17 | import { exists, isArray, isFileValid } from './misc' | 17 | import { exists, isArray, isFileValid } from './misc' |
18 | import { VideoChannelModel } from '../../models/video/video-channel' | 18 | import { VideoChannelModel } from '../../models/video/video-channel' |
19 | import { UserModel } from '../../models/account/user' | 19 | import { UserModel } from '../../models/account/user' |
20 | import * as magnetUtil from 'magnet-uri' | ||
20 | 21 | ||
21 | const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS | 22 | const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS |
22 | const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES | 23 | const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES |
@@ -126,6 +127,13 @@ function isVideoFileSizeValid (value: string) { | |||
126 | return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE) | 127 | return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE) |
127 | } | 128 | } |
128 | 129 | ||
130 | function isVideoMagnetUriValid (value: string) { | ||
131 | if (!exists(value)) return false | ||
132 | |||
133 | const parsed = magnetUtil.decode(value) | ||
134 | return parsed && isVideoFileInfoHashValid(parsed.infoHash) | ||
135 | } | ||
136 | |||
129 | function checkUserCanManageVideo (user: UserModel, video: VideoModel, right: UserRight, res: Response) { | 137 | function checkUserCanManageVideo (user: UserModel, video: VideoModel, right: UserRight, res: Response) { |
130 | // Retrieve the user who did the request | 138 | // Retrieve the user who did the request |
131 | if (video.isOwned() === false) { | 139 | if (video.isOwned() === false) { |
@@ -214,6 +222,7 @@ export { | |||
214 | isScheduleVideoUpdatePrivacyValid, | 222 | isScheduleVideoUpdatePrivacyValid, |
215 | isVideoAbuseReasonValid, | 223 | isVideoAbuseReasonValid, |
216 | isVideoFile, | 224 | isVideoFile, |
225 | isVideoMagnetUriValid, | ||
217 | isVideoStateValid, | 226 | isVideoStateValid, |
218 | isVideoViewsValid, | 227 | isVideoViewsValid, |
219 | isVideoRatingTypeValid, | 228 | isVideoRatingTypeValid, |
diff --git a/server/helpers/utils.ts b/server/helpers/utils.ts index 7abcec5d7..f4cc5547d 100644 --- a/server/helpers/utils.ts +++ b/server/helpers/utils.ts | |||
@@ -9,6 +9,8 @@ import { ApplicationModel } from '../models/application/application' | |||
9 | import { pseudoRandomBytesPromise, unlinkPromise } from './core-utils' | 9 | import { pseudoRandomBytesPromise, unlinkPromise } from './core-utils' |
10 | import { logger } from './logger' | 10 | import { logger } from './logger' |
11 | import { isArray } from './custom-validators/misc' | 11 | import { isArray } from './custom-validators/misc' |
12 | import * as crypto from "crypto" | ||
13 | import { join } from "path" | ||
12 | 14 | ||
13 | const isCidr = require('is-cidr') | 15 | const isCidr = require('is-cidr') |
14 | 16 | ||
@@ -181,8 +183,14 @@ async function getServerActor () { | |||
181 | return Promise.resolve(serverActor) | 183 | return Promise.resolve(serverActor) |
182 | } | 184 | } |
183 | 185 | ||
186 | function generateVideoTmpPath (id: string) { | ||
187 | const hash = crypto.createHash('sha256').update(id).digest('hex') | ||
188 | return join(CONFIG.STORAGE.VIDEOS_DIR, hash + '-import.mp4') | ||
189 | } | ||
190 | |||
184 | type SortType = { sortModel: any, sortValue: string } | 191 | type SortType = { sortModel: any, sortValue: string } |
185 | 192 | ||
193 | |||
186 | // --------------------------------------------------------------------------- | 194 | // --------------------------------------------------------------------------- |
187 | 195 | ||
188 | export { | 196 | export { |
@@ -195,5 +203,6 @@ export { | |||
195 | computeResolutionsToTranscode, | 203 | computeResolutionsToTranscode, |
196 | resetSequelizeInstance, | 204 | resetSequelizeInstance, |
197 | getServerActor, | 205 | getServerActor, |
198 | SortType | 206 | SortType, |
207 | generateVideoTmpPath | ||
199 | } | 208 | } |
diff --git a/server/helpers/webtorrent.ts b/server/helpers/webtorrent.ts new file mode 100644 index 000000000..fce88a1f6 --- /dev/null +++ b/server/helpers/webtorrent.ts | |||
@@ -0,0 +1,31 @@ | |||
1 | import { logger } from './logger' | ||
2 | import { generateVideoTmpPath } from './utils' | ||
3 | import * as WebTorrent from 'webtorrent' | ||
4 | import { createWriteStream } from 'fs' | ||
5 | |||
6 | function downloadWebTorrentVideo (target: string) { | ||
7 | const path = generateVideoTmpPath(target) | ||
8 | |||
9 | logger.info('Importing torrent video %s', target) | ||
10 | |||
11 | return new Promise<string>((res, rej) => { | ||
12 | const webtorrent = new WebTorrent() | ||
13 | |||
14 | const torrent = webtorrent.add(target, torrent => { | ||
15 | if (torrent.files.length !== 1) throw new Error('The number of files is not equal to 1 for ' + target) | ||
16 | |||
17 | const file = torrent.files[ 0 ] | ||
18 | file.createReadStream().pipe(createWriteStream(path)) | ||
19 | }) | ||
20 | |||
21 | torrent.on('done', () => res(path)) | ||
22 | |||
23 | torrent.on('error', err => rej(err)) | ||
24 | }) | ||
25 | } | ||
26 | |||
27 | // --------------------------------------------------------------------------- | ||
28 | |||
29 | export { | ||
30 | downloadWebTorrentVideo | ||
31 | } | ||
diff --git a/server/helpers/youtube-dl.ts b/server/helpers/youtube-dl.ts index c59ab9de0..77986f407 100644 --- a/server/helpers/youtube-dl.ts +++ b/server/helpers/youtube-dl.ts | |||
@@ -1,18 +1,17 @@ | |||
1 | import * as youtubeDL from 'youtube-dl' | 1 | import * as youtubeDL from 'youtube-dl' |
2 | import { truncate } from 'lodash' | 2 | import { truncate } from 'lodash' |
3 | import { CONFIG, CONSTRAINTS_FIELDS, VIDEO_CATEGORIES } from '../initializers' | 3 | import { CONSTRAINTS_FIELDS, VIDEO_CATEGORIES } from '../initializers' |
4 | import { join } from 'path' | ||
5 | import * as crypto from 'crypto' | ||
6 | import { logger } from './logger' | 4 | import { logger } from './logger' |
5 | import { generateVideoTmpPath } from './utils' | ||
7 | 6 | ||
8 | export type YoutubeDLInfo = { | 7 | export type YoutubeDLInfo = { |
9 | name: string | 8 | name?: string |
10 | description: string | 9 | description?: string |
11 | category: number | 10 | category?: number |
12 | licence: number | 11 | licence?: number |
13 | nsfw: boolean | 12 | nsfw?: boolean |
14 | tags: string[] | 13 | tags?: string[] |
15 | thumbnailUrl: string | 14 | thumbnailUrl?: string |
16 | } | 15 | } |
17 | 16 | ||
18 | function getYoutubeDLInfo (url: string): Promise<YoutubeDLInfo> { | 17 | function getYoutubeDLInfo (url: string): Promise<YoutubeDLInfo> { |
@@ -30,10 +29,9 @@ function getYoutubeDLInfo (url: string): Promise<YoutubeDLInfo> { | |||
30 | } | 29 | } |
31 | 30 | ||
32 | function downloadYoutubeDLVideo (url: string) { | 31 | function downloadYoutubeDLVideo (url: string) { |
33 | const hash = crypto.createHash('sha256').update(url).digest('hex') | 32 | const path = generateVideoTmpPath(url) |
34 | const path = join(CONFIG.STORAGE.VIDEOS_DIR, hash + '-import.mp4') | ||
35 | 33 | ||
36 | logger.info('Importing video %s', url) | 34 | logger.info('Importing youtubeDL video %s', url) |
37 | 35 | ||
38 | const options = [ '-f', 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best', '-o', path ] | 36 | const options = [ '-f', 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best', '-o', path ] |
39 | 37 | ||