forked from darickc/MMM-BackgroundSlideshow
-
Notifications
You must be signed in to change notification settings - Fork 0
/
node_helper.js
executable file
·193 lines (172 loc) · 5.71 KB
/
node_helper.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/* global Module */
/* node_helper.js
*
* Magic Mirror
* Module: MMM-BackgroundSlideshow
*
* Magic Mirror By Michael Teeuw http://michaelteeuw.nl
* MIT Licensed.
*
* Module MMM-BackgroundSlideshow By Darick Carpenter
* MIT Licensed.
*/
// call in the required classes
const Log = require('../../js/logger.js');
var NodeHelper = require('node_helper');
var FileSystemImageSlideshow = require('fs');
const { exec } = require('child_process');
var express = require('express');
const basePath = '/images/';
// the main module helper create
module.exports = NodeHelper.create({
expressInstance: undefined,
// subclass start method, clears the initial config array
start: function () {
this.excludePaths = new Set();
this.validImageFileExtensions = new Set();
this.expressInstance = this.expressApp;
},
// shuffles an array at random and returns it
shuffleArray: function (array) {
for (let i = array.length - 1; i > 0; i--) {
// j is a random index in [0, i].
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
},
// sort by filename attribute
sortByFilename: function (a, b) {
aL = a.path.toLowerCase();
bL = b.path.toLowerCase();
if (aL > bL) return 1;
else return -1;
},
// sort by created attribute
sortByCreated: function (a, b) {
aL = a.created;
bL = b.created;
if (aL > bL) return 1;
else return -1;
},
// sort by created attribute
sortByModified: function (a, b) {
aL = a.modified;
bL = b.modified;
if (aL > bL) return 1;
else return -1;
},
sortImageList: function (imageList, sortBy, sortDescending) {
let sortedList = imageList;
switch (sortBy) {
case 'created':
// Log.log('Sorting by created date...');
sortedList = imageList.sort(this.sortByCreated);
break;
case 'modified':
// Log.log('Sorting by modified date...');
sortedList = imageList.sort(this.sortByModified);
break;
default:
// sort by name
// Log.log('Sorting by name...');
sortedList = imageList.sort(this.sortByFilename);
}
// If the user chose to sort in descending order then reverse the array
if (sortDescending === true) {
// Log.log('Reversing sort order...');
sortedList = sortedList.reverse();
}
return sortedList;
},
// checks there's a valid image file extension
checkValidImageFileExtension: function (filename) {
if (!filename.includes('.')) {
// No file extension.
return false;
}
const fileExtension = filename.split('.').pop().toLowerCase();
return this.validImageFileExtensions.has(fileExtension);
},
// gathers the image list
gatherImageList: function (config) {
// create an empty main image list
let imageList = [];
for (let i = 0; i < config.imagePaths.length; i++) {
this.getFiles(config.imagePaths[i], imageList, config);
}
imageList = config.randomizeImageOrder
? this.shuffleArray(imageList)
: this.sortImageList(
imageList,
config.sortImagesBy,
config.sortImagesDescending
);
// build the return payload
const returnPayload = {
identifier: config.identifier,
imageList: imageList.map((item) => basePath + item.path) // map the array to only extract the paths
};
// send the image list back
this.sendSocketNotification('BACKGROUNDSLIDESHOW_FILELIST', returnPayload);
},
getFiles(path, imageList, config) {
const contents = FileSystemImageSlideshow.readdirSync(path);
for (let i = 0; i < contents.length; i++) {
if (this.excludePaths.has(contents[i])) {
continue;
}
const currentItem = path + '/' + contents[i];
const stats = FileSystemImageSlideshow.lstatSync(currentItem);
if (stats.isDirectory() && config.recursiveSubDirectories) {
this.getFiles(currentItem, imageList, config);
} else if (stats.isFile()) {
const isValidImageFileExtension = this.checkValidImageFileExtension(
currentItem
);
if (isValidImageFileExtension) {
imageList.push({
path: currentItem,
created: stats.ctimeMs,
modified: stats.mtimeMs
});
}
}
}
},
// subclass socketNotificationReceived, received notification from module
socketNotificationReceived: function (notification, payload) {
if (notification === 'BACKGROUNDSLIDESHOW_REGISTER_CONFIG') {
const config = payload;
this.expressInstance.use(
basePath + config.imagePaths[0],
express.static(config.imagePaths[0], { maxAge: 3600000 })
);
// Create set of excluded subdirectories.
this.excludePaths = new Set(config.excludePaths);
// Create set of valid image extensions.
const validExtensionsList = config.validImageFileExtensions
.toLowerCase()
.split(',');
this.validImageFileExtensions = new Set(validExtensionsList);
// Get the image list in a non-blocking way since large # of images would cause
// the MagicMirror startup banner to get stuck sometimes.
setTimeout(() => {
this.gatherImageList(config);
}, 200);
} else if (notification === 'BACKGROUNDSLIDESHOW_PLAY_VIDEO') {
Log.info('mw got BACKGROUNDSLIDESHOW_PLAY_VIDEO');
Log.info(
'cmd line:' + 'omxplayer --win 0,0,1920,1080 --alpha 180 ' + payload[0]
);
exec(
'omxplayer --win 0,0,1920,1080 --alpha 180 ' + payload[0],
(e, stdout, stderr) => {
this.sendSocketNotification('BACKGROUNDSLIDESHOW_PLAY', null);
Log.info('mw video done');
}
);
}
}
});
//------------ end -------------