WIP plugins: move plugin CLI in peertube script
[oweals/peertube.git] / server / tools / peertube-plugins.ts
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 }