@iobroker/socket-classes 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -69,6 +69,9 @@ io.close();
69
69
  -->
70
70
 
71
71
  ## Changelog
72
+ ### 0.1.8 (2022-05-07)
73
+ * (bluefox) Corrected readLogs command and implement file subscriptions
74
+
72
75
  ### 0.1.7 (2022-05-05)
73
76
  * (bluefox) Caught some sentry errors
74
77
 
@@ -142,29 +142,30 @@ class SocketAdmin extends SocketCommon {
142
142
 
143
143
  if (this.server && this.server.sockets) {
144
144
  this.server.sockets.connected.forEach(socket =>
145
- this.__updateSession(socket));
145
+ this.commands.publish(socket, 'stateChange', id, state));
146
+ }
147
+ }
146
148
 
147
- this.server.sockets.emit('stateChange', id, state);
149
+ fileChange(id, fileName, size) {
150
+ if (this.server && this.server.sockets) {
151
+ this.server.sockets.connected.forEach(socket =>
152
+ this.commands.publishFile(socket, id, fileName, size));
148
153
  }
149
154
  }
150
155
 
151
156
  repoUpdated() {
152
157
  if (this.server && this.server.sockets) {
158
+ this.server.sockets.connected.forEach(socket =>
159
+ this.__updateSession(socket));
160
+
153
161
  this.server.sockets.emit('repoUpdated');
154
162
  }
155
163
  }
156
164
 
157
165
  objectChange(id, obj) {
158
166
  if (this.server && this.server.sockets) {
159
- const clients = this.server.sockets.connected;
160
-
161
- for (const i in clients) {
162
- if (clients.hasOwnProperty(i)) {
163
- this.__updateSession(clients[i]);
164
- }
165
- }
166
-
167
- this.server.sockets.emit('objectChange', id, obj);
167
+ this.server.sockets.connected.forEach(socket =>
168
+ this.commands.publish(socket, 'objectChange', id, obj));
168
169
  }
169
170
  }
170
171
 
@@ -172,8 +173,15 @@ class SocketAdmin extends SocketCommon {
172
173
  this.commands.subscribe(null, type, pattern);
173
174
  }
174
175
 
