diff --git a/AABrowserAPI/API.js b/AABrowserAPI/API.js
new file mode 100644
index 000000000..67a3b3660
--- /dev/null
+++ b/AABrowserAPI/API.js
@@ -0,0 +1,128 @@
+exports.newAPI = function newAPI() {
+
+ let thisObject = {
+ saveBotCode: saveBotCode,
+ initialize: initialize
+ }
+
+ let serverConfig;
+
+ return thisObject;
+
+ function initialize(pServerConfig) {
+
+ serverConfig = pServerConfig;
+
+ }
+
+ function saveBotCode(pSourceCode, callBackFunction) {
+
+ writeData("AAMasters", "AAMariam-Trading-Bot", "Trading-Process/User.Bot.js", pSourceCode, onDataWritten);
+
+ function onDataWritten(err) {
+
+ if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
+
+ console.log("[ERROR] API -> saveBotCode -> Source code file could not be saved. ");
+ console.log("[ERROR] API -> saveBotCode -> err.message = " + err.message);
+
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ return;
+ }
+
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+ }
+ }
+
+ function writeData(pOrg, pRepo, pPath, pFileContent, callBackFunction) {
+
+ try {
+
+ if (CONSOLE_LOG === true) { console.log("[INFO] API -> writeData -> Entering function."); }
+ if (CONSOLE_LOG === true) { console.log("[INFO] API -> writeData -> pOrg = " + pOrg); }
+ if (CONSOLE_LOG === true) { console.log("[INFO] API -> writeData -> pRepo = " + pRepo); }
+ if (CONSOLE_LOG === true) { console.log("[INFO] API -> writeData -> pPath = " + pPath); }
+
+ if (CONSOLE_LOG === true) { console.log("[INFO] API -> writeData -> " + pOrg + '.' + pRepo + '.' + pPath + " NOT found at cache."); }
+
+ let storage = require('azure-storage');
+ let connectionString;
+
+ switch (serverConfig.environment) {
+
+ case "Develop": {
+
+ connectionString = serverConfig.configAndPlugins.Develop.connectionString;
+ break;
+ }
+
+ case "Production": {
+
+ connectionString = serverConfig.configAndPlugins.Production.connectionString;
+ break;
+ }
+ }
+
+ let blobService = storage.createBlobService(connectionString);
+ let blobPath = pOrg + "/" + pRepo + "/" + pPath;
+ let blobText = nodeify(pFileContent.toString());
+
+ blobService.createBlockBlobFromText('aaplatform', blobPath, blobText, onFileReceived);
+
+ function onFileReceived(err, text, response) {
+
+ try {
+
+ if (CONSOLE_LOG === true) { console.log("[INFO] API -> writeData -> onFileReceived -> Entering function."); }
+ if (CONSOLE_LOG === true) { console.log("[INFO] API -> writeData -> onFileReceived -> err = " + JSON.stringify(err)); }
+ if (LOG_FILE_CONTENT === true) { console.log("[INFO] API -> writeData -> onFileReceived -> response = " + JSON.stringify(response)); }
+ if (CONSOLE_LOG === true) { console.log("[INFO] API -> writeData -> onFileReceived -> pOrg = " + pOrg); }
+ if (CONSOLE_LOG === true) { console.log("[INFO] API -> writeData -> onFileReceived -> pRepo = " + pRepo); }
+ if (CONSOLE_LOG === true) { console.log("[INFO] API -> writeData -> onFileReceived -> pPath = " + pPath); }
+
+ if (err !== null || text === null) {
+
+ if (CONSOLE_LOG === true) { console.log("[ERROR] API -> writeData -> onFileReceived -> Error Received from API Library. "); }
+ if (CONSOLE_LOG === true) { console.log("[ERROR] API -> writeData -> onFileReceived -> err = " + JSON.stringify(err)); }
+ if (CONSOLE_LOG === true) { console.log("[ERROR] API -> writeData -> onFileReceived -> Returning an empty JSON object string. "); }
+
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ return;
+
+ }
+
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+
+ } catch (err) {
+ console.log("[ERROR] API -> writeData -> onFileReceived -> err.message = " + err.message);
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+
+ } catch (err) {
+ console.log("[ERROR] API -> writeData -> err.message = " + err.message);
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+
+ function nodeify(pData) {
+
+
+ let start = pData.indexOf('function') + 9;
+ let end = pData.indexOf('(') + 0;
+
+ let functionName = pData.substring(start, end);
+
+ let result = "exports." + functionName + " = " + pData;
+
+ result = replaceAll(result, "webRequire", "require");
+ result = replaceAll(result, "window", "global");
+
+ return result;
+
+ function replaceAll(text, search, replacement) {
+ return text.replace(new RegExp(search, 'g'), replacement);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/CloudVM/CloudSupport.js b/CloudVM/CloudSupport.js
index bd9f9cbfe..691074e3b 100644
--- a/CloudVM/CloudSupport.js
+++ b/CloudVM/CloudSupport.js
@@ -9,28 +9,7 @@ When running at the clode on NodeJS some things work diffently that at the brows
-function onBotPlayPressed(pUI_COMMANDS) {
- window.SHALL_BOT_STOP = false;
-
- window.CURRENT_ENVIRONMENT = "Develop";
- window.STORAGE_PERMISSIONS = ecosystem.getStoragePermissions();
- window.EXCHANGE_KEYS = ecosystem.getExchangeKeys();
-
- cloudVM.initialize(pUI_COMMANDS, onInitialized);
-
- function onInitialized() {
-
- cloudVM.start();
- }
-
-}
-
-function onBotStopPressed() {
-
- window.SHALL_BOT_STOP = true;
-
-}
function webRequire(pModulePath) {
@@ -162,7 +141,7 @@ function downloadModule(pPath, callBackFunction) {
}
}
-function callServer(pPath, callBackFunction) {
+function callServer(pContentToSend, pPath, callBackFunction) {
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
@@ -172,9 +151,20 @@ function callServer(pPath, callBackFunction) {
}
};
- xhttp.open("GET", pPath, true);
- xhttp.send();
+ if (pContentToSend === undefined) {
+
+ xhttp.open("GET", pPath, true);
+ xhttp.send();
+
+ } else {
+
+ let blob = new Blob([pContentToSend], { type: 'text/plain' });
+
+ xhttp.open("POST", pPath, true);
+ xhttp.send(blob);
+
+ }
}
diff --git a/CloudVM/CloudVM.js b/CloudVM/CloudVM.js
new file mode 100644
index 000000000..6b7957952
--- /dev/null
+++ b/CloudVM/CloudVM.js
@@ -0,0 +1,79 @@
+
+function newCloudVM() {
+
+ const MODULE_NAME = "CloudVM";
+ const INFO_LOG = false;
+ const ERROR_LOG = true;
+ const logger = newWebDebugLog();
+ logger.fileName = MODULE_NAME;
+
+ var thisObject = {
+ onBotPlayPressed: onBotPlayPressed,
+ onBotStopPressed: onBotStopPressed
+ };
+
+ let root = newRoot();
+ let intervalHandler;
+ let previousBotCode = "";
+
+ return thisObject;
+
+ function onBotPlayPressed(pUI_COMMANDS) {
+
+ window.SHALL_BOT_STOP = false;
+
+ window.CURRENT_ENVIRONMENT = "Develop";
+ window.STORAGE_PERMISSIONS = ecosystem.getStoragePermissions();
+ window.EXCHANGE_KEYS = ecosystem.getExchangeKeys();
+ window.USER_LOGGED_IN = window.localStorage.getItem("userName");
+ window.USER_DEV_TEAM = window.localStorage.getItem("devTeam");
+
+ root.initialize(pUI_COMMANDS, onInitialized);
+
+ function onInitialized() {
+
+ root.start();
+
+ intervalHandler = setInterval(checkForChangesInBotCode, 10000);
+
+ }
+
+ }
+
+ function onBotStopPressed() {
+
+ window.SHALL_BOT_STOP = true;
+
+ }
+
+ function checkForChangesInBotCode() {
+
+ let botFunction = newUserBot;
+
+ if (botFunction !== undefined) {
+
+ let currentBotCode = botFunction.toString();
+
+ if (previousBotCode !== "") {
+
+ if (currentBotCode !== previousBotCode) {
+
+ console.log("Bot code changes detected.");
+
+ let path = "AABrowserAPI" + "/"
+ + "saveBotCode"
+ ;
+
+ callServer(currentBotCode, path, onServerResponse);
+
+ function onServerResponse(err) {
+
+ console.log("Server responded: " + err);
+ }
+ }
+ }
+
+ previousBotCode = currentBotCode;
+ }
+ }
+}
\ No newline at end of file
diff --git a/CloudVM/PoloniexAPIClient.js b/CloudVM/PoloniexAPIClient.js
index 7fab924f5..c144e4384 100644
--- a/CloudVM/PoloniexAPIClient.js
+++ b/CloudVM/PoloniexAPIClient.js
@@ -87,7 +87,7 @@
+ pMarketAssetB
;
- callServer(path + "/NO-LOG", onServerResponse);
+ callServer(undefined, path + "/NO-LOG", onServerResponse);
function onServerResponse(pServerResponse) {
@@ -106,7 +106,7 @@
+ pPositionId
;
- callServer(path + "/NO-LOG", onServerResponse);
+ callServer(undefined, path + "/NO-LOG", onServerResponse);
function onServerResponse(pServerResponse) {
@@ -127,7 +127,7 @@
+ pAmountB
;
- callServer(path + "/NO-LOG", onServerResponse);
+ callServer(undefined, path + "/NO-LOG", onServerResponse);
function onServerResponse(pServerResponse) {
@@ -148,7 +148,7 @@
+ pAmountB
;
- callServer(path + "/NO-LOG", onServerResponse);
+ callServer(undefined, path + "/NO-LOG", onServerResponse);
function onServerResponse(pServerResponse) {
@@ -169,7 +169,7 @@
+ pPositionAmountB
;
- callServer(path + "/NO-LOG", onServerResponse);
+ callServer(undefined, path + "/NO-LOG", onServerResponse);
function onServerResponse(pServerResponse) {
@@ -187,7 +187,7 @@
+ secret
;
- callServer(path + "/NO-LOG", onServerResponse);
+ callServer(undefined, path + "/NO-LOG", onServerResponse);
function onServerResponse(pServerResponse) {
diff --git a/Dashboard.js b/Dashboard.js
index c56b6d7ce..e9a1b2f68 100644
--- a/Dashboard.js
+++ b/Dashboard.js
@@ -89,7 +89,7 @@ function convertTimePeriodToName(pTimePeriod) {
}
}
-let cloudVM = newRoot();
+let cloudVM = newCloudVM();
const DEBUG_START_UP_DELAY = 0 //3000; // This is a waiting time in case there is a need to debug the very first steps of initialization, to be able to hit F12 on time.
const INITIAL_DEFAULT_MARKET = 2; // This is the market that will be shown when loading the site for the first time.
diff --git a/Panels/TimeControlPanel.js b/Panels/TimeControlPanel.js
index ce66a8d7d..ed780ab2b 100644
--- a/Panels/TimeControlPanel.js
+++ b/Panels/TimeControlPanel.js
@@ -199,13 +199,13 @@ function newTimeControlPanel() {
case "Step Backwards":
- pressStepBackwards();
+ //pressStepBackwards();
break;
case "Pause":
//pressPause();
- onBotStopPressed();
+ cloudVM.onBotStopPressed();
break;
case "Step Forward":
@@ -222,7 +222,7 @@ function newTimeControlPanel() {
eventHandler: thisObject.container.eventHandler
};
- onBotPlayPressed(UI_COMMANDS);
+ cloudVM.onBotPlayPressed(UI_COMMANDS);
//pressPlayForward();
break;
diff --git a/Project.njsproj b/Project.njsproj
index d64639f83..c06abbfb7 100644
--- a/Project.njsproj
+++ b/Project.njsproj
@@ -29,12 +29,18 @@
true
+
+ Code
+
Code
+
+ Code
+
@@ -164,6 +170,7 @@
+
diff --git a/index.html b/index.html
index c9e85b804..b2179ef31 100644
--- a/index.html
+++ b/index.html
@@ -14,6 +14,7 @@
+
diff --git a/server.js b/server.js
index 3553404dd..09c0ab10d 100644
--- a/server.js
+++ b/server.js
@@ -7,6 +7,31 @@ if (CONSOLE_LOG === true) { console.log("[INFO] server -> Node Server Starting."
let serverConfig;
+global.DEFAULT_OK_RESPONSE = {
+ result: "Ok",
+ message: "Operation Succeeded"
+};
+
+global.DEFAULT_FAIL_RESPONSE = {
+ result: "Fail",
+ message: "Operation Failed"
+};
+
+global.DEFAULT_RETRY_RESPONSE = {
+ result: "Retry",
+ message: "Retry Later"
+};
+
+global.CUSTOM_OK_RESPONSE = {
+ result: "Ok, but check Message",
+ message: "Custom Message"
+};
+
+global.CUSTOM_FAIL_RESPONSE = {
+ result: "Fail Because",
+ message: "Custom Message"
+};
+
let githubData = new Map;
let storageData = new Map;
let fileSystemData = new Map;
@@ -366,6 +391,34 @@ function onBrowserRequest(request, response) {
}
break;
+ case "AABrowserAPI": // This means the Scripts folder.
+ {
+ const AABROSER_API_MODULE = require('./AABrowserAPI/' + 'API');
+ let api = AABROSER_API_MODULE.newAPI();
+
+ api.initialize(serverConfig);
+
+ processPost(request, response, onPostReceived)
+
+ function onPostReceived(pData) {
+
+ switch (requestParameters[2]) {
+
+ case "saveBotCode": {
+ api.saveBotCode(pData, onResponse);
+ break;
+ }
+
+ }
+
+ function onResponse(err, pResponse) {
+
+ respondWithContent(JSON.stringify(pResponse), response);
+ }
+ }
+ }
+ break;
+
case "Scripts": // This means the Scripts folder.
{
@@ -967,3 +1020,26 @@ function returnEmptyArray() {
}
}
+function processPost(request, response, callback) {
+ let data = "";
+ if (typeof callback !== 'function') return null;
+
+ if (request.method == 'POST') {
+ request.on('data', function (pData) {
+ data += pData;
+ if (data.length > 1e6) {
+ data = "";
+ response.writeHead(413, { 'Content-Type': 'text/plain' }).end();
+ request.connection.destroy();
+ }
+ });
+
+ request.on('end', function () {
+ callback(data);
+ });
+
+ } else {
+ response.writeHead(405, { 'Content-Type': 'text/plain' });
+ response.end();
+ }
+}
\ No newline at end of file