OpenROV /
openrov-cockpit
| 1 | var logger; |
||
| 2 | const nedb = require('nedb'); |
||
|
0 ignored issues
–
show
Backwards Compatibility
introduced
by
Loading history...
|
|||
| 3 | const path = require('path'); |
||
|
0 ignored issues
–
show
|
|||
| 4 | const bluebird = require('bluebird'); |
||
|
0 ignored issues
–
show
|
|||
| 5 | const mkdirp = require('mkdirp'); |
||
|
0 ignored issues
–
show
|
|||
| 6 | const Listener = require('Listener'); |
||
|
0 ignored issues
–
show
|
|||
| 7 | |||
| 8 | var _announcementScheduled = false; |
||
| 9 | class Notifications { |
||
|
0 ignored issues
–
show
|
|||
| 10 | |||
| 11 | constructor(name, deps) { |
||
| 12 | logger= deps.logger; |
||
| 13 | |||
| 14 | logger.info("Loaded Notifications plugin"); |
||
| 15 | |||
| 16 | this.globalBus = deps.globalEventLoop; // This is the server-side messaging bus. The MCU sends messages to server plugins over this |
||
| 17 | this.cockpitBus = deps.cockpit; // This is the server<->client messaging bus. This is how the server talks to the browser |
||
| 18 | var self = this; |
||
| 19 | this.db = null; //db not yet initialized |
||
| 20 | |||
| 21 | this.listeners = { |
||
| 22 | settings: new Listener(self.globalBus, 'settings-change.notifications', true, function(settings) { |
||
| 23 | self.settings = settings.notifications; |
||
| 24 | self.initDB() |
||
| 25 | .then(self.announceNotices.bind(self)); |
||
| 26 | }), |
||
| 27 | |||
| 28 | peristentNotices: new Listener(self.globalBus, 'notification', false, function(notice) { |
||
| 29 | self.cockpitBus.emit('plugin.notification.notify', { |
||
| 30 | timestamp: Date.now(), |
||
| 31 | notice: notice |
||
| 32 | }); |
||
| 33 | if (!self.db) { |
||
| 34 | return; //ignore persistening if the db is not ready |
||
| 35 | } |
||
| 36 | |||
| 37 | self.db.insert({ |
||
| 38 | timestamp: Date.now(), |
||
| 39 | notice: notice |
||
| 40 | }); |
||
| 41 | }), |
||
| 42 | |||
| 43 | clear: new Listener(self.cockpitBus, 'plugin.notifications.clear', false, function() { |
||
| 44 | self.db.removeAsync({}, { |
||
| 45 | multi: true |
||
| 46 | }) |
||
| 47 | .then(function(numRemoved) { |
||
| 48 | trace(`Cleared ${numRemoved} notifications`); |
||
|
0 ignored issues
–
show
'template literal syntax' is only available in ES6 (use 'esversion: 6').
Generally using ECMAScript 6 specific syntax is fine if you are sure that it is already supported by all engines which are supposed to run this code. Further Reading: Loading history...
|
|||
| 49 | self.announceNotices(); |
||
| 50 | }) |
||
|
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: Loading history...
|
|||
| 51 | }) |
||
| 52 | } |
||
|
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: Loading history...
|
|||
| 53 | } |
||
| 54 | |||
| 55 | |||
| 56 | start() { |
||
| 57 | // Enable the listeners! |
||
| 58 | this.listeners.settings.enable(); |
||
| 59 | this.listeners.peristentNotices.enable(); |
||
| 60 | this.listeners.clear.enable(); |
||
| 61 | if (process.env.NODE_ENV == "development") { |
||
| 62 | this.globalBus.emit("notification", "Notification service started"); |
||
| 63 | } |
||
| 64 | } |
||
| 65 | |||
| 66 | // This is called when the plugin is disabled |
||
| 67 | stop() { |
||
| 68 | // Disable listeners |
||
| 69 | this.listeners.settings.disable(); |
||
| 70 | this.listeners.peristentNotices.disable(); |
||
| 71 | this.listeners.clear.disable(); |
||
| 72 | } |
||
| 73 | |||
| 74 | announceNotices() { |
||
| 75 | var self = this; |
||
| 76 | if (_announcementScheduled) { |
||
| 77 | return; |
||
| 78 | } |
||
| 79 | setTimeout(function() { |
||
| 80 | self.getAllNotifications() |
||
| 81 | .then(function(notices) { |
||
| 82 | self.cockpitBus.emit("plugin.notification.all-notices", notices); |
||
| 83 | }) |
||
| 84 | .catch(function(ex) { |
||
| 85 | throw ex; |
||
| 86 | }) |
||
| 87 | .then(function() { |
||
| 88 | _announcementScheduled = false; |
||
| 89 | }); |
||
| 90 | }, 1000 * 60); //Throttle at 1 per minute |
||
| 91 | |||
| 92 | } |
||
| 93 | |||
| 94 | getAllNotifications() { |
||
| 95 | return this.db.findAsync({}); |
||
| 96 | } |
||
| 97 | |||
| 98 | initDB() { |
||
| 99 | var self = this; |
||
| 100 | return bluebird.try(function() { |
||
| 101 | if (self.db){ |
||
| 102 | //Only initialize once, changes to settings used by nedb will requires a process restart. |
||
| 103 | return; |
||
| 104 | } |
||
| 105 | if (process.env.NODE_ENV == "development") { |
||
| 106 | self.db = new nedb(); |
||
| 107 | bluebird.promisifyAll(self.db); |
||
| 108 | //This intentionally does not honor selective debug logging. |
||
| 109 | logger.warn('neDB intialized as inMemory -- ONLY USE FOR TESTING'); |
||
| 110 | } else { |
||
| 111 | var nedbDir = process.env.DATADIR || '/etc' |
||
|
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: Loading history...
|
|||
| 112 | mkdirp.sync(path.join(nedbDir, 'OpenROV')); |
||
| 113 | logger.debug('database: ' + path.join(nedbDir, 'OpenROV/notifications.db')); |
||
| 114 | self.db = new nedb({ |
||
| 115 | filename: path.join(nedbDir, 'OpenROV/notifications.db'), |
||
| 116 | autoload: true |
||
| 117 | }); |
||
| 118 | bluebird.promisifyAll(self.db); |
||
| 119 | self.db.persistence.setAutocompactionInterval(process.env.AutocompactionInterval || 1000 * 60 * 10); |
||
| 120 | } |
||
| 121 | |||
| 122 | }) |
||
|
0 ignored issues
–
show
There should be a semicolon.
Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers. Further Readings: Loading history...
|
|||
| 123 | } |
||
| 124 | |||
| 125 | // This is used to define user settings for the plugin. We populated some example properties below. |
||
| 126 | // The UI for changing the settings is automatically generated in the Settings applet. |
||
| 127 | getSettingSchema() |
||
| 128 | { |
||
| 129 | //from http://json-schema.org/examples.html |
||
| 130 | return [{ |
||
| 131 | 'title': 'Notification Settings', |
||
| 132 | 'type': 'object', |
||
| 133 | 'id': 'notifications', |
||
| 134 | 'properties': { |
||
| 135 | 'persistBetweenReboots': { |
||
| 136 | 'type': 'boolean', |
||
| 137 | 'default': true |
||
| 138 | } |
||
| 139 | } |
||
| 140 | }]; |
||
| 141 | } |
||
| 142 | |||
| 143 | } |
||
| 144 | |||
| 145 | module.exports = function(name, deps) { |
||
| 146 | return new Notifications(name, deps); |
||
| 147 | }; |
||
| 148 |