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.ts83
1 files changed, 41 insertions, 42 deletions
diff --git a/server/tools/peertube-import-videos.ts b/server/tools/peertube-import-videos.ts
index c7e85b570..0efe87810 100644
--- a/server/tools/peertube-import-videos.ts
+++ b/server/tools/peertube-import-videos.ts
@@ -12,7 +12,7 @@ import { accessSync, constants } from 'fs'
12import { remove } from 'fs-extra' 12import { remove } from 'fs-extra'
13import { sha256 } from '../helpers/core-utils' 13import { sha256 } from '../helpers/core-utils'
14import { buildOriginallyPublishedAt, safeGetYoutubeDL } from '../helpers/youtube-dl' 14import { buildOriginallyPublishedAt, safeGetYoutubeDL } from '../helpers/youtube-dl'
15import { buildCommonVideoOptions, buildVideoAttributesFromCommander, getServerCredentials, getLogger } from './cli' 15import { buildCommonVideoOptions, buildVideoAttributesFromCommander, getLogger, getServerCredentials } from './cli'
16 16
17type UserInfo = { 17type UserInfo = {
18 username: string 18 username: string
@@ -40,30 +40,29 @@ command
40 .option('-T, --tmpdir <tmpdir>', 'Working directory', __dirname) 40 .option('-T, --tmpdir <tmpdir>', 'Working directory', __dirname)
41 .parse(process.argv) 41 .parse(process.argv)
42 42
43let log = getLogger(program[ 'verbose' ]) 43const log = getLogger(program['verbose'])
44 44
45getServerCredentials(command) 45getServerCredentials(command)
46 .then(({ url, username, password }) => { 46 .then(({ url, username, password }) => {
47 if (!program[ 'targetUrl' ]) { 47 if (!program['targetUrl']) {
48 exitError('--target-url field is required.') 48 exitError('--target-url field is required.')
49 } 49 }
50 50
51 try { 51 try {
52 accessSync(program[ 'tmpdir' ], constants.R_OK | constants.W_OK) 52 accessSync(program['tmpdir'], constants.R_OK | constants.W_OK)
53 } catch (e) { 53 } catch (e) {
54 exitError('--tmpdir %s: directory does not exist or is not accessible', program[ 'tmpdir' ]) 54 exitError('--tmpdir %s: directory does not exist or is not accessible', program['tmpdir'])
55 } 55 }
56 56
57 url = normalizeTargetUrl(url) 57 url = normalizeTargetUrl(url)
58 program[ 'targetUrl' ] = normalizeTargetUrl(program[ 'targetUrl' ]) 58 program['targetUrl'] = normalizeTargetUrl(program['targetUrl'])
59 59
60 const user = { username, password } 60 const user = { username, password }
61 61
62 run(url, user) 62 run(url, user)
63 .catch(err => { 63 .catch(err => exitError(err))
64 exitError(err)
65 })
66 }) 64 })
65 .catch(err => console.error(err))
67 66
68async function run (url: string, user: UserInfo) { 67async function run (url: string, user: UserInfo) {
69 if (!user.password) { 68 if (!user.password) {
@@ -73,7 +72,7 @@ async function run (url: string, user: UserInfo) {
73 const youtubeDL = await safeGetYoutubeDL() 72 const youtubeDL = await safeGetYoutubeDL()
74 73
75 const options = [ '-j', '--flat-playlist', '--playlist-reverse' ] 74 const options = [ '-j', '--flat-playlist', '--playlist-reverse' ]
76 youtubeDL.getInfo(program[ 'targetUrl' ], options, processOptions, async (err, info) => { 75 youtubeDL.getInfo(program['targetUrl'], options, processOptions, async (err, info) => {
77 if (err) { 76 if (err) {
78 exitError(err.message) 77 exitError(err.message)
79 } 78 }
@@ -82,10 +81,10 @@ async function run (url: string, user: UserInfo) {
82 81
83 // Normalize utf8 fields 82 // Normalize utf8 fields
84 infoArray = [].concat(info) 83 infoArray = [].concat(info)
85 if (program[ 'first' ]) { 84 if (program['first']) {
86 infoArray = infoArray.slice(0, program[ 'first' ]) 85 infoArray = infoArray.slice(0, program['first'])
87 } else if (program[ 'last' ]) { 86 } else if (program['last']) {
88 infoArray = infoArray.slice(-program[ 'last' ]) 87 infoArray = infoArray.slice(-program['last'])
89 } 88 }
90 infoArray = infoArray.map(i => normalizeObject(i)) 89 infoArray = infoArray.map(i => normalizeObject(i))
91 90
@@ -93,22 +92,22 @@ async function run (url: string, user: UserInfo) {
93 92
94 for (const info of infoArray) { 93 for (const info of infoArray) {
95 await processVideo({ 94 await processVideo({
96 cwd: program[ 'tmpdir' ], 95 cwd: program['tmpdir'],
97 url, 96 url,
98 user, 97 user,
99 youtubeInfo: info 98 youtubeInfo: info
100 }) 99 })
101 } 100 }
102 101
103 log.info('Video/s for user %s imported: %s', user.username, program[ 'targetUrl' ]) 102 log.info('Video/s for user %s imported: %s', user.username, program['targetUrl'])
104 process.exit(0) 103 process.exit(0)
105 }) 104 })
106} 105}
107 106
108function processVideo (parameters: { 107function processVideo (parameters: {
109 cwd: string, 108 cwd: string
110 url: string, 109 url: string
111 user: { username: string, password: string }, 110 user: { username: string, password: string }
112 youtubeInfo: any 111 youtubeInfo: any
113}) { 112}) {
114 const { youtubeInfo, cwd, url, user } = parameters 113 const { youtubeInfo, cwd, url, user } = parameters
@@ -119,17 +118,17 @@ function processVideo (parameters: {
119 const videoInfo = await fetchObject(youtubeInfo) 118 const videoInfo = await fetchObject(youtubeInfo)
120 log.debug('Fetched object.', videoInfo) 119 log.debug('Fetched object.', videoInfo)
121 120
122 if (program[ 'since' ]) { 121 if (program['since']) {
123 if (buildOriginallyPublishedAt(videoInfo).getTime() < program[ 'since' ].getTime()) { 122 if (buildOriginallyPublishedAt(videoInfo).getTime() < program['since'].getTime()) {
124 log.info('Video "%s" has been published before "%s", don\'t upload it.\n', 123 log.info('Video "%s" has been published before "%s", don\'t upload it.\n',
125 videoInfo.title, formatDate(program[ 'since' ])) 124 videoInfo.title, formatDate(program['since']))
126 return res() 125 return res()
127 } 126 }
128 } 127 }
129 if (program[ 'until' ]) { 128 if (program['until']) {
130 if (buildOriginallyPublishedAt(videoInfo).getTime() > program[ 'until' ].getTime()) { 129 if (buildOriginallyPublishedAt(videoInfo).getTime() > program['until'].getTime()) {
131 log.info('Video "%s" has been published after "%s", don\'t upload it.\n', 130 log.info('Video "%s" has been published after "%s", don\'t upload it.\n',
132 videoInfo.title, formatDate(program[ 'until' ])) 131 videoInfo.title, formatDate(program['until']))
133 return res() 132 return res()
134 } 133 }
135 } 134 }
@@ -174,11 +173,11 @@ function processVideo (parameters: {
174} 173}
175 174
176async function uploadVideoOnPeerTube (parameters: { 175async function uploadVideoOnPeerTube (parameters: {
177 videoInfo: any, 176 videoInfo: any
178 videoPath: string, 177 videoPath: string
179 cwd: string, 178 cwd: string
180 url: string, 179 url: string
181 user: { username: string; password: string } 180 user: { username: string, password: string }
182}) { 181}) {
183 const { videoInfo, videoPath, cwd, url, user } = parameters 182 const { videoInfo, videoPath, cwd, url, user } = parameters
184 183
@@ -206,9 +205,9 @@ async function uploadVideoOnPeerTube (parameters: {
206 205
207 const defaultAttributes = { 206 const defaultAttributes = {
208 name: truncate(videoInfo.title, { 207 name: truncate(videoInfo.title, {
209 'length': CONSTRAINTS_FIELDS.VIDEOS.NAME.max, 208 length: CONSTRAINTS_FIELDS.VIDEOS.NAME.max,
210 'separator': /,? +/, 209 separator: /,? +/,
211 'omission': ' […]' 210 omission: ' […]'
212 }), 211 }),
213 category, 212 category,
214 licence, 213 licence,
@@ -255,7 +254,7 @@ async function uploadVideoOnPeerTube (parameters: {
255async function getCategory (categories: string[], url: string) { 254async function getCategory (categories: string[], url: string) {
256 if (!categories) return undefined 255 if (!categories) return undefined
257 256
258 const categoryString = categories[ 0 ] 257 const categoryString = categories[0]
259 258
260 if (categoryString === 'News & Politics') return 11 259 if (categoryString === 'News & Politics') return 11
261 260
@@ -263,7 +262,7 @@ async function getCategory (categories: string[], url: string) {
263 const categoriesServer = res.body 262 const categoriesServer = res.body
264 263
265 for (const key of Object.keys(categoriesServer)) { 264 for (const key of Object.keys(categoriesServer)) {
266 const categoryServer = categoriesServer[ key ] 265 const categoryServer = categoriesServer[key]
267 if (categoryString.toLowerCase() === categoryServer.toLowerCase()) return parseInt(key, 10) 266 if (categoryString.toLowerCase() === categoryServer.toLowerCase()) return parseInt(key, 10)
268 } 267 }
269 268
@@ -285,12 +284,12 @@ function normalizeObject (obj: any) {
285 // Deprecated key 284 // Deprecated key
286 if (key === 'resolution') continue 285 if (key === 'resolution') continue
287 286
288 const value = obj[ key ] 287 const value = obj[key]
289 288
290 if (typeof value === 'string') { 289 if (typeof value === 'string') {
291 newObj[ key ] = value.normalize() 290 newObj[key] = value.normalize()
292 } else { 291 } else {
293 newObj[ key ] = value 292 newObj[key] = value
294 } 293 }
295 } 294 }
296 295
@@ -302,7 +301,7 @@ function fetchObject (info: any) {
302 301
303 return new Promise<any>(async (res, rej) => { 302 return new Promise<any>(async (res, rej) => {
304 const youtubeDL = await safeGetYoutubeDL() 303 const youtubeDL = await safeGetYoutubeDL()
305 youtubeDL.getInfo(url, undefined, processOptions, async (err, videoInfo) => { 304 youtubeDL.getInfo(url, undefined, processOptions, (err, videoInfo) => {
306 if (err) return rej(err) 305 if (err) return rej(err)
307 306
308 const videoInfoWithUrl = Object.assign(videoInfo, { url }) 307 const videoInfoWithUrl = Object.assign(videoInfo, { url })
@@ -313,10 +312,10 @@ function fetchObject (info: any) {
313 312
314function buildUrl (info: any) { 313function buildUrl (info: any) {
315 const webpageUrl = info.webpage_url as string 314 const webpageUrl = info.webpage_url as string
316 if (webpageUrl && webpageUrl.match(/^https?:\/\//)) return webpageUrl 315 if (webpageUrl?.match(/^https?:\/\//)) return webpageUrl
317 316
318 const url = info.url as string 317 const url = info.url as string
319 if (url && url.match(/^https?:\/\//)) return url 318 if (url?.match(/^https?:\/\//)) return url
320 319
321 // It seems youtube-dl does not return the video url 320 // It seems youtube-dl does not return the video url
322 return 'https://www.youtube.com/watch?v=' + info.id 321 return 'https://www.youtube.com/watch?v=' + info.id
@@ -384,7 +383,7 @@ function parseDate (dateAsStr: string): Date {
384} 383}
385 384
386function formatDate (date: Date): string { 385function formatDate (date: Date): string {
387 return date.toISOString().split('T')[ 0 ] 386 return date.toISOString().split('T')[0]
388} 387}
389 388
390function exitError (message: string, ...meta: any[]) { 389function exitError (message: string, ...meta: any[]) {