aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tools
diff options
context:
space:
mode:
Diffstat (limited to 'server/tools')
-rw-r--r--server/tools/cli.ts52
-rw-r--r--server/tools/peertube-auth.ts20
-rw-r--r--server/tools/peertube-get-access-token.ts22
-rw-r--r--server/tools/peertube-import-videos.ts44
-rw-r--r--server/tools/peertube-plugins.ts45
-rw-r--r--server/tools/peertube-redundancy.ts25
-rw-r--r--server/tools/peertube-repl.ts1
-rw-r--r--server/tools/peertube-upload.ts22
-rw-r--r--server/tools/peertube-watch.ts38
-rw-r--r--server/tools/peertube.ts17
10 files changed, 141 insertions, 145 deletions
diff --git a/server/tools/cli.ts b/server/tools/cli.ts
index d5416fc38..cc89fe46e 100644
--- a/server/tools/cli.ts
+++ b/server/tools/cli.ts
@@ -69,23 +69,25 @@ function deleteSettings () {
69} 69}
70 70
71function getRemoteObjectOrDie ( 71function getRemoteObjectOrDie (
72 program: any, 72 program: CommanderStatic,
73 settings: Settings, 73 settings: Settings,
74 netrc: Netrc 74 netrc: Netrc
75): { url: string, username: string, password: string } { 75): { url: string, username: string, password: string } {
76 if (!program['url'] || !program['username'] || !program['password']) { 76 const options = program.opts()
77
78 if (!options.url || !options.username || !options.password) {
77 // No remote and we don't have program parameters: quit 79 // No remote and we don't have program parameters: quit
78 if (settings.remotes.length === 0 || Object.keys(netrc.machines).length === 0) { 80 if (settings.remotes.length === 0 || Object.keys(netrc.machines).length === 0) {
79 if (!program['url']) console.error('--url field is required.') 81 if (!options.url) console.error('--url field is required.')
80 if (!program['username']) console.error('--username field is required.') 82 if (!options.username) console.error('--username field is required.')
81 if (!program['password']) console.error('--password field is required.') 83 if (!options.password) console.error('--password field is required.')
82 84
83 return process.exit(-1) 85 return process.exit(-1)
84 } 86 }
85 87
86 let url: string = program['url'] 88 let url: string = options.url
87 let username: string = program['username'] 89 let username: string = options.username
88 let password: string = program['password'] 90 let password: string = options.password
89 91
90 if (!url && settings.default !== -1) url = settings.remotes[settings.default] 92 if (!url && settings.default !== -1) url = settings.remotes[settings.default]
91 93
@@ -98,9 +100,9 @@ function getRemoteObjectOrDie (
98 } 100 }
99 101
100 return { 102 return {
101 url: program['url'], 103 url: options.url,
102 username: program['username'], 104 username: options.username,
103 password: program['password'] 105 password: options.password
104 } 106 }
105} 107}
106 108
@@ -127,6 +129,8 @@ function buildCommonVideoOptions (command: CommanderStatic) {
127} 129}
128 130
129async function buildVideoAttributesFromCommander (url: string, command: CommanderStatic, defaultAttributes: any = {}) { 131async function buildVideoAttributesFromCommander (url: string, command: CommanderStatic, defaultAttributes: any = {}) {
132 const options = command.opts()
133
130 const defaultBooleanAttributes = { 134 const defaultBooleanAttributes = {
131 nsfw: false, 135 nsfw: false,
132 commentsEnabled: true, 136 commentsEnabled: true,
@@ -137,8 +141,8 @@ async function buildVideoAttributesFromCommander (url: string, command: Commande
137 const booleanAttributes: { [id in keyof typeof defaultBooleanAttributes]: boolean } | {} = {} 141 const booleanAttributes: { [id in keyof typeof defaultBooleanAttributes]: boolean } | {} = {}
138 142
139 for (const key of Object.keys(defaultBooleanAttributes)) { 143 for (const key of Object.keys(defaultBooleanAttributes)) {
140 if (command[key] !== undefined) { 144 if (options[key] !== undefined) {
141 booleanAttributes[key] = command[key] 145 booleanAttributes[key] = options[key]
142 } else if (defaultAttributes[key] !== undefined) { 146 } else if (defaultAttributes[key] !== undefined) {
143 booleanAttributes[key] = defaultAttributes[key] 147 booleanAttributes[key] = defaultAttributes[key]
144 } else { 148 } else {
@@ -147,20 +151,20 @@ async function buildVideoAttributesFromCommander (url: string, command: Commande
147 } 151 }
148 152
149 const videoAttributes = { 153 const videoAttributes = {
150 name: command['videoName'] || defaultAttributes.name, 154 name: options.videoName || defaultAttributes.name,
151 category: command['category'] || defaultAttributes.category || undefined, 155 category: options.category || defaultAttributes.category || undefined,
152 licence: command['licence'] || defaultAttributes.licence || undefined, 156 licence: options.licence || defaultAttributes.licence || undefined,
153 language: command['language'] || defaultAttributes.language || undefined, 157 language: options.language || defaultAttributes.language || undefined,
154 privacy: command['privacy'] || defaultAttributes.privacy || VideoPrivacy.PUBLIC, 158 privacy: options.privacy || defaultAttributes.privacy || VideoPrivacy.PUBLIC,
155 support: command['support'] || defaultAttributes.support || undefined, 159 support: options.support || defaultAttributes.support || undefined,
156 description: command['videoDescription'] || defaultAttributes.description || undefined, 160 description: options.videoDescription || defaultAttributes.description || undefined,
157 tags: command['tags'] || defaultAttributes.tags || undefined 161 tags: options.tags || defaultAttributes.tags || undefined
158 } 162 }
159 163
160 Object.assign(videoAttributes, booleanAttributes) 164 Object.assign(videoAttributes, booleanAttributes)
161 165
162 if (command['channelName']) { 166 if (options.channelName) {
163 const res = await getVideoChannel(url, command['channelName']) 167 const res = await getVideoChannel(url, options.channelName)
164 const videoChannel: VideoChannel = res.body 168 const videoChannel: VideoChannel = res.body
165 169
166 Object.assign(videoAttributes, { channelId: videoChannel.id }) 170 Object.assign(videoAttributes, { channelId: videoChannel.id })
@@ -173,7 +177,7 @@ async function buildVideoAttributesFromCommander (url: string, command: Commande
173 return videoAttributes 177 return videoAttributes
174} 178}
175 179
176function getServerCredentials (program: any) { 180function getServerCredentials (program: CommanderStatic) {
177 return Promise.all([ getSettings(), getNetrc() ]) 181 return Promise.all([ getSettings(), getNetrc() ])
178 .then(([ settings, netrc ]) => { 182 .then(([ settings, netrc ]) => {
179 return getRemoteObjectOrDie(program, settings, netrc) 183 return getRemoteObjectOrDie(program, settings, netrc)
diff --git a/server/tools/peertube-auth.ts b/server/tools/peertube-auth.ts
index 6a0b89fe2..e54649002 100644
--- a/server/tools/peertube-auth.ts
+++ b/server/tools/peertube-auth.ts
@@ -66,7 +66,8 @@ program
66 .option('-U, --username <username>', 'Username') 66 .option('-U, --username <username>', 'Username')
67 .option('-p, --password <token>', 'Password') 67 .option('-p, --password <token>', 'Password')
68 .option('--default', 'add the entry as the new default') 68 .option('--default', 'add the entry as the new default')
69 .action(options => { 69 .action((options: program.OptionValues) => {
70 /* eslint-disable no-import-assign */
70 prompt.override = options 71 prompt.override = options
71 prompt.start() 72 prompt.start()
72 prompt.get({ 73 prompt.get({
@@ -102,7 +103,7 @@ program
102 process.exit(-1) 103 process.exit(-1)
103 } 104 }
104 105
105 await setInstance(result.url, result.username, result.password, program['default']) 106 await setInstance(result.url, result.username, result.password, options.default)
106 107
107 process.exit(0) 108 process.exit(0)
108 }) 109 })
@@ -160,15 +161,12 @@ program
160 } 161 }
161 }) 162 })
162 163
163program.on('--help', function () { 164program.addHelpText('after', '\n\n Examples:\n\n' +
164 console.log(' Examples:') 165 ' $ peertube auth add -u https://peertube.cpy.re -U "PEERTUBE_USER" --password "PEERTUBE_PASSWORD"\n' +
165 console.log() 166 ' $ peertube auth add -u https://peertube.cpy.re -U root\n' +
166 console.log(' $ peertube auth add -u https://peertube.cpy.re -U "PEERTUBE_USER" --password "PEERTUBE_PASSWORD"') 167 ' $ peertube auth list\n' +
167 console.log(' $ peertube auth add -u https://peertube.cpy.re -U root') 168 ' $ peertube auth del https://peertube.cpy.re\n'
168 console.log(' $ peertube auth list') 169)
169 console.log(' $ peertube auth del https://peertube.cpy.re')
170 console.log()
171})
172 170
173if (!process.argv.slice(2).length) { 171if (!process.argv.slice(2).length) {
174 program.outputHelp() 172 program.outputHelp()
diff --git a/server/tools/peertube-get-access-token.ts b/server/tools/peertube-get-access-token.ts
index 6d47d8922..b2c278c48 100644
--- a/server/tools/peertube-get-access-token.ts
+++ b/server/tools/peertube-get-access-token.ts
@@ -10,25 +10,27 @@ program
10 .option('-p, --password <token>', 'Password') 10 .option('-p, --password <token>', 'Password')
11 .parse(process.argv) 11 .parse(process.argv)
12 12
13const options = program.opts()
14
13if ( 15if (
14 !program['url'] || 16 !options.url ||
15 !program['username'] || 17 !options.username ||
16 !program['password'] 18 !options.password
17) { 19) {
18 if (!program['url']) console.error('--url field is required.') 20 if (!options.url) console.error('--url field is required.')
19 if (!program['username']) console.error('--username field is required.') 21 if (!options.username) console.error('--username field is required.')
20 if (!program['password']) console.error('--password field is required.') 22 if (!options.password) console.error('--password field is required.')
21 23
22 process.exit(-1) 24 process.exit(-1)
23} 25}
24 26
25getClient(program.url) 27getClient(options.url)
26 .then(res => { 28 .then(res => {
27 const server = { 29 const server = {
28 url: program['url'], 30 url: options.url,
29 user: { 31 user: {
30 username: program['username'], 32 username: options.username,
31 password: program['password'] 33 password: options.password
32 }, 34 },
33 client: { 35 client: {
34 id: res.body.client_id, 36 id: res.body.client_id,
diff --git a/server/tools/peertube-import-videos.ts b/server/tools/peertube-import-videos.ts
index 65798adb4..d91767c29 100644
--- a/server/tools/peertube-import-videos.ts
+++ b/server/tools/peertube-import-videos.ts
@@ -45,22 +45,24 @@ command
45 .usage("[global options] [ -- youtube-dl options]") 45 .usage("[global options] [ -- youtube-dl options]")
46 .parse(process.argv) 46 .parse(process.argv)
47 47
48const log = getLogger(program['verbose']) 48const options = command.opts()
49
50const log = getLogger(options.verbose)
49 51
50getServerCredentials(command) 52getServerCredentials(command)
51 .then(({ url, username, password }) => { 53 .then(({ url, username, password }) => {
52 if (!program['targetUrl']) { 54 if (!options.targetUrl) {
53 exitError('--target-url field is required.') 55 exitError('--target-url field is required.')
54 } 56 }
55 57
56 try { 58 try {
57 accessSync(program['tmpdir'], constants.R_OK | constants.W_OK) 59 accessSync(options.tmpdir, constants.R_OK | constants.W_OK)
58 } catch (e) { 60 } catch (e) {
59 exitError('--tmpdir %s: directory does not exist or is not accessible', program['tmpdir']) 61 exitError('--tmpdir %s: directory does not exist or is not accessible', options.tmpdir)
60 } 62 }
61 63
62 url = normalizeTargetUrl(url) 64 url = normalizeTargetUrl(url)
63 program['targetUrl'] = normalizeTargetUrl(program['targetUrl']) 65 options.targetUrl = normalizeTargetUrl(options.targetUrl)
64 66
65 const user = { username, password } 67 const user = { username, password }
66 68
@@ -76,7 +78,7 @@ async function run (url: string, user: UserInfo) {
76 78
77 const youtubeDL = await safeGetYoutubeDL() 79 const youtubeDL = await safeGetYoutubeDL()
78 80
79 let info = await getYoutubeDLInfo(youtubeDL, program['targetUrl'], command.args) 81 let info = await getYoutubeDLInfo(youtubeDL, options.targetUrl, command.args)
80 82
81 if (!Array.isArray(info)) info = [ info ] 83 if (!Array.isArray(info)) info = [ info ]
82 84
@@ -92,10 +94,10 @@ async function run (url: string, user: UserInfo) {
92 let infoArray: any[] 94 let infoArray: any[]
93 95
94 infoArray = [].concat(info) 96 infoArray = [].concat(info)
95 if (program['first']) { 97 if (options.first) {
96 infoArray = infoArray.slice(0, program['first']) 98 infoArray = infoArray.slice(0, options.first)
97 } else if (program['last']) { 99 } else if (options.last) {
98 infoArray = infoArray.slice(-program['last']) 100 infoArray = infoArray.slice(-options.last)
99 } 101 }
100 // Normalize utf8 fields 102 // Normalize utf8 fields
101 infoArray = infoArray.map(i => normalizeObject(i)) 103 infoArray = infoArray.map(i => normalizeObject(i))
@@ -104,12 +106,12 @@ async function run (url: string, user: UserInfo) {
104 106
105 for (const [ index, info ] of infoArray.entries()) { 107 for (const [ index, info ] of infoArray.entries()) {
106 try { 108 try {
107 if (index > 0 && program['waitInterval']) { 109 if (index > 0 && options.waitInterval) {
108 log.info("Wait for %d seconds before continuing.", program['waitInterval'] / 1000) 110 log.info("Wait for %d seconds before continuing.", options.waitInterval / 1000)
109 await new Promise(res => setTimeout(res, program['waitInterval'])) 111 await new Promise(res => setTimeout(res, options.waitInterval))
110 } 112 }
111 await processVideo({ 113 await processVideo({
112 cwd: program['tmpdir'], 114 cwd: options.tmpdir,
113 url, 115 url,
114 user, 116 user,
115 youtubeInfo: info 117 youtubeInfo: info
@@ -119,7 +121,7 @@ async function run (url: string, user: UserInfo) {
119 } 121 }
120 } 122 }
121 123
122 log.info('Video/s for user %s imported: %s', user.username, program['targetUrl']) 124 log.info('Video/s for user %s imported: %s', user.username, options.targetUrl)
123 process.exit(0) 125 process.exit(0)
124} 126}
125 127
@@ -137,14 +139,14 @@ async function processVideo (parameters: {
137 log.debug('Fetched object.', videoInfo) 139 log.debug('Fetched object.', videoInfo)
138 140
139 const originallyPublishedAt = buildOriginallyPublishedAt(videoInfo) 141 const originallyPublishedAt = buildOriginallyPublishedAt(videoInfo)
140 if (program['since'] && originallyPublishedAt && originallyPublishedAt.getTime() < program['since'].getTime()) { 142 if (options.since && originallyPublishedAt && originallyPublishedAt.getTime() < options.since.getTime()) {
141 log.info('Video "%s" has been published before "%s", don\'t upload it.\n', 143 log.info('Video "%s" has been published before "%s", don\'t upload it.\n',
142 videoInfo.title, formatDate(program['since'])) 144 videoInfo.title, formatDate(options.since))
143 return 145 return
144 } 146 }
145 if (program['until'] && originallyPublishedAt && originallyPublishedAt.getTime() > program['until'].getTime()) { 147 if (options.until && originallyPublishedAt && originallyPublishedAt.getTime() > options.until.getTime()) {
146 log.info('Video "%s" has been published after "%s", don\'t upload it.\n', 148 log.info('Video "%s" has been published after "%s", don\'t upload it.\n',
147 videoInfo.title, formatDate(program['until'])) 149 videoInfo.title, formatDate(options.until))
148 return 150 return
149 } 151 }
150 152
@@ -161,11 +163,11 @@ async function processVideo (parameters: {
161 163
162 log.info('Downloading video "%s"...', videoInfo.title) 164 log.info('Downloading video "%s"...', videoInfo.title)
163 165
164 const options = [ '-f', getYoutubeDLVideoFormat(), ...command.args, '-o', path ] 166 const youtubeDLOptions = [ '-f', getYoutubeDLVideoFormat(), ...command.args, '-o', path ]
165 try { 167 try {
166 const youtubeDL = await safeGetYoutubeDL() 168 const youtubeDL = await safeGetYoutubeDL()
167 const youtubeDLExec = promisify(youtubeDL.exec).bind(youtubeDL) 169 const youtubeDLExec = promisify(youtubeDL.exec).bind(youtubeDL)
168 const output = await youtubeDLExec(videoInfo.url, options, processOptions) 170 const output = await youtubeDLExec(videoInfo.url, youtubeDLOptions, processOptions)
169 log.info(output.join('\n')) 171 log.info(output.join('\n'))
170 await uploadVideoOnPeerTube({ 172 await uploadVideoOnPeerTube({
171 cwd, 173 cwd,
diff --git a/server/tools/peertube-plugins.ts b/server/tools/peertube-plugins.ts
index 05b75fab2..08e8cd713 100644
--- a/server/tools/peertube-plugins.ts
+++ b/server/tools/peertube-plugins.ts
@@ -10,6 +10,7 @@ import { getAdminTokenOrDie, getServerCredentials } from './cli'
10import { PeerTubePlugin } from '../../shared/models/plugins/peertube-plugin.model' 10import { PeerTubePlugin } from '../../shared/models/plugins/peertube-plugin.model'
11import { isAbsolute } from 'path' 11import { isAbsolute } from 'path'
12import * as CliTable3 from 'cli-table3' 12import * as CliTable3 from 'cli-table3'
13import commander = require('commander')
13 14
14program 15program
15 .name('plugins') 16 .name('plugins')
@@ -33,7 +34,7 @@ program
33 .option('-p, --password <token>', 'Password') 34 .option('-p, --password <token>', 'Password')
34 .option('-P --path <path>', 'Install from a path') 35 .option('-P --path <path>', 'Install from a path')
35 .option('-n, --npm-name <npmName>', 'Install from npm') 36 .option('-n, --npm-name <npmName>', 'Install from npm')
36 .action((options) => installPluginCLI(options)) 37 .action((options, command) => installPluginCLI(command, options))
37 38
38program 39program
39 .command('update') 40 .command('update')
@@ -43,7 +44,7 @@ program
43 .option('-p, --password <token>', 'Password') 44 .option('-p, --password <token>', 'Password')
44 .option('-P --path <path>', 'Update from a path') 45 .option('-P --path <path>', 'Update from a path')
45 .option('-n, --npm-name <npmName>', 'Update from npm') 46 .option('-n, --npm-name <npmName>', 'Update from npm')
46 .action((options) => updatePluginCLI(options)) 47 .action((options, command) => updatePluginCLI(command, options))
47 48
48program 49program
49 .command('uninstall') 50 .command('uninstall')
@@ -52,7 +53,7 @@ program
52 .option('-U, --username <username>', 'Username') 53 .option('-U, --username <username>', 'Username')
53 .option('-p, --password <token>', 'Password') 54 .option('-p, --password <token>', 'Password')
54 .option('-n, --npm-name <npmName>', 'NPM plugin/theme name') 55 .option('-n, --npm-name <npmName>', 'NPM plugin/theme name')
55 .action(options => uninstallPluginCLI(options)) 56 .action((options, command) => uninstallPluginCLI(command, options))
56 57
57if (!process.argv.slice(2).length) { 58if (!process.argv.slice(2).length) {
58 program.outputHelp() 59 program.outputHelp()
@@ -60,6 +61,8 @@ if (!process.argv.slice(2).length) {
60 61
61program.parse(process.argv) 62program.parse(process.argv)
62 63
64const options = program.opts()
65
63// ---------------------------------------------------------------------------- 66// ----------------------------------------------------------------------------
64 67
65async function pluginsListCLI () { 68async function pluginsListCLI () {
@@ -67,8 +70,8 @@ async function pluginsListCLI () {
67 const accessToken = await getAdminTokenOrDie(url, username, password) 70 const accessToken = await getAdminTokenOrDie(url, username, password)
68 71
69 let pluginType: PluginType 72 let pluginType: PluginType
70 if (program['onlyThemes']) pluginType = PluginType.THEME 73 if (options.onlyThemes) pluginType = PluginType.THEME
71 if (program['onlyPlugins']) pluginType = PluginType.PLUGIN 74 if (options.onlyPlugins) pluginType = PluginType.PLUGIN
72 75
73 const res = await listPlugins({ 76 const res = await listPlugins({
74 url, 77 url,
@@ -101,27 +104,27 @@ async function pluginsListCLI () {
101 process.exit(0) 104 process.exit(0)
102} 105}
103 106
104async function installPluginCLI (options: any) { 107async function installPluginCLI (command: commander.CommanderStatic, options: commander.OptionValues) {
105 if (!options['path'] && !options['npmName']) { 108 if (!options.path && !options.npmName) {
106 console.error('You need to specify the npm name or the path of the plugin you want to install.\n') 109 console.error('You need to specify the npm name or the path of the plugin you want to install.\n')
107 program.outputHelp() 110 program.outputHelp()
108 process.exit(-1) 111 process.exit(-1)
109 } 112 }
110 113
111 if (options['path'] && !isAbsolute(options['path'])) { 114 if (options.path && !isAbsolute(options.path)) {
112 console.error('Path should be absolute.') 115 console.error('Path should be absolute.')
113 process.exit(-1) 116 process.exit(-1)
114 } 117 }
115 118
116 const { url, username, password } = await getServerCredentials(options) 119 const { url, username, password } = await getServerCredentials(command)
117 const accessToken = await getAdminTokenOrDie(url, username, password) 120 const accessToken = await getAdminTokenOrDie(url, username, password)
118 121
119 try { 122 try {
120 await installPlugin({ 123 await installPlugin({
121 url, 124 url,
122 accessToken, 125 accessToken,
123 npmName: options['npmName'], 126 npmName: options.npmName,
124 path: options['path'] 127 path: options.path
125 }) 128 })
126 } catch (err) { 129 } catch (err) {
127 console.error('Cannot install plugin.', err) 130 console.error('Cannot install plugin.', err)
@@ -132,27 +135,27 @@ async function installPluginCLI (options: any) {
132 process.exit(0) 135 process.exit(0)
133} 136}
134 137
135async function updatePluginCLI (options: any) { 138async function updatePluginCLI (command: commander.CommanderStatic, options: commander.OptionValues) {
136 if (!options['path'] && !options['npmName']) { 139 if (!options.path && !options.npmName) {
137 console.error('You need to specify the npm name or the path of the plugin you want to update.\n') 140 console.error('You need to specify the npm name or the path of the plugin you want to update.\n')
138 program.outputHelp() 141 program.outputHelp()
139 process.exit(-1) 142 process.exit(-1)
140 } 143 }
141 144
142 if (options['path'] && !isAbsolute(options['path'])) { 145 if (options.path && !isAbsolute(options.path)) {
143 console.error('Path should be absolute.') 146 console.error('Path should be absolute.')
144 process.exit(-1) 147 process.exit(-1)
145 } 148 }
146 149
147 const { url, username, password } = await getServerCredentials(options) 150 const { url, username, password } = await getServerCredentials(command)
148 const accessToken = await getAdminTokenOrDie(url, username, password) 151 const accessToken = await getAdminTokenOrDie(url, username, password)
149 152
150 try { 153 try {
151 await updatePlugin({ 154 await updatePlugin({
152 url, 155 url,
153 accessToken, 156 accessToken,
154 npmName: options['npmName'], 157 npmName: options.npmName,
155 path: options['path'] 158 path: options.path
156 }) 159 })
157 } catch (err) { 160 } catch (err) {
158 console.error('Cannot update plugin.', err) 161 console.error('Cannot update plugin.', err)
@@ -163,21 +166,21 @@ async function updatePluginCLI (options: any) {
163 process.exit(0) 166 process.exit(0)
164} 167}
165 168
166async function uninstallPluginCLI (options: any) { 169async function uninstallPluginCLI (command: commander.CommanderStatic, options: commander.OptionValues) {
167 if (!options['npmName']) { 170 if (!options.npmName) {
168 console.error('You need to specify the npm name of the plugin/theme you want to uninstall.\n') 171 console.error('You need to specify the npm name of the plugin/theme you want to uninstall.\n')
169 program.outputHelp() 172 program.outputHelp()
170 process.exit(-1) 173 process.exit(-1)
171 } 174 }
172 175
173 const { url, username, password } = await getServerCredentials(options) 176 const { url, username, password } = await getServerCredentials(command)
174 const accessToken = await getAdminTokenOrDie(url, username, password) 177 const accessToken = await getAdminTokenOrDie(url, username, password)
175 178
176 try { 179 try {
177 await uninstallPlugin({ 180 await uninstallPlugin({
178 url, 181 url,
179 accessToken, 182 accessToken,
180 npmName: options['npmName'] 183 npmName: options.npmName
181 }) 184 })
182 } catch (err) { 185 } catch (err) {
183 console.error('Cannot uninstall plugin.', err) 186 console.error('Cannot uninstall plugin.', err)
diff --git a/server/tools/peertube-redundancy.ts b/server/tools/peertube-redundancy.ts
index fe482daf4..5bc80ddb9 100644
--- a/server/tools/peertube-redundancy.ts
+++ b/server/tools/peertube-redundancy.ts
@@ -14,6 +14,7 @@ import { URL } from 'url'
14import { uniq } from 'lodash' 14import { uniq } from 'lodash'
15 15
16import bytes = require('bytes') 16import bytes = require('bytes')
17import commander = require('commander')
17 18
18program 19program
19 .name('plugins') 20 .name('plugins')
@@ -42,7 +43,7 @@ program
42 .option('-U, --username <username>', 'Username') 43 .option('-U, --username <username>', 'Username')
43 .option('-p, --password <token>', 'Password') 44 .option('-p, --password <token>', 'Password')
44 .option('-v, --video <videoId>', 'Video id to duplicate') 45 .option('-v, --video <videoId>', 'Video id to duplicate')
45 .action((options) => addRedundancyCLI(options)) 46 .action((options, command) => addRedundancyCLI(options, command))
46 47
47program 48program
48 .command('remove') 49 .command('remove')
@@ -51,7 +52,7 @@ program
51 .option('-U, --username <username>', 'Username') 52 .option('-U, --username <username>', 'Username')
52 .option('-p, --password <token>', 'Password') 53 .option('-p, --password <token>', 'Password')
53 .option('-v, --video <videoId>', 'Video id to remove from redundancies') 54 .option('-v, --video <videoId>', 'Video id to remove from redundancies')
54 .action((options) => removeRedundancyCLI(options)) 55 .action((options, command) => removeRedundancyCLI(options, command))
55 56
56if (!process.argv.slice(2).length) { 57if (!process.argv.slice(2).length) {
57 program.outputHelp() 58 program.outputHelp()
@@ -104,13 +105,13 @@ async function listRedundanciesCLI (target: VideoRedundanciesTarget) {
104 process.exit(0) 105 process.exit(0)
105} 106}
106 107
107async function addRedundancyCLI (options: { videoId: number }) { 108async function addRedundancyCLI (options: { video: number }, command: commander.CommanderStatic) {
108 const { url, username, password } = await getServerCredentials(program) 109 const { url, username, password } = await getServerCredentials(command)
109 const accessToken = await getAdminTokenOrDie(url, username, password) 110 const accessToken = await getAdminTokenOrDie(url, username, password)
110 111
111 if (!options['video'] || validator.isInt('' + options['video']) === false) { 112 if (!options.video || validator.isInt('' + options.video) === false) {
112 console.error('You need to specify the video id to duplicate and it should be a number.\n') 113 console.error('You need to specify the video id to duplicate and it should be a number.\n')
113 program.outputHelp() 114 command.outputHelp()
114 process.exit(-1) 115 process.exit(-1)
115 } 116 }
116 117
@@ -118,7 +119,7 @@ async function addRedundancyCLI (options: { videoId: number }) {
118 await addVideoRedundancy({ 119 await addVideoRedundancy({
119 url, 120 url,
120 accessToken, 121 accessToken,
121 videoId: options['video'] 122 videoId: options.video
122 }) 123 })
123 124
124 console.log('Video will be duplicated by your instance!') 125 console.log('Video will be duplicated by your instance!')
@@ -137,17 +138,17 @@ async function addRedundancyCLI (options: { videoId: number }) {
137 } 138 }
138} 139}
139 140
140async function removeRedundancyCLI (options: { videoId: number }) { 141async function removeRedundancyCLI (options: { video: number }, command: commander.CommanderStatic) {
141 const { url, username, password } = await getServerCredentials(program) 142 const { url, username, password } = await getServerCredentials(command)
142 const accessToken = await getAdminTokenOrDie(url, username, password) 143 const accessToken = await getAdminTokenOrDie(url, username, password)
143 144
144 if (!options['video'] || validator.isInt('' + options['video']) === false) { 145 if (!options.video || validator.isInt('' + options.video) === false) {
145 console.error('You need to specify the video id to remove from your redundancies.\n') 146 console.error('You need to specify the video id to remove from your redundancies.\n')
146 program.outputHelp() 147 command.outputHelp()
147 process.exit(-1) 148 process.exit(-1)
148 } 149 }
149 150
150 const videoId = parseInt(options['video'] + '', 10) 151 const videoId = parseInt(options.video + '', 10)
151 152
152 let redundancies = await listVideoRedundanciesData(url, accessToken, 'my-videos') 153 let redundancies = await listVideoRedundanciesData(url, accessToken, 'my-videos')
153 let videoRedundancy = redundancies.find(r => videoId === r.id) 154 let videoRedundancy = redundancies.find(r => videoId === r.id)
diff --git a/server/tools/peertube-repl.ts b/server/tools/peertube-repl.ts
index a5c35e9ea..a38d51801 100644
--- a/server/tools/peertube-repl.ts
+++ b/server/tools/peertube-repl.ts
@@ -82,7 +82,6 @@ const start = async () => {
82 } 82 }
83 replServer.defineCommand('reset', resetCommand) 83 replServer.defineCommand('reset', resetCommand)
84 replServer.defineCommand('r', resetCommand) 84 replServer.defineCommand('r', resetCommand)
85
86} 85}
87 86
88start() 87start()
diff --git a/server/tools/peertube-upload.ts b/server/tools/peertube-upload.ts
index 8de952e7b..86c7f3d91 100644
--- a/server/tools/peertube-upload.ts
+++ b/server/tools/peertube-upload.ts
@@ -22,16 +22,18 @@ command
22 .option('-f, --file <file>', 'Video absolute file path') 22 .option('-f, --file <file>', 'Video absolute file path')
23 .parse(process.argv) 23 .parse(process.argv)
24 24
25const options = command.opts()
26
25getServerCredentials(command) 27getServerCredentials(command)
26 .then(({ url, username, password }) => { 28 .then(({ url, username, password }) => {
27 if (!program['videoName'] || !program['file']) { 29 if (!options.videoName || !options.file) {
28 if (!program['videoName']) console.error('--video-name is required.') 30 if (!options.videoName) console.error('--video-name is required.')
29 if (!program['file']) console.error('--file is required.') 31 if (!options.file) console.error('--file is required.')
30 32
31 process.exit(-1) 33 process.exit(-1)
32 } 34 }
33 35
34 if (isAbsolute(program['file']) === false) { 36 if (isAbsolute(options.file) === false) {
35 console.error('File path should be absolute.') 37 console.error('File path should be absolute.')
36 process.exit(-1) 38 process.exit(-1)
37 } 39 }
@@ -46,21 +48,21 @@ getServerCredentials(command)
46async function run (url: string, username: string, password: string) { 48async function run (url: string, username: string, password: string) {
47 const accessToken = await getAccessToken(url, username, password) 49 const accessToken = await getAccessToken(url, username, password)
48 50
49 await access(program['file'], constants.F_OK) 51 await access(options.file, constants.F_OK)
50 52
51 console.log('Uploading %s video...', program['videoName']) 53 console.log('Uploading %s video...', options.videoName)
52 54
53 const videoAttributes = await buildVideoAttributesFromCommander(url, program) 55 const videoAttributes = await buildVideoAttributesFromCommander(url, program)
54 56
55 Object.assign(videoAttributes, { 57 Object.assign(videoAttributes, {
56 fixture: program['file'], 58 fixture: options.file,
57 thumbnailfile: program['thumbnail'], 59 thumbnailfile: options.thumbnail,
58 previewfile: program['preview'] 60 previewfile: options.preview
59 }) 61 })
60 62
61 try { 63 try {
62 await uploadVideo(url, accessToken, videoAttributes) 64 await uploadVideo(url, accessToken, videoAttributes)
63 console.log(`Video ${program['videoName']} uploaded.`) 65 console.log(`Video ${options.videoName} uploaded.`)
64 process.exit(0) 66 process.exit(0)
65 } catch (err) { 67 } catch (err) {
66 console.error(require('util').inspect(err)) 68 console.error(require('util').inspect(err))
diff --git a/server/tools/peertube-watch.ts b/server/tools/peertube-watch.ts
index b8e750a37..6d9cfa3b7 100644
--- a/server/tools/peertube-watch.ts
+++ b/server/tools/peertube-watch.ts
@@ -8,40 +8,30 @@ import { execSync } from 'child_process'
8program 8program
9 .name('watch') 9 .name('watch')
10 .arguments('<url>') 10 .arguments('<url>')
11 .option('-g, --gui <player>', 'player type', /^(airplay|stdout|chromecast|mpv|vlc|mplayer|xbmc)$/i, 'vlc') 11 .addOption(
12 new program.Option('-g, --gui <player>', 'player type')
13 .default('vlc')
14 .choices([ 'airplay', 'stdout', 'chromecast', 'mpv', 'vlc', 'mplayer', 'xbmc' ])
15 )
12 .option('-r, --resolution <res>', 'video resolution', '480') 16 .option('-r, --resolution <res>', 'video resolution', '480')
13 .on('--help', function () { 17 .addHelpText('after', '\n\n Examples:\n\n' +
14 console.log(' Available Players:') 18 ' $ peertube watch -g mpv https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10\n' +
15 console.log() 19 ' $ peertube watch --gui stdout https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10\n' +
16 console.log(' - mpv') 20 ' $ peertube watch https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10\n'
17 console.log(' - mplayer') 21 )
18 console.log(' - vlc') 22 .action((url, options) => run(url, options))
19 console.log(' - stdout')
20 console.log(' - xbmc')
21 console.log(' - airplay')
22 console.log(' - chromecast')
23 console.log()
24 console.log()
25 console.log(' Examples:')
26 console.log()
27 console.log(' $ peertube watch -g mpv https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10')
28 console.log(' $ peertube watch --gui stdout https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10')
29 console.log(' $ peertube watch https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10')
30 console.log()
31 })
32 .action((url, cmd) => run(url, cmd))
33 .parse(process.argv) 23 .parse(process.argv)
34 24
35function run (url: string, program: any) { 25function run (url: string, options: program.OptionValues) {
36 if (!url) { 26 if (!url) {
37 console.error('<url> positional argument is required.') 27 console.error('<url> positional argument is required.')
38 process.exit(-1) 28 process.exit(-1)
39 } 29 }
40 30
41 const cmd = 'node ' + join(__dirname, 'node_modules', 'webtorrent-hybrid', 'bin', 'cmd.js') 31 const cmd = 'node ' + join(__dirname, 'node_modules', 'webtorrent-hybrid', 'bin', 'cmd.js')
42 const args = ` --${program.gui} ` + 32 const args = ` --${options.gui} ` +
43 url.replace('videos/watch', 'download/torrents') + 33 url.replace('videos/watch', 'download/torrents') +
44 `-${program.resolution}.torrent` 34 `-${options.resolution}.torrent`
45 35
46 try { 36 try {
47 execSync(cmd + args) 37 execSync(cmd + args)
diff --git a/server/tools/peertube.ts b/server/tools/peertube.ts
index 88dd5f7f6..655f07f0c 100644
--- a/server/tools/peertube.ts
+++ b/server/tools/peertube.ts
@@ -69,17 +69,12 @@ getSettings()
69 : 'instance ' + settings.remotes[settings.default] + ' selected' 69 : 'instance ' + settings.remotes[settings.default] + ' selected'
70 70
71 program 71 program
72 .on('--help', function () { 72 .addHelpText('after', '\n\n State: ' + state + '\n\n' +
73 console.log() 73 ' Examples:\n\n' +
74 console.log(' State: ' + state) 74 ' $ peertube auth add -u "PEERTUBE_URL" -U "PEERTUBE_USER" --password "PEERTUBE_PASSWORD"\n' +
75 console.log() 75 ' $ peertube up <videoFile>\n' +
76 console.log(' Examples:') 76 ' $ peertube watch https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10\n'
77 console.log() 77 )
78 console.log(' $ peertube auth add -u "PEERTUBE_URL" -U "PEERTUBE_USER" --password "PEERTUBE_PASSWORD"')
79 console.log(' $ peertube up <videoFile>')
80 console.log(' $ peertube watch https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10')
81 console.log()
82 })
83 .parse(process.argv) 78 .parse(process.argv)
84 }) 79 })
85 .catch(err => console.error(err)) 80 .catch(err => console.error(err))