342 lines
9.7 KiB
TypeScript
342 lines
9.7 KiB
TypeScript
import { logger } from '@squeebot/core/lib/core';
|
|
import { IRepository } from '@squeebot/core/lib/plugin/repository';
|
|
import { ReadLine } from 'readline';
|
|
import { Squeebot } from './core';
|
|
|
|
export class SqueebotCLI {
|
|
constructor(private bot: Squeebot) {}
|
|
|
|
private async checkUpdate(repo: IRepository): Promise<void> {
|
|
const updatable = await this.bot.repositoryManager.checkForUpdates(repo);
|
|
if (updatable.length) {
|
|
logger.log('[%s] The following plugins can be updated:', repo.name,
|
|
updatable.map((u) => u.name).join(', '));
|
|
} else {
|
|
logger.log('[%s] All plugins are up-to-date!', repo.name);
|
|
}
|
|
}
|
|
|
|
private async repositoryCommand(...args: any[]): Promise<void> {
|
|
const help = 'repository add <url> | update <name> | remove <name>';
|
|
if (!args[0] || args[0] === 'help') {
|
|
logger.log(help);
|
|
return;
|
|
}
|
|
|
|
switch (args[0]) {
|
|
case 'a':
|
|
case 'i':
|
|
case 'add':
|
|
case 'install':
|
|
if (!args[1]) {
|
|
logger.error('URL is required');
|
|
return;
|
|
}
|
|
|
|
for (const urlp of args.slice(1)) {
|
|
const repo = await this.bot.repositoryManager.installRepository(urlp);
|
|
logger.log('Installed repository %s!', repo.name);
|
|
}
|
|
break;
|
|
case 'r':
|
|
case 'rem':
|
|
case 'remove':
|
|
case 'uninstall':
|
|
if (!args[1]) {
|
|
logger.error('Name is required');
|
|
return;
|
|
}
|
|
|
|
for (const namep of args.slice(1)) {
|
|
await this.bot.repositoryManager.uninstallRepository(namep);
|
|
logger.log('Installed repository %s.', namep);
|
|
};
|
|
break;
|
|
case 'u':
|
|
case 'upd':
|
|
case 'update':
|
|
if (!args[1]) {
|
|
const repos = this.bot.repositoryManager.getAll();
|
|
for (const repo of repos) {
|
|
await this.checkUpdate(repo);
|
|
}
|
|
return;
|
|
}
|
|
|
|
for (const namep of args.slice(1)) {
|
|
const repo = this.bot.repositoryManager.getRepoByName(namep);
|
|
if (!repo) {
|
|
logger.error('No such repository "%s" found.', namep);
|
|
return;
|
|
}
|
|
|
|
await this.checkUpdate(repo);
|
|
};
|
|
break;
|
|
default:
|
|
logger.log(help);
|
|
}
|
|
}
|
|
|
|
private async pluginCommand(...args: any[]): Promise<void> {
|
|
const help = 'plugin install | update | uninstall | enable | disable | start | stop | list | running [<name>]';
|
|
if (!args[0] || args[0] === 'help' || (!args[1] && args[0] !== 'list' && args[0] !== 'running')) {
|
|
logger.log(help);
|
|
return;
|
|
}
|
|
|
|
switch (args[0]) {
|
|
case 'i':
|
|
case 'u':
|
|
case 'install':
|
|
case 'update':
|
|
for (const name of args.slice(1)) {
|
|
const mf = await this.bot.repositoryManager.installPlugin(name);
|
|
logger.log('Installed plugin %s version %s!', mf.name, mf.version);
|
|
}
|
|
break;
|
|
case 'uninst':
|
|
case 'remove':
|
|
case 'uninstall':
|
|
for (const name of args.slice(1)) {
|
|
await this.bot.repositoryManager.uninstallPlugin(name)
|
|
logger.log('Uninstalled plugin %s.', name);
|
|
}
|
|
break;
|
|
case 'list':
|
|
logger.log('Installed plugins:',
|
|
this.bot.pluginManager.availablePlugins.map((mf) => mf.name).join(', '));
|
|
break;
|
|
case 'running':
|
|
logger.log('Currently running plugins:',
|
|
this.bot.pluginManager.getLoaded().map((p) => p.manifest.name).join(', '));
|
|
break;
|
|
case 's':
|
|
case 'run':
|
|
case 'load':
|
|
case 'start':
|
|
for (const name of args.slice(1)) {
|
|
const plugin = this.bot.pluginManager.getAvailableByName(name);
|
|
if (!plugin) {
|
|
logger.error('"%s" is not available. Maybe try installing it? plugin install', name, name);
|
|
return;
|
|
}
|
|
|
|
await this.bot.pluginManager.load(plugin);
|
|
logger.log('Started plugin "%s" successfully.', name);
|
|
}
|
|
break;
|
|
case 'stop':
|
|
case 'kill':
|
|
for (const name of args.slice(1)) {
|
|
if (!this.bot.pluginManager.getAvailableByName(name)) {
|
|
logger.error('No such plugin is available.');
|
|
return;
|
|
}
|
|
|
|
logger.log('Stopping plugin', name);
|
|
|
|
this.bot.stream.emitTo(name, 'pluginUnload', name);
|
|
}
|
|
break;
|
|
case 'enable':
|
|
for (const name of args.slice(1)) {
|
|
if (!this.bot.pluginManager.getAvailableByName(name)) {
|
|
logger.error('No such plugin "%s" is available.', name);
|
|
return;
|
|
}
|
|
|
|
logger.log('Enabling plugin', name);
|
|
|
|
if (!this.bot.config.config.enabled) {
|
|
this.bot.config.config.enabled = [name];
|
|
return;
|
|
}
|
|
|
|
if (this.bot.config.config.enabled.indexOf(name) === -1) {
|
|
this.bot.config.config.enabled.push(name);
|
|
}
|
|
}
|
|
|
|
await this.bot.config.save();
|
|
break;
|
|
case 'disable':
|
|
for (const name of args.slice(1)) {
|
|
if (!this.bot.pluginManager.getAvailableByName(name)) {
|
|
logger.error('No such plugin "%s" is available.', name);
|
|
return;
|
|
}
|
|
|
|
logger.log('Disabling plugin', name);
|
|
|
|
if (!this.bot.config.config.enabled) {
|
|
return;
|
|
}
|
|
|
|
const indx = this.bot.config.config.enabled.indexOf(name);
|
|
if (indx > -1) {
|
|
this.bot.config.config.enabled.splice(indx, 1);
|
|
}
|
|
}
|
|
|
|
await this.bot.config.save();
|
|
break;
|
|
default:
|
|
logger.log(help);
|
|
}
|
|
}
|
|
|
|
private async channelCommand(...args: any[]): Promise<void> {
|
|
const help = 'channel new | del | list | addplugin | delplugin [<name>] [<plugin>]';
|
|
if (!args[0] || args[0] === 'help' || (!args[1] && args[0] !== 'list')) {
|
|
logger.log(help);
|
|
return;
|
|
}
|
|
|
|
switch(args[0]) {
|
|
case 'new':
|
|
if (this.bot.channelManager.getChannelByName(args[1])) {
|
|
logger.error('A channel by that name already exists!');
|
|
break;
|
|
}
|
|
|
|
this.bot.channelManager.addChannel({
|
|
name: args[1],
|
|
plugins: [],
|
|
enabled: true,
|
|
});
|
|
|
|
logger.log('Channel added!');
|
|
break;
|
|
case 'del':
|
|
case 'delete':
|
|
case 'remove':
|
|
for (const name of args.slice(1)) {
|
|
const chan = this.bot.channelManager.getChannelByName(name);
|
|
if (!chan) {
|
|
logger.error('No such channel "%s" exists!', name);
|
|
return;
|
|
}
|
|
|
|
this.bot.channelManager.removeChannel(chan);
|
|
|
|
logger.log('Channel "%s" removed!', name);
|
|
}
|
|
break;
|
|
case 'addp':
|
|
case 'addplugin':
|
|
const chan1 = this.bot.channelManager.getChannelByName(args[1]);
|
|
if (!chan1) {
|
|
logger.error('No such channel exists!');
|
|
return;
|
|
}
|
|
|
|
if (!args[2]) {
|
|
logger.error('A plugin name is required.');
|
|
return;
|
|
}
|
|
|
|
for (const name of args.slice(2)) {
|
|
if (chan1.plugins.indexOf(name) === -1) {
|
|
chan1.plugins.push(name);
|
|
}
|
|
|
|
logger.log('Plugin "%s" added to channel!', name);
|
|
}
|
|
break;
|
|
case 'list':
|
|
logger.log('Channels:\n', this.bot.channelManager.getAll().map((chan) => {
|
|
return ` => ${chan.name}: ${chan.plugins.join(', ')} (${chan.enabled ? 'enabled' : 'disabled'})`;
|
|
}).join('\n'));
|
|
break;
|
|
case 'remp':
|
|
case 'delp':
|
|
case 'remplugin':
|
|
case 'delplugin':
|
|
const chan2 = this.bot.channelManager.getChannelByName(args[1]);
|
|
if (!chan2) {
|
|
logger.error('No such channel exists!');
|
|
return;
|
|
}
|
|
|
|
if (!args[2]) {
|
|
logger.error('A plugin name is required.');
|
|
return;
|
|
}
|
|
|
|
for (const name of args.slice(2)) {
|
|
const idx = chan2.plugins.indexOf(args[2]);
|
|
if (idx !== -1) {
|
|
chan2.plugins.splice(idx, 1);
|
|
}
|
|
logger.log('Plugin "%s" added to channel!', name);
|
|
}
|
|
|
|
break;
|
|
case 'enable':
|
|
for (const name of args.slice(1)) {
|
|
const chan = this.bot.channelManager.getChannelByName(name);
|
|
if (!chan) {
|
|
logger.error('No such channel "%s" exists!', name);
|
|
return;
|
|
}
|
|
|
|
chan.enabled = true;
|
|
logger.log('Channel "%s" enabled!', name);
|
|
}
|
|
break;
|
|
case 'disable':
|
|
for (const name of args.slice(1)) {
|
|
const chan = this.bot.channelManager.getChannelByName(name);
|
|
if (!chan) {
|
|
logger.error('No such channel "%s" exists!', name);
|
|
return;
|
|
}
|
|
|
|
chan.enabled = false;
|
|
logger.log('Channel "%s" disabled!', name);
|
|
}
|
|
break;
|
|
}
|
|
|
|
this.bot.config.config.channels = this.bot.channelManager.getAll();
|
|
await this.bot.config.save();
|
|
}
|
|
|
|
public attach(rl: ReadLine) {
|
|
rl.on('line', (line: string) => {
|
|
const split = line.split(' ');
|
|
|
|
if (!split[0]) {
|
|
return;
|
|
}
|
|
|
|
switch(split[0]) {
|
|
case 'r':
|
|
case 'repo':
|
|
case 'repository':
|
|
this.repositoryCommand(...split.slice(1)).catch(
|
|
e => logger.error(e.message));
|
|
break;
|
|
case 'p':
|
|
case 'pl':
|
|
case 'plugin':
|
|
this.pluginCommand(...split.slice(1)).catch(
|
|
e => logger.error(e.message));
|
|
break;
|
|
case 'c':
|
|
case 'chan':
|
|
case 'channel':
|
|
this.channelCommand(...split.slice(1)).catch(
|
|
e => logger.error(e.message));
|
|
break;
|
|
case 'stop':
|
|
case 'exit':
|
|
case 'quit':
|
|
case 'shutdown':
|
|
this.bot.shutdown();
|
|
break;
|
|
}
|
|
});
|
|
}
|
|
} |