]>
Commit | Line | Data |
---|---|---|
a7fea183 C |
1 | import * as program from 'commander' |
2 | import { createWriteStream } from 'fs' | |
3 | import { join } from 'path' | |
4 | import { cursorTo } from 'readline' | |
5 | import * as youtubeDL from 'youtube-dl' | |
6 | import { VideoPrivacy } from '../../shared/models/videos' | |
7 | import { unlinkPromise } from '../helpers/core-utils' | |
8 | import { getClient, getVideoCategories, login, searchVideo, uploadVideo } from '../tests/utils' | |
9 | ||
10 | program | |
11 | .option('-u, --url <url>', 'Server url') | |
12 | .option('-U, --username <username>', 'Username') | |
13 | .option('-p, --password <token>', 'Password') | |
14 | .option('-y, --youtube-url <directory>', 'Youtube URL') | |
15 | .parse(process.argv) | |
16 | ||
17 | if ( | |
18 | !program['url'] || | |
19 | !program['username'] || | |
20 | !program['password'] || | |
21 | !program['youtubeUrl'] | |
22 | ) { | |
23 | throw new Error('All arguments are required.') | |
24 | } | |
25 | ||
26 | run().catch(err => console.error(err)) | |
27 | ||
28 | let accessToken: string | |
29 | ||
30 | async function run () { | |
31 | const res = await getClient(program['url']) | |
32 | const client = { | |
33 | id: res.body.client_id, | |
34 | secret: res.body.client_secret | |
35 | } | |
36 | ||
37 | const user = { | |
38 | username: program['username'], | |
39 | password: program['password'] | |
40 | } | |
41 | ||
42 | const res2 = await login(program['url'], client, user) | |
43 | accessToken = res2.body.access_token | |
44 | ||
45 | youtubeDL.getInfo(program['youtubeUrl'], [ '-j', '--flat-playlist' ], async (err, info) => { | |
46 | if (err) throw err | |
47 | ||
48 | const videos = info.map(i => { | |
49 | return { url: 'https://www.youtube.com/watch?v=' + i.id, name: i.title } | |
50 | }) | |
51 | ||
52 | console.log('Will download and upload %d videos.\n', videos.length) | |
53 | ||
54 | for (const video of videos) { | |
55 | await processVideo(video) | |
56 | } | |
57 | ||
58 | console.log('I\'m finished!') | |
59 | process.exit(0) | |
60 | }) | |
61 | } | |
62 | ||
63 | function processVideo (videoUrlName: { name: string, url: string }) { | |
64 | return new Promise(async res => { | |
65 | const result = await searchVideo(program['url'], videoUrlName.name) | |
66 | if (result.body.total !== 0) { | |
67 | console.log('Video "%s" already exist, don\'t reupload it.\n', videoUrlName.name) | |
68 | return res() | |
69 | } | |
70 | ||
71 | const video = youtubeDL(videoUrlName.url) | |
72 | let videoInfo | |
73 | let videoPath: string | |
74 | ||
75 | video.on('error', err => console.error(err)) | |
76 | ||
77 | let size = 0 | |
78 | video.on('info', info => { | |
79 | videoInfo = info | |
80 | size = info.size | |
81 | ||
82 | videoPath = join(__dirname, size + '.mp4') | |
83 | console.log('Creating "%s" of video "%s".', videoPath, videoInfo.title) | |
84 | ||
85 | video.pipe(createWriteStream(videoPath)) | |
86 | }) | |
87 | ||
88 | let pos = 0 | |
89 | video.on('data', chunk => { | |
90 | pos += chunk.length | |
91 | // `size` should not be 0 here. | |
92 | if (size) { | |
93 | const percent = (pos / size * 100).toFixed(2) | |
94 | writeWaitingPercent(percent) | |
95 | } | |
96 | }) | |
97 | ||
98 | video.on('end', async () => { | |
99 | await uploadVideoOnPeerTube(videoInfo, videoPath) | |
100 | ||
101 | return res() | |
102 | }) | |
103 | }) | |
104 | } | |
105 | ||
106 | function writeWaitingPercent (p: string) { | |
107 | cursorTo(process.stdout, 0) | |
108 | process.stdout.write(`waiting ... ${p}%`) | |
109 | } | |
110 | ||
111 | async function uploadVideoOnPeerTube (videoInfo: any, videoPath: string) { | |
112 | const category = await getCategory(videoInfo.categories) | |
113 | const licence = getLicence(videoInfo.license) | |
114 | const language = 13 | |
115 | ||
116 | const videoAttributes = { | |
117 | name: videoInfo.title, | |
118 | category, | |
119 | licence, | |
120 | language, | |
121 | nsfw: false, | |
122 | commentsEnabled: true, | |
123 | description: videoInfo.description, | |
124 | tags: videoInfo.tags.slice(0, 5), | |
125 | privacy: VideoPrivacy.PUBLIC, | |
126 | fixture: videoPath | |
127 | } | |
128 | ||
129 | console.log('\nUploading on PeerTube video "%s".', videoAttributes.name) | |
130 | await uploadVideo(program['url'], accessToken, videoAttributes) | |
131 | await unlinkPromise(videoPath) | |
132 | console.log('Uploaded video "%s"!\n', videoAttributes.name) | |
133 | } | |
134 | ||
135 | async function getCategory (categories: string[]) { | |
136 | const categoryString = categories[0] | |
137 | ||
138 | if (categoryString === 'News & Politics') return 11 | |
139 | ||
140 | const res = await getVideoCategories(program['url']) | |
141 | const categoriesServer = res.body | |
142 | ||
143 | for (const key of Object.keys(categoriesServer)) { | |
144 | const categoryServer = categoriesServer[key] | |
145 | if (categoryString.toLowerCase() === categoryServer.toLowerCase()) return parseInt(key, 10) | |
146 | } | |
147 | ||
148 | return undefined | |
149 | } | |
150 | ||
151 | function getLicence (licence: string) { | |
152 | if (licence.indexOf('Creative Commons Attribution licence') !== -1) return 1 | |
153 | ||
154 | return undefined | |
155 | } |