aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/helpers
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-08-06 17:13:39 +0200
committerChocobozzz <me@florianbigard.com>2018-08-08 09:30:31 +0200
commitce33919c24e7402d92d81f3cd8e545df52d98240 (patch)
tree7e131a2f8df649899d0a71294665cf386ffb50d4 /server/helpers
parent788487140c500abeb69ca44daf3a9e26efa8d36f (diff)
downloadPeerTube-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.ts9
-rw-r--r--server/helpers/utils.ts11
-rw-r--r--server/helpers/webtorrent.ts31
-rw-r--r--server/helpers/youtube-dl.ts24
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'
17import { exists, isArray, isFileValid } from './misc' 17import { exists, isArray, isFileValid } from './misc'
18import { VideoChannelModel } from '../../models/video/video-channel' 18import { VideoChannelModel } from '../../models/video/video-channel'
19import { UserModel } from '../../models/account/user' 19import { UserModel } from '../../models/account/user'
20import * as magnetUtil from 'magnet-uri'
20 21
21const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS 22const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
22const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES 23const 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
130function isVideoMagnetUriValid (value: string) {
131 if (!exists(value)) return false
132
133 const parsed = magnetUtil.decode(value)
134 return parsed && isVideoFileInfoHashValid(parsed.infoHash)
135}
136
129function checkUserCanManageVideo (user: UserModel, video: VideoModel, right: UserRight, res: Response) { 137function 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'
9import { pseudoRandomBytesPromise, unlinkPromise } from './core-utils' 9import { pseudoRandomBytesPromise, unlinkPromise } from './core-utils'
10import { logger } from './logger' 10import { logger } from './logger'
11import { isArray } from './custom-validators/misc' 11import { isArray } from './custom-validators/misc'
12import * as crypto from "crypto"
13import { join } from "path"
12 14
13const isCidr = require('is-cidr') 15const 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
186function 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
184type SortType = { sortModel: any, sortValue: string } 191type SortType = { sortModel: any, sortValue: string }
185 192
193
186// --------------------------------------------------------------------------- 194// ---------------------------------------------------------------------------
187 195
188export { 196export {
@@ -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 @@
1import { logger } from './logger'
2import { generateVideoTmpPath } from './utils'
3import * as WebTorrent from 'webtorrent'
4import { createWriteStream } from 'fs'
5
6function 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
29export {
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 @@
1import * as youtubeDL from 'youtube-dl' 1import * as youtubeDL from 'youtube-dl'
2import { truncate } from 'lodash' 2import { truncate } from 'lodash'
3import { CONFIG, CONSTRAINTS_FIELDS, VIDEO_CATEGORIES } from '../initializers' 3import { CONSTRAINTS_FIELDS, VIDEO_CATEGORIES } from '../initializers'
4import { join } from 'path'
5import * as crypto from 'crypto'
6import { logger } from './logger' 4import { logger } from './logger'
5import { generateVideoTmpPath } from './utils'
7 6
8export type YoutubeDLInfo = { 7export 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
18function getYoutubeDLInfo (url: string): Promise<YoutubeDLInfo> { 17function getYoutubeDLInfo (url: string): Promise<YoutubeDLInfo> {
@@ -30,10 +29,9 @@ function getYoutubeDLInfo (url: string): Promise<YoutubeDLInfo> {
30} 29}
31 30
32function downloadYoutubeDLVideo (url: string) { 31function 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