UNPKG

6.2 kBJavaScriptView Raw
1/**
2* Main platform. Handles the core interop of the program and
3* acts as the glue code for the various parts of the code.
4*
5* Written By:
6* Matthew Knox
7*
8* License:
9* MIT License. All code unless otherwise specified is
10* Copyright (c) Matthew Knox and Contributors 2015.
11*/
12
13const figlet = require('figlet'),
14 EventEmitter = require('events').EventEmitter;
15
16class Platform extends EventEmitter {
17 constructor(integrations) {
18 super();
19 this.config = require.once('./config.js');
20 this.integrationManager = require.once('./integrations/integrations.js');
21 this.integrationManager.setIntegrations(integrations);
22 this.defaultPrefix = '/';
23 this.packageInfo = require.once('../package.json');
24 this.modulesLoader = require.once('./modules/modules.js');
25 this.statusFlag = global.StatusFlag.NotStarted;
26 this.onShutdown = null;
27 this.waitingTime = 250;
28 this.packageInfo.name = this.packageInfo.name.toProperCase();
29 }
30
31 _handleTransaction (module, args) {
32 let returnVal = null;
33 const timeout = setTimeout(function () {
34 if (returnVal !== null) {
35 return;
36 }
37 args[0].sendTyping(args[1].thread_id);
38 }, this.waitingTime);
39 try {
40 returnVal = module.run.apply(this, args);
41 }
42 catch (e) {
43 args[0].sendMessage($$`${args[1].body} failed ${args[1].sender_name} caused it`, args[1].thread_id);
44 console.critical(e);
45 }
46 finally {
47 clearTimeout(timeout);
48 }
49
50 return returnVal;
51 }
52
53 onMessage (api, event) {
54 let matchArgs = [event, api.commandPrefix],
55 runArgs = [api, event],
56 loadedModules = this.modulesLoader.getLoadedModules();
57
58 event.module_match_count = 0;
59 for (let i = 0; i < loadedModules.length; i++) {
60 let matchResult;
61 try {
62 matchResult = loadedModules[i].match.apply(loadedModules[i], matchArgs);
63 }
64 catch (e) {
65 console.error($$`BrokenModule ${loadedModules[i].name}`);
66 console.critical(e);
67 continue;
68 }
69
70 if (matchResult) {
71 event.module_match_count++;
72 let transactionRes = this._handleTransaction(loadedModules[i], runArgs);
73 if (event.shouldAbort || transactionRes) {
74 return;
75 }
76 }
77 }
78 }
79
80 getIntegrationApis () {
81 let integs = this.integrationManager.getSetIntegrations(),
82 apis = {};
83 for (let key in integs) {
84 if (!integs.hasOwnProperty(key)) {
85 continue;
86 }
87 apis[key] = integs[key].getApi();
88 }
89 return apis;
90 }
91
92 _firstRun () {
93 const git = require.once('./git.js'),
94 path = require('path'),
95 defaultModules = [
96 ['https://github.com/concierge/creator.git', 'creator'],
97 ['https://github.com/concierge/help.git', 'help'],
98 ['https://github.com/concierge/kpm.git', 'kpm'],
99 ['https://github.com/concierge/ping.git', 'ping'],
100 ['https://github.com/concierge/restart.git', 'restart'],
101 ['https://github.com/concierge/shutdown.git', 'shutdown'],
102 ['https://github.com/concierge/update.git', 'update']
103 ];
104
105 for (let i = 0; i < defaultModules.length; i++) {
106 console.warn($$`Attempting to install module from "${defaultModules[i][0]}"`);
107 git.clone(defaultModules[i][0], path.join(global.__modulesPath, defaultModules[i][1]), (err) => {
108 if (err) {
109 console.critical(err);
110 console.error($$`Failed to install module from "${defaultModules[i][0]}"`);
111 }
112 else {
113 console.warn($$`"${defaultModules[i][1]}" (${'core_' + this.packageInfo.version}) is now installed.`);
114 }
115 });
116 }
117 }
118
119 start () {
120 if (this.statusFlag !== global.StatusFlag.NotStarted) {
121 throw new Error($$`StartError`);
122 }
123
124 console.title(figlet.textSync(this.packageInfo.name.toProperCase()));
125
126 console.title(' ' + this.packageInfo.version);
127 console.info('------------------------------------');
128 console.warn($$`StartingSystem`);
129
130 // Load system config
131 console.warn($$`LoadingSystemConfig`);
132 $$.setLocale(this.config.getConfig('i18n').locale);
133 this.integrationManager.setIntegrationConfigs(this);
134 let firstRun = this.config.getConfig('firstRun');
135 if (!firstRun.hasRun) {
136 firstRun.hasRun = true;
137 this._firstRun();
138 }
139 this.allowLoopback = !!this.config.getConfig('loopback').enabled;
140
141 // Load modules
142 console.warn($$`LoadingModules`);
143 this.modulesLoader.loadAllModules(this);
144
145 // Starting output
146 console.warn($$`StartingIntegrations`);
147 this.integrationManager.startIntegrations(this.onMessage.bind(this));
148
149 this.statusFlag = global.StatusFlag.Started;
150 console.warn($$`SystemStarted` + ' ' + $$`HelloWorld`.rainbow);
151 }
152
153 shutdown (flag) {
154 if (this.statusFlag !== global.StatusFlag.Started) {
155 throw new Error($$`ShutdownError`);
156 }
157 if (!flag) {
158 flag = global.StatusFlag.Unknown;
159 }
160
161 // Stop output integrations
162 this.integrationManager.stopIntegrations();
163
164 // Unload user modules
165 this.modulesLoader.unloadAllModules(this.config);
166
167 this.config.saveSystemConfig();
168 this.statusFlag = flag ? flag : global.StatusFlag.Shutdown;
169
170 console.warn($$`${this.packageInfo.name} Shutdown`);
171 this.emit('shutdown', this.statusFlag);
172 }
173};
174
175module.exports = Platform;