aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tools/peertube-import-videos.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/tools/peertube-import-videos.ts')
-rw-r--r--server/tools/peertube-import-videos.ts106
1 files changed, 41 insertions, 65 deletions
diff --git a/server/tools/peertube-import-videos.ts b/server/tools/peertube-import-videos.ts
index f50aafc35..9a366dbbd 100644
--- a/server/tools/peertube-import-videos.ts
+++ b/server/tools/peertube-import-videos.ts
@@ -5,14 +5,14 @@ import * as program from 'commander'
5import { join } from 'path' 5import { join } from 'path'
6import { VideoPrivacy } from '../../shared/models/videos' 6import { VideoPrivacy } from '../../shared/models/videos'
7import { doRequestAndSaveToFile } from '../helpers/requests' 7import { doRequestAndSaveToFile } from '../helpers/requests'
8import { CONSTRAINTS_FIELDS } from '../initializers' 8import { CONSTRAINTS_FIELDS } from '../initializers/constants'
9import { getClient, getVideoCategories, login, searchVideoWithSort, uploadVideo } from '../../shared/utils/index' 9import { getClient, getVideoCategories, login, searchVideoWithSort, uploadVideo } from '../../shared/extra-utils/index'
10import { truncate } from 'lodash' 10import { truncate } from 'lodash'
11import * as prompt from 'prompt' 11import * as prompt from 'prompt'
12import { remove } from 'fs-extra' 12import { remove } from 'fs-extra'
13import { sha256 } from '../helpers/core-utils' 13import { sha256 } from '../helpers/core-utils'
14import { safeGetYoutubeDL } from '../helpers/youtube-dl' 14import { buildOriginallyPublishedAt, safeGetYoutubeDL } from '../helpers/youtube-dl'
15import { getSettings, netrc } from './cli' 15import { getNetrc, getRemoteObjectOrDie, getSettings } from './cli'
16 16
17let accessToken: string 17let accessToken: string
18let client: { id: string, secret: string } 18let client: { id: string, secret: string }
@@ -32,58 +32,30 @@ program
32 .option('-v, --verbose', 'Verbose mode') 32 .option('-v, --verbose', 'Verbose mode')
33 .parse(process.argv) 33 .parse(process.argv)
34 34
35getSettings() 35Promise.all([ getSettings(), getNetrc() ])
36.then(settings => { 36 .then(([ settings, netrc ]) => {
37 if ( 37 const { url, username, password } = getRemoteObjectOrDie(program, settings)
38 (!program['url'] ||
39 !program['username'] ||
40 !program['password']) &&
41 (settings.remotes.length === 0)
42 ) {
43 if (!program['url']) console.error('--url field is required.')
44 if (!program['username']) console.error('--username field is required.')
45 if (!program['password']) console.error('--password field is required.')
46 if (!program['targetUrl']) console.error('--targetUrl field is required.')
47 process.exit(-1)
48 }
49
50 if (
51 (!program['url'] ||
52 !program['username'] ||
53 !program['password']) &&
54 (settings.remotes.length > 0)
55 ) {
56 if (!program['url']) {
57 program['url'] = (settings.default !== -1) ?
58 settings.remotes[settings.default] :
59 settings.remotes[0]
60 }
61 38
62 if (!program['username']) program['username'] = netrc.machines[program['url']].login 39 if (!program[ 'targetUrl' ]) {
63 if (!program['password']) program['password'] = netrc.machines[program['url']].password 40 console.error('--targetUrl field is required.')
64 }
65 41
66 if ( 42 process.exit(-1)
67 !program['targetUrl'] 43 }
68 ) {
69 if (!program['targetUrl']) console.error('--targetUrl field is required.')
70 process.exit(-1)
71 }
72 44
73 removeEndSlashes(program['url']) 45 removeEndSlashes(url)
74 removeEndSlashes(program['targetUrl']) 46 removeEndSlashes(program[ 'targetUrl' ])
75 47
76 const user = { 48 const user = {
77 username: program['username'], 49 username: username,
78 password: program['password'] 50 password: password
79 } 51 }
80 52
81 run(user, program['url']) 53 run(user, url)
82 .catch(err => { 54 .catch(err => {
83 console.error(err) 55 console.error(err)
84 process.exit(-1) 56 process.exit(-1)
85 }) 57 })
86}) 58 })
87 59
88async function promptPassword () { 60async function promptPassword () {
89 return new Promise((res, rej) => { 61 return new Promise((res, rej) => {
@@ -126,7 +98,7 @@ async function run (user, url: string) {
126 const youtubeDL = await safeGetYoutubeDL() 98 const youtubeDL = await safeGetYoutubeDL()
127 99
128 const options = [ '-j', '--flat-playlist', '--playlist-reverse' ] 100 const options = [ '-j', '--flat-playlist', '--playlist-reverse' ]
129 youtubeDL.getInfo(program['targetUrl'], options, processOptions, async (err, info) => { 101 youtubeDL.getInfo(program[ 'targetUrl' ], options, processOptions, async (err, info) => {
130 if (err) { 102 if (err) {
131 console.log(err.message) 103 console.log(err.message)
132 process.exit(1) 104 process.exit(1)
@@ -143,20 +115,20 @@ async function run (user, url: string) {
143 console.log('Will download and upload %d videos.\n', infoArray.length) 115 console.log('Will download and upload %d videos.\n', infoArray.length)
144 116
145 for (const info of infoArray) { 117 for (const info of infoArray) {
146 await processVideo(info, program['language'], processOptions.cwd, url, user) 118 await processVideo(info, program[ 'language' ], processOptions.cwd, url, user)
147 } 119 }
148 120
149 console.log('Video/s for user %s imported: %s', program['username'], program['targetUrl']) 121 console.log('Video/s for user %s imported: %s', program[ 'username' ], program[ 'targetUrl' ])
150 process.exit(0) 122 process.exit(0)
151 }) 123 })
152} 124}
153 125
154function processVideo (info: any, languageCode: string, cwd: string, url: string, user) { 126function processVideo (info: any, languageCode: string, cwd: string, url: string, user) {
155 return new Promise(async res => { 127 return new Promise(async res => {
156 if (program['verbose']) console.log('Fetching object.', info) 128 if (program[ 'verbose' ]) console.log('Fetching object.', info)
157 129
158 const videoInfo = await fetchObject(info) 130 const videoInfo = await fetchObject(info)
159 if (program['verbose']) console.log('Fetched object.', videoInfo) 131 if (program[ 'verbose' ]) console.log('Fetched object.', videoInfo)
160 132
161 const result = await searchVideoWithSort(url, videoInfo.title, '-match') 133 const result = await searchVideoWithSort(url, videoInfo.title, '-match')
162 134
@@ -197,9 +169,9 @@ async function uploadVideoOnPeerTube (videoInfo: any, videoPath: string, cwd: st
197 let tags = [] 169 let tags = []
198 if (Array.isArray(videoInfo.tags)) { 170 if (Array.isArray(videoInfo.tags)) {
199 tags = videoInfo.tags 171 tags = videoInfo.tags
200 .filter(t => t.length < CONSTRAINTS_FIELDS.VIDEOS.TAG.max && t.length > CONSTRAINTS_FIELDS.VIDEOS.TAG.min) 172 .filter(t => t.length < CONSTRAINTS_FIELDS.VIDEOS.TAG.max && t.length > CONSTRAINTS_FIELDS.VIDEOS.TAG.min)
201 .map(t => t.normalize()) 173 .map(t => t.normalize())
202 .slice(0, 5) 174 .slice(0, 5)
203 } 175 }
204 176
205 let thumbnailfile 177 let thumbnailfile
@@ -212,6 +184,8 @@ async function uploadVideoOnPeerTube (videoInfo: any, videoPath: string, cwd: st
212 }, thumbnailfile) 184 }, thumbnailfile)
213 } 185 }
214 186
187 const originallyPublishedAt = buildOriginallyPublishedAt(videoInfo)
188
215 const videoAttributes = { 189 const videoAttributes = {
216 name: truncate(videoInfo.title, { 190 name: truncate(videoInfo.title, {
217 'length': CONSTRAINTS_FIELDS.VIDEOS.NAME.max, 191 'length': CONSTRAINTS_FIELDS.VIDEOS.NAME.max,
@@ -224,13 +198,15 @@ async function uploadVideoOnPeerTube (videoInfo: any, videoPath: string, cwd: st
224 nsfw: isNSFW(videoInfo), 198 nsfw: isNSFW(videoInfo),
225 waitTranscoding: true, 199 waitTranscoding: true,
226 commentsEnabled: true, 200 commentsEnabled: true,
201 downloadEnabled: true,
227 description: videoInfo.description || undefined, 202 description: videoInfo.description || undefined,
228 support: undefined, 203 support: undefined,
229 tags, 204 tags,
230 privacy: VideoPrivacy.PUBLIC, 205 privacy: VideoPrivacy.PUBLIC,
231 fixture: videoPath, 206 fixture: videoPath,
232 thumbnailfile, 207 thumbnailfile,
233 previewfile: thumbnailfile 208 previewfile: thumbnailfile,
209 originallyPublishedAt: originallyPublishedAt ? originallyPublishedAt.toISOString() : null
234 } 210 }
235 211
236 console.log('\nUploading on PeerTube video "%s".', videoAttributes.name) 212 console.log('\nUploading on PeerTube video "%s".', videoAttributes.name)
@@ -259,7 +235,7 @@ async function uploadVideoOnPeerTube (videoInfo: any, videoPath: string, cwd: st
259async function getCategory (categories: string[], url: string) { 235async function getCategory (categories: string[], url: string) {
260 if (!categories) return undefined 236 if (!categories) return undefined
261 237
262 const categoryString = categories[0] 238 const categoryString = categories[ 0 ]
263 239
264 if (categoryString === 'News & Politics') return 11 240 if (categoryString === 'News & Politics') return 11
265 241
@@ -267,7 +243,7 @@ async function getCategory (categories: string[], url: string) {
267 const categoriesServer = res.body 243 const categoriesServer = res.body
268 244
269 for (const key of Object.keys(categoriesServer)) { 245 for (const key of Object.keys(categoriesServer)) {
270 const categoryServer = categoriesServer[key] 246 const categoryServer = categoriesServer[ key ]
271 if (categoryString.toLowerCase() === categoryServer.toLowerCase()) return parseInt(key, 10) 247 if (categoryString.toLowerCase() === categoryServer.toLowerCase()) return parseInt(key, 10)
272 } 248 }
273 249
@@ -291,12 +267,12 @@ function normalizeObject (obj: any) {
291 // Deprecated key 267 // Deprecated key
292 if (key === 'resolution') continue 268 if (key === 'resolution') continue
293 269
294 const value = obj[key] 270 const value = obj[ key ]
295 271
296 if (typeof value === 'string') { 272 if (typeof value === 'string') {
297 newObj[key] = value.normalize() 273 newObj[ key ] = value.normalize()
298 } else { 274 } else {
299 newObj[key] = value 275 newObj[ key ] = value
300 } 276 }
301 } 277 }
302 278