diff options
Diffstat (limited to 'server/tools/peertube-import-videos.ts')
-rw-r--r-- | server/tools/peertube-import-videos.ts | 106 |
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' | |||
5 | import { join } from 'path' | 5 | import { join } from 'path' |
6 | import { VideoPrivacy } from '../../shared/models/videos' | 6 | import { VideoPrivacy } from '../../shared/models/videos' |
7 | import { doRequestAndSaveToFile } from '../helpers/requests' | 7 | import { doRequestAndSaveToFile } from '../helpers/requests' |
8 | import { CONSTRAINTS_FIELDS } from '../initializers' | 8 | import { CONSTRAINTS_FIELDS } from '../initializers/constants' |
9 | import { getClient, getVideoCategories, login, searchVideoWithSort, uploadVideo } from '../../shared/utils/index' | 9 | import { getClient, getVideoCategories, login, searchVideoWithSort, uploadVideo } from '../../shared/extra-utils/index' |
10 | import { truncate } from 'lodash' | 10 | import { truncate } from 'lodash' |
11 | import * as prompt from 'prompt' | 11 | import * as prompt from 'prompt' |
12 | import { remove } from 'fs-extra' | 12 | import { remove } from 'fs-extra' |
13 | import { sha256 } from '../helpers/core-utils' | 13 | import { sha256 } from '../helpers/core-utils' |
14 | import { safeGetYoutubeDL } from '../helpers/youtube-dl' | 14 | import { buildOriginallyPublishedAt, safeGetYoutubeDL } from '../helpers/youtube-dl' |
15 | import { getSettings, netrc } from './cli' | 15 | import { getNetrc, getRemoteObjectOrDie, getSettings } from './cli' |
16 | 16 | ||
17 | let accessToken: string | 17 | let accessToken: string |
18 | let client: { id: string, secret: string } | 18 | let 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 | ||
35 | getSettings() | 35 | Promise.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 | ||
88 | async function promptPassword () { | 60 | async 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 | ||
154 | function processVideo (info: any, languageCode: string, cwd: string, url: string, user) { | 126 | function 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 | |||
259 | async function getCategory (categories: string[], url: string) { | 235 | async 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 | ||