UNPKG

7.36 kBJavaScriptView Raw
1var cp = require('child_process'),
2 os = require('os'),
3 fs = require('fs'),
4 path = require('path'),
5 shellwords = require('shellwords'),
6 semver = require('semver'),
7 clone = require('lodash.clonedeep');
8
9
10var escapeQuotes = function (str) {
11 if (typeof str === 'string') {
12 return str.replace(/(["$`\\])/g, '\\$1');
13 } else {
14 return str;
15 }
16};
17
18var inArray = function (arr, val) {
19 for(var i = 0; i < arr.length; i++) {
20 if (arr[i] === val) {
21 return true;
22 }
23 }
24 return false;
25};
26
27var notifySendFlags = {
28 "u": "urgency",
29 "urgency": "urgency",
30 "t": "expire-time",
31 "e": "expire-time",
32 "expire": "expire-time",
33 "expire-time": "expire-time",
34 "i": "icon",
35 "icon": "icon",
36 "c": "category",
37 "category": "category",
38 "subtitle": "category",
39 "h": "hint",
40 "hint": "hint"
41};
42
43module.exports.command = function (notifier, options, cb) {
44 notifier = shellwords.escape(notifier);
45 return cp.exec(notifier + ' ' + options.join(' '), function (error, stdout, stderr) {
46 if (error) return cb(error);
47 cb(stderr, stdout);
48 });
49};
50
51module.exports.fileCommand = function (notifier, options, cb) {
52 return cp.execFile(notifier, options, function (error, stdout, stderr) {
53 if (error) return cb(error, stdout);
54 cb(stderr, stdout);
55 });
56};
57
58module.exports.immediateFileCommand = function (notifier, options, cb) {
59 notifierExists(notifier, function (exists) {
60 if (!exists) return cb(new Error('Notifier (' + notifier + ') not found on system.'));
61 cp.execFile(notifier, options);
62 cb();
63 });
64};
65
66function notifierExists (notifier, cb) {
67 return fs.stat(notifier, function (err, stat) {
68 if (!err) return cb(stat.isFile());
69
70 // Check if Windows alias
71 if (!!path.extname(notifier)) {
72 // Has extentioon, no need to check more
73 return cb(false);
74 }
75
76 // Check if there is an exe file in the directory
77 return fs.stat(notifier + '.exe', function (err, stat) {
78 cb(stat.isFile());
79 });
80 });
81}
82
83var mapAppIcon = function (options) {
84 if (options.appIcon) {
85 options.icon = options.appIcon;
86 delete options.appIcon;
87 }
88
89 return options;
90};
91
92var mapText = function (options) {
93 if (options.text) {
94 options.message = options.text;
95 delete options.text;
96 }
97
98 return options;
99};
100
101var mapIconShorthand = function (options) {
102 if (options.i) {
103 options.icon = options.i;
104 delete options.i;
105 }
106
107 return options;
108};
109
110module.exports.mapToNotifySend = function (options) {
111 options = mapAppIcon(options);
112 options = mapText(options);
113
114 for (var key in options) {
115 if (key === "message" || key === "title") continue;
116 if (options.hasOwnProperty(key) && (notifySendFlags[key] != key)) {
117 options[notifySendFlags[key]] = options[key];
118 delete options[key];
119 }
120 }
121
122 return options;
123};
124
125module.exports.mapToGrowl = function (options) {
126 options = mapAppIcon(options);
127 options = mapIconShorthand(options);
128
129 if (options.text) {
130 options.message = options.text;
131 delete options.text;
132 }
133
134 if (options.icon && !Buffer.isBuffer(options.icon)) {
135 options.icon = fs.readFileSync(options.icon);
136 }
137
138 return options;
139};
140
141module.exports.mapToMac = function (options) {
142 options = mapIconShorthand(options);
143 options = mapText(options);
144
145 if (options.icon) {
146 options.appIcon = options.icon;
147 delete options.icon;
148 }
149
150 if (options.sound === true) {
151 options.sound = 'Bottle';
152 }
153
154 if (options.sound === false) {
155 delete options.sound;
156 }
157
158 return options;
159};
160
161module.exports.actionJackerDecorator = function (emitter, options, fn, mapper) {
162 options = clone(options);
163 fn = fn || function (err, data) {};
164 return function (err, data) {
165 fn.apply(emitter, [err, data]);
166 if (err || !mapper || !data) return;
167
168 var key = mapper(data);
169 if (!key) return;
170 emitter.emit(key, emitter, options);
171 };
172};
173
174module.exports.constructArgumentList = function (options, extra) {
175 var args = [];
176 extra = extra || {};
177
178 // Massive ugly setup. Default args
179 var initial = extra.initial || [];
180 var keyExtra = extra.keyExtra || "";
181 var allowedArguments = extra.allowedArguments || [];
182 var noEscape = extra.noEscape !== void 0;
183 var checkForAllowed = extra.allowedArguments !== void 0;
184 var explicitTrue = !!extra.explicitTrue;
185 var wrapper = extra.wrapper === void 0 ? '"' : extra.wrapper;
186
187 var escapeFn = noEscape ? function (i) { return i; } : escapeQuotes;
188
189 initial.forEach(function (val) {
190 args.push(wrapper + escapeFn(val) + wrapper);
191 });
192 for(var key in options) {
193 if (options.hasOwnProperty(key) && (!checkForAllowed || inArray(allowedArguments, key))) {
194 if (explicitTrue && options[key] === true) args.push('-' + keyExtra + key);
195 else if (explicitTrue && options[key] === false) continue;
196 else args.push('-' + keyExtra + key, wrapper + escapeFn(options[key]) + wrapper);
197 }
198 }
199 return args;
200};
201
202module.exports.mapToWin8 = function (options){
203
204 options = mapAppIcon(options);
205 options = mapText(options);
206
207 if(options.icon){
208 options.p = options.icon;
209 delete options.icon;
210 }
211
212 if(options.message){
213 // Remove escape char to debug "HRESULT : 0xC00CE508" exception
214 options.m = options.message.replace(/\x1b/g, '');
215 delete options.message;
216 }
217
218 if (options.title) {
219 options.t = options.title;
220 delete options.title;
221 }
222
223 if (options.quiet || options.silent) {
224 options.q = options.quiet || options.silent;
225 delete options.quiet;
226 delete options.silent;
227 }
228
229 if (options.q !== false) {
230 options.q = true;
231 } else {
232 delete options.q;
233 }
234
235 if (options.sound) {
236 delete options.q;
237 delete options.sound;
238 }
239
240 if (options.wait) {
241 options.w = options.wait;
242 delete options.wait;
243 }
244
245 return options;
246};
247
248module.exports.mapToNotifu = function (options) {
249 options = mapAppIcon(options);
250 options = mapText(options);
251
252 if(options.icon){
253 options.i = options.icon;
254 delete options.icon;
255 }
256
257 if(options.message){
258 options.m = options.message;
259 delete options.message;
260 }
261
262 if (options.title) {
263 options.p = options.title;
264 delete options.title;
265 }
266
267 if (options.time) {
268 options.d = options.time;
269 delete options.time;
270 }
271
272 if (options.q !== false) {
273 options.q = true;
274 } else {
275 delete options.q;
276 }
277
278 if (options.quiet === false) {
279 delete options.q;
280 delete options.quiet;
281 }
282
283 if (options.sound) {
284 delete options.q;
285 delete options.sound;
286 }
287
288 if (options.t) {
289 options.d = options.t;
290 delete options.t;
291 }
292
293 return options;
294};
295
296module.exports.isMac = function() {
297 return os.type() === 'Darwin';
298};
299
300module.exports.isMountainLion = function() {
301 return os.type() === 'Darwin' && semver.satisfies(garanteeSemverFormat(os.release()), '>=12.0.0');
302};
303
304module.exports.isWin8 = function() {
305 return os.type() === 'Windows_NT' && semver.satisfies(garanteeSemverFormat(os.release()), '>=6.2.9200');
306};
307
308module.exports.isLessThanWin8 = function() {
309 return os.type() === 'Windows_NT' && semver.satisfies(garanteeSemverFormat(os.release()), '<6.2.9200');
310};
311
312function garanteeSemverFormat (version) {
313 if (version.split('.').length === 2) {
314 version += '.0';
315 }
316 return version;
317}