diff options
Diffstat (limited to 'server/tools')
-rw-r--r-- | server/tools/cli.ts | 18 | ||||
-rw-r--r-- | server/tools/peertube-auth.ts | 12 | ||||
-rw-r--r-- | server/tools/peertube-import-videos.ts | 34 | ||||
-rw-r--r-- | server/tools/peertube-plugins.ts | 162 | ||||
-rw-r--r-- | server/tools/peertube-upload.ts | 55 | ||||
-rw-r--r-- | server/tools/peertube.ts | 5 |
6 files changed, 224 insertions, 62 deletions
diff --git a/server/tools/cli.ts b/server/tools/cli.ts index 2eec51aa4..67755022c 100644 --- a/server/tools/cli.ts +++ b/server/tools/cli.ts | |||
@@ -1,7 +1,8 @@ | |||
1 | import { Netrc } from 'netrc-parser' | 1 | import { Netrc } from 'netrc-parser' |
2 | import { getAppNumber, isTestInstance } from '../helpers/core-utils' | 2 | import { getAppNumber, isTestInstance } from '../helpers/core-utils' |
3 | import { join } from 'path' | 3 | import { join } from 'path' |
4 | import { getVideoChannel, root } from '../../shared/extra-utils' | 4 | import { root } from '../../shared/extra-utils/miscs/miscs' |
5 | import { getVideoChannel } from '../../shared/extra-utils/videos/video-channels' | ||
5 | import { Command } from 'commander' | 6 | import { Command } from 'commander' |
6 | import { VideoChannel, VideoPrivacy } from '../../shared/models/videos' | 7 | import { VideoChannel, VideoPrivacy } from '../../shared/models/videos' |
7 | 8 | ||
@@ -64,7 +65,11 @@ function deleteSettings () { | |||
64 | }) | 65 | }) |
65 | } | 66 | } |
66 | 67 | ||
67 | function getRemoteObjectOrDie (program: any, settings: Settings, netrc: Netrc) { | 68 | function getRemoteObjectOrDie ( |
69 | program: any, | ||
70 | settings: Settings, | ||
71 | netrc: Netrc | ||
72 | ): { url: string, username: string, password: string } { | ||
68 | if (!program['url'] || !program['username'] || !program['password']) { | 73 | if (!program['url'] || !program['username'] || !program['password']) { |
69 | // No remote and we don't have program parameters: quit | 74 | // No remote and we don't have program parameters: quit |
70 | if (settings.remotes.length === 0 || Object.keys(netrc.machines).length === 0) { | 75 | if (settings.remotes.length === 0 || Object.keys(netrc.machines).length === 0) { |
@@ -161,6 +166,13 @@ async function buildVideoAttributesFromCommander (url: string, command: Command, | |||
161 | return videoAttributes | 166 | return videoAttributes |
162 | } | 167 | } |
163 | 168 | ||
169 | function getServerCredentials (program: any) { | ||
170 | return Promise.all([ getSettings(), getNetrc() ]) | ||
171 | .then(([ settings, netrc ]) => { | ||
172 | return getRemoteObjectOrDie(program, settings, netrc) | ||
173 | }) | ||
174 | } | ||
175 | |||
164 | // --------------------------------------------------------------------------- | 176 | // --------------------------------------------------------------------------- |
165 | 177 | ||
166 | export { | 178 | export { |
@@ -172,6 +184,8 @@ export { | |||
172 | writeSettings, | 184 | writeSettings, |
173 | deleteSettings, | 185 | deleteSettings, |
174 | 186 | ||
187 | getServerCredentials, | ||
188 | |||
175 | buildCommonVideoOptions, | 189 | buildCommonVideoOptions, |
176 | buildVideoAttributesFromCommander | 190 | buildVideoAttributesFromCommander |
177 | } | 191 | } |
diff --git a/server/tools/peertube-auth.ts b/server/tools/peertube-auth.ts index 1035d664a..d4ad56e47 100644 --- a/server/tools/peertube-auth.ts +++ b/server/tools/peertube-auth.ts | |||
@@ -1,8 +1,8 @@ | |||
1 | import * as program from 'commander' | 1 | import * as program from 'commander' |
2 | import * as prompt from 'prompt' | 2 | import * as prompt from 'prompt' |
3 | import { getSettings, writeSettings, getNetrc } from './cli' | 3 | import { getNetrc, getSettings, writeSettings } from './cli' |
4 | import { isHostValid } from '../helpers/custom-validators/servers' | ||
5 | import { isUserUsernameValid } from '../helpers/custom-validators/users' | 4 | import { isUserUsernameValid } from '../helpers/custom-validators/users' |
5 | import { getAccessToken, login } from '../../shared/extra-utils' | ||
6 | 6 | ||
7 | const Table = require('cli-table') | 7 | const Table = require('cli-table') |
8 | 8 | ||
@@ -76,6 +76,14 @@ program | |||
76 | } | 76 | } |
77 | } | 77 | } |
78 | }, async (_, result) => { | 78 | }, async (_, result) => { |
79 | // Check credentials | ||
80 | try { | ||
81 | await getAccessToken(result.url, result.username, result.password) | ||
82 | } catch (err) { | ||
83 | console.error(err.message) | ||
84 | process.exit(-1) | ||
85 | } | ||
86 | |||
79 | await setInstance(result.url, result.username, result.password, program['default']) | 87 | await setInstance(result.url, result.username, result.password, program['default']) |
80 | 88 | ||
81 | process.exit(0) | 89 | process.exit(0) |
diff --git a/server/tools/peertube-import-videos.ts b/server/tools/peertube-import-videos.ts index d7bb00e02..1f0350442 100644 --- a/server/tools/peertube-import-videos.ts +++ b/server/tools/peertube-import-videos.ts | |||
@@ -11,7 +11,7 @@ import * as prompt from 'prompt' | |||
11 | import { remove } from 'fs-extra' | 11 | import { remove } from 'fs-extra' |
12 | import { sha256 } from '../helpers/core-utils' | 12 | import { sha256 } from '../helpers/core-utils' |
13 | import { buildOriginallyPublishedAt, safeGetYoutubeDL } from '../helpers/youtube-dl' | 13 | import { buildOriginallyPublishedAt, safeGetYoutubeDL } from '../helpers/youtube-dl' |
14 | import { buildCommonVideoOptions, buildVideoAttributesFromCommander, getNetrc, getRemoteObjectOrDie, getSettings } from './cli' | 14 | import { buildCommonVideoOptions, buildVideoAttributesFromCommander, getServerCredentials } from './cli' |
15 | 15 | ||
16 | type UserInfo = { | 16 | type UserInfo = { |
17 | username: string | 17 | username: string |
@@ -36,27 +36,25 @@ command | |||
36 | .option('-v, --verbose', 'Verbose mode') | 36 | .option('-v, --verbose', 'Verbose mode') |
37 | .parse(process.argv) | 37 | .parse(process.argv) |
38 | 38 | ||
39 | Promise.all([ getSettings(), getNetrc() ]) | 39 | getServerCredentials(command) |
40 | .then(([ settings, netrc ]) => { | 40 | .then(({ url, username, password }) => { |
41 | const { url, username, password } = getRemoteObjectOrDie(program, settings, netrc) | 41 | if (!program[ 'targetUrl' ]) { |
42 | console.error('--targetUrl field is required.') | ||
42 | 43 | ||
43 | if (!program[ 'targetUrl' ]) { | 44 | process.exit(-1) |
44 | console.error('--targetUrl field is required.') | 45 | } |
45 | |||
46 | process.exit(-1) | ||
47 | } | ||
48 | 46 | ||
49 | removeEndSlashes(url) | 47 | removeEndSlashes(url) |
50 | removeEndSlashes(program[ 'targetUrl' ]) | 48 | removeEndSlashes(program[ 'targetUrl' ]) |
51 | 49 | ||
52 | const user = { username, password } | 50 | const user = { username, password } |
53 | 51 | ||
54 | run(url, user) | 52 | run(url, user) |
55 | .catch(err => { | 53 | .catch(err => { |
56 | console.error(err) | 54 | console.error(err) |
57 | process.exit(-1) | 55 | process.exit(-1) |
58 | }) | 56 | }) |
59 | }) | 57 | }) |
60 | 58 | ||
61 | async function run (url: string, user: UserInfo) { | 59 | async function run (url: string, user: UserInfo) { |
62 | if (!user.password) { | 60 | if (!user.password) { |
diff --git a/server/tools/peertube-plugins.ts b/server/tools/peertube-plugins.ts new file mode 100644 index 000000000..d5e024383 --- /dev/null +++ b/server/tools/peertube-plugins.ts | |||
@@ -0,0 +1,162 @@ | |||
1 | import * as program from 'commander' | ||
2 | import { PluginType } from '../../shared/models/plugins/plugin.type' | ||
3 | import { getAccessToken } from '../../shared/extra-utils/users/login' | ||
4 | import { getMyUserInformation } from '../../shared/extra-utils/users/users' | ||
5 | import { installPlugin, listPlugins, uninstallPlugin } from '../../shared/extra-utils/server/plugins' | ||
6 | import { getServerCredentials } from './cli' | ||
7 | import { User, UserRole } from '../../shared/models/users' | ||
8 | import { PeerTubePlugin } from '../../shared/models/plugins/peertube-plugin.model' | ||
9 | import { isAbsolute } from 'path' | ||
10 | |||
11 | const Table = require('cli-table') | ||
12 | |||
13 | program | ||
14 | .name('plugins') | ||
15 | .usage('[command] [options]') | ||
16 | |||
17 | program | ||
18 | .command('list') | ||
19 | .description('List installed plugins') | ||
20 | .option('-u, --url <url>', 'Server url') | ||
21 | .option('-U, --username <username>', 'Username') | ||
22 | .option('-p, --password <token>', 'Password') | ||
23 | .option('-t, --only-themes', 'List themes only') | ||
24 | .option('-P, --only-plugins', 'List plugins only') | ||
25 | .action(() => pluginsListCLI()) | ||
26 | |||
27 | program | ||
28 | .command('install') | ||
29 | .description('Install a plugin or a theme') | ||
30 | .option('-u, --url <url>', 'Server url') | ||
31 | .option('-U, --username <username>', 'Username') | ||
32 | .option('-p, --password <token>', 'Password') | ||
33 | .option('-P --path <path>', 'Install from a path') | ||
34 | .option('-n, --npm-name <npmName>', 'Install from npm') | ||
35 | .action((options) => installPluginCLI(options)) | ||
36 | |||
37 | program | ||
38 | .command('uninstall') | ||
39 | .description('Uninstall a plugin or a theme') | ||
40 | .option('-u, --url <url>', 'Server url') | ||
41 | .option('-U, --username <username>', 'Username') | ||
42 | .option('-p, --password <token>', 'Password') | ||
43 | .option('-n, --npm-name <npmName>', 'NPM plugin/theme name') | ||
44 | .action(options => uninstallPluginCLI(options)) | ||
45 | |||
46 | if (!process.argv.slice(2).length) { | ||
47 | program.outputHelp() | ||
48 | } | ||
49 | |||
50 | program.parse(process.argv) | ||
51 | |||
52 | // ---------------------------------------------------------------------------- | ||
53 | |||
54 | async function pluginsListCLI () { | ||
55 | const { url, username, password } = await getServerCredentials(program) | ||
56 | const accessToken = await getAdminTokenOrDie(url, username, password) | ||
57 | |||
58 | let type: PluginType | ||
59 | if (program['onlyThemes']) type = PluginType.THEME | ||
60 | if (program['onlyPlugins']) type = PluginType.PLUGIN | ||
61 | |||
62 | const res = await listPlugins({ | ||
63 | url, | ||
64 | accessToken, | ||
65 | start: 0, | ||
66 | count: 100, | ||
67 | sort: 'name', | ||
68 | type | ||
69 | }) | ||
70 | const plugins: PeerTubePlugin[] = res.body.data | ||
71 | |||
72 | const table = new Table({ | ||
73 | head: ['name', 'version', 'homepage'], | ||
74 | colWidths: [ 50, 10, 50 ] | ||
75 | }) | ||
76 | |||
77 | for (const plugin of plugins) { | ||
78 | const npmName = plugin.type === PluginType.PLUGIN | ||
79 | ? 'peertube-plugin-' + plugin.name | ||
80 | : 'peertube-theme-' + plugin.name | ||
81 | |||
82 | table.push([ | ||
83 | npmName, | ||
84 | plugin.version, | ||
85 | plugin.homepage | ||
86 | ]) | ||
87 | } | ||
88 | |||
89 | console.log(table.toString()) | ||
90 | process.exit(0) | ||
91 | } | ||
92 | |||
93 | async function installPluginCLI (options: any) { | ||
94 | if (!options['path'] && !options['npmName']) { | ||
95 | console.error('You need to specify the npm name or the path of the plugin you want to install.\n') | ||
96 | program.outputHelp() | ||
97 | process.exit(-1) | ||
98 | } | ||
99 | |||
100 | if (options['path'] && !isAbsolute(options['path'])) { | ||
101 | console.error('Path should be absolute.') | ||
102 | process.exit(-1) | ||
103 | } | ||
104 | |||
105 | const { url, username, password } = await getServerCredentials(options) | ||
106 | const accessToken = await getAdminTokenOrDie(url, username, password) | ||
107 | |||
108 | try { | ||
109 | await installPlugin({ | ||
110 | url, | ||
111 | accessToken, | ||
112 | npmName: options['npmName'], | ||
113 | path: options['path'] | ||
114 | }) | ||
115 | } catch (err) { | ||
116 | console.error('Cannot install plugin.', err) | ||
117 | process.exit(-1) | ||
118 | return | ||
119 | } | ||
120 | |||
121 | console.log('Plugin installed.') | ||
122 | process.exit(0) | ||
123 | } | ||
124 | |||
125 | async function uninstallPluginCLI (options: any) { | ||
126 | if (!options['npmName']) { | ||
127 | console.error('You need to specify the npm name of the plugin/theme you want to uninstall.\n') | ||
128 | program.outputHelp() | ||
129 | process.exit(-1) | ||
130 | } | ||
131 | |||
132 | const { url, username, password } = await getServerCredentials(options) | ||
133 | const accessToken = await getAdminTokenOrDie(url, username, password) | ||
134 | |||
135 | try { | ||
136 | await uninstallPlugin({ | ||
137 | url, | ||
138 | accessToken, | ||
139 | npmName: options[ 'npmName' ] | ||
140 | }) | ||
141 | } catch (err) { | ||
142 | console.error('Cannot uninstall plugin.', err) | ||
143 | process.exit(-1) | ||
144 | return | ||
145 | } | ||
146 | |||
147 | console.log('Plugin uninstalled.') | ||
148 | process.exit(0) | ||
149 | } | ||
150 | |||
151 | async function getAdminTokenOrDie (url: string, username: string, password: string) { | ||
152 | const accessToken = await getAccessToken(url, username, password) | ||
153 | const resMe = await getMyUserInformation(url, accessToken) | ||
154 | const me: User = resMe.body | ||
155 | |||
156 | if (me.role !== UserRole.ADMINISTRATOR) { | ||
157 | console.error('Cannot list plugins if you are not administrator.') | ||
158 | process.exit(-1) | ||
159 | } | ||
160 | |||
161 | return accessToken | ||
162 | } | ||
diff --git a/server/tools/peertube-upload.ts b/server/tools/peertube-upload.ts index c00205e8f..d9f9a8ead 100644 --- a/server/tools/peertube-upload.ts +++ b/server/tools/peertube-upload.ts | |||
@@ -1,9 +1,9 @@ | |||
1 | import * as program from 'commander' | 1 | import * as program from 'commander' |
2 | import { access, constants } from 'fs-extra' | 2 | import { access, constants } from 'fs-extra' |
3 | import { isAbsolute } from 'path' | 3 | import { isAbsolute } from 'path' |
4 | import { getClient, login } from '../../shared/extra-utils' | 4 | import { getAccessToken } from '../../shared/extra-utils' |
5 | import { uploadVideo } from '../../shared/extra-utils/' | 5 | import { uploadVideo } from '../../shared/extra-utils/' |
6 | import { buildCommonVideoOptions, buildVideoAttributesFromCommander, getNetrc, getRemoteObjectOrDie, getSettings } from './cli' | 6 | import { buildCommonVideoOptions, buildVideoAttributesFromCommander, getServerCredentials } from './cli' |
7 | 7 | ||
8 | let command = program | 8 | let command = program |
9 | .name('upload') | 9 | .name('upload') |
@@ -11,7 +11,6 @@ let command = program | |||
11 | command = buildCommonVideoOptions(command) | 11 | command = buildCommonVideoOptions(command) |
12 | 12 | ||
13 | command | 13 | command |
14 | |||
15 | .option('-u, --url <url>', 'Server url') | 14 | .option('-u, --url <url>', 'Server url') |
16 | .option('-U, --username <username>', 'Username') | 15 | .option('-U, --username <username>', 'Username') |
17 | .option('-p, --password <token>', 'Password') | 16 | .option('-p, --password <token>', 'Password') |
@@ -20,44 +19,28 @@ command | |||
20 | .option('-f, --file <file>', 'Video absolute file path') | 19 | .option('-f, --file <file>', 'Video absolute file path') |
21 | .parse(process.argv) | 20 | .parse(process.argv) |
22 | 21 | ||
23 | Promise.all([ getSettings(), getNetrc() ]) | 22 | getServerCredentials(command) |
24 | .then(([ settings, netrc ]) => { | 23 | .then(({ url, username, password }) => { |
25 | const { url, username, password } = getRemoteObjectOrDie(program, settings, netrc) | 24 | if (!program[ 'videoName' ] || !program[ 'file' ]) { |
26 | 25 | if (!program[ 'videoName' ]) console.error('--video-name is required.') | |
27 | if (!program[ 'videoName' ] || !program[ 'file' ]) { | 26 | if (!program[ 'file' ]) console.error('--file is required.') |
28 | if (!program[ 'videoName' ]) console.error('--video-name is required.') | ||
29 | if (!program[ 'file' ]) console.error('--file is required.') | ||
30 | 27 | ||
31 | process.exit(-1) | 28 | process.exit(-1) |
32 | } | 29 | } |
33 | 30 | ||
34 | if (isAbsolute(program[ 'file' ]) === false) { | 31 | if (isAbsolute(program[ 'file' ]) === false) { |
35 | console.error('File path should be absolute.') | 32 | console.error('File path should be absolute.') |
36 | process.exit(-1) | 33 | process.exit(-1) |
37 | } | 34 | } |
38 | 35 | ||
39 | run(url, username, password).catch(err => { | 36 | run(url, username, password).catch(err => { |
40 | console.error(err) | 37 | console.error(err) |
41 | process.exit(-1) | 38 | process.exit(-1) |
42 | }) | 39 | }) |
43 | }) | 40 | }) |
44 | 41 | ||
45 | async function run (url: string, username: string, password: string) { | 42 | async function run (url: string, username: string, password: string) { |
46 | const resClient = await getClient(url) | 43 | const accessToken = await getAccessToken(url, username, password) |
47 | const client = { | ||
48 | id: resClient.body.client_id, | ||
49 | secret: resClient.body.client_secret | ||
50 | } | ||
51 | |||
52 | const user = { username, password } | ||
53 | |||
54 | let accessToken: string | ||
55 | try { | ||
56 | const res = await login(url, client, user) | ||
57 | accessToken = res.body.access_token | ||
58 | } catch (err) { | ||
59 | throw new Error('Cannot authenticate. Please check your username/password.') | ||
60 | } | ||
61 | 44 | ||
62 | await access(program[ 'file' ], constants.F_OK) | 45 | await access(program[ 'file' ], constants.F_OK) |
63 | 46 | ||
diff --git a/server/tools/peertube.ts b/server/tools/peertube.ts index daa5586c3..e79a7e041 100644 --- a/server/tools/peertube.ts +++ b/server/tools/peertube.ts | |||
@@ -18,13 +18,10 @@ program | |||
18 | .command('get-access-token', 'get a peertube access token', { noHelp: true }).alias('token') | 18 | .command('get-access-token', 'get a peertube access token', { noHelp: true }).alias('token') |
19 | .command('watch', 'watch a video in the terminal ✩°。⋆').alias('w') | 19 | .command('watch', 'watch a video in the terminal ✩°。⋆').alias('w') |
20 | .command('repl', 'initiate a REPL to access internals') | 20 | .command('repl', 'initiate a REPL to access internals') |
21 | .command('plugins [action]', 'manage plugins on a local instance').alias('p') | ||
21 | 22 | ||
22 | /* Not Yet Implemented */ | 23 | /* Not Yet Implemented */ |
23 | program | 24 | program |
24 | .command('plugins [action]', | ||
25 | 'manage plugins on a local instance', | ||
26 | { noHelp: true } as program.CommandOptions | ||
27 | ).alias('p') | ||
28 | .command('diagnostic [action]', | 25 | .command('diagnostic [action]', |
29 | 'like couple therapy, but for your instance', | 26 | 'like couple therapy, but for your instance', |
30 | { noHelp: true } as program.CommandOptions | 27 | { noHelp: true } as program.CommandOptions |