176
+ subscribeFile(id, pattern) {
177
+ this.commands.subscribe(null, 'fileChange', id, pattern);
178
+ }
179
+
175
180
  sendCommand(obj) {
176
- if (this.commands.sendCommand(obj) && this.server) {
181
+ if (this.commands.sendCommand(obj) && this.server && this.server.sockets) {
182
+ this.server.sockets.connected.forEach(socket =>
183
+ this.__updateSession(socket));
184
+
177
185
  this.server.sockets.emit(obj.command, obj.message.id, obj.message.data);
178
186
  }
179
187
  }
@@ -66,6 +66,8 @@ class SocketCommands {
66
66
  mkdir: {type: 'file', operation: 'write'},
67
67
  chmodFile: {type: 'file', operation: 'write'},
68
68
  chownFile: {type: 'file', operation: 'write'},
69
+ subscribeFiles: {type: 'file', operation: 'read'},
70
+ unsubscribeFiles: {type: 'file', operation: 'read'},
69
71
 
70
72
  authEnabled: {type: '', operation: ''},
71
73
  disconnect: {type: '', operation: ''},
@@ -209,24 +211,8 @@ class SocketCommands {
209
211
  }
210
212
  }
211
213
 
212
- _subscribeStates(socket, pattern, callback) {
213
- if (this._checkPermissions(socket, 'subscribe', callback, pattern)) {
214
- if (pattern && typeof pattern === 'object' && pattern instanceof Array) {
215
- for (let p = 0; p < pattern.length; p++) {
216
- this.subscribe(socket, 'stateChange', pattern[p]);
217
- }
218
- } else {
219
- this.subscribe(socket, 'stateChange', pattern);
220
- }
221
-
222
- this.adapter.log.level === 'debug' && this._showSubscribes(socket, 'stateChange');
223
-
224
- typeof callback === 'function' && setImmediate(callback, null);
225
- }
226
- }
227
-
228
214
  publish(socket, type, id, obj) {
229
- if (socket && socket.subscribe && socket.subscribe[type]) {
215
+ if (socket && socket.subscribe && socket.subscribe[type] && this._updateSession(socket)) {
230
216
  return !!socket.subscribe[type].find(sub => {
231
217
  if (sub.regex.test(id)) {
232
218
  socket.emit(type, id, obj);
@@ -234,15 +220,51 @@ class SocketCommands {
234
220
  }
235
221
  });
236
222
  }
223
+
237
224
  return false;
238
225
  }
239
226
 
240
- subscribe(socket, type, pattern) {
227
+ publishFile(socket, id, fileName, size) {
228
+ if (socket && socket.subscribe && socket.subscribe.fileChange && this._updateSession(socket)) {
229
+ const key = id + '####' + fileName;
230
+ return !!socket.subscribe.fileChange.find(sub => {
231
+ if (sub.regex.test(key)) {
232
+ socket.emit('fileChange', id, fileName, size);
233
+ return true;
234
+ }
235
+ });
236
+ }
237
+
238
+ return false;
239
+ }
240
+
241
+ _showSubscribes(socket, type) {
242
+ if (socket && socket.subscribe) {
243
+ const s = socket.subscribe[type] || [];
244
+ const ids = [];
245
+ for (let i = 0; i < s.length; i++) {
246
+ ids.push(s[i].pattern);
247
+ }
248
+ this.adapter.log.debug('Subscribes: ' + ids.join(', '));
249
+ } else {
250
+ this.adapter.log.debug('Subscribes: no subscribes');
251
+ }
252
+ }
253
+
254
+ subscribe(socket, type, pattern, patternFile) {
241
255
  this.subscribes[type] = this.subscribes[type] || {};
242
256
 
257
+ let p;
258
+ let key;
243
259
  pattern = pattern.toString();
260
+ if (patternFile && type === 'fileChange') {
261
+ patternFile = patternFile.toString();
262
+ key = pattern + '####' + patternFile;
263
+ } else {
264
+ key = pattern;
265
+ }
244
266
 
245
- const p = pattern2RegEx(pattern);
267
+ p = pattern2RegEx(key);
246
268
  if (p === null) {
247
269
  return this.adapter.log.warn('Empty pattern on subscribe!');
248
270
  }
@@ -252,44 +274,42 @@ class SocketCommands {
252
274
  socket.subscribe = socket.subscribe || {};
253
275
  s = socket.subscribe[type] = socket.subscribe[type] || [];
254
276
 
255
- if (s.find(item => item.pattern === pattern)) {
277
+ if (s.find(item => item.pattern === key)) {
256
278
  return;
257
279
  }
258
- s.push({pattern, regex: new RegExp(p)});
280
+ s.push({pattern: key, regex: new RegExp(p)});
259
281
  }
260
282
 
261
- if (this.subscribes[type][pattern] === undefined) {
262
- this.subscribes[type][pattern] = 1;
283
+ if (this.subscribes[type][key] === undefined) {
284
+ this.subscribes[type][key] = 1;
263
285
  if (type === 'stateChange') {
264
286
  this.adapter.subscribeForeignStates(pattern);
265
287
  } else if (type === 'objectChange') {
266
288
  this.adapter.subscribeForeignObjects && this.adapter.subscribeForeignObjects(pattern);
267
289
  } else if (type === 'log') {
268
290
  this.adapter.requireLog && this.adapter.requireLog(true);
291
+ } else if (type === 'fileChange') {
292
+ this.adapter.subscribeForeignFiles && this.adapter.subscribeForeignFiles(pattern, patternFile);
269
293
  }
270
294
  } else {
271
- this.subscribes[type][pattern]++;
295
+ this.subscribes[type][key]++;
272
296
  }
273
297
  };
274
298
 
275
- _showSubscribes(socket, type) {
276
- if (socket && socket.subscribe) {
277
- const s = socket.subscribe[type] || [];
278
- const ids = [];
279
- for (let i = 0; i < s.length; i++) {
280
- ids.push(s[i].pattern);
281
- }
282
- this.adapter.log.debug('Subscribes: ' + ids.join(', '));
283
- } else {
284
- this.adapter.log.debug('Subscribes: no subscribes');
285
- }
286
- }
287
-
288
- unsubscribe(socket, type, pattern) {
299
+ unsubscribe(socket, type, pattern, patternFile) {
289
300
  //console.log((socket._name || socket.id) + ' unsubscribe ' + pattern);
290
- this.subscribes[type] = this.subscribes[type] || {};
301
+ if (!this.subscribes[type]) {
302
+ return;
303
+ }
291
304
 
305
+ let key;
292
306
  pattern = pattern.toString();
307
+ if (patternFile && type === 'fileChange') {
308
+ patternFile = patternFile.toString();
309
+ key = pattern + '####' + patternFile;
310
+ } else {
311
+ key = pattern;
312
+ }
293
313
 
294
314
  if (socket && typeof socket === 'object') {
295
315
  if (!socket.subscribe || !socket.subscribe[type]) {
@@ -297,12 +317,12 @@ class SocketCommands {
297
317
  }
298
318
 
299
319
  for (let i = socket.subscribe[type].length - 1; i >= 0; i--) {
300
- if (socket.subscribe[type][i].pattern === pattern) {
320
+ if (socket.subscribe[type][i].pattern === key) {
301
321
 
302
322
  // Remove pattern from global list
303
- if (this.subscribes[type][pattern] !== undefined) {
304
- this.subscribes[type][pattern]--;
305
- if (this.subscribes[type][pattern] <= 0) {
323
+ if (this.subscribes[type][key] !== undefined) {
324
+ this.subscribes[type][key]--;
325
+ if (this.subscribes[type][key] <= 0) {
306
326
  if (type === 'stateChange') {
307
327
  //console.log((socket._name || socket.id) + ' unsubscribeForeignStates ' + pattern);
308
328
  this.adapter.unsubscribeForeignStates(pattern);
@@ -312,6 +332,9 @@ class SocketCommands {
312
332
  } else if (type === 'log') {
313
333
  //console.log((socket._name || socket.id) + ' requireLog false');
314
334
  this.adapter.requireLog && this.adapter.requireLog(false);
335
+ } else if (type === 'fileChange') {
336
+ //console.log((socket._name || socket.id) + ' requireLog false');
337
+ this.adapter.unsubscribeForeignFiles && this.adapter.unsubscribeForeignFiles(pattern, patternFile);
315
338
  }
316
339
  delete this.subscribes[type][pattern];
317
340
  }
@@ -322,26 +345,25 @@ class SocketCommands {
322
345
  return;
323
346
  }
324
347
  }
325
- } else if (pattern) {
348
+ } else if (key) {
326
349
  // Remove pattern from global list
327
- if (this.subscribes[type][pattern] !== undefined) {
328
- this.subscribes[type][pattern]--;
329
- if (this.subscribes[type][pattern] <= 0) {
350
+ if (this.subscribes[type][key] !== undefined) {
351
+ this.subscribes[type][key]--;
352
+ if (this.subscribes[type][key] <= 0) {
330
353
  if (type === 'stateChange') {
331
354
  this.adapter.unsubscribeForeignStates(pattern);
332
355
  } else if (type === 'objectChange') {
333
356
  this.adapter.unsubscribeForeignObjects && this.adapter.unsubscribeForeignObjects(pattern);
334
357
  } else if (type === 'log') {
335
358
  this.adapter.requireLog && this.adapter.requireLog(false);
359
+ } else if (type === 'fileChange') {
360
+ this.adapter.unsubscribeForeignFiles && this.adapter.unsubscribeForeignFiles(pattern, patternFile);
336
361
  }
337
- delete this.subscribes[type][pattern];
362
+ delete this.subscribes[type][key];
338
363
  }
339
364
  }
340
365
  } else {
341
- for (pattern in this.subscribes[type]) {
342
- if (!Object.prototype.hasOwnProperty.call(this.subscribes[type], pattern)) {
343
- continue;
344
- }
366
+ Object.keys(this.subscribes[type]).forEach(pattern => {
345
367
  if (type === 'stateChange') {
346
368
  //console.log((socket._name || socket.id) + ' unsubscribeForeignStates ' + pattern);
347
369
  this.adapter.unsubscribeForeignStates(pattern);
@@ -351,20 +373,24 @@ class SocketCommands {
351
373
  } else if (type === 'log') {
352
374
  //console.log((socket._name || socket.id) + ' requireLog false');
353
375
  this.adapter.requireLog && this.adapter.requireLog(false);
376
+ } else if (type === 'fileChange') {
377
+ const [id, fileName] = pattern.split('####');
378
+ this.adapter.unsubscribeForeignFiles && this.adapter.unsubscribeForeignFiles(id, fileName);
354
379
  }
355
- delete this.subscribes[type][pattern];
356
- }
380
+ });
381
+
382
+ this.subscribes[type] = {}
357
383
  }
358
384
  };
359
385
 
360
- unsubscribeSocket(socket, type) {
386
+ subscribeSocket(socket, type) {
361
387
  if (!socket || !socket.subscribe) {
362
388
  return;
363
389
  }
364
390
 
365
391
  if (!type) {
366
392
  // all
367
- return Object.keys(socket.subscribe).forEach(type => this.unsubscribeSocket(socket, type));
393
+ return Object.keys(socket.subscribe).forEach(type => this.subscribeSocket(socket, type));
368
394
  }
369
395
 
370
396
  if (!socket.subscribe[type]) {
@@ -373,30 +399,29 @@ class SocketCommands {
373
399
 
374
400
  for (let i = 0; i < socket.subscribe[type].length; i++) {
375
401
  const pattern = socket.subscribe[type][i].pattern;
376
- if (this.subscribes[type][pattern] !== undefined) {
377
- this.subscribes[type][pattern]--;
378
- if (this.subscribes[type][pattern] <= 0) {
379
- if (type === 'stateChange') {
380
- this.adapter.unsubscribeForeignStates(pattern);
381
- } else if (type === 'objectChange') {
382
- this.adapter.unsubscribeForeignObjects && this.adapter.unsubscribeForeignObjects(pattern);
383
- } else if (type === 'log') {
384
- this.adapter.requireLog && this.adapter.requireLog(false);
385
- }
386
- delete this.subscribes[type][pattern];
402
+ if (this.subscribes[type][pattern] === undefined) {
403
+ this.subscribes[type][pattern] = 1;
404
+ if (type === 'stateChange') {
405
+ this.adapter.subscribeForeignStates(pattern);
406
+ } else if (type === 'objectChange') {
407
+ this.adapter.subscribeForeignObjects && this.adapter.subscribeForeignObjects(pattern);
408
+ } else if (type === 'log') {
409
+ this.adapter.requireLog && this.adapter.requireLog(true);
387
410
  }
411
+ } else {
412
+ this.subscribes[type][pattern]++;
388
413
  }
389
414
  }
390
415
  }
391
416
 
392
- subscribeSocket(socket, type) {
417
+ unsubscribeSocket(socket, type) {
393
418
  if (!socket || !socket.subscribe) {
394
419
  return;
395
420
  }
396
421
 
397
422
  if (!type) {
398
423
  // all
399
- return Object.keys(socket.subscribe).forEach(type => this.subscribeSocket(socket, type));
424
+ return Object.keys(socket.subscribe).forEach(type => this.unsubscribeSocket(socket, type));
400
425
  }
401
426
 
402
427
  if (!socket.subscribe[type]) {
@@ -405,18 +430,35 @@ class SocketCommands {
405
430
 
406
431
  for (let i = 0; i < socket.subscribe[type].length; i++) {
407
432
  const pattern = socket.subscribe[type][i].pattern;
408
- if (this.subscribes[type][pattern] === undefined) {
409
- this.subscribes[type][pattern] = 1;
410
- if (type === 'stateChange') {
411
- this.adapter.subscribeForeignStates(pattern);
412
- } else if (type === 'objectChange') {
413
- this.adapter.subscribeForeignObjects && this.adapter.subscribeForeignObjects(pattern);
414
- } else if (type === 'log') {
415
- this.adapter.requireLog && this.adapter.requireLog(true);
433
+ if (this.subscribes[type][pattern] !== undefined) {
434
+ this.subscribes[type][pattern]--;
435
+ if (this.subscribes[type][pattern] <= 0) {
436
+ if (type === 'stateChange') {
437
+ this.adapter.unsubscribeForeignStates(pattern);
438
+ } else if (type === 'objectChange') {
439
+ this.adapter.unsubscribeForeignObjects && this.adapter.unsubscribeForeignObjects(pattern);
440
+ } else if (type === 'log') {
441
+ this.adapter.requireLog && this.adapter.requireLog(false);
442
+ }
443
+ delete this.subscribes[type][pattern];
444
+ }
445
+ }
446
+ }
447
+ }
448
+
449
+ _subscribeStates(socket, pattern, callback) {
450
+ if (this._checkPermissions(socket, 'subscribe', callback, pattern)) {
451
+ if (pattern && typeof pattern === 'object' && pattern instanceof Array) {
452
+ for (let p = 0; p < pattern.length; p++) {
453
+ this.subscribe(socket, 'stateChange', pattern[p]);
416
454
  }
417
455
  } else {
418
- this.subscribes[type][pattern]++;
456
+ this.subscribe(socket, 'stateChange', pattern);
419
457
  }
458
+
459
+ this.adapter.log.level === 'debug' && this._showSubscribes(socket, 'stateChange');
460
+
461
+ typeof callback === 'function' && setImmediate(callback, null);
420
462
  }
421
463
  }
422
464
 
@@ -436,6 +478,38 @@ class SocketCommands {
436
478
  }
437
479
  }
438
480
 
481
+ _subscribeFiles(socket, id, pattern, callback) {
482
+ if (this._checkPermissions(socket, 'subscribeFiles', callback, pattern)) {
483
+ if (pattern && typeof pattern === 'object' && pattern instanceof Array) {
484
+ for (let p = 0; p < pattern.length; p++) {
485
+ this.subscribe(socket, 'fileChange', id, pattern[p]);
486
+ }
487
+ } else {
488
+ this.subscribe(socket, 'fileChange', id, pattern);
489
+ }
490
+
491
+ this.adapter.log.level === 'debug' && this._showSubscribes(socket, 'fileChange');
492
+
493
+ typeof callback === 'function' && setImmediate(callback, null);
494
+ }
495
+ }
496
+
497
+ _unsubscribeFiles(socket, id, pattern, callback) {
498
+ if (this._checkPermissions(socket, 'unsubscribeFiles', callback, pattern)) {
499
+ if (pattern && typeof pattern === 'object' && pattern instanceof Array) {
500
+ for (let p = 0; p < pattern.length; p++) {
501
+ this.unsubscribe(socket, 'fileChange', id, pattern[p]);
502
+ }
503
+ } else {
504
+ this.unsubscribe(socket, 'fileChange', pattern);
505
+ }
506
+
507
+ this.adapter.log.level === 'debug' && this._showSubscribes(socket, 'fileChange');
508
+
509
+ typeof callback === 'function' && setImmediate(callback, null);
510
+ }
511
+ }
512
+
439
513
  addCommandHandler(command, handler) {
440
514
  if (handler) {
441
515
  this.commands[command] = handler;
@@ -765,6 +839,10 @@ class SocketCommands {
765
839
  SocketCommands._fixCallback(callback, err, ...args));
766
840
  }
767
841
  };
842
+
843
+ this.commands['subscribeFiles'] = (socket, id, pattern, callback) => this._subscribeFiles(socket, id, pattern, callback);
844
+
845
+ this.commands['unsubscribeFiles'] = (socket, id, pattern, callback) => this._unsubscribeFiles(socket, id, pattern, callback);
768
846
  }
769
847
 
770
848
  __initCommandsStates() {
@@ -1,5 +1,6 @@
1
1
  const SocketCommands = require('./socketCommands');
2
2
  const axios = require('axios');
3
+ const path = require('path');
3
4
 
4
5
  class SocketCommandsAdmin extends SocketCommands {
5
6
  static ALLOW_CACHE = [
@@ -658,7 +659,7 @@ class SocketCommandsAdmin extends SocketCommands {
658
659
  const stat = fs.lstatSync(fileName + '/' + files[f]);
659
660
  if (!stat.isDirectory()) {
660
661
  result.list.push({
661
- fileName: 'log/' + transport + '/' + files[f],
662
+ fileName: `log/${transport}/${files[f]}`,
662
663
  size: stat.size
663
664
  });
664
665
  }
@@ -349,6 +349,10 @@ class SocketCommon {
349
349
  return this.commands.publish(socket, type, id, obj);
350
350
  }
351
351
 
352
+ publishFile(socket, id, fileName, size) {
353
+ return this.commands.publishFile(socket, id, fileName, size);
354
+ }
355
+
352
356
  close() {
353
357
  this._unsubscribeAll();
354
358
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iobroker/socket-classes",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "ioBroker server-side web sockets",
5
5
  "author": {
6
6
  "name": "bluefox",