-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsmart.cpp
7098 lines (5853 loc) · 215 KB
/
smart.cpp
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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#ifdef INCLUDE_HERE
//NOTE: splitting the iDogWatch.com from SemanticMarker.org ..
// 6.11.23 the UserDB that node-red reads from is a COPY of the master if
// run seperately (split).
//! this is the address things use for later
var _semanticMarkerFlowURL = "https://SemanticMarker.org/bot/";
// this is before moving to the new smart deck..
var _useOldSMARTDeck = true;
//var _semanticMarkerFlowURL = "http://localhost:1880/";
//var _semanticMarkerFlowURL = "http://localhost:2001/";
//! address of the rootBotURL (iDogwatch.com right now)
//! THis is the address of the node-red we are calling..
var _rootBotURL = "https://iDogWatch.com/bot";
//var _rootBotURL = "http://localhost:1880";
// BELOW: defines var _rootBotURL = "https://iDogWatch.com/bot";
// These are all the "messages" vs localhost:1880
// NOTE: these can modify the agent (but are done by the AWS instance)
//NOTE: 'addUser' and 'adddevice' could be sent to the SemanticMarker.org bot as well (a duplicate, or at least
// and in-sync version (versus a duplicate)
// Change to TRUE on the final version.. AND uncomment out the _devicesJSON (since the JSON cannot use a " "
//let _useFinal = true;
let _useFinal = false;
var _username = null;
var _password = null;
// _word is used for the guest password .. I think it was a worry the cookie was goofy..
// 12.11.23 .. put back _guestPassword
var _guestPassword;
var _saveUserInfo;
var _devicesJSON = [{"deviceName":"_GENERIC_"},{"deviceName":"ScoobyDoo"},{"deviceName":"PumpkinUno"},{"deviceName":"GreyGoose"},{"deviceName":"DukeGEN3"},{"deviceName":"HowieFeeder"}, {"deviceName":"M55"}, {"deviceName":"M5Rainier"}, {"deviceName":"LauraBabe"}, {"deviceName":"M522"}, {"deviceName":"M5Rainier"}, {"deviceName":"M5WRR"},{"deviceName":"MoonShot"},{"deviceName":"LacieUSBC"}];
//Array of: [uuid, deckname, deckcat, deckpassword, date]
var _smartDecks = [];
// 10.31.23
//Array of: [gpassword: pass]
var _guestPasswordsJSON = [];
//! initialize when refreshing after logoff
function initGlobals()
{
_smartDecks = [];
_devicesJSON = [];
_username = "";
_password = "";
_guestPassword = "";
_UUIDNumbers = [];
_guestPasswordsJSON = [];
//clear out the SMART Deck
document.getElementById('_UUID_Select').innerHTML = "";
document.getElementById('flowsSM').innerHTML = "";
}
// checks username password have values ..
function validUserInfo()
{
if (_username && _username.length > 0 &&
_password && _password.length > 0)
return true;
else
return false;
}
//NO _useFinal
if (_useFinal)
{
_username = "{{req.params.NAME}}";
_password = "{{req.params.PASSWORD}}";
_guestPassword = "{{req.params.guestPassword}}";
// userInfo == "super" or "normal"
_saveUserInfo = "{{req.params.userinfo}}";
// ***** manually uncommend out the following.. ****
//_devicesJSON = {{{payload.devicenames}}};
//_smartDecks = {{{payload.smartDecksJSON}}};
}
else
{
//_username = "[email protected]";
//_password = "pass";
//_username = "test";
//_password = "test";
_guestPassword = "NOT_SET";
_devicesJSON = [{"deviceName":"_GENERIC_"},{"deviceName":"ScoobyDoo"},{"deviceName":"PumpkinUno"},{"deviceName":"GreyGoose"},{"deviceName":"DukeGEN3"},{"deviceName":"HowieFeeder"}, {"deviceName":"M55"}, {"deviceName":"M5Rainier"}, {"deviceName":"LauraBabe"}, {"deviceName":"M522"}, {"deviceName":"M5Rainier"}, {"deviceName":"M5WRR"},{"deviceName":"MoonShot"},{"deviceName":"LacieUSBC"}];
//_smartDecks = [{"uuid":"OvdEK4Ks_j2Z","deckname":"marker1","deckcat":"LegacyMarkers","deckpassword":"darwin","date":1679955654862}];
}
//TODO: make it like the _flowJSON
var _UUIDNumbers = [];
// modified by Base64 or Pulldown
var _deviceName;
var _isSendToAll;
// This has to be in sync with mainModule.h
var _lastSMPage = "sm14";
//! variables (fixed right now) for the Semantic Marker parameters
//!@see https://github.com/konacurrents/KSQRAvatar/issues/54
//! This is returned when creating a SM user..
var _SemanticMarker_UUID = "soIZ1iH7FK";
// currently these are hardwired and must be lock step ([0] == username, and [0] == _username)
// eg. [{"USERNAME":_username},{"PASSWORD",_password}]
var _SemanticMarkerParameters = ["USERNAME","PASSWORD","GUESTPASSWORD"];
// on startup these are unknown..
var _SemanticMarkerValues = [_username, _password, _guestPassword];
//! called to set the values .. after they are known
function setSemanticMarkerUserPasswordValues()
{
console.log("setSemanticMarkerUserPasswordValues: " + _username + ", " + _password + "," + _guestPassword);
_SemanticMarkerValues = [_username, _password, _guestPassword];
}
//! the delay in seconds
var _commandDelay;
//! last run number
var _nextRunCommand;
//! count of commands
var _maxRunCommands;
//! logout .. erases cookies
function logout()
{
alert("This logs you out so next time you have to enter password and optionally a different username");
_username = "";
_password = "";
saveCookies();
// requestLoginWindow(true);
document.getElementById("_Login").hidden = false;
//initGlobals();
// do a full page reload .. hopefully that clears the screen
location.reload();
//initWebPage();
}
//! login
function login()
{
//requestLoginWindow(true);
location.reload();
}
//! try a login.
//! Cannot hide password yet: https://stackoverflow.com/questions/9554987/how-can-i-hide-the-password-entered-via-a-javascript-dialog-prompt
function requestLoginWindow(doReadCookies)
{
if (doReadCookies)
readCookies();
// basically is password is null then ask for both.. but reuse the username
// but if username null do it too
if (!validUserInfo())
{
let username = prompt("Please enter your username: ",_username);
_username = username;
let password = prompt("Please enter password","");
_password = password;
}
saveCookies();
reloadUserAgent();
}
/* ****************************** End Globals ****************** */
// 3.27.23
// update the _UUID_Select with the options..
// uses global _smartDecks so that needs to be updated
// on a refresh on new SmartDeck and on "Get User SM Flows"
function parseSmartDecks(agentUUID)
{
// update the selection ..
// _UUID_Select
var uuidSelect = document.getElementById('_UUUID_Select');
// Category
// Name (UUID)
// Name2 (UUID)
// Category
//!Try sorting by Category, then Num
//! https://stackoverflow.com/questions/4833651/javascript-array-sort-and-unique
//! First find the categories..
var deckCategories = []; //deckCat
var uuidNumbers = []; //UUID
var deckNames = [];
// create a new smartDecks with the main agent included..
var allDecks = _smartDecks;
var mainAgentCategory = "Main Agent";
// this is created already in the conversion to SMUsers DB
if (_useOldSMARTDeck)
{
var alreadyAdded = false;
// see if already done...
for (var i=0; i< allDecks.length; i++)
{
if (allDecks[i].uuid == agentUUID)
{
alreadyAdded = true;
break;
}
}
if (!alreadyAdded)
{
// add main deck.. at the front..
allDecks.push(
{
"uuid":agentUUID,
"deckcat": mainAgentCategory,
"deckname":"Root"
});
}
}
// the main agent isn't in the smart decks .. so add it..
for (var i=0; i< allDecks.length;i++)
{
var deck = allDecks[i];
var uuid = deck.uuid;
var deckCategory = deck.deckcat;
var deckName = deck.deckname;
deckCategories.push(deckCategory);
uuidNumbers.push(uuid);
deckNames.push(deckName);
}
//!alphebet sort
deckCategories.sort();
//!alphebet sort
deckNames.sort();
//! sort numbers so 10 and 100 are in right order (Actually not used as the NAME is the sort)
//! https://stackoverflow.com/questions/1063007/how-to-sort-an-array-of-integers-correctly
uuidNumbers.sort(function(a,b) { return a-b; });
// now make them unique (new Set) and back to an array
deckCategories = Array.from(new Set(deckCategories));
//sort
deckCategories.sort();
//how to make the Main one first?? TODO..
// Will remove it.. then add to the front..
var mainIndex = deckCategories.indexOf(mainAgentCategory);
// remove
deckCategories.splice(mainIndex, 1);
// add to front
deckCategories.unshift(mainAgentCategory);
uuidNumbers = Array.from(new Set(uuidNumbers));
deckNames = Array.from(new Set(deckNames));
flowsHTML = "";
//! groups: https://stackoverflow.com/questions/17316540/make-some-options-in-a-select-menu-unselectable
for (deckCategory of deckCategories)
{
flowsHTML += "<optgroup label='" + deckCategory + "'>" + "\n";
for (deckName of deckNames)
{
for (var i =0; i< allDecks.length; i++)
{
var deck = allDecks[i];
thisUUID = deck.uuid;
thisDeckCat = deck.deckcat;
thisDeckName = deck.deckname;
// only continue if same deck category
if (thisDeckCat.localeCompare(deckCategory) != 0)
continue;
// only continue if same deck name
if (thisDeckName.localeCompare(deckName) != 0)
continue;
// now we are the correct deckCategory, and deckName
for (uuidNum of uuidNumbers)
{
if (!thisUUID)
continue;
if (thisUUID.localeCompare(uuidNum) != 0)
continue;
// Finally output an option (name:UUID)
flowsHTML += "<option value='" + thisUUID + "'>" + thisDeckName + " (" + uuidNum + ")" + "</option>\n";
}
}
}
flowsHTML += "</optgroup> \n";
}
//update the html select _UUID_Select
document.getElementById('_UUID_Select').innerHTML = flowsHTML;
//5.6.23
// Store the _UUID's of this Agent. Then if we traverse to another Smart DECK
// From a different user (such as through inheritance), it won't think is
// can save (without cloning).
// NOTE: if we clone, then it would be nice to fix the parent - to now point to this one..
_UUIDNumbers = uuidNumbers;
}
// 2048 characters on the URL max..
//!invoke the urlID
function invokeURL(url)
{
window.open(url);
}
//!invoke the urlID
function invokeURLid(urlID)
{
var url = document.getElementById(urlID).value;
//! use the web format
url += "&format=web";
window.open(url);
//callGetCommand(url);
}
/* ******** START NOT USED
//TODO.. get the RUN SemanticMarkers working...
//! make web get call
function callGetCommand(url)
{
var xhttp = new XMLHttpRequest();
//!https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readystatechange_event
xhttp.onreadystatechange = function() {
// called when open is finished
if (this.readyState == 4 && this.status == 200)
{
}
};
//! shows the command at this element
document.getElementById('_commandRunText').value = url;
xhttp.open("GET", url, true);
xhttp.send();
}
//! array of links for the flow
var _finalLinkArray;
//!runSemanticMarkers (recursive after the next delay) until max is hit
function runSemanticMarkers()
{
_commandDelay = document.getElementById('_delayAmountId').value;
if (_nextRunCommand >= _maxRunCommands)
{
alert("Finished running commands");
_nextRunCommand = 0;
return;
}
// grab the next run command (from the select)
var command = _finalLinkArray[_nextRunCommand];
_nextRunCommand++;
// call it..
callGetCommand(command);
//recurse
var delayInMilliseconds = _commandDelay * 1000;
setTimeout(function()
{
runSemanticMarkers();
}, delayInMilliseconds);
}
//!runSemanticMarker
//@param linkId == <select option array>
function runSemanticMarker(linkId)
{
// this uses the parameters .. rep
//var command = document.getElementById(linkId).value;
//callGetCommand(command);
//set default
_nextRunCommand = 0;
// the array of commands
_finalLinkArray = [];
// commands = option array
var commands = document.getElementById(linkId);
//! foreach arg.. replace the Parameter with the equilivent instance (eg. password -> _password)
for (var i=0; i< commands.length; i++)
{
var command = commands[i].innerHTML;
_finalLinkArray.push(command);
}
//set max
_maxRunCommands = _finalLinkArray.length;
//
runSemanticMarkers();
}
********* END not used ********/
//!invoke the urlID, but tack on the extraURL
function invokeURLid2(urlID, extraURL)
{
var url = document.getElementById(urlID).value;
url = url + extraURL;
window.open(url);
//callGetCommand(url);
}
//! gets and saves UUID
//! global: _uuidStringText
function updateSemanticMarkerUUID()
{
var uuid = document.getElementById('_uuidStringText').value;
_SemanticMarker_UUID = uuid;
}
//! strips spaces, but supports numbers letters and _
function createValidDeviceName(deviceName)
{
// replace NOT of these NOTE: "_" is NOW allowed. 9.5.23
var name = deviceName.replace(/[^a-zA-Z0-9_]/g, "");
return name;
}
//!strip spaces (THis is wrong.. it only removes the start/end spaces
function stripSpaces(cmd)
{
//cmd = cmd.trim();
//! https://stackoverflow.com/questions/5963182/how-to-remove-spaces-from-a-string-using-javascript
cmd = cmd.replace(/\s/g, '');
return cmd;
}
//! strips spaces, but supports numbers letters and _
function createValidFlowName(flowName)
{
// replace NOT of these
var name = flowName.replace(/[^a-zA-Z0-9_]/g, "");
return name;
}
//! changes a string to replace spaces with %20
function escapeSpacesInString(string)
{
// need to escape the & (as far as we know)
//string = string.replace(/&/g,"\\&");
string = string.replace(/ /g,"%20");
return string;
}
//! changes a string to replace spaces with %20
//! ISSUE: https://stackoverflow.com/questions/11449577/why-is-base64-encode-adding-a-slash-in-the-result
function escapeBase64InString(string)
{
// When received, to atob(str)
// then str = decodeURIComponent(atob(str))
// escape the URI first..
var moreString2 = encodeURIComponent(string);
// Then the btoa doesn't have "/" in it..
var s2 = btoa(moreString2);
return s2;
// need to escape the & (as far as we know)
//string = string.replace(/&/g,"\\&");
//var moreString = btoa(string);
//string = moreString;
//string = string.replace(/ /g,"%20");
//return string;
}
// object = {"SM":sm,"img":<img src=... }
var _base64Images = [];
//! 5.9.23 call the getSM/UUID/FLOW and when
//! it returns, store the <img src=base64 ..
//! gets or creates a UUID for existing user "/createuuid"
function requestBase64Image(uuid, flowNum)
{
let thisSM = createSM(uuid, flowNum);
var command = _semanticMarkerFlowURL + "getSM/" + uuid + "/" + flowNum ;
//! see if already cached..
for (let i=0;i < _base64Images.length; i++)
{
if (thisSM.localeCompare(_base64Images[i].SM)==0)
{
console.log("Already grabbed _base64Image for: " + thisSM);
return;
}
}
// create placeholder
var object = {"SM":thisSM,"img":null};
//add to the list being requested
_base64Images.push(object);
var xhttp = new XMLHttpRequest();
// update the wait count
changeWaitingCount();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//!result is the USER object (not the SemanticMaker object)
var jsonReply = this.responseText;
// console.log("reply: " + jsonReply);
if (jsonReply && jsonReply.indexOf("error") >= 0)
{
alert(jsonReply);
return;
}
if (jsonReply.length == 0 )
{
alert("You must login to your agent");
return;
}
//! update the outstanding request for this image
for (let i=0;i < _base64Images.length; i++)
{
if (thisSM.localeCompare(_base64Images[i].SM)==0)
{
_base64Images[i].img = jsonReply;
}
}
// update the wait count
changeWaitingCount();
}
};
xhttp.open("GET",command, true);
xhttp.send();
}
//! gets the smartDecks of the user 6.13.23
// if (!_useOldSMARTDeck) .. still working the transition (this isn't in SM.org yet)
function getSMSmartDecks(uuidStringTextId)
{
var command = _semanticMarkerFlowURL + "getuserdecks/" + _username + "/" + _password ;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//!result is the USER object (not the SemanticMaker object)
var jsonReply = this.responseText;
console.log("reply: " + jsonReply);
if (jsonReply && jsonReply.indexOf("error") >= 0)
{
alert(jsonReply);
return;
}
if (jsonReply.length == 0 )
{
alert("You must login to your agent");
return;
}
var userJSON = JSON.parse(jsonReply);
// grab array of smart decks
//var smartDecks = userJSON.smartDecks;
smartDecks = userJSON;
_smartDecks = smartDecks;
//var uuid = userJSON.uuid;
//document.getElementById(uuidStringTextId).value = uuid;
// update the deck options
parseSmartDecks(null);
}
};
xhttp.open("GET",command, true);
xhttp.send();
}
//! gets or creates a UUID for existing user "/createuuid"
function getSMUserUUID(uuidStringTextId)
{
if (!validUserInfo())
return;
var command = _semanticMarkerFlowURL + "createuuid/" + _username + "/" + _password ;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//!result is the USER object (not the SemanticMaker object)
var jsonReply = this.responseText;
console.log("reply: " + jsonReply);
var userJSON = JSON.parse(jsonReply);
var uuid = userJSON.uuid;
document.getElementById(uuidStringTextId).value = uuid;
// update the deck options (Call from getSMUserUUID...
parseSmartDecks(uuid);
}
};
xhttp.open("GET",command, true);
xhttp.send();
}
//!create the list of devices.. Fill in the idDeviceListOptions (which has the select already formed)
function createDeviceListOptions(idDeviceListOptions)
{
var htmlSelect = "";
htmlSelect += "<option value='NO_ONE'>NO_ONE</option>";
htmlSelect += "\n";
htmlSelect += "<option value='--ALL--'>--ALL--</option>";
htmlSelect += "\n";
// used for sorting later..
var deviceNames = [];
// go through list, but dont include GENERIC and DEFAULT
for (var i =0; i< _devicesJSON.length; i++)
{
//Not sorting yet..
let deviceName = _devicesJSON[i].deviceName;
if ("_GENERIC_".localeCompare(deviceName)!=0 && "_DEFAULT_".localeCompare(deviceName) != 0)
{
deviceNames.push(deviceName);
}
}
//now sort
deviceNames.sort();
for (var i =0; i< deviceNames.length; i++)
{
let deviceName = deviceNames[i];
// create option for the deviceName
htmlSelect += "<option value='" + deviceName + "'>" + deviceName + "</option>";
htmlSelect += "\n";
}
document.getElementById(idDeviceListOptions).innerHTML = htmlSelect;
}
//! 10.31.23
//!create the list of guest passwords.. Fill in the guestPasswordsSelectID (which has the select already formed)
function createGuestPasswordListOptions(guestPasswordsSelectID)
{
var htmlSelect = "";
htmlSelect += "<option value='NONE'>NONE</option>";
htmlSelect += "\n";
// used for sorting later..
var guestPasswords = [];
// go through list, but dont include GENERIC and DEFAULT
for (var i =0; i< _guestPasswordsJSON.length; i++)
{
//Not sorting yet..
let guestPassword = _guestPasswordsJSON[i].gpassword;
guestPasswords.push(guestPassword);
}
//now sort
guestPasswords.sort();
for (var i =0; i< guestPasswords.length; i++)
{
let guestPassword = guestPasswords[i];
// create option for the deviceName
htmlSelect += "<option value='" + guestPassword + "'>" + guestPassword + "</option>";
htmlSelect += "\n";
}
document.getElementById(guestPasswordsSelectID).innerHTML = htmlSelect;
}
//! wraps addNewGuestPassword
function sendAddNewGuestPassword(idGuestPasswordString)
{
var addPassword = document.getElementById(idGuestPasswordString).value;
var values = [_username, _password, addPassword];
sendURLValues("addguestpassword", values);
}
//! wraps removeGuestPassword
function sendRemoveGuestPassword(idGuestPasswordString)
{
var removePassword = document.getElementById(idGuestPasswordString).value;
var values = [_username, _password, removePassword];
sendURLValues("removeguestpassword", values);
}
//! just sent all for FEED and CAPTURE, using send: feed
function sendAllCommand(command, cmd)
{
_isSendToAll = true;
var commandPath = getCommandPath(command);
sendGETCommand(commandPath + "/" + cmd);
}
//! returns string up the argments..
//! sets up the device and isSendToAll
function setupDevice(idDevices)
{
var deviceName = document.getElementById(idDevices).value;
if ("--ALL--".localeCompare(deviceName)==0)
_isSendToAll = true;
else
_isSendToAll = false;
_deviceName = deviceName;
}
//! sets using the password provided, so can be user password or guest password
//! This uses knowledge of _isSentToAll, and _deviceName, and this command (which tacks on Device if needed)
function getCommandPathWithPassword(command,password)
{
if (!validUserInfo())
return;
var commandPath = "";
if (_isSendToAll)
{
commandPath = _rootBotURL + "/" + command + "/" + _username + "/" + password;
}
else
{
//NOTE: lowercase all..
command = command + "device";
commandPath = _rootBotURL + "/" + command + "/" + _username + "/" + password + "/" + _deviceName;
}
return commandPath;
}
//! Returns a SemanticMarker parameterized command string
//! This uses knowledge of _isSentToAll, and _deviceName, and this command (which tacks on Device if needed)
function getCommandPathWithSMParameters(command)
{
var commandPath = "";
if (_isSendToAll)
{
commandPath = _rootBotURL + "/" + command + "/" + _SemanticMarkerParameters[0] + "/" + _SemanticMarkerParameters[1];
}
else
{
//NOTE: lowercase all..
command = command + "device";
commandPath = _rootBotURL + "/" + command + "/" + _SemanticMarkerParameters[0] + "/" + _SemanticMarkerParameters[1] + "/" + _deviceName;
}
return commandPath;
}
//! This uses knowledge of _isSentToAll, and _deviceName, and this command (which tacks on Device if needed)
function getCommandPath(command)
{
return getCommandPathWithPassword(command,_password);
}
//! This uses knowledge of _isSentToAll, and _deviceName, and this command (which tacks on Device if needed)
function getCommandPathGuest(command)
{
// _word is the guest password
// 11.21.23 .. if the _guestPasswordsSelectId is set, then use that one..
// id="_guestPasswordsSelectID" class="select btnB" >x</select>
var selectedGuestPassword = document.getElementById('_guestPasswordsSelectID').value;
var command;
if (selectedGuestPassword && selectedGuestPassword.length > 0 && selectedGuestPassword != "NONE")
command = getCommandPathWithPassword(command,selectedGuestPassword);
else
command = getCommandPathWithPassword(command,_guestPassword);
console.log("Guest command = '" + command + "'");
return command;
}
//! wraps the command no args, but this is sent as a guest
function sendNoArgsGuest(idDevices, idCmd)
{
// one way: but not doing that here..
// using feedguestdevice/U/P/device
// https://iDogWatch.com/bot/feedguestdevices/[email protected]/GPASS?device=ScoobyDoo
// sets _devices
setupDevice(idDevices);
// the command, which we might change below based on _isSendToAll
var command = document.getElementById(idCmd).value;
//eg. feedguest<device>/USER/GPASS/<device>
//feedguest/name/guest or feedguestdevice/name/guest/device
// this will use guest password..
var commandPath = getCommandPathGuest(command);
//! https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send
sendGETCommand(commandPath);
}
//! wraps the command no args
function sendNoArgs(idDevices, idCmd)
{
setupDevice(idDevices);
// the command. NOTE: there are some that use the "send" syntax still 5.4.23
var cmd = document.getElementById(idCmd).value;
var command = "cmd";
if ("status".localeCompare(cmd)==0
|| "temp".localeCompare(cmd)==0
|| "capture".localeCompare(cmd)==0
|| "volume".localeCompare(cmd)==0)
command = "send";
var commandPath = getCommandPath(command);
//! 1.13.24
cmd += getCurrentGroupNameQuery(false);
// bot/cmddevice/NAME/PASS/device/CMD
//! https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send
sendGETCommand(commandPath + "/" + cmd);
}
//! wraps the command no args. Send "feed" or "capture" for example without arguments
function sendCommandToDevice(idDevices, cmd)
{
setupDevice(idDevices);
// the command
var command = "cmd";
var commandPath = getCommandPath(command);
//! https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send
sendGETCommand(commandPath + "/" + cmd);
}
//! 12.17.23 return a base64 string from a JSON string
function createBase64FromJSON(stringJSON)
{
var base64StringJSON = escapeBase64InString(stringJSON);
return base64StringJSON;
}
//! 12.17.23 create base64
function createBase64ForCredentials()
{
var stringJSON = { "username" : _username,
"password" : _password,
"guestPassword" : _guestPassword
};
var base = createBase64FromJSON(JSON.stringify(stringJSON));
return base;
}
//! Special case sending any set:val commands
//! set:cmd, val:arg
//! This version converts the val into base64, and the command is added with 64
function sendAnySetCommand64Both(idDevices, anySetCommandId, anySetValId, encodeQuery)
{
// the command (base) .. device is tacked on
var command = "set64";
if (encodeQuery)
{
// the _device global is updated to a base64 value
// The name has to escape the spaces and | and &
var device = document.getElementById(idDevices).value;
device = device.replace(/&/g,"\\&");
device = device.replace(/\|/g,"\\|");
device = device.replace(/ /g,"\\ ");
_deviceName = escapeBase64InString(device);
command += "query";
// set64query
// the global _isSendToAll is false for this encodeQuery
_isSendToAll = false;
}
else
{
// the global _isSendToAll is modified based on the idDevices state..
setupDevice(idDevices);
}
// encode the device as well.
var commandPath = getCommandPath(command);
//! 1.11.24 kinda kludge. if set64device replace with set64device2 (if not encodeQuery)
//! The web should have a command like "set64_2" that way the "getCommandPath()" is unchanged
//! since it just tacks on the "device" part
if (!encodeQuery)
{
commandPath = commandPath.replace("set64device","set64device2");
}
var cmd = document.getElementById(anySetCommandId).value;
// strip spaces on cmd..
cmd = cmd.replace(/\s+/g, '');
var arg = document.getElementById(anySetValId).value;
// escape the spaces
arg = escapeBase64InString(arg);
//arg = arg.replace(/\s+/g, '');
//<!-- dawgpackTopicId used in the sendAnySetCommand64 --->
var topicSet = document.getElementById('dawgpackTopicId').value;
var isDawgpack = topicSet.localeCompare("dawgpack")==0;
var path = commandPath + "/" + cmd + "/" + arg;
if (isDawgpack)
path += "?topic=dawgpack";
//! https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send
sendGETCommand(path);
}
//! wraps the command no args
function sendNoArgsM5(idDevices, idCmd)
{
setupDevice(idDevices);
// the command
var cmd = document.getElementById(idCmd).value;
var command = "cmd";
var commandPath = getCommandPath(command);
//! 1.13.24
commandPath += getCurrentGroupNameQuery(false);
//! https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send
sendGETCommand(commandPath + "/" + cmd);
}
//! cycles through pages
function cycleM5Pages(idDevices, idCmd)
{
// known last page..
var currentPage = document.getElementById(idCmd).value;
if (currentPage.localeCompare(_lastSMPage)==0)
currentPage = "sm0";
else
{
// get the number part:
var num = parseInt(currentPage.substring(2));
num ++;
currentPage = "sm" + num;