Program Listing for File FSWebServerNoScreen.cpp
↰ Return to documentation for file (/home/fabio/Arduino/MyLvglWatch-20220910/FSWebServerNoScreen.cpp)
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#define FILESYSTEM SPIFFS
// You only need to format the filesystem once
#define FORMAT_FILESYSTEM false
#define DBG_OUTPUT_PORT Serial
#if FILESYSTEM == FFat
#include <FFat.h>
#endif
#if FILESYSTEM == SPIFFS
#include <SPIFFS.h>
#endif
#include "config.h" // need this to get watch and RTC handlers
#include "NetworkNoScreen.h"
/*
const char* ssid = "NameOfNetworkTP";
const char* password = "0123456789";
*/
const char* host = "esp32fs";
WebServer server(80);
//holds the current upload
File fsUploadFile;
static bool webServerFSStarted = false;
//format bytes
String formatBytes(size_t bytes) {
if (bytes < 1024) {
return String(bytes) + "B";
} else if (bytes < (1024 * 1024)) {
return String(bytes / 1024.0) + "KB";
} else if (bytes < (1024 * 1024 * 1024)) {
return String(bytes / 1024.0 / 1024.0) + "MB";
} else {
return String(bytes / 1024.0 / 1024.0 / 1024.0) + "GB";
}
}
String getContentType(String filename) {
if (server.hasArg("download")) {
return "application/octet-stream";
} else if (filename.endsWith(".htm")) {
return "text/html";
} else if (filename.endsWith(".html")) {
return "text/html";
} else if (filename.endsWith(".css")) {
return "text/css";
} else if (filename.endsWith(".js")) {
return "application/javascript";
} else if (filename.endsWith(".png")) {
return "image/png";
} else if (filename.endsWith(".gif")) {
return "image/gif";
} else if (filename.endsWith(".jpg")) {
return "image/jpeg";
} else if (filename.endsWith(".ico")) {
return "image/x-icon";
} else if (filename.endsWith(".xml")) {
return "text/xml";
} else if (filename.endsWith(".pdf")) {
return "application/x-pdf";
} else if (filename.endsWith(".zip")) {
return "application/x-zip";
} else if (filename.endsWith(".gz")) {
return "application/x-gzip";
}
return "text/plain";
}
bool exists(String path){
bool yes = false;
File file = FILESYSTEM.open(path, "r");
if(!file.isDirectory()){
yes = true;
}
file.close();
return yes;
}
bool handleFileRead(String path) {
DBG_OUTPUT_PORT.println("handleFileRead: " + path);
if (path.endsWith("/")) {
path += "index.htm";
}
String contentType = getContentType(path);
String pathWithGz = path + ".gz";
if (exists(pathWithGz) || exists(path)) {
if (exists(pathWithGz)) {
path += ".gz";
}
File file = FILESYSTEM.open(path, "r");
server.streamFile(file, contentType);
file.close();
return true;
}
return false;
}
void handleFileUpload() {
if (server.uri() != "/edit") {
return;
}
HTTPUpload& upload = server.upload();
switch (upload.status) {
case UPLOAD_FILE_START: DBG_OUTPUT_PORT.print ("START "); break;
case UPLOAD_FILE_WRITE: DBG_OUTPUT_PORT.print ("WRITE "); break;
case UPLOAD_FILE_END: DBG_OUTPUT_PORT.print ("END "); break;
default: DBG_OUTPUT_PORT.print (upload.status);
}
DBG_OUTPUT_PORT.print (" filename: ");
DBG_OUTPUT_PORT.println (upload.filename);
if (upload.status == UPLOAD_FILE_START) {
String filename = upload.filename;
if (!filename.startsWith("/")) {
filename = "/" + filename;
}
DBG_OUTPUT_PORT.print("handleFileUpload Name: "); DBG_OUTPUT_PORT.println(filename);
fsUploadFile = FILESYSTEM.open(filename, "w");
filename = String();
} else if (upload.status == UPLOAD_FILE_WRITE) {
//DBG_OUTPUT_PORT.print("handleFileUpload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize);
if (fsUploadFile) {
fsUploadFile.write(upload.buf, upload.currentSize);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (fsUploadFile) {
fsUploadFile.close();
}
DBG_OUTPUT_PORT.print("handleFileUpload Size: "); DBG_OUTPUT_PORT.println(upload.totalSize);
}
}
void handleFileDelete() {
if (server.args() == 0) {
return server.send(500, "text/plain", "BAD ARGS");
}
String path = server.arg(0);
DBG_OUTPUT_PORT.println("handleFileDelete: " + path);
if (path == "/") {
return server.send(500, "text/plain", "BAD PATH");
}
if (!exists(path)) {
return server.send(404, "text/plain", "FileNotFound");
}
FILESYSTEM.remove(path);
server.send(200, "text/plain", "");
path = String();
}
void handleFileCreate() {
if (server.args() == 0) {
return server.send(500, "text/plain", "BAD ARGS");
}
String path = server.arg(0);
DBG_OUTPUT_PORT.println("handleFileCreate: " + path);
if (path == "/") {
return server.send(500, "text/plain", "BAD PATH");
}
if (exists(path)) {
return server.send(500, "text/plain", "FILE EXISTS");
}
File file = FILESYSTEM.open(path, "w");
if (file) {
file.close();
} else {
return server.send(500, "text/plain", "CREATE FAILED");
}
server.send(200, "text/plain", "");
path = String();
}
void handleFileList() {
if (!server.hasArg("dir")) {
server.send(500, "text/plain", "BAD ARGS");
return;
}
String path = server.arg("dir");
DBG_OUTPUT_PORT.println("handleFileList: " + path);
File root = FILESYSTEM.open(path);
path = String();
String output = "[";
if(root.isDirectory()){
File file = root.openNextFile();
while(file){
if (output != "[") {
output += ',';
}
output += "{\"type\":\"";
output += (file.isDirectory()) ? "dir" : "file";
output += "\",\"name\":\"";
output += String(file.name()).substring(1);
output += "\"}";
file = root.openNextFile();
}
}
output += "]";
server.send(200, "text/json", output);
}
int recordEvent (const char *desc) {
/* Open filesystem, open for append, or, create file named 'eventlog.csv'
* store function arguments as a line, close file, close FS.
* if fail, return a negative error code
*/
setCpuFrequencyMhz(240); // to WRITE THE FILE FASTER
TTGOClass *ttgo = TTGOClass::getWatch(); // pointer to watch internals
PCF8563_Class *rtc = ttgo->rtc; // pointer to RTC (real-time clock)
// if (FILESYSTEM.begin()) {
/* O sistema de arquivos pode estar montado porque o servidor está ativo.
* Neste caso, não convém desmontar o sistema de arquivo.
* MAS a API não tem função que verifica se o FS está ou não montado.
* então vou testar o flag webServerFSStarted.
* esta função não muda o flag do web server.
*/
if (!webServerFSStarted) FILESYSTEM.begin();
File file = FILESYSTEM.open("/eventLog.csv", "a");
char recordBuffer[1024];
recordBuffer[0]='\0'; // empty string
strcat (recordBuffer,rtc->formatDateTime(PCF_TIMEFORMAT_YYYY_MM_DD)); // libraries/TTGO_TWatch_Library/src/drive/rtc/pcf8563.cpp
strcat (recordBuffer, "T"); // https://en.wikipedia.org/wiki/ISO_8601
strcat (recordBuffer, rtc->formatDateTime(PCF_TIMEFORMAT_HMS));
strcat (recordBuffer, "-03");
strcat (recordBuffer, " ; ");
strcat (recordBuffer, desc);
file.println (recordBuffer);
file.close();
if (!webServerFSStarted) FILESYSTEM.end(); // https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html#end
return 0; // OK
}
void startWebServerFS(void) {
setCpuFrequencyMhz(240); // maximum speed
DBG_OUTPUT_PORT.begin(115200);
DBG_OUTPUT_PORT.print("\n");
DBG_OUTPUT_PORT.setDebugOutput(true);
if (FORMAT_FILESYSTEM) FILESYSTEM.format();
FILESYSTEM.begin();
{
File root = FILESYSTEM.open("/");
File file = root.openNextFile();
while(file){
String fileName = file.name();
size_t fileSize = file.size();
DBG_OUTPUT_PORT.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
file = root.openNextFile();
}
DBG_OUTPUT_PORT.printf("\n");
}
wiFiOn();
MDNS.begin(host);
DBG_OUTPUT_PORT.print("Open http://");
DBG_OUTPUT_PORT.print(host);
DBG_OUTPUT_PORT.println(".local/edit to see the file browser");
//SERVER INIT
//list directory
server.on("/list", HTTP_GET, handleFileList);
//load editor
server.on("/edit", HTTP_GET, []() {
if (!handleFileRead("/edit.htm")) {
server.send(404, "text/plain", "FileNotFound");
}
});
//create file
server.on("/edit", HTTP_PUT, handleFileCreate);
//delete file
server.on("/edit", HTTP_DELETE, handleFileDelete);
//first callback is called after the request has ended with all parsed arguments
//second callback handles file uploads at that location
server.on("/edit", HTTP_POST, []() {
server.send(200, "text/plain", "");
}, handleFileUpload);
//called when the url is not defined here
//use it to load content from FILESYSTEM
server.onNotFound([]() {
if (!handleFileRead(server.uri())) {
server.send(404, "text/plain", "FileNotFound");
}
});
//get heap status, analog input value and all GPIO statuses in one json call
server.on("/all", HTTP_GET, []() {
String json = "{";
json += "\"heap\":" + String(ESP.getFreeHeap());
// json += ", \"analog\":" + String(analogRead(A0));
json += ", \"analog\":" + String(255);
json += ", \"gpio\":" + String((uint32_t)(0));
json += "}";
server.send(200, "text/json", json);
json = String();
});
server.begin();
DBG_OUTPUT_PORT.println("HTTP server started");
webServerFSStarted = true;
}
void closeWebServerandSPIFFSandWiFi() {
webServerFSStarted=false;
server.stop(); // https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WebServer/src/ESP8266WebServer.h
FILESYSTEM.end(); // https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html#end
wiFiOff();
}
bool webServerFSTestAndHandle(void){ // to insert into loop() function
if (webServerFSStarted)
server.handleClient();
return webServerFSStarted;
}