1 | #!/usr/bin/env node
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | var multiparty = require('multiparty');
|
20 | var http = require('http');
|
21 | var https = require('https');
|
22 | var util = require('util');
|
23 | var path = require("path");
|
24 | var upath = require("upath");
|
25 | require("date-format-lite");
|
26 | var mv = require('mv');
|
27 | var fs = require('fs');
|
28 | var exec = require('child_process').exec;
|
29 | var spawn = require('child_process').spawn;
|
30 | var drivelist = require('drivelist');
|
31 | var uuid = require('node-uuid');
|
32 | var fsExtra = require('fs-extra');
|
33 | var klaw = require('klaw');
|
34 | var separateReqPool = {maxSockets: 10};
|
35 | var request = require("request");
|
36 | var needle = require('needle');
|
37 | var readChunk = require('read-chunk');
|
38 | var fileType = require('file-type');
|
39 | var shredfile = require('shredfile')();
|
40 | var queryStringLib = require('querystring');
|
41 | var async = require('async');
|
42 |
|
43 |
|
44 | var verbose = false;
|
45 | var outdirDefaultParent = '/medimage';
|
46 | var outdirPhotos = '/photos';
|
47 | var defaultTitle = "image";
|
48 | var currentDisks = [];
|
49 | var configFile = __dirname + '/../config.json';
|
50 | var newConfigFile = '/../config-original/linORIGINALconfig.json';
|
51 |
|
52 | var addonsConfigFile = __dirname + '/../addons/config.json';
|
53 | var htmlHeaderFile = __dirname + '/../public/components/header.html';
|
54 | var htmlHeaderCode = "";
|
55 | var noFurtherFiles = "none";
|
56 | var pairingURL = "https://atomjump.com/med-genid.php";
|
57 | var listenPort = 5566;
|
58 | var remoteReadTimer = null;
|
59 | var globalId = "";
|
60 | var httpsFlag = false;
|
61 | var serverOptions = {};
|
62 | var bytesTransferred = 0;
|
63 | var noWin = false;
|
64 | var maxUploadSize = 10485760;
|
65 | var readingRemoteServer = false;
|
66 | var allowPhotosLeaving = false;
|
67 | var allowGettingRemotePhotos = false;
|
68 |
|
69 | var changeReadUrl = "";
|
70 | var flapSimulation = false;
|
71 | var flapState = false;
|
72 | var webProxy = null;
|
73 |
|
74 |
|
75 | var allowedTypes = [ { "extension": ".jpg", "mime": "image/jpeg" },
|
76 | { "extension": ".pdf", "mime": "application/pdf" },
|
77 | { "extension": ".mp4", "mime": "video/mp4" },
|
78 | { "extension": ".mp3", "mime": "audio/mpeg" },
|
79 | { "extension": ".m4v", "mime": "video/mp4" },
|
80 | { "extension": ".m4a", "mime": "audio/m4a" },
|
81 | { "extension": ".csv", "mime": "text/csv" },
|
82 | { "extension": ".json", "mime": "application/json" } ];
|
83 |
|
84 | var allowedChars = "a-zA-z0-9#._-";
|
85 |
|
86 |
|
87 | var addons = [];
|
88 | global.globalConfig = null;
|
89 |
|
90 |
|
91 | process.on('SIGINT', function() {
|
92 | console.log("Requesting a shutdown.");
|
93 | setTimeout(function() {
|
94 |
|
95 | console.log("Clean exit.");
|
96 | process.exit(0);
|
97 | }, 100);
|
98 | });
|
99 |
|
100 |
|
101 |
|
102 | if((process.argv[2]) && (process.argv[2] == '-verbose')){
|
103 | verbose = true;
|
104 | }
|
105 |
|
106 | if(process.env.npm_package_config_configFile) {
|
107 |
|
108 | configFile = process.env.npm_package_config_configFile;
|
109 | console.log("Using config file:" + configFile);
|
110 |
|
111 | }
|
112 |
|
113 |
|
114 | function pushIfNew(arry, str) {
|
115 |
|
116 | console.log("Attempting to add to array:" + str);
|
117 | for (var i = 0; i < arry.length; i++) {
|
118 | if (arry[i] === str) {
|
119 | return;
|
120 | }
|
121 | }
|
122 | console.log("Pushing string");
|
123 | arry.push(str);
|
124 | return arry;
|
125 | }
|
126 |
|
127 |
|
128 | function serverParentDir() {
|
129 |
|
130 | var curdir = normalizeInclWinNetworks(__dirname + "/..");
|
131 | return curdir;
|
132 | }
|
133 |
|
134 | function ensurePhotoReadableWindows(fullPath, cb) {
|
135 |
|
136 |
|
137 | var platform = process.platform;
|
138 | if(verbose == true) console.log(process.platform);
|
139 | var isWin = /^win/.test(platform);
|
140 | if(verbose == true) console.log("IsWin=" + isWin);
|
141 | if(isWin) {
|
142 |
|
143 |
|
144 | var run = 'icacls ' + fullPath + ' /t /grant Everyone:(OI)(CI)F';
|
145 | if(verbose == true) console.log("Running:" + run);
|
146 | exec(run, function(error, stdout, stderr){
|
147 | console.log(stdout);
|
148 | if(cb) {
|
149 | if(error) {
|
150 | cb(error);
|
151 | } else {
|
152 | cb(null);
|
153 | }
|
154 | }
|
155 | });
|
156 | } else {
|
157 | if(cb) {
|
158 | cb(null);
|
159 | }
|
160 |
|
161 | }
|
162 | }
|
163 |
|
164 |
|
165 | function shredWrapper(fullPath, theFile) {
|
166 | var platform = process.platform;
|
167 | if(verbose == true) console.log(process.platform);
|
168 | var isWin = /^win/.test(platform);
|
169 | if(verbose == true) console.log("IsWin=" + isWin);
|
170 | if(isWin) {
|
171 |
|
172 | var tempFile = fs.openSync(fullPath, 'r');
|
173 | fs.closeSync(tempFile);
|
174 |
|
175 | fs.unlinkSync(fullPath);
|
176 | console.log("Sent on and deleted " + theFile);
|
177 |
|
178 | } else {
|
179 |
|
180 | shredfile.shred(fullPath, function(err, file) {
|
181 | if(err) {
|
182 | console.log(err);
|
183 | return;
|
184 | }
|
185 | console.log("Sent on and shredded " + theFile);
|
186 | });
|
187 | }
|
188 |
|
189 | }
|
190 |
|
191 |
|
192 | function ensureDirectoryWritableWindows(fullPath, cb) {
|
193 |
|
194 |
|
195 | var platform = process.platform;
|
196 | if(verbose == true) console.log(process.platform);
|
197 | var isWin = /^win/.test(platform);
|
198 | if(verbose == true) console.log("IsWin=" + isWin);
|
199 | if(isWin) {
|
200 |
|
201 |
|
202 | var run = 'icacls ' + fullPath + ' /grant Everyone:(OI)(CI)F';
|
203 | if(verbose == true) console.log("Running:" + run);
|
204 | exec(run, function(error, stdout, stderr){
|
205 | console.log(stdout);
|
206 | if(cb) {
|
207 | if(error) {
|
208 | cb(error);
|
209 | } else {
|
210 | cb(null);
|
211 | }
|
212 | }
|
213 | });
|
214 | } else {
|
215 |
|
216 | cb(null);
|
217 | }
|
218 | }
|
219 |
|
220 |
|
221 | function readHTMLHeader(cb) {
|
222 |
|
223 |
|
224 |
|
225 | fs.readFile(htmlHeaderFile, function read(err, data) {
|
226 | if (err) {
|
227 |
|
228 | cb("Sorry, cannot read the header file " + htmlHeaderFile, null);
|
229 | return;
|
230 | } else {
|
231 | htmlHeaderCode = data;
|
232 | cb(null, data);
|
233 | }
|
234 | });
|
235 |
|
236 | }
|
237 |
|
238 |
|
239 | function checkConfigCurrent(setProxy, cb) {
|
240 |
|
241 |
|
242 |
|
243 |
|
244 |
|
245 |
|
246 | fs.readFile(configFile, function read(err, data) {
|
247 | if (err) {
|
248 |
|
249 |
|
250 |
|
251 | fs.stat(configFile, function(ferr, stat) {
|
252 | if(ferr == null) {
|
253 |
|
254 | cb("Sorry, cannot read the config file! Please check your file permissions. " + ferr);
|
255 | } else if(ferr.code == 'ENOENT') {
|
256 |
|
257 |
|
258 |
|
259 |
|
260 |
|
261 | fsExtra.copy(__dirname + newConfigFile, configFile, function (err) {
|
262 | if (err) {
|
263 | return console.error(err)
|
264 | } else {
|
265 |
|
266 |
|
267 |
|
268 |
|
269 | checkConfigCurrent(setProxy, cb);
|
270 | return;
|
271 | }
|
272 | })
|
273 | } else {
|
274 |
|
275 | cb("Sorry, cannot read the config file! Please check your file permissions. " + ferr);
|
276 | }
|
277 | });
|
278 |
|
279 |
|
280 | } else {
|
281 | if(data) {
|
282 | var content = JSON.parse(data);
|
283 | } else {
|
284 | if(global.globalConfig) {
|
285 | content = global.globalConfig;
|
286 | } else {
|
287 | cb("Sorry, the config file is blank.");
|
288 | return;
|
289 | }
|
290 | }
|
291 |
|
292 | if(!content.globalId) {
|
293 |
|
294 |
|
295 |
|
296 | }
|
297 |
|
298 |
|
299 | if(setProxy) {
|
300 | content.readProxy = setProxy;
|
301 | }
|
302 |
|
303 | if((globalId)&&(validateGlobalId(globalId) !== false)) {
|
304 | content.globalId = globalId;
|
305 | }
|
306 |
|
307 | if(content.globalId) {
|
308 | globalId = content.globalId;
|
309 | }
|
310 |
|
311 | if(content.listenPort) {
|
312 | listenPort = content.listenPort;
|
313 | }
|
314 |
|
315 | if(content.allowedTypes) {
|
316 | allowedTypes = content.allowedTypes;
|
317 | }
|
318 |
|
319 | if(content.httpsKey) {
|
320 |
|
321 | httpsFlag = true;
|
322 | if(!serverOptions.key) {
|
323 | serverOptions.key = fs.readFileSync(content.httpsKey);
|
324 | console.log("https key loaded");
|
325 | }
|
326 | }
|
327 |
|
328 | if(content.httpsCert) {
|
329 |
|
330 | httpsFlag = true;
|
331 | if(!serverOptions.cert) {
|
332 | serverOptions.cert = fs.readFileSync(content.httpsCert);
|
333 | console.log("https cert loaded");
|
334 | }
|
335 |
|
336 | }
|
337 |
|
338 | if(content.webProxy) {
|
339 |
|
340 |
|
341 |
|
342 | webProxy = content.webProxy;
|
343 |
|
344 | }
|
345 |
|
346 |
|
347 |
|
348 | if(content.allowPhotosLeaving) {
|
349 | allowPhotosLeaving = content.allowPhotosLeaving;
|
350 | }
|
351 |
|
352 |
|
353 |
|
354 | if(content.allowGettingRemotePhotos) {
|
355 | allowGettingRemotePhotos = content.allowGettingRemotePhotos;
|
356 | }
|
357 |
|
358 |
|
359 | if(content.allowedChars) {
|
360 | allowedChars = content.allowedChars;
|
361 | }
|
362 |
|
363 |
|
364 | if(bytesTransferred != 0) {
|
365 |
|
366 | content.transfer = bytesTransferred;
|
367 | } else {
|
368 | if(content.transfer) {
|
369 |
|
370 | bytesTransferred = content.transfer;
|
371 | }
|
372 |
|
373 | }
|
374 |
|
375 |
|
376 | if(content.onStartBackupDriveDetect == true) {
|
377 |
|
378 | drivelist.list(function(error, disks) {
|
379 | if (error) {
|
380 | console.log("Warning: couldn't get the current drives for BackupDriveDetect. Error:" + error);
|
381 |
|
382 | } else {
|
383 |
|
384 | for(var cnt=0; cnt< disks.length; cnt++) {
|
385 |
|
386 | if(verbose == true) console.log("Drive detected:" + JSON.stringify(disks[cnt]));
|
387 | var drive = disks[cnt].mountpoint;
|
388 |
|
389 | if(drive) {
|
390 |
|
391 | if(serverParentDir().indexOf(drive) < 0) {
|
392 |
|
393 |
|
394 |
|
395 | if (!fs.existsSync(normalizeInclWinNetworks(drive + outdirDefaultParent))){
|
396 | fs.mkdirSync(normalizeInclWinNetworks(drive + outdirDefaultParent));
|
397 | }
|
398 |
|
399 | if (!fs.existsSync(normalizeInclWinNetworks(drive + outdirDefaultParent + outdirPhotos))){
|
400 | fs.mkdirSync(normalizeInclWinNetworks(drive + outdirDefaultParent + outdirPhotos));
|
401 | }
|
402 |
|
403 |
|
404 | if(content.onStartBackupDriveDetect == true) {
|
405 | content.backupTo = pushIfNew(content.backupTo, drive + outdirDefaultParent + outdirPhotos);
|
406 | }
|
407 | }
|
408 | }
|
409 | }
|
410 |
|
411 | try {
|
412 | var newContent = JSON.stringify(content, null, 6);
|
413 | }
|
414 | catch(err) {
|
415 | cb("Error: the config file cannot be written: " + err.message);
|
416 | return;
|
417 | }
|
418 |
|
419 | if(newContent) {
|
420 |
|
421 | globalConfig = content;
|
422 |
|
423 |
|
424 | fs.writeFile(configFile, newContent, function(err) {
|
425 |
|
426 |
|
427 | if(verbose == true) console.log("The config file was saved!");
|
428 |
|
429 |
|
430 | if((content.readProxy) && (content.readProxy != "")) {
|
431 | startReadRemoteServer(content.readProxy);
|
432 | }
|
433 |
|
434 | if(err) {
|
435 | if(verbose == true) console.log("Warning: The config file was not saved! Error: " + err);
|
436 | cb(err);
|
437 | } else {
|
438 | cb(null);
|
439 | }
|
440 | });
|
441 | } else {
|
442 |
|
443 | cb("Error: was about to save a blank config.");
|
444 | }
|
445 |
|
446 |
|
447 | }
|
448 |
|
449 | });
|
450 | } else {
|
451 |
|
452 | try {
|
453 | var newContent = JSON.stringify(content, null, 6);
|
454 | }
|
455 | catch(err) {
|
456 | cb("Error: the config file cannot be written: " + err.message);
|
457 | return;
|
458 | }
|
459 |
|
460 | if(newContent) {
|
461 |
|
462 | globalConfig = content;
|
463 |
|
464 |
|
465 | fs.writeFile(configFile, newContent, function(err) {
|
466 |
|
467 | if(verbose == true) console.log("The config file was saved!");
|
468 |
|
469 |
|
470 | if((content.readProxy) && (content.readProxy != "")) {
|
471 | startReadRemoteServer(content.readProxy);
|
472 | }
|
473 |
|
474 | if(err) {
|
475 | if(verbose == true) console.log("Warning: The config file was not saved! Error: " + err);
|
476 | cb(err);
|
477 | } else {
|
478 | cb(null);
|
479 | }
|
480 | });
|
481 | } else {
|
482 |
|
483 | cb("Error: was about to save a blank config.");
|
484 |
|
485 | }
|
486 |
|
487 |
|
488 |
|
489 | }
|
490 |
|
491 |
|
492 |
|
493 |
|
494 | };
|
495 | });
|
496 |
|
497 | }
|
498 |
|
499 |
|
500 | function fileWalk(startDir, cb)
|
501 | {
|
502 |
|
503 | var items = [];
|
504 | if(verbose == true) console.log("Searching:" + startDir);
|
505 |
|
506 | if (fsExtra.existsSync(normalizeInclWinNetworks(startDir))){
|
507 | try {
|
508 | var walk = klaw(startDir);
|
509 |
|
510 | walk.on('data', function (item) {
|
511 | if(verbose == true) console.log("Found:" + item.path);
|
512 | items.push(item.path);
|
513 | })
|
514 | .on('end', function () {
|
515 | for(var cnt = 0; cnt< items.length; cnt++) {
|
516 |
|
517 |
|
518 | for(var type = 0; type < allowedTypes.length; type++) {
|
519 |
|
520 | if(items[cnt].indexOf(allowedTypes[type].extension) >= 0) {
|
521 | cb(items[cnt], allowedTypes[type].mime);
|
522 | return;
|
523 | }
|
524 | }
|
525 | }
|
526 |
|
527 | cb(null);
|
528 | });
|
529 | } catch(err) {
|
530 | console.log("Error reading:" + err);
|
531 | cb(null);
|
532 | }
|
533 | } else {
|
534 | cb(null);
|
535 |
|
536 | }
|
537 |
|
538 |
|
539 | }
|
540 |
|
541 |
|
542 | function formatBytes(bytes,decimals) {
|
543 |
|
544 | if(verbose == true) console.log("Bytes: " + bytes);
|
545 | if(bytes == 0) return 'None';
|
546 | var k = 1000;
|
547 | var dm = decimals + 1 || 3;
|
548 | var sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
549 | var i = Math.floor(Math.log(bytes) / Math.log(k));
|
550 | return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
551 | }
|
552 |
|
553 |
|
554 | function download(uri, callback){
|
555 |
|
556 |
|
557 |
|
558 |
|
559 | request.head({url: uri, pool: separateReqPool, forever: true, proxy: webProxy }, function(err, res, body){
|
560 | if(err) {
|
561 | console.log("Error requesting from proxy:" + err);
|
562 | callback(err);
|
563 | } else {
|
564 | if(verbose == true) {
|
565 | console.log(JSON.stringify(res.headers));
|
566 | console.log('content-type:', res.headers['content-type']);
|
567 | console.log('content-length:', res.headers['content-length']);
|
568 | console.log('file-name:', res.headers['file-name']);
|
569 | }
|
570 |
|
571 | if(res.headers['file-name']) {
|
572 |
|
573 |
|
574 | var dirFile = res.headers['file-name'];
|
575 | dirFile = trimChar(dirFile.replace(globalId + '/', ''));
|
576 |
|
577 |
|
578 | var createFile = normalizeInclWinNetworks(trailSlash(serverParentDir()) + trailSlash(outdirPhotos) + dirFile);
|
579 |
|
580 |
|
581 | if(verbose == true) console.log("Creating file:" + createFile);
|
582 | var dirCreate = path.dirname(createFile);
|
583 | if(verbose == true) console.log("Creating dir:" + dirCreate);
|
584 |
|
585 |
|
586 | fsExtra.ensureDir(dirCreate, function(err) {
|
587 | if(err) {
|
588 | console.log("Warning: Could not create directory for: " + dirCreate);
|
589 | callback("Warning: Could not create directory for: " + dirCreate);
|
590 | } else {
|
591 | if(verbose == true) console.log("Created dir:" + dirCreate);
|
592 | ensureDirectoryWritableWindows(dirCreate, function(err) {
|
593 |
|
594 | if(err) {
|
595 |
|
596 | console.log("Error processing dir:" + err);
|
597 | callback("Error processing dir:" + err);
|
598 | } else {
|
599 |
|
600 | if(verbose == true) console.log("Directory processed");
|
601 | if(verbose == true) console.log("About to create local file " + createFile + " from uri:" + uri);
|
602 |
|
603 |
|
604 | var stream = request({url: uri, pool: separateReqPool, forever: true });
|
605 | var alreadyClosed = false;
|
606 | stream.pipe(fs.createWriteStream(createFile)
|
607 | .on('error', function(err) {
|
608 | console.log("Error writing to file");
|
609 | callback(err);
|
610 | })
|
611 | )
|
612 | .on('close', function() {
|
613 |
|
614 | console.log("Downloaded successfully!" + createFile);
|
615 | if(alreadyClosed == false) {
|
616 | alreadyClosed = true;
|
617 |
|
618 |
|
619 | if(uri.indexOf("atomjump.com") >= 0) {
|
620 | try {
|
621 |
|
622 | var stats = fs.statSync(createFile);
|
623 | var fileSizeInBytes = stats["size"];
|
624 | bytesTransferred += fileSizeInBytes;
|
625 |
|
626 |
|
627 | checkConfigCurrent(null, function() {
|
628 |
|
629 | })
|
630 | }
|
631 | catch(err) {
|
632 | console.log('Warning: file ' + createFile + ' did not exist.');
|
633 | }
|
634 | }
|
635 |
|
636 | if(createFile.indexOf(".jpg") >= 0) {
|
637 | var event = "photoWritten";
|
638 | } else {
|
639 | var event = "fileWritten";
|
640 | }
|
641 |
|
642 | addOns(event, function(err, normalBackup) {
|
643 | if(err) {
|
644 | console.log("Error writing file:" + err);
|
645 | } else {
|
646 | if(verbose == true) console.log("Add-on completed running");
|
647 |
|
648 | }
|
649 |
|
650 | if(normalBackup == true) {
|
651 |
|
652 |
|
653 | backupFile(createFile, "", dirFile, { });
|
654 | }
|
655 | }, createFile);
|
656 |
|
657 |
|
658 |
|
659 |
|
660 | callback(null);
|
661 | } else {
|
662 | console.log("2nd close event");
|
663 | }
|
664 | });
|
665 |
|
666 |
|
667 | }
|
668 |
|
669 |
|
670 |
|
671 | });
|
672 |
|
673 | }
|
674 | });
|
675 |
|
676 |
|
677 | } else {
|
678 |
|
679 | if(verbose == true) console.log("No file to download");
|
680 | callback(null);
|
681 | }
|
682 |
|
683 | }
|
684 | });
|
685 |
|
686 |
|
687 | }
|
688 |
|
689 |
|
690 |
|
691 | function startReadRemoteServer(url)
|
692 | {
|
693 | if(allowGettingRemotePhotos == false) {
|
694 | console.log("Error: Sorry, this server is not configured to read a remote server.");
|
695 | return;
|
696 | }
|
697 |
|
698 | if(readingRemoteServer == false) {
|
699 | readingRemoteServer = true;
|
700 | readRemoteServer(url);
|
701 | } else {
|
702 |
|
703 | changeReadUrl = url;
|
704 |
|
705 | }
|
706 | }
|
707 |
|
708 | function readRemoteServer(url)
|
709 | {
|
710 |
|
711 |
|
712 |
|
713 |
|
714 | if(changeReadUrl != "") {
|
715 | url = changeReadUrl;
|
716 | changeReadUrl = "";
|
717 | }
|
718 |
|
719 | var _url = url;
|
720 |
|
721 |
|
722 |
|
723 | setTimeout(function() {
|
724 | process.stdout.write("'");
|
725 | var thisComplete = false;
|
726 | download(url, function(){
|
727 | if(verbose == true) console.log("Ping status: " + thisComplete);
|
728 | if(thisComplete == false) {
|
729 |
|
730 | thisComplete = true;
|
731 | readRemoteServer(_url);
|
732 | }
|
733 | });
|
734 |
|
735 |
|
736 | setTimeout(function() {
|
737 | if(verbose == true) console.log("Ping status after 1 minutes time: " + thisComplete);
|
738 | if(thisComplete == false) {
|
739 |
|
740 | thisComplete = true;
|
741 | readRemoteServer(_url);
|
742 | }
|
743 | }, 60000);
|
744 |
|
745 | }, 5000);
|
746 |
|
747 |
|
748 | }
|
749 |
|
750 | function trailSlash(str)
|
751 | {
|
752 | if(str.slice(-1) == "/") {
|
753 | return str;
|
754 | } else {
|
755 | var retStr = str + "/";
|
756 | return retStr;
|
757 | }
|
758 |
|
759 | }
|
760 |
|
761 |
|
762 | function normalizeInclWinNetworks(path)
|
763 | {
|
764 |
|
765 |
|
766 |
|
767 | if((path[0] == "\\")&&(path[1] == "\\")) {
|
768 |
|
769 | return "\/" + upath.normalize(path);
|
770 | } else {
|
771 | if((path[0] == "\/")&&(path[1] == "\/")) {
|
772 |
|
773 | return "\/" + upath.normalize(path);
|
774 | } else {
|
775 | return upath.normalize(path);
|
776 | }
|
777 | }
|
778 |
|
779 | }
|
780 |
|
781 |
|
782 |
|
783 | function backupFile(thisPath, outhashdir, finalFileName, opts, cb)
|
784 | {
|
785 |
|
786 |
|
787 |
|
788 |
|
789 |
|
790 |
|
791 |
|
792 |
|
793 |
|
794 |
|
795 |
|
796 |
|
797 | var lastNewPath = thisPath;
|
798 |
|
799 | if(!opts) {
|
800 | opts = {};
|
801 | }
|
802 | if(!opts.first) {
|
803 | opts.first = true;
|
804 | }
|
805 | if(!opts.secondary) {
|
806 | opts.secondary = true;
|
807 | }
|
808 | if(!opts.keepOriginal) {
|
809 | opts.keepOriginal = "useMasterConfig";
|
810 | }
|
811 | if(!cb) {
|
812 | cb = function() {};
|
813 | }
|
814 |
|
815 |
|
816 |
|
817 |
|
818 |
|
819 | fs.readFile(configFile, function read(err, data) {
|
820 | if (err) {
|
821 | console.log("Warning: Error reading config file for backup options: " + err);
|
822 | cb(err, null);
|
823 | } else {
|
824 | if(data) {
|
825 | var content = JSON.parse(data);
|
826 | } else {
|
827 |
|
828 | var content = global.globalConfig;
|
829 | }
|
830 |
|
831 |
|
832 | if(content.backupTo) {
|
833 |
|
834 |
|
835 |
|
836 |
|
837 | async.eachOf(content.backupTo,
|
838 |
|
839 | function(runBlock, cnt, callback){
|
840 |
|
841 |
|
842 | if((cnt == 0) && (opts.first == false)) {
|
843 |
|
844 | callback(null);
|
845 | return;
|
846 | }
|
847 |
|
848 | if((cnt > 0)&& (opts.secondary == false)) {
|
849 |
|
850 | callback(null);
|
851 | return;
|
852 |
|
853 | }
|
854 |
|
855 |
|
856 | if(outhashdir) {
|
857 | var targetDir = normalizeInclWinNetworks(trailSlash(content.backupTo[cnt]) + trailSlash(outhashdir));
|
858 | } else {
|
859 | var targetDir = normalizeInclWinNetworks(trailSlash(content.backupTo[cnt]));
|
860 |
|
861 | }
|
862 | var target = targetDir + finalFileName;
|
863 | target = normalizeInclWinNetworks(target.trim());
|
864 | lastNewPath = target;
|
865 | thisPath = normalizeInclWinNetworks(thisPath.trim());
|
866 |
|
867 |
|
868 | if(verbose == true) console.log("Backing up " + thisPath + " to:" + target);
|
869 |
|
870 | fsExtra.ensureDir(targetDir, function(err) {
|
871 | if(err) {
|
872 | console.log("Warning: Could not create directory for backup: " + targetDir + " Err:" + err);
|
873 | callback(err);
|
874 | } else {
|
875 | try {
|
876 |
|
877 | if(thisPath !== target) {
|
878 | console.log("Copying " + thisPath + " to " + target);
|
879 | fsExtra.copy(thisPath, target, function(err) {
|
880 | if (err) {
|
881 | callback(err, null);
|
882 | } else {
|
883 |
|
884 | ensurePhotoReadableWindows(target);
|
885 |
|
886 |
|
887 | if(opts.keepOriginal == "useMasterConfig") {
|
888 |
|
889 |
|
890 | opts.keepOriginal = true;
|
891 | if( typeof content.keepMaster === 'undefined') {
|
892 |
|
893 | } else {
|
894 | if(content.keepMaster == false) {
|
895 | opts.keepOriginal = false;
|
896 | }
|
897 | }
|
898 | }
|
899 |
|
900 | if(opts.keepOriginal == false) {
|
901 |
|
902 | fsExtra.remove(thisPath, function(err) {
|
903 | if (err) {
|
904 | console.error('Warning: there was a problem removing: ' + err.message)
|
905 | callback(err, null);
|
906 | } else {
|
907 | console.log('Removed the file: ' + thisPath);
|
908 | callback(null);
|
909 | }
|
910 | });
|
911 |
|
912 | } else {
|
913 | callback(null);
|
914 | }
|
915 | }
|
916 |
|
917 |
|
918 | })
|
919 | } else {
|
920 |
|
921 | callback(null);
|
922 | }
|
923 |
|
924 |
|
925 |
|
926 | } catch (err) {
|
927 | console.error('Warning: there was a problem backing up: ' + err.message);
|
928 | callback(err, null);
|
929 | }
|
930 | }
|
931 | });
|
932 |
|
933 | },
|
934 | function(err){
|
935 |
|
936 | if(err) {
|
937 | console.log('ERR:' + err);
|
938 | cb(err, null);
|
939 | } else {
|
940 | if(verbose == true) console.log('Completed all backups!');
|
941 | cb(null, lastNewPath);
|
942 | }
|
943 | }
|
944 | );
|
945 |
|
946 |
|
947 |
|
948 | } else {
|
949 |
|
950 | cb(null, lastNewPath);
|
951 | }
|
952 |
|
953 | }
|
954 |
|
955 | });
|
956 | }
|
957 |
|
958 |
|
959 | function getPlatform() {
|
960 | var platform = process.platform;
|
961 | if(verbose == true) console.log(process.platform);
|
962 | var isWin = /^win/.test(platform);
|
963 | if(verbose == true) console.log("IsWin=" + isWin);
|
964 | if(isWin) {
|
965 | if(process.arch == 'x64') {
|
966 | return "win64";
|
967 | } else {
|
968 | return "win32";
|
969 | }
|
970 | } else {
|
971 | if(platform == "darwin") {
|
972 | return "mac";
|
973 | } else {
|
974 | return "unix";
|
975 | }
|
976 |
|
977 | }
|
978 | }
|
979 |
|
980 |
|
981 |
|
982 |
|
983 |
|
984 |
|
985 |
|
986 | function myExec(cmdLine, priority, cb) {
|
987 |
|
988 |
|
989 |
|
990 |
|
991 |
|
992 |
|
993 |
|
994 |
|
995 |
|
996 |
|
997 |
|
998 |
|
999 |
|
1000 | switch(priority) {
|
1001 | case 'high':
|
1002 | cmds = cmdLine.split(" ");
|
1003 | var argv = [];
|
1004 | var globalId = {};
|
1005 | var scriptPath = "";
|
1006 | if(cmds[0]) {
|
1007 |
|
1008 | }
|
1009 |
|
1010 | if(cmds[1]) {
|
1011 | scriptPath = cmds[1];
|
1012 | }
|
1013 |
|
1014 | if(cmds[2]) {
|
1015 |
|
1016 | cmds.splice(0, 2);
|
1017 | argv = cmds;
|
1018 | } else {
|
1019 |
|
1020 | argv = [];
|
1021 | }
|
1022 |
|
1023 | if(verbose == true) console.log("Global id:" + globalId + " scriptPath:" + scriptPath + " argv:" + JSON.stringify(argv));
|
1024 |
|
1025 | var lib = require(scriptPath);
|
1026 |
|
1027 | var mycb = cb;
|
1028 | lib.medImage(argv, function(err, retVal) {
|
1029 | if(err) {
|
1030 | console.log("Error:" + err);
|
1031 | mycb(err, "", "");
|
1032 | } else {
|
1033 | if(retVal) {
|
1034 | if(!retVal.stdout) retVal.stdout = "";
|
1035 | if(!retVal.stderr) retVal.stderr = "";
|
1036 | mycb(null, retVal.stdout, retVal.stderr);
|
1037 | } else {
|
1038 | mycb(null,"","");
|
1039 |
|
1040 | }
|
1041 | }
|
1042 |
|
1043 | });
|
1044 |
|
1045 |
|
1046 |
|
1047 |
|
1048 |
|
1049 | break;
|
1050 |
|
1051 |
|
1052 | case 'medium':
|
1053 |
|
1054 | cmds = cmdLine.split(" ");
|
1055 | var args = [];
|
1056 | var command = "";
|
1057 | if(cmds[0]) {
|
1058 | command = cmds[0];
|
1059 | if(command == "node") {
|
1060 | command = process.execPath;
|
1061 | }
|
1062 | }
|
1063 |
|
1064 | if(cmds[1]) {
|
1065 | cmds.splice(0, 1);
|
1066 | var args = cmds;
|
1067 | }
|
1068 |
|
1069 | var outputStdOut = "";
|
1070 | var outputStdError = "";
|
1071 |
|
1072 | var running = spawn(command, args);
|
1073 |
|
1074 |
|
1075 | running.stdout.on('data', (data) => {
|
1076 | if(verbose == true) console.log(data.toString());
|
1077 | outputStdOut += data.toString();
|
1078 |
|
1079 | });
|
1080 |
|
1081 | running.stderr.on('data', (data) => {
|
1082 | if(verbose == true) console.log(data.toString());
|
1083 | outputStdError += data.toString();
|
1084 | });
|
1085 |
|
1086 | running.on('close', (code, signal) => {
|
1087 | if(verbose == true) console.log(`Child process exited with code ${code} ` + outputStdOut);
|
1088 | if(signal) {
|
1089 | cb(code, outputStdOut, outputStdError);
|
1090 | } else {
|
1091 | cb(null, outputStdOut, outputStdError);
|
1092 | }
|
1093 | });
|
1094 |
|
1095 | break;
|
1096 |
|
1097 | case 'low':
|
1098 | exec(cmdLine, { maxBuffer: 2000 * 1024 }, cb);
|
1099 | break;
|
1100 |
|
1101 | case 'glacial':
|
1102 |
|
1103 |
|
1104 | var outputStdOut = "";
|
1105 | var outputStdError = "";
|
1106 |
|
1107 |
|
1108 | cmds = cmdLine.split(" ");
|
1109 | var args = [];
|
1110 | var command = "";
|
1111 | if(cmds[0]) {
|
1112 | args = cmds;
|
1113 | }
|
1114 |
|
1115 |
|
1116 | var platform = getPlatform();
|
1117 | if((platform == "win32")||(platform == "win64")) {
|
1118 | command = "cmd.exe"
|
1119 | args.unshift('/low','/s','/c');
|
1120 |
|
1121 | } else {
|
1122 |
|
1123 | command = "nice";
|
1124 | args.unshift('-10');
|
1125 | }
|
1126 |
|
1127 | var running = spawn(command, args);
|
1128 |
|
1129 | running.stdout.on('data', (data) => {
|
1130 | if(verbose == true) console.log(data.toString());
|
1131 | outputStdOut += data.toString();
|
1132 |
|
1133 | });
|
1134 |
|
1135 | running.stderr.on('data', (data) => {
|
1136 | if(verbose == true) console.log(data.toString());
|
1137 | outputStdError += data.toString();
|
1138 | });
|
1139 |
|
1140 | running.on('close', (code, signal) => {
|
1141 | if(signal) {
|
1142 | cb(code, outputStdOut, outputStdError);
|
1143 | } else {
|
1144 | cb(null, outputStdOut, outputStdError);
|
1145 | }
|
1146 | });
|
1147 |
|
1148 | break;
|
1149 |
|
1150 | default:
|
1151 |
|
1152 |
|
1153 | exec(cmdLine, { maxBuffer: 2000 * 1024 }, cb);
|
1154 |
|
1155 | break;
|
1156 |
|
1157 | }
|
1158 |
|
1159 | return;
|
1160 | }
|
1161 |
|
1162 |
|
1163 | function validateGlobalId(globalId) {
|
1164 |
|
1165 |
|
1166 |
|
1167 |
|
1168 |
|
1169 | if(globalId.length > 16) {
|
1170 | var format = /^[a-zA-Z0-9]+$/;
|
1171 | if(format.test(globalId) === true) {
|
1172 | return globalId;
|
1173 | } else {
|
1174 | return false;
|
1175 | }
|
1176 |
|
1177 | }
|
1178 | return false;
|
1179 |
|
1180 | }
|
1181 |
|
1182 |
|
1183 | function runCommandPhotoWritten(runBlock, backupAtEnd, param1, param2, param3, cb) {
|
1184 |
|
1185 | var cmdLine = runBlock.runProcess;
|
1186 | cmdLine = cmdLine.replace(/parentdir/g, serverParentDir());
|
1187 |
|
1188 | cmdLine = cmdLine.replace(/param1/g, param1);
|
1189 | cmdLine = cmdLine.replace(/param2/g, param2);
|
1190 | cmdLine = cmdLine.replace(/param3/g, param3);
|
1191 | console.log("Running addon line: " + cmdLine);
|
1192 |
|
1193 |
|
1194 |
|
1195 | myExec(cmdLine, runBlock.priority, function(err, stdout, stderr) {
|
1196 | if (err) {
|
1197 |
|
1198 | console.log("There was a problem running the addon. Error:" + err + "\n\nStdout:" + stdout + "\n\nStderr:" + stderr);
|
1199 | cb(err);
|
1200 |
|
1201 | } else {
|
1202 |
|
1203 | if((stdout)||(stderr)) {
|
1204 | console.log("Stdout from command:" + stdout + "\n\nStderr" + stderr);
|
1205 | }
|
1206 |
|
1207 |
|
1208 |
|
1209 |
|
1210 | backupFilesStr = "backupFiles:";
|
1211 | var backupFiles = "";
|
1212 | var backStart = stdout.lastIndexOf(backupFilesStr);
|
1213 |
|
1214 |
|
1215 |
|
1216 | backupFileRenamedStr = "backupFileRenamed:";
|
1217 | if(stdout.lastIndexOf(backupFileRenamedStr) > -1) {
|
1218 | backStart = stdout.lastIndexOf(backupFileRenamedStr);
|
1219 | normalBackup = false;
|
1220 | }
|
1221 |
|
1222 | returnparams = "returnParams:";
|
1223 | var returnStart = stdout.lastIndexOf(returnparams);
|
1224 |
|
1225 |
|
1226 |
|
1227 | if(backStart > -1) {
|
1228 |
|
1229 |
|
1230 | if(returnStart > -1) {
|
1231 |
|
1232 | var backLen = returnStart - backStart;
|
1233 | backupFiles = stdout.substr(backStart, backLen);
|
1234 | } else {
|
1235 |
|
1236 | backupFiles = stdout.substr(backStart);
|
1237 |
|
1238 | }
|
1239 |
|
1240 |
|
1241 | console.log("Backing up requested of " + backupFiles);
|
1242 | backupFiles = backupFiles.replace(backupFilesStr,"");
|
1243 | backupFiles = backupFiles.replace(backupFileRenamedStr,"");
|
1244 | backupFiles = backupFiles.trim();
|
1245 | if(verbose == true) console.log("Backing up string in server:" + backupFiles);
|
1246 | var backupArray = backupFiles.split(";");
|
1247 | if(verbose == true) console.log("Backing up array:" + JSON.stringify(backupArray));
|
1248 |
|
1249 |
|
1250 | for(var cnt = 0; cnt<backupArray.length; cnt++) {
|
1251 |
|
1252 |
|
1253 |
|
1254 |
|
1255 |
|
1256 | var photoParentDir = normalizeInclWinNetworks(serverParentDir() + outdirPhotos);
|
1257 | if(verbose == true) console.log("Backing up requested files from script");
|
1258 | if(verbose == true) console.log("photoParentDir=" + photoParentDir);
|
1259 | var finalFileName = normalizeInclWinNetworks(backupArray[cnt]);
|
1260 | finalFileName = finalFileName.replace(photoParentDir,"").trim();
|
1261 | if(verbose == true) console.log("finalFileName=" + finalFileName);
|
1262 | var thisPath = normalizeInclWinNetworks(backupArray[cnt].trim());
|
1263 | if(verbose == true) console.log("thisPath=" + thisPath);
|
1264 | backupAtEnd.push({ "thisPath": thisPath,
|
1265 | "finalFileName": finalFileName });
|
1266 |
|
1267 | }
|
1268 | }
|
1269 |
|
1270 |
|
1271 |
|
1272 | reloadConfig = "reloadConfig:true";
|
1273 | if(stdout.lastIndexOf(reloadConfig) > -1) {
|
1274 | checkConfigCurrent(null, function() {
|
1275 |
|
1276 |
|
1277 |
|
1278 | readHTMLHeader(function(err) {
|
1279 | if(err) {
|
1280 | console.log(err);
|
1281 | }
|
1282 | });
|
1283 |
|
1284 | });
|
1285 | }
|
1286 |
|
1287 |
|
1288 |
|
1289 | if(verbose == true) console.log(`stdout: ${stdout}`);
|
1290 | if(verbose == true) console.log(`stderr: ${stderr}`);
|
1291 |
|
1292 | cb(null);
|
1293 | }
|
1294 |
|
1295 | });
|
1296 | }
|
1297 |
|
1298 |
|
1299 |
|
1300 |
|
1301 | function addOns(eventType, cb, param1, param2, param3)
|
1302 | {
|
1303 |
|
1304 |
|
1305 |
|
1306 | fs.readFile(addonsConfigFile, function read(err, data) {
|
1307 | if (err) {
|
1308 | console.log("Warning: Error reading addons config file: " + err);
|
1309 | } else {
|
1310 | if(data) {
|
1311 | var content = JSON.parse(data);
|
1312 | } else {
|
1313 |
|
1314 | var content = global.globalConfig;
|
1315 | }
|
1316 |
|
1317 | if(verbose == true) {
|
1318 | console.log("Got content of addons config");
|
1319 | }
|
1320 |
|
1321 | switch(eventType)
|
1322 | {
|
1323 | case "photoWritten":
|
1324 |
|
1325 | if(content.events.photoWritten) {
|
1326 |
|
1327 | var normalBackup = true;
|
1328 | var evs = content.events.photoWritten;
|
1329 | var backupAtEnd = [];
|
1330 |
|
1331 |
|
1332 | console.log("PARAM1:" + param1);
|
1333 |
|
1334 |
|
1335 |
|
1336 |
|
1337 |
|
1338 |
|
1339 | async.eachOfSeries(evs,
|
1340 |
|
1341 | function(runBlock, cnt, callback){
|
1342 |
|
1343 |
|
1344 |
|
1345 |
|
1346 | if(runBlock.active == true) {
|
1347 |
|
1348 |
|
1349 |
|
1350 |
|
1351 | if((runBlock.useTargetFolderFile)&&(runBlock.useTargetFolderFile == true)) {
|
1352 |
|
1353 |
|
1354 |
|
1355 | var cmdLine = runBlock.runProcess;
|
1356 | cmdLine = cmdLine.replace(/parentdir/g, serverParentDir());
|
1357 |
|
1358 | cmdLine = cmdLine.replace(/param1/g, param1);
|
1359 | cmdLine = cmdLine.replace(/param2/g, param2);
|
1360 | cmdLine = cmdLine.replace(/param3/g, param3);
|
1361 |
|
1362 | var photoParentDir = normalizeInclWinNetworks(serverParentDir() + outdirPhotos);
|
1363 | if(verbose == true) console.log("Backing up requested files from script");
|
1364 | if(verbose == true) console.log("photoParentDir=" + photoParentDir);
|
1365 | var finalFileName = normalizeInclWinNetworks(param1);
|
1366 | finalFileName = finalFileName.replace(photoParentDir,"").trim();
|
1367 | if(verbose == true) console.log("finalFileName=" + finalFileName);
|
1368 | var thisPath = normalizeInclWinNetworks(param1);
|
1369 | if(verbose == true) console.log("thisPath=" + thisPath);
|
1370 |
|
1371 |
|
1372 |
|
1373 | backupFile(thisPath, "", finalFileName, { }, function(err, newPath) {
|
1374 |
|
1375 | if(err) {
|
1376 | callback(err, null);
|
1377 | } else {
|
1378 |
|
1379 | runCommandPhotoWritten(runBlock, backupAtEnd, newPath, param2, param3, function(err) {
|
1380 | if(err) {
|
1381 | callback(err);
|
1382 | } else {
|
1383 |
|
1384 |
|
1385 | callback(null);
|
1386 | }
|
1387 | });
|
1388 | }
|
1389 |
|
1390 | });
|
1391 | } else {
|
1392 |
|
1393 |
|
1394 | runCommandPhotoWritten(runBlock, backupAtEnd, param1, param2, param3, function(err) {
|
1395 | if(err) {
|
1396 | callback(err);
|
1397 | } else {
|
1398 |
|
1399 |
|
1400 | callback(null);
|
1401 | }
|
1402 |
|
1403 | });
|
1404 | }
|
1405 | } else {
|
1406 |
|
1407 | callback(null);
|
1408 | }
|
1409 |
|
1410 | },
|
1411 | function(err){
|
1412 |
|
1413 | if(err) {
|
1414 | console.log('ERR:' + err);
|
1415 | } else {
|
1416 | console.log('Completed all photoWritten events!');
|
1417 |
|
1418 |
|
1419 | for(var cnt = 0; cnt < backupAtEnd.length; cnt++) {
|
1420 | backupFile(backupAtEnd[cnt].thisPath, "", backupAtEnd[cnt].finalFileName, { });
|
1421 | }
|
1422 |
|
1423 |
|
1424 |
|
1425 | cb(null, normalBackup);
|
1426 | }
|
1427 | }
|
1428 | );
|
1429 |
|
1430 | }
|
1431 |
|
1432 | break;
|
1433 |
|
1434 |
|
1435 | case "fileWritten":
|
1436 |
|
1437 |
|
1438 | if(content.events.fileWritten) {
|
1439 |
|
1440 | var normalBackup = true;
|
1441 | var evs = content.events.fileWritten;
|
1442 | var backupAtEnd = [];
|
1443 |
|
1444 |
|
1445 | console.log("PARAM1:" + param1);
|
1446 |
|
1447 |
|
1448 |
|
1449 |
|
1450 |
|
1451 |
|
1452 | async.eachOfSeries(evs,
|
1453 |
|
1454 | function(runBlock, cnt, callback){
|
1455 |
|
1456 |
|
1457 |
|
1458 |
|
1459 | if(runBlock.active == true) {
|
1460 |
|
1461 |
|
1462 |
|
1463 |
|
1464 | if((runBlock.useTargetFolderFile)&&(runBlock.useTargetFolderFile == true)) {
|
1465 |
|
1466 |
|
1467 |
|
1468 | var cmdLine = runBlock.runProcess;
|
1469 | cmdLine = cmdLine.replace(/parentdir/g, serverParentDir());
|
1470 |
|
1471 | cmdLine = cmdLine.replace(/param1/g, param1);
|
1472 | cmdLine = cmdLine.replace(/param2/g, param2);
|
1473 | cmdLine = cmdLine.replace(/param3/g, param3);
|
1474 |
|
1475 | var photoParentDir = normalizeInclWinNetworks(serverParentDir() + outdirPhotos);
|
1476 | if(verbose == true) console.log("Backing up requested files from script");
|
1477 | if(verbose == true) console.log("photoParentDir=" + photoParentDir);
|
1478 | var finalFileName = normalizeInclWinNetworks(param1);
|
1479 | finalFileName = finalFileName.replace(photoParentDir,"").trim();
|
1480 | if(verbose == true) console.log("finalFileName=" + finalFileName);
|
1481 | var thisPath = normalizeInclWinNetworks(param1);
|
1482 | if(verbose == true) console.log("thisPath=" + thisPath);
|
1483 |
|
1484 |
|
1485 |
|
1486 | backupFile(thisPath, "", finalFileName, { }, function(err, newPath) {
|
1487 |
|
1488 | if(err) {
|
1489 | callback(err, null);
|
1490 | } else {
|
1491 |
|
1492 | runCommandPhotoWritten(runBlock, backupAtEnd, newPath, param2, param3, function(err) {
|
1493 | if(err) {
|
1494 | callback(err);
|
1495 | } else {
|
1496 |
|
1497 |
|
1498 | callback(null);
|
1499 | }
|
1500 | });
|
1501 | }
|
1502 |
|
1503 | });
|
1504 | } else {
|
1505 |
|
1506 |
|
1507 | runCommandPhotoWritten(runBlock, backupAtEnd, param1, param2, param3, function(err) {
|
1508 | if(err) {
|
1509 | callback(err);
|
1510 | } else {
|
1511 |
|
1512 |
|
1513 | callback(null);
|
1514 | }
|
1515 |
|
1516 | });
|
1517 | }
|
1518 | } else {
|
1519 |
|
1520 | callback(null);
|
1521 | }
|
1522 |
|
1523 | },
|
1524 | function(err){
|
1525 |
|
1526 | if(err) {
|
1527 | console.log('ERR:' + err);
|
1528 | } else {
|
1529 | console.log('Completed all fileWritten events!');
|
1530 |
|
1531 |
|
1532 | for(var cnt = 0; cnt < backupAtEnd.length; cnt++) {
|
1533 | backupFile(backupAtEnd[cnt].thisPath, "", backupAtEnd[cnt].finalFileName, { });
|
1534 | }
|
1535 |
|
1536 |
|
1537 |
|
1538 | cb(null, normalBackup);
|
1539 | }
|
1540 | }
|
1541 | );
|
1542 |
|
1543 | }
|
1544 |
|
1545 | break;
|
1546 |
|
1547 |
|
1548 | case "urlRequest":
|
1549 | if(verbose == true) console.log("URL request of " + param1);
|
1550 |
|
1551 | if(content.events && content.events.urlRequest) {
|
1552 |
|
1553 | var evs = content.events.urlRequest;
|
1554 | for(var cnt = 0; cnt< evs.length; cnt++) {
|
1555 |
|
1556 |
|
1557 | var scriptChk = evs[cnt].scriptURLName;
|
1558 | if(verbose == true) console.log("Checking against:" + scriptChk);
|
1559 |
|
1560 | if(param1.substr(0,scriptChk.length) == scriptChk) {
|
1561 | if(evs[cnt].active == true) {
|
1562 |
|
1563 | var cmdLine = evs[cnt].runProcess;
|
1564 | cmdLine = cmdLine.replace(/parentdir/g, serverParentDir());
|
1565 |
|
1566 | param1 = param1.replace("%23", "#");
|
1567 | param1 = param1.replace("%20", " ");
|
1568 |
|
1569 | var queryString = encodeURIComponent(param1.replace(scriptChk + "?",""));
|
1570 |
|
1571 |
|
1572 | cmdLine = cmdLine.replace(/param1/g, queryString);
|
1573 | if(verbose == true) console.log("Running addon line: " + cmdLine);
|
1574 |
|
1575 | if(evs[cnt].waitForRequestFinish) {
|
1576 |
|
1577 | var waitForIt = evs[cnt].waitForRequestFinish;
|
1578 | }
|
1579 |
|
1580 |
|
1581 | myExec(cmdLine, evs[cnt].priority, function(err, stdout, stderr) {
|
1582 | if (err) {
|
1583 |
|
1584 | console.log("There was a problem running the addon. Error:" + err + "\n\nStdout:" + stdout + "\n\nStderr:" + stderr);
|
1585 | return;
|
1586 | }
|
1587 |
|
1588 |
|
1589 | if(stdout) {
|
1590 | console.log(`stdout: ${stdout}`);
|
1591 | }
|
1592 | if(stderr) {
|
1593 | console.log(`stderr: ${stderr}`);
|
1594 | }
|
1595 |
|
1596 |
|
1597 | if(waitForIt) {
|
1598 |
|
1599 | returnparams = "returnParams:";
|
1600 | var params = "";
|
1601 | if(verbose == true) console.log("Stdout:" + stdout);
|
1602 | var returnStart = stdout.lastIndexOf(returnparams);
|
1603 |
|
1604 | reloadConfig = "reloadConfig:true";
|
1605 | if(stdout.lastIndexOf(reloadConfig) > -1) {
|
1606 | checkConfigCurrent(null, function() {
|
1607 |
|
1608 |
|
1609 |
|
1610 | readHTMLHeader(function(err) {
|
1611 | if(err) {
|
1612 | console.log(err);
|
1613 | }
|
1614 | });
|
1615 |
|
1616 | });
|
1617 | }
|
1618 |
|
1619 |
|
1620 | if(returnStart > -1) {
|
1621 |
|
1622 | params = stdout.substr(returnStart);
|
1623 | params = params.replace(returnparams + "?","");
|
1624 | params = params.replace(returnparams,"");
|
1625 | params = params.trim();
|
1626 | if(verbose == true) console.log("Params returned=" + params);
|
1627 | }
|
1628 |
|
1629 |
|
1630 |
|
1631 |
|
1632 | backupFilesStr = "backupFiles:";
|
1633 | var backupFiles = "";
|
1634 | var backStart = stdout.lastIndexOf(backupFilesStr);
|
1635 |
|
1636 | if(backStart > -1) {
|
1637 | if(verbose == true) console.log("Backing up requested");
|
1638 |
|
1639 |
|
1640 | if(returnStart > -1) {
|
1641 |
|
1642 | var backLen = returnStart - backStart;
|
1643 | backupFiles = stdout.substr(backStart, backLen);
|
1644 | } else {
|
1645 |
|
1646 | backupFiles = stdout.substr(backStart);
|
1647 |
|
1648 | }
|
1649 | backupFiles = backupFiles.replace(backupFilesStr,"");
|
1650 | backupFiles = backupFiles.trim();
|
1651 | if(verbose == true) console.log("Backing up string in server:" + backupFiles);
|
1652 | var backupArray = backupFiles.split(";");
|
1653 | if(verbose == true) console.log("Backing up array:" + JSON.stringify(backupArray));
|
1654 |
|
1655 |
|
1656 | for(var cnt = 0; cnt<backupArray.length; cnt++) {
|
1657 |
|
1658 |
|
1659 |
|
1660 |
|
1661 |
|
1662 | var photoParentDir = normalizeInclWinNetworks(serverParentDir() + outdirPhotos);
|
1663 | if(verbose == true) console.log("Backing up requested files from script");
|
1664 | if(verbose == true) console.log("photoParentDir=" + photoParentDir);
|
1665 | var finalFileName = normalizeInclWinNetworks(backupArray[cnt]);
|
1666 | finalFileName = finalFileName.replace(photoParentDir,"");
|
1667 | if(verbose == true) console.log("finalFileName=" + finalFileName);
|
1668 | var thisPath = normalizeInclWinNetworks(backupArray[cnt]);
|
1669 | if(verbose == true) console.log("thisPath=" + thisPath);
|
1670 | backupFile(thisPath, "", finalFileName, { });
|
1671 | }
|
1672 | }
|
1673 |
|
1674 |
|
1675 | cb(waitForIt, params);
|
1676 | } else {
|
1677 |
|
1678 | returnPhotoFile = "returnPhotoFile:";
|
1679 | var params = "";
|
1680 | if(verbose == true) console.log("Stdout:" + stdout);
|
1681 | var returnStart = stdout.lastIndexOf(returnPhotoFile);
|
1682 |
|
1683 | if(returnStart > -1) {
|
1684 |
|
1685 | params = stdout.substr(returnStart);
|
1686 | params = params.replace("returnPhotoFile:?","");
|
1687 | params = params.replace("returnPhotoFile:","");
|
1688 | params = params.trim();
|
1689 | if(verbose == true) console.log("Photo file returned=" + params);
|
1690 |
|
1691 |
|
1692 | cb(params, null);
|
1693 |
|
1694 | }
|
1695 |
|
1696 |
|
1697 |
|
1698 | }
|
1699 |
|
1700 | });
|
1701 |
|
1702 | if((evs[cnt].waitForRequestFinish)||(evs[cnt].waitForRequestFinish == "")) {
|
1703 |
|
1704 | } else {
|
1705 |
|
1706 | if(verbose == true) console.log("Checking after request:" + evs[cnt].afterRequest);
|
1707 | if(evs[cnt].afterRequest) {
|
1708 |
|
1709 | cb(evs[cnt].afterRequest);
|
1710 | } else {
|
1711 | cb("");
|
1712 | }
|
1713 | }
|
1714 | }
|
1715 | }
|
1716 |
|
1717 | }
|
1718 |
|
1719 | }
|
1720 |
|
1721 |
|
1722 | break;
|
1723 |
|
1724 |
|
1725 | case "displayMenu":
|
1726 |
|
1727 | break;
|
1728 |
|
1729 | };
|
1730 | }
|
1731 | });
|
1732 |
|
1733 | return;
|
1734 |
|
1735 | }
|
1736 |
|
1737 |
|
1738 | function trimChar(string, charToRemove) {
|
1739 | while(string.substring(0,1) == charToRemove) {
|
1740 | string = string.substring(1);
|
1741 | }
|
1742 |
|
1743 | while(string.slice(-1) == charToRemove) {
|
1744 | string = string.slice(0, -1);
|
1745 | }
|
1746 |
|
1747 | return string;
|
1748 | }
|
1749 |
|
1750 | function escapeRegExp(str) {
|
1751 | return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
|
1752 | }
|
1753 |
|
1754 | function replaceAll(str, find, replace) {
|
1755 | return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
|
1756 | }
|
1757 |
|
1758 |
|
1759 | function httpHttpsCreateServer(options) {
|
1760 |
|
1761 |
|
1762 | readHTMLHeader(function(err) {
|
1763 | if(err) {
|
1764 | console.log(err);
|
1765 | } else {
|
1766 |
|
1767 | if(httpsFlag == true) {
|
1768 | console.log("Starting https server.");
|
1769 | https.createServer(options, handleServer).listen(listenPort);
|
1770 |
|
1771 |
|
1772 | } else {
|
1773 | console.log("Starting http server.");
|
1774 | http.createServer(handleServer).listen(listenPort);
|
1775 | }
|
1776 | }
|
1777 | });
|
1778 |
|
1779 | }
|
1780 |
|
1781 |
|
1782 |
|
1783 |
|
1784 | function getFileFromUserStr(inFile)
|
1785 | {
|
1786 | if(verbose == true) console.log("getFileFromUserStr:" + inFile);
|
1787 | var outFile = inFile;
|
1788 |
|
1789 | outFile = outFile.replace('.jpg','');
|
1790 | outFile = outFile.replace('.jpeg','');
|
1791 | outFile = replaceAll(outFile, "..", "");
|
1792 |
|
1793 | var re = new RegExp("[^" + allowedChars + "]", "g");
|
1794 | outFile = outFile.replace(re, "");
|
1795 |
|
1796 | outFile = trimChar(outFile, '/');
|
1797 | outFile = trimChar(outFile,'\\');
|
1798 |
|
1799 |
|
1800 |
|
1801 | var words = outFile.split('-');
|
1802 |
|
1803 |
|
1804 | var finalFileName = "";
|
1805 | var outhashdir = "";
|
1806 |
|
1807 | for(var cnt = 0; cnt< words.length; cnt++) {
|
1808 | if(words[cnt].charAt(0) == '#') {
|
1809 | var getDir = words[cnt].replace('#','');
|
1810 |
|
1811 |
|
1812 | getDir = trimChar(getDir, '/');
|
1813 | getDir = trimChar(getDir, '\\');
|
1814 |
|
1815 |
|
1816 | if(verbose == true) console.log('Comparing ' + getDir + ' with ' + globalId);
|
1817 | if(getDir != globalId) {
|
1818 | outhashdir = outhashdir + '/' + getDir;
|
1819 | if(verbose == true) console.log('OutHashDir:' + outhashdir);
|
1820 | }
|
1821 | } else {
|
1822 |
|
1823 | var thisWord = words[cnt];
|
1824 | thisWord = trimChar(thisWord, '/');
|
1825 | thisWord = trimChar(thisWord, '\\');
|
1826 |
|
1827 |
|
1828 | if(finalFileName.length > 0) {
|
1829 | finalFileName = finalFileName + '-';
|
1830 | }
|
1831 | finalFileName = finalFileName + thisWord;
|
1832 | }
|
1833 | }
|
1834 |
|
1835 | finalFileName = finalFileName + '.jpg';
|
1836 | return normalizeInclWinNetworks(outhashdir + '/' + finalFileName);
|
1837 | }
|
1838 |
|
1839 |
|
1840 | function handleServer(_req, _res) {
|
1841 |
|
1842 | var req = _req;
|
1843 | var res = _res;
|
1844 | var body = [];
|
1845 |
|
1846 |
|
1847 |
|
1848 | if (req.url === '/api/photo' && req.method === 'POST') {
|
1849 |
|
1850 |
|
1851 | var form = new multiparty.Form({maxFilesSize: maxUploadSize});
|
1852 |
|
1853 |
|
1854 | form.parse(req, function(err, fields, files) {
|
1855 |
|
1856 |
|
1857 |
|
1858 | if(err) {
|
1859 | console.log("Error uploading file " + JSON.stringify(err))
|
1860 |
|
1861 | res.writeHead(400, {'content-type': 'text/plain'});
|
1862 | res.end("Invalid request: " + err.message);
|
1863 | return;
|
1864 |
|
1865 | } else {
|
1866 |
|
1867 |
|
1868 | var parentDir = serverParentDir();
|
1869 | if(verbose == true) console.log("This drive:" + parentDir);
|
1870 | var outdir = parentDir + outdirPhotos;
|
1871 |
|
1872 | if(verbose == true) console.log('Outdir:' + outdir);
|
1873 |
|
1874 |
|
1875 | if(verbose == true) console.log('Files ' + JSON.stringify(files, null, 4));
|
1876 |
|
1877 | if(files && files.file1 && files.file1[0]) {
|
1878 |
|
1879 |
|
1880 |
|
1881 |
|
1882 |
|
1883 | var buffer = readChunk.sync(files.file1[0].path, 0, 12);
|
1884 | var fileObj = fileType(buffer);
|
1885 | if((!fileObj)||(!fileObj.mime) || (fileObj.mime != 'image/jpeg')) {
|
1886 |
|
1887 | var ext = null;
|
1888 |
|
1889 | if(fileObj) {
|
1890 | for(var type = 0; type < allowedTypes.length; type++) {
|
1891 | if(fileObj.mime === allowedTypes[type].mime) {
|
1892 |
|
1893 | var ext = allowedTypes[type].extension;
|
1894 | var ext2 = ext;
|
1895 | }
|
1896 |
|
1897 | }
|
1898 | }
|
1899 |
|
1900 | if(!ext) {
|
1901 |
|
1902 | console.log("Error uploading file. Only certain files (e.g. jpg) are allowed.");
|
1903 | res.statusCode = 400;
|
1904 | res.end();
|
1905 | return;
|
1906 | }
|
1907 | } else {
|
1908 | var ext = ".jpg";
|
1909 | var ext2 = ".jpeg";
|
1910 |
|
1911 | }
|
1912 |
|
1913 |
|
1914 |
|
1915 |
|
1916 |
|
1917 | var title = files.file1[0].originalFilename;
|
1918 |
|
1919 | res.writeHead(200, {'content-type': 'text/plain'});
|
1920 | var returnStr = 'Received upload successfully!';
|
1921 | if(verbose == true) returnStr += 'Check ' + normalizeInclWinNetworks(parentDir + outdirPhotos) + ' for your image.';
|
1922 | res.write(returnStr + '\n\n');
|
1923 | res.end();
|
1924 |
|
1925 |
|
1926 |
|
1927 | var outFile = title;
|
1928 | outFile = outFile.replace(ext,'');
|
1929 | outFile = outFile.replace(ext2,'');
|
1930 | outFile = replaceAll(outFile, "..", "");
|
1931 |
|
1932 | var re = new RegExp("[^" + allowedChars + "]", "g");
|
1933 | outFile = outFile.replace(re, "");
|
1934 |
|
1935 |
|
1936 | outFile = trimChar(outFile, '/');
|
1937 | outFile = trimChar(outFile,'\\');
|
1938 |
|
1939 |
|
1940 |
|
1941 | var words = outFile.split('-');
|
1942 |
|
1943 | var finalFileName = "";
|
1944 | var outhashdir = "";
|
1945 |
|
1946 | for(var cnt = 0; cnt< words.length; cnt++) {
|
1947 | if(words[cnt].charAt(0) == '#') {
|
1948 | var getDir = words[cnt].replace('#','');
|
1949 |
|
1950 |
|
1951 | getDir = trimChar(getDir, '/');
|
1952 | getDir = trimChar(getDir, '\\');
|
1953 |
|
1954 |
|
1955 | if(verbose == true) console.log('Comparing ' + getDir + ' with ' + globalId);
|
1956 | if(getDir != globalId) {
|
1957 | outhashdir = outhashdir + '/' + getDir;
|
1958 | if(verbose == true) console.log('OutHashDir:' + outhashdir);
|
1959 | }
|
1960 | } else {
|
1961 |
|
1962 | var thisWord = words[cnt];
|
1963 | thisWord = trimChar(thisWord, '/');
|
1964 | thisWord = trimChar(thisWord, '\\');
|
1965 |
|
1966 |
|
1967 | if(finalFileName.length > 0) {
|
1968 | finalFileName = finalFileName + '-';
|
1969 | }
|
1970 | finalFileName = finalFileName + thisWord;
|
1971 | }
|
1972 | }
|
1973 |
|
1974 |
|
1975 |
|
1976 | if (!fs.existsSync(normalizeInclWinNetworks(parentDir + outdirPhotos))){
|
1977 | if(verbose == true) console.log('Creating dir:' + normalizeInclWinNetworks(parentDir + outdirPhotos));
|
1978 |
|
1979 | fsExtra.mkdirsSync(normalizeInclWinNetworks(parentDir + outdirPhotos));
|
1980 | if(verbose == true) console.log('Created OK dir:' + normalizeInclWinNetworks(parentDir + outdirPhotos));
|
1981 |
|
1982 | }
|
1983 |
|
1984 |
|
1985 | outdir = parentDir + outdirPhotos + outhashdir;
|
1986 | if (!fs.existsSync(normalizeInclWinNetworks(outdir))){
|
1987 | if(verbose == true) console.log('Creating dir:' + normalizeInclWinNetworks(outdir));
|
1988 | fsExtra.mkdirsSync(normalizeInclWinNetworks(outdir));
|
1989 | if(verbose == true) console.log('Created OK');
|
1990 |
|
1991 | }
|
1992 |
|
1993 |
|
1994 |
|
1995 | finalFileName = finalFileName + ext;
|
1996 |
|
1997 |
|
1998 | var fullPath = outdir + '/' + finalFileName;
|
1999 | if(verbose == true) console.log("Moving " + files.file1[0].path + " to " + fullPath);
|
2000 | mv(files.file1[0].path, fullPath, {mkdirp: true}, function(err) {
|
2001 |
|
2002 |
|
2003 |
|
2004 | if(err) {
|
2005 | console.log(err);
|
2006 |
|
2007 | } else {
|
2008 | console.log('\n' + finalFileName + ' file uploaded');
|
2009 |
|
2010 |
|
2011 | ensurePhotoReadableWindows(fullPath);
|
2012 |
|
2013 |
|
2014 |
|
2015 |
|
2016 |
|
2017 |
|
2018 |
|
2019 |
|
2020 | if(ext === ".jpg") {
|
2021 | var event = "photoWritten";
|
2022 | } else {
|
2023 | var event = "fileWritten";
|
2024 | }
|
2025 |
|
2026 |
|
2027 |
|
2028 | addOns(event, function(err, normalBackup) {
|
2029 | if(err) {
|
2030 | console.log("Error writing file:" + err);
|
2031 | } else {
|
2032 | if(verbose == true) console.log("Add-on completed running");
|
2033 |
|
2034 | }
|
2035 |
|
2036 | if(normalBackup == true) {
|
2037 |
|
2038 |
|
2039 |
|
2040 |
|
2041 | if(verbose == true) console.log("Backups:");
|
2042 | var thisPath = fullPath;
|
2043 |
|
2044 |
|
2045 | backupFile(thisPath, outhashdir, finalFileName, { });
|
2046 | }
|
2047 | }, fullPath);
|
2048 |
|
2049 |
|
2050 |
|
2051 |
|
2052 |
|
2053 | }
|
2054 | });
|
2055 | } else {
|
2056 |
|
2057 | console.log("Error uploading file. No file on server.");
|
2058 | res.statusCode = 400;
|
2059 | res.end();
|
2060 | return;
|
2061 | }
|
2062 |
|
2063 | }
|
2064 |
|
2065 |
|
2066 |
|
2067 |
|
2068 |
|
2069 |
|
2070 |
|
2071 |
|
2072 |
|
2073 | });
|
2074 |
|
2075 | return;
|
2076 |
|
2077 | } else {
|
2078 |
|
2079 |
|
2080 | req.on('error', function(err) {
|
2081 |
|
2082 | console.error(err.stack);
|
2083 |
|
2084 | res.statusCode = 400;
|
2085 | res.end();
|
2086 | });
|
2087 |
|
2088 | req.on('data', function(chunk) {
|
2089 | body.push(chunk);
|
2090 | });
|
2091 |
|
2092 | req.on('end', function() {
|
2093 |
|
2094 | if(flapSimulation == true) {
|
2095 | if(flapState == true) {
|
2096 | flapState = false;
|
2097 |
|
2098 | return;
|
2099 | } else {
|
2100 | flapState = true;
|
2101 | }
|
2102 |
|
2103 | }
|
2104 |
|
2105 |
|
2106 |
|
2107 |
|
2108 | var url = req.url;
|
2109 | if((url == '/') || (url == "") || (url == "/index.html")) {
|
2110 | url = "/pages/index.html";
|
2111 |
|
2112 |
|
2113 | var formattedBytes = formatBytes(bytesTransferred, 1);
|
2114 | var customString = { "CUSTOMSTRING": formattedBytes };
|
2115 |
|
2116 | if(allowGettingRemotePhotos == false) {
|
2117 |
|
2118 | customString.SYNCING = "false";
|
2119 |
|
2120 | } else {
|
2121 | customString.SYNCING = "true";
|
2122 | }
|
2123 |
|
2124 |
|
2125 | } else {
|
2126 |
|
2127 | var customString = null;
|
2128 | }
|
2129 |
|
2130 | var removeAfterwards = false;
|
2131 | var read = '/read/';
|
2132 | var pair = '/pair';
|
2133 | var check = '/check=';
|
2134 | var addonreq = '/addon/';
|
2135 |
|
2136 | if(verbose == true) console.log("Url requested:" + url);
|
2137 |
|
2138 | if(url.substr(0,pair.length) == pair) {
|
2139 |
|
2140 |
|
2141 | var fullPairingUrl = pairingURL;
|
2142 |
|
2143 | var queryString = url.substr(pair.length);
|
2144 |
|
2145 |
|
2146 | checkConfigCurrent(null, function() {
|
2147 |
|
2148 |
|
2149 | var data = {};
|
2150 | var vars = queryString.split('&');
|
2151 | for (var i = 0; i < vars.length; i++) {
|
2152 | var pair = vars[i].split('=');
|
2153 | data[pair[0]] = decodeURIComponent(pair[1]);
|
2154 |
|
2155 | }
|
2156 |
|
2157 |
|
2158 | if(globalId != "") {
|
2159 |
|
2160 | data.guid = globalId;
|
2161 |
|
2162 | }
|
2163 |
|
2164 | if(queryString) {
|
2165 | fullPairingUrl = fullPairingUrl + queryString;
|
2166 |
|
2167 | }
|
2168 | console.log("Request for pairing:" + fullPairingUrl);
|
2169 |
|
2170 | var options = {};
|
2171 | if(webProxy) {
|
2172 | options.proxy = webProxy;
|
2173 | }
|
2174 | options.follow = 1;
|
2175 |
|
2176 |
|
2177 | needle.post(fullPairingUrl, data, options, function(error, response) {
|
2178 | if(error) {
|
2179 | console.log("Pairing error:" + error);
|
2180 | var replace = {
|
2181 | "CUSTOMCODE": "[Pairing error: " + error + "]",
|
2182 | "CUSTOMCOUNTRY": "[Unknown]",
|
2183 | "STANDARDHEADER": htmlHeaderCode
|
2184 | };
|
2185 |
|
2186 |
|
2187 | checkConfigCurrent(readProx, function() {
|
2188 |
|
2189 |
|
2190 |
|
2191 | var outdir = __dirname + "/../public/pages/passcode.html";
|
2192 | serveUpFile(outdir, null, res, false, replace);
|
2193 | return;
|
2194 | });
|
2195 | } else {
|
2196 |
|
2197 | if (response.statusCode == 200) {
|
2198 | console.log(response.body);
|
2199 |
|
2200 | var codes = response.body.split(" ");
|
2201 | var passcode = codes[0];
|
2202 | newGlobalId = validateGlobalId(codes[1]);
|
2203 | if(newGlobalId !== false) {
|
2204 | globalId = codes[1];
|
2205 | var guid = globalId;
|
2206 | var proxyServer = codes[2].replace("\n", "");
|
2207 | if(codes[3]) {
|
2208 | var country = decodeURIComponent(codes[3].replace("\n", ""));
|
2209 | } else {
|
2210 |
|
2211 | var country = "[Unknown]";
|
2212 | }
|
2213 |
|
2214 | var readProx = proxyServer + "/read/" + guid;
|
2215 | console.log("Proxy set to:" + readProx);
|
2216 | } else {
|
2217 | passcode = "----";
|
2218 | var country = "[Sorry there was a problem contacting the pairing server. Please try again, or check 'Service Status'.]";
|
2219 | }
|
2220 |
|
2221 |
|
2222 |
|
2223 | var replace = {
|
2224 | "CUSTOMCODE": passcode,
|
2225 | "CUSTOMCOUNTRY": country,
|
2226 | "STANDARDHEADER": htmlHeaderCode
|
2227 | };
|
2228 |
|
2229 |
|
2230 | checkConfigCurrent(readProx, function() {
|
2231 |
|
2232 |
|
2233 |
|
2234 | var outdir = __dirname + "/../public/pages/passcode.html";
|
2235 | serveUpFile(outdir, null, res, false, replace);
|
2236 | return;
|
2237 | });
|
2238 |
|
2239 |
|
2240 | } else {
|
2241 |
|
2242 | console.log("Pairing error:" + error + " Status: " + response.statusCode);
|
2243 | var replace = {
|
2244 | "CUSTOMCODE": "[Pairing error: " + error + " Status: " + response.statusCode + "]",
|
2245 | "CUSTOMCOUNTRY": "[Unknown]",
|
2246 | "STANDARDHEADER": htmlHeaderCode
|
2247 | };
|
2248 |
|
2249 |
|
2250 | checkConfigCurrent(readProx, function() {
|
2251 |
|
2252 |
|
2253 |
|
2254 | var outdir = __dirname + "/../public/pages/passcode.html";
|
2255 | serveUpFile(outdir, null, res, false, replace);
|
2256 | return;
|
2257 | });
|
2258 |
|
2259 | }
|
2260 | }
|
2261 | });
|
2262 | });
|
2263 |
|
2264 |
|
2265 | } else {
|
2266 |
|
2267 |
|
2268 | if(url.substr(0,read.length) == read) {
|
2269 |
|
2270 | if(allowPhotosLeaving != true) {
|
2271 |
|
2272 | console.log("Read request detected (blocked by config.json): " + url);
|
2273 | res.writeHead(400, {'content-type': 'text/html'});
|
2274 | res.end("Sorry, you cannot read from this server. Please check the server's config.json.");
|
2275 | return;
|
2276 | }
|
2277 |
|
2278 |
|
2279 |
|
2280 | var codeDir = url.substr(read.length);
|
2281 | var parentDir = serverParentDir();
|
2282 | if(verbose == true) console.log("This drive:" + parentDir);
|
2283 | if(verbose == true) console.log("Coded directory:" + codeDir);
|
2284 |
|
2285 | if(codeDir.length <= 0) {
|
2286 | console.log("Cannot read without a directory");
|
2287 | return;
|
2288 | }
|
2289 |
|
2290 | var outdir = normalizeInclWinNetworks(parentDir + outdirPhotos + '/' + codeDir);
|
2291 | var compareWith = normalizeInclWinNetworks(parentDir + outdirPhotos);
|
2292 |
|
2293 | if(verbose == true) console.log("Output directory to scan " + outdir + ". Must include:" + compareWith);
|
2294 |
|
2295 |
|
2296 | if(outdir.indexOf(compareWith) > -1) {
|
2297 |
|
2298 |
|
2299 |
|
2300 | fileWalk(outdir, function(outfile, mime, cnt) {
|
2301 |
|
2302 | if(outfile) {
|
2303 |
|
2304 | outfile = normalizeInclWinNetworks(outfile);
|
2305 | var localFileName = outfile.replace(compareWith, "");
|
2306 | if(verbose == true) console.log("Local file to download via proxy as:" + localFileName);
|
2307 | if(verbose == true) console.log("About to download (eventually delete): " + outfile);
|
2308 |
|
2309 | if(req.method === "HEAD") {
|
2310 |
|
2311 | res.writeHead(200, {'content-type': mime, 'file-name': localFileName });
|
2312 | res.end();
|
2313 |
|
2314 | } else {
|
2315 |
|
2316 | serveUpFile(outfile,localFileName, res, true);
|
2317 | }
|
2318 |
|
2319 | } else {
|
2320 |
|
2321 |
|
2322 | if(verbose == true) {
|
2323 | console.log("No images");
|
2324 | } else {
|
2325 | process.stdout.write(".");
|
2326 | }
|
2327 | res.writeHead(200, {'content-type': 'text/html'});
|
2328 | res.end(noFurtherFiles);
|
2329 | return;
|
2330 |
|
2331 | }
|
2332 | });
|
2333 | } else {
|
2334 | console.log("Security exception detected in " + outdir);
|
2335 | return;
|
2336 | }
|
2337 |
|
2338 | } else {
|
2339 |
|
2340 |
|
2341 |
|
2342 | if(url.substr(0,check.length) == check) {
|
2343 |
|
2344 |
|
2345 |
|
2346 |
|
2347 | if(allowPhotosLeaving != true) {
|
2348 | console.log("Read request detected (blocked by config.json): " + url);
|
2349 | res.writeHead(400, {'content-type': 'text/html'});
|
2350 | res.end("Sorry, you cannot read from this server. Please check the server's config.json.");
|
2351 | return;
|
2352 | }
|
2353 |
|
2354 |
|
2355 | var codeFile = decodeURIComponent(url.substr(check.length));
|
2356 |
|
2357 |
|
2358 |
|
2359 |
|
2360 | var parentDir = serverParentDir();
|
2361 | if(verbose == true) console.log("This drive:" + parentDir);
|
2362 | if(verbose == true) console.log("Coded file:" + codeFile);
|
2363 |
|
2364 | if(codeFile.length <= 0) {
|
2365 | console.log("Cannot read without a file");
|
2366 | return;
|
2367 | }
|
2368 |
|
2369 | var checkFile = getFileFromUserStr(codeFile);
|
2370 | var fullCheck = parentDir + outdirPhotos + checkFile;
|
2371 | if(verbose == true) console.log("Checking file:" + fullCheck);
|
2372 |
|
2373 |
|
2374 | fs.stat(fullCheck, function(ferr, stat) {
|
2375 | if((ferr == null)&&(stat.isFile() == true)) {
|
2376 |
|
2377 | res.writeHead(200, {'content-type': 'text/html'});
|
2378 | res.end("true");
|
2379 | if(verbose == true) console.log("true");
|
2380 | return;
|
2381 |
|
2382 | } else {
|
2383 |
|
2384 | res.writeHead(200, {'content-type': 'text/html'});
|
2385 | res.end("false");
|
2386 | if(verbose == true) console.log("false");
|
2387 | return;
|
2388 | }
|
2389 | });
|
2390 |
|
2391 |
|
2392 |
|
2393 | } else {
|
2394 |
|
2395 |
|
2396 | if(url.substr(0,addonreq.length) == addonreq) {
|
2397 |
|
2398 |
|
2399 | var thisQueryString = url.substr(addonreq.length);
|
2400 | var newLocation = "";
|
2401 |
|
2402 |
|
2403 |
|
2404 | |
2405 |
|
2406 |
|
2407 |
|
2408 |
|
2409 |
|
2410 |
|
2411 | addOns("urlRequest", function(newLocation, params) {
|
2412 |
|
2413 |
|
2414 | if(newLocation != "") {
|
2415 |
|
2416 | if(params) {
|
2417 | var replace = queryStringLib.parse(params);
|
2418 | } else {
|
2419 | var replace = null;
|
2420 | }
|
2421 |
|
2422 | if((replace) && (replace.CHANGELOCATION)) {
|
2423 | newLocation = replace.CHANGELOCATION;
|
2424 |
|
2425 | }
|
2426 |
|
2427 | if(replace) {
|
2428 | replace.STANDARDHEADER = htmlHeaderCode;
|
2429 | }
|
2430 |
|
2431 | var outdir = __dirname + "/../public/pages/" + newLocation;
|
2432 | if(verbose == true) console.log("Serving up file:" + outdir);
|
2433 |
|
2434 |
|
2435 | if((res.headersSent) && (res.headersSent == true)) {
|
2436 |
|
2437 | } else {
|
2438 | res.setHeader("Cache-Control", 'private, no-cache, no-store, must-revalidate');
|
2439 | res.setHeader("Expires", "-1");
|
2440 | res.setHeader("Pragma", "no-cache");
|
2441 | }
|
2442 |
|
2443 | serveUpFile(outdir, null, res, false, replace);
|
2444 | } else {
|
2445 |
|
2446 | if(verbose == true) console.log("Completing browser request");
|
2447 | res.writeHead(200, {'content-type': 'text/html'});
|
2448 | res.end();
|
2449 | }
|
2450 |
|
2451 |
|
2452 | }, thisQueryString);
|
2453 |
|
2454 |
|
2455 |
|
2456 | } else {
|
2457 |
|
2458 |
|
2459 | var outdir = __dirname + "/../public" + url;
|
2460 |
|
2461 | if(customString) {
|
2462 | customString.STANDARDHEADER = htmlHeaderCode;
|
2463 | } else {
|
2464 |
|
2465 | if((url.endsWith(".html"))&&(url !== "snippet.html")) {
|
2466 |
|
2467 | var customString = {};
|
2468 | customString.STANDARDHEADER = htmlHeaderCode;
|
2469 |
|
2470 | }
|
2471 | }
|
2472 |
|
2473 | serveUpFile(outdir, null, res, false, customString);
|
2474 | }
|
2475 | }
|
2476 | }
|
2477 | }
|
2478 |
|
2479 | });
|
2480 | }
|
2481 | }
|
2482 |
|
2483 |
|
2484 | function serveUpFile(fullFile, theFile, res, deleteAfterwards, customStringList) {
|
2485 |
|
2486 |
|
2487 |
|
2488 |
|
2489 |
|
2490 |
|
2491 |
|
2492 |
|
2493 | var sections = normalizeInclWinNetworks(fullFile).split("?");
|
2494 | var normpath = sections[0];
|
2495 |
|
2496 | if(verbose == true) console.log(normpath);
|
2497 |
|
2498 |
|
2499 |
|
2500 |
|
2501 | var ext = path.extname(normpath);
|
2502 | var contentType = 'text/html';
|
2503 | var stream = true;
|
2504 |
|
2505 | if(customStringList) {
|
2506 |
|
2507 | stream = false;
|
2508 |
|
2509 | }
|
2510 |
|
2511 |
|
2512 | if (ext === '.png') {
|
2513 | contentType = 'image/png';
|
2514 | stream = false;
|
2515 | }
|
2516 | if (ext === '.jpg') {
|
2517 | contentType = 'image/jpeg';
|
2518 | stream = false;
|
2519 | }
|
2520 |
|
2521 | if(ext === '.svg') {
|
2522 | contentType = 'image/svg+xml';
|
2523 | stream = false;
|
2524 | }
|
2525 |
|
2526 | if(ext === '.css') {
|
2527 | contentType = 'text/css';
|
2528 | }
|
2529 |
|
2530 |
|
2531 | for(var type = 0; type < allowedTypes.length; type++) {
|
2532 | if(ext === allowedTypes[type].extension) {
|
2533 | contentType = allowedTypes[type].mime;
|
2534 | if(verbose == true) console.log(contentType);
|
2535 | }
|
2536 |
|
2537 | }
|
2538 |
|
2539 |
|
2540 |
|
2541 |
|
2542 |
|
2543 |
|
2544 | if((stream == false)&&(deleteAfterwards != true)) {
|
2545 |
|
2546 |
|
2547 | fs.readFile(normpath, function (err,data) {
|
2548 |
|
2549 |
|
2550 | if (err) {
|
2551 | res.writeHead(404);
|
2552 | res.end(JSON.stringify(err));
|
2553 | return;
|
2554 | }
|
2555 |
|
2556 |
|
2557 | if((contentType != 'image/jpeg')&&
|
2558 | (contentType != 'image/png')) {
|
2559 |
|
2560 |
|
2561 | var strData = data.toString();
|
2562 |
|
2563 | for (var key in customStringList) {
|
2564 | strData = strData.replace(new RegExp(key, 'g'), customStringList[key]);
|
2565 |
|
2566 | }
|
2567 |
|
2568 | data = JSON.parse( JSON.stringify( strData ) );
|
2569 | }
|
2570 |
|
2571 | res.on('error', function(err){
|
2572 |
|
2573 | res.statusCode = 400;
|
2574 | res.end();
|
2575 | })
|
2576 |
|
2577 | if((res.headersSent) && (res.headersSent == true)) {
|
2578 |
|
2579 | } else {
|
2580 | res.writeHead(200, {'Content-Type': contentType, 'file-name': theFile});
|
2581 | }
|
2582 |
|
2583 | res.end(data, function(err) {
|
2584 |
|
2585 | if(err) {
|
2586 | console.log(err);
|
2587 | } else {
|
2588 |
|
2589 |
|
2590 | if(deleteAfterwards == true) {
|
2591 |
|
2592 |
|
2593 |
|
2594 |
|
2595 |
|
2596 | if(verbose == true) console.log("About to shred:" + normpath);
|
2597 | shredWrapper(normpath, theFile);
|
2598 |
|
2599 |
|
2600 | }
|
2601 |
|
2602 | }
|
2603 | });
|
2604 | });
|
2605 | } else {
|
2606 |
|
2607 |
|
2608 |
|
2609 |
|
2610 | if((res.headersSent) && (res.headersSent == true)) {
|
2611 |
|
2612 | } else {
|
2613 | res.writeHead(200, {'content-type': contentType, 'file-name': theFile});
|
2614 | }
|
2615 |
|
2616 |
|
2617 | var stream = fs.createReadStream(normpath);
|
2618 | stream.on('error', function(err) {
|
2619 | console.log(JSON.stringify(err))
|
2620 |
|
2621 | return;
|
2622 | })
|
2623 |
|
2624 | stream.on('end', function() {
|
2625 |
|
2626 | if(deleteAfterwards == true) {
|
2627 |
|
2628 |
|
2629 |
|
2630 |
|
2631 |
|
2632 | if(verbose == true) console.log("About to shred:" + normpath);
|
2633 | shredWrapper(normpath, theFile);
|
2634 |
|
2635 |
|
2636 | }
|
2637 | });
|
2638 |
|
2639 | stream.on('finish', function() {
|
2640 | console.log("On finish event");
|
2641 | });
|
2642 |
|
2643 | stream.pipe(res);
|
2644 | }
|
2645 |
|
2646 | }
|
2647 |
|
2648 |
|
2649 | checkConfigCurrent(null, function(err) {
|
2650 |
|
2651 | if(err) {
|
2652 | console.log("Error updating config.json: " + err);
|
2653 | process.exit(0);
|
2654 | }
|
2655 |
|
2656 | httpHttpsCreateServer(serverOptions);
|
2657 | });
|