1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | const figlet = require('figlet'),
|
14 | EventEmitter = require('events').EventEmitter;
|
15 |
|
16 | class 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 |
|
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 |
|
142 | console.warn($$`LoadingModules`);
|
143 | this.modulesLoader.loadAllModules(this);
|
144 |
|
145 |
|
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 |
|
162 | this.integrationManager.stopIntegrations();
|
163 |
|
164 |
|
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 |
|
175 | module.exports = Platform;
|