129 lines
3.4 KiB
TypeScript
129 lines
3.4 KiB
TypeScript
import * as path from 'path';
|
|
|
|
import { ChannelManager } from '@squeebot/core/lib/channel';
|
|
|
|
import { PluginManager, PluginMetaLoader } from '@squeebot/core/lib/plugin';
|
|
|
|
import { RepositoryManager } from '@squeebot/core/lib/plugin/repository';
|
|
|
|
import { NPMExecutor } from '@squeebot/core/lib/npm';
|
|
|
|
import { Configuration, IEnvironment } from '@squeebot/core/lib/types';
|
|
|
|
import { ScopedEventEmitter } from '@squeebot/core/lib/util';
|
|
|
|
import { ISqueebotCore, logger } from '@squeebot/core/lib/core';
|
|
|
|
const defaultConfiguration: {[key: string]: any} = {
|
|
channels: [],
|
|
enabled: [],
|
|
name: 'squeebot',
|
|
};
|
|
|
|
export class Squeebot implements ISqueebotCore {
|
|
public npm: NPMExecutor = new NPMExecutor(this.environment, '@squeebot/core');
|
|
|
|
public stream: ScopedEventEmitter = new ScopedEventEmitter();
|
|
|
|
public pluginManager: PluginManager = new PluginManager(
|
|
[],
|
|
this.stream,
|
|
this.environment,
|
|
this.npm);
|
|
|
|
public repositoryManager: RepositoryManager = new RepositoryManager(
|
|
this.environment,
|
|
this.pluginManager,
|
|
);
|
|
|
|
public channelManager: ChannelManager = new ChannelManager(this.stream);
|
|
|
|
public pluginLoader: PluginMetaLoader = new PluginMetaLoader(
|
|
this.environment,
|
|
);
|
|
|
|
public config: Configuration = new Configuration(
|
|
this.environment,
|
|
path.join(this.environment.configurationPath, 'squeebot.json'),
|
|
defaultConfiguration,
|
|
);
|
|
|
|
private shuttingDown = false;
|
|
|
|
constructor(public environment: IEnvironment) {}
|
|
|
|
public async initialize(autostart: boolean = true): Promise<void> {
|
|
// Load configuration
|
|
await this.config.load();
|
|
|
|
// Initialize npm executor
|
|
await this.npm.loadPackageFile();
|
|
|
|
// Load all plugins
|
|
const plugins = await this.pluginLoader.loadAll();
|
|
|
|
// Give manager all loaded manifests
|
|
this.pluginManager.addAvailable(plugins);
|
|
|
|
// Load repositories
|
|
await this.repositoryManager.loadFromFiles();
|
|
|
|
// Start channels
|
|
this.channelManager.initialize(this.config.get('channels'));
|
|
|
|
if (autostart) {
|
|
// Start enabled plugins
|
|
await this.startPlugins();
|
|
}
|
|
|
|
// Send core on request
|
|
this.stream.on('core', 'request-core', (pl: string) =>
|
|
this.stream.emitTo(pl, 'core', this));
|
|
}
|
|
|
|
public async startPlugins(): Promise<void> {
|
|
for (const pluginName of this.config.get('enabled')) {
|
|
const getManifest = this.pluginManager.getAvailableByName(pluginName);
|
|
if (!getManifest) {
|
|
logger.error(new Error(`Failed to start ${pluginName}: no manifest available. You might not have installed it.`));
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await this.pluginManager.load(getManifest);
|
|
} catch (e) {
|
|
logger.error('Failed to start %s:', pluginName, e.stack);
|
|
}
|
|
}
|
|
}
|
|
|
|
public attachReadline(rl: any): void {
|
|
// Pass readline to logger
|
|
logger.setReadline(rl);
|
|
|
|
// Send readline on request
|
|
this.stream.on('core', 'request-cli', () =>
|
|
this.stream.emit('cli', rl));
|
|
|
|
// Handle readline events
|
|
rl.on('line', (l: string) => this.stream.emit('cli-line', l));
|
|
rl.on('SIGINT', () => this.shutdown());
|
|
}
|
|
|
|
public shutdown(): void {
|
|
if (this.shuttingDown) {
|
|
return;
|
|
}
|
|
|
|
logger.warn('Shutting down..');
|
|
|
|
this.shuttingDown = true;
|
|
this.stream.on('core', 'shutdown', (state: number) => {
|
|
if (state > 0) {
|
|
this.config.save().then((x) => process.exit(0));
|
|
}
|
|
});
|
|
this.stream.emitTo('core', 'shutdown', 0);
|
|
}
|
|
}
|