1
0
mirror of https://github.com/bdring/Grbl_Esp32.git synced 2025-09-01 02:21:46 +02:00

Use JSONencoder in WebServer.cpp

This commit is contained in:
Mitch Bradley
2021-03-06 14:17:14 -10:00
parent deabc100f6
commit 22392491ec
5 changed files with 98 additions and 133 deletions

View File

@@ -154,4 +154,20 @@ namespace WebUI {
member("S", max);
member("M", min);
}
void JSONencoder::filesystemStats(uint64_t total, uint64_t used) {
member("total", total ? ESPResponseStream::formatBytes(total) : "-1");
member("used", ESPResponseStream::formatBytes(used + 1));
int occupied_percent;
if (total) {
occupied_percent = (used * 100) / total;
//minimum if even one byte is used is 1%
if (occupied_percent <= 1) {
occupied_percent = 1;
}
} else {
occupied_percent = -1;
}
member("occupation", occupied_percent);
}
}

View File

@@ -78,5 +78,7 @@ namespace WebUI {
void begin_webui(const char* p, const char* help, const char* type, const char* val);
void begin_webui(const char* p, const char* help, const char* type, const int val);
void begin_webui(const char* p, const char* help, const char* type, const char* val, int min, int max);
void filesystemStats(uint64_t total, uint64_t used);
};
}

View File

@@ -101,6 +101,20 @@ namespace WebUI {
long Web_Server::get_client_ID() { return _id_connection; }
void Web_Server::dontCache() { _webserver->sendHeader("Cache-Control", "no-cache"); }
void Web_Server::sendJSON(int code, JSONencoder j) { _webserver->send(code, "application/json", j.end()); }
void Web_Server::sendStatus(int code, const char* status, const char* auth, const char* user) {
JSONencoder j(false);
j.begin();
j.member("status", status);
if (auth) {
j.member("authentication_lvl", auth);
}
if (user) {
j.member("user", user);
}
sendJSON(code, j);
}
bool Web_Server::begin() {
bool no_error = true;
_setupdone = false;
@@ -524,9 +538,8 @@ namespace WebUI {
//login status check
void Web_Server::handle_login() {
# ifdef ENABLE_AUTHENTICATION
String smsg;
char * smsg, auths;
String sUser, sPassword;
String auths;
int code = 200;
bool msg_alert_error = false;
//disconnect can be done anytime no need to check credential
@@ -540,22 +553,25 @@ namespace WebUI {
}
ClearAuthIP(_webserver->client().remoteIP(), sessionID.c_str());
_webserver->sendHeader("Set-Cookie", "ESPSESSIONID=0");
_webserver->sendHeader("Cache-Control", "no-cache");
String buffer2send = "{\"status\":\"Ok\",\"authentication_lvl\":\"guest\"}";
_webserver->send(code, "application/json", buffer2send);
dontCache();
sendStatus(code, "Ok", "guest", NULL);
//_webserver->client().stop();
return;
}
AuthenticationLevel auth_level = is_authenticated();
if (auth_level == AuthenticationLevel::LEVEL_GUEST) {
auths = "guest";
} else if (auth_level == AuthenticationLevel::LEVEL_USER) {
auths = "user";
} else if (auth_level == AuthenticationLevel::LEVEL_ADMIN) {
auths = "admin";
} else {
auths = "???";
switch (auth_level) {
case AuthenticationLevel::LEVEL_GUEST:
auths = "guest";
break;
case AuthenticationLevel::LEVEL_USER:
auths = "user";
break;
case AuthenticationLevel::LEVEL_ADMIN:
auths = "admin";
break;
default:
auths = "???";
}
//check is it is a submission or a query
@@ -636,7 +652,7 @@ namespace WebUI {
String tmps = "ESPSESSIONID=";
tmps += current_auth->sessionID;
_webserver->sendHeader("Set-Cookie", tmps);
_webserver->sendHeader("Cache-Control", "no-cache");
dontCache();
switch (current_auth->level) {
case AuthenticationLevel::LEVEL_ADMIN:
auths = "admin";
@@ -660,11 +676,7 @@ namespace WebUI {
smsg = "Ok";
}
//build JSON
String buffer2send = "{\"status\":\"" + smsg + "\",\"authentication_lvl\":\"";
buffer2send += auths;
buffer2send += "\"}";
_webserver->send(code, "application/json", buffer2send);
sendStatus(code, smsg, auths, NULL);
} else {
if (auth_level != AuthenticationLevel::LEVEL_GUEST) {
String cookie = _webserver->header("Cookie");
@@ -679,16 +691,11 @@ namespace WebUI {
}
}
}
String buffer2send = "{\"status\":\"200\",\"authentication_lvl\":\"";
buffer2send += auths;
buffer2send += "\",\"user\":\"";
buffer2send += sUser;
buffer2send += "\"}";
_webserver->send(code, "application/json", buffer2send);
sendStatus(code, "200", auths, sUser.c_str());
}
# else
_webserver->sendHeader("Cache-Control", "no-cache");
_webserver->send(200, "application/json", "{\"status\":\"Ok\",\"authentication_lvl\":\"admin\"}");
dontCache();
sendStatus(200, "Ok", "admin", NULL);
# endif
}
//SPIFFS
@@ -815,15 +822,15 @@ namespace WebUI {
}
}
String jsonfile = "{";
String ptmp = path;
JSONencoder j(false);
j.begin();
String ptmp = path;
if ((path != "/") && (path[path.length() - 1] = '/')) {
ptmp = path.substring(0, path.length() - 1);
}
File dir = SPIFFS.open(ptmp);
jsonfile += "\"files\":[";
bool firstentry = true;
j.begin_array("files");
String subdirlist = "";
File fileparsed = dir.openNextFile();
while (fileparsed) {
@@ -858,37 +865,19 @@ namespace WebUI {
}
}
if (addtolist) {
if (!firstentry) {
jsonfile += ",";
} else {
firstentry = false;
}
jsonfile += "{";
jsonfile += "\"name\":\"";
jsonfile += filename;
jsonfile += "\",\"size\":\"";
jsonfile += size;
jsonfile += "\"";
jsonfile += "}";
j.begin_object();
j.member("name", filename);
j.member("size", size);
j.end_object();
}
fileparsed = dir.openNextFile();
}
jsonfile += "],";
jsonfile += "\"path\":\"" + path + "\",";
jsonfile += "\"status\":\"" + status + "\",";
size_t totalBytes;
size_t usedBytes;
totalBytes = SPIFFS.totalBytes();
usedBytes = SPIFFS.usedBytes();
jsonfile += "\"total\":\"" + ESPResponseStream::formatBytes(totalBytes) + "\",";
jsonfile += "\"used\":\"" + ESPResponseStream::formatBytes(usedBytes) + "\",";
jsonfile.concat(F("\"occupation\":\""));
jsonfile += String(100 * usedBytes / totalBytes);
jsonfile += "\"";
jsonfile += "}";
path = "";
_webserver->sendHeader("Cache-Control", "no-cache");
_webserver->send(200, "application/json", jsonfile);
j.end_array();
j.member("path", path);
j.member("status", status);
j.filesystemStats(uint64_t(SPIFFS.totalBytes()), uint64_t(SPIFFS.usedBytes()));
dontCache();
sendJSON(200, j);
_upload_status = UploadStatusType::NONE;
}
@@ -1059,13 +1048,8 @@ namespace WebUI {
return;
}
String jsonfile = "{\"status\":\"";
jsonfile += String(int32_t(uint8_t(_upload_status)));
jsonfile += "\"}";
//send status
_webserver->sendHeader("Cache-Control", "no-cache");
_webserver->send(200, "application/json", jsonfile);
dontCache();
sendStatus(200, String(int32_t(uint8_t(_upload_status))).c_str(), NULL, NULL);
//if success restart
if (_upload_status == UploadStatusType::SUCCESSFUL) {
@@ -1219,7 +1203,7 @@ namespace WebUI {
//this is only for admin and user
if (is_authenticated() == AuthenticationLevel::LEVEL_GUEST) {
_upload_status = UploadStatusType::NONE;
_webserver->send(401, "application/json", "{\"status\":\"Authentication failed!\"}");
sendStatus(401, "Authentication failed!", NULL, NULL);
return;
}
@@ -1229,15 +1213,10 @@ namespace WebUI {
sstatus = "Upload failed";
_upload_status = UploadStatusType::NONE;
}
bool list_files = true;
uint64_t totalspace = 0;
uint64_t usedspace = 0;
SDState state = get_sd_state(true);
SDState state = get_sd_state(true);
if (state != SDState::Idle) {
String status = "{\"status\":\"";
status += state == SDState::NotPresent ? "No SD Card\"}" : "Busy\"}";
_webserver->sendHeader("Cache-Control", "no-cache");
_webserver->send(200, "application/json", status);
dontCache();
sendStatus(200, state == SDState::NotPresent ? "No SD Card" : "Busy", NULL, NULL);
return;
}
set_sd_state(SDState::BusyParsing);
@@ -1315,85 +1294,52 @@ namespace WebUI {
}
}
}
//check if no need build file list
if (_webserver->hasArg("dontlist") && _webserver->arg("dontlist") == "yes") {
list_files = false;
}
// TODO Settings - consider using the JSONEncoder class
String jsonfile = "{";
JSONencoder j(false);
j.begin();
if (path != "/") {
path = path.substring(0, path.length() - 1);
}
if (path != "/" && !SD.exists(path)) {
jsonfile += "\"status\":\" " + path + " does not exist on SD Card\"}";
j.member("status", path + " does not exist on SD Card");
} else {
jsonfile += "\"files\":[";
if (list_files) {
j.begin_array("files");
if (!_webserver->hasArg("dontlist") || !(_webserver->arg("dontlist") == "yes")) {
File dir = SD.open(path);
if (!dir.isDirectory()) {
dir.close();
}
dir.rewindDirectory();
File entry = dir.openNextFile();
int i = 0;
while (entry) {
COMMANDS::wait(1);
if (i > 0) {
jsonfile += ",";
}
jsonfile += "{\"name\":\"";
j.begin_object();
String tmpname = entry.name();
int pos = tmpname.lastIndexOf("/");
tmpname = tmpname.substring(pos + 1);
jsonfile += tmpname;
jsonfile += "\",\"shortname\":\""; //No need here
jsonfile += tmpname;
jsonfile += "\",\"size\":\"";
// files have sizes, directories do not
jsonfile += entry.isDirectory() ? "-1" : ESPResponseStream::formatBytes(entry.size());
jsonfile += "\",\"datetime\":\"";
//TODO - can be done later
jsonfile += "\"}";
i++;
j.member("name", tmpname);
j.member("shortname", tmpname);
j.member("size", entry.isDirectory() ? "-1" : ESPResponseStream::formatBytes(entry.size()));
// Omit the timestamp because Grbl_ESP32 systems rarely have
// reliable knowledge of the current date and time, so timestamps
// on uploaded files are unlikely to be useful.
j.member("datetime", "");
j.end_object();
entry.close();
entry = dir.openNextFile();
}
dir.close();
}
jsonfile += "],\"path\":\"";
jsonfile += path + "\",";
jsonfile += "\"total\":\"";
j.end_array();
String stotalspace, susedspace;
//SDCard are in GB or MB but no less
totalspace = SD.totalBytes();
usedspace = SD.usedBytes();
stotalspace = ESPResponseStream::formatBytes(totalspace);
susedspace = ESPResponseStream::formatBytes(usedspace + 1);
uint32_t occupedspace = 1;
uint32_t usedspace2 = usedspace / (1024 * 1024);
uint32_t totalspace2 = totalspace / (1024 * 1024);
occupedspace = (usedspace2 * 100) / totalspace2;
//minimum if even one byte is used is 1%
if (occupedspace <= 1) {
occupedspace = 1;
}
jsonfile += totalspace ? stotalspace : "-1";
jsonfile += "\",\"used\":\"";
jsonfile += susedspace;
jsonfile += "\",\"occupation\":\"";
jsonfile += totalspace ? String(occupedspace) : "-1";
jsonfile += "\",";
jsonfile += "\"mode\":\"direct\",";
jsonfile += "\"status\":\"";
jsonfile += sstatus + "\"";
jsonfile += "}";
_webserver->sendHeader("Cache-Control", "no-cache");
j.member("path", path);
j.member("status", sstatus);
j.filesystemStats(SD.totalBytes(), SD.usedBytes());
j.member("mode", "direct");
}
_webserver->send(200, "application/json", jsonfile);
dontCache();
sendJSON(200, j);
_upload_status = UploadStatusType::NONE;
set_sd_state(SDState::Idle);
SD.end();
@@ -1406,7 +1352,7 @@ namespace WebUI {
//this is only for admin and user
if (is_authenticated() == AuthenticationLevel::LEVEL_GUEST) {
_upload_status = UploadStatusType::FAILED;
_webserver->send(401, "application/json", "{\"status\":\"Authentication failed!\"}");
sendStatus(401, "Authentication failed!", NULL, NULL);
pushError(ESP_ERROR_AUTHENTICATION, "Upload rejected", 401);
} else {
//retrieve current file id

View File

@@ -94,6 +94,9 @@ namespace WebUI {
static void SDFile_direct_upload();
static bool deleteRecursive(String path);
#endif
static void dontCache();
static void sendJSON(int code, JSONencoder j);
static void sendStatus(int code, const char* status, const char* auth, const char* user);
};
extern Web_Server web_server;

View File

@@ -869,9 +869,7 @@ namespace WebUI {
j.begin_array("files");
listDirJSON(SPIFFS, "/", 4, &j);
j.end_array();
j.member("total", SPIFFS.totalBytes());
j.member("used", SPIFFS.usedBytes());
j.member("occupation", String(100 * SPIFFS.usedBytes() / SPIFFS.totalBytes()));
j.filesystemStats(SPIFFS.totalBytes(), SPIFFS.usedBytes());
webPrint(j.end());
if (espresponse->client() != CLIENT_WEBUI) {
webPrintln("");