You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AutoConnect/examples/FSBrowser/FSBrowser.ino

354 lines
10 KiB

7 years ago
/*
FSWebServer - Example WebServer with SPIFFS backend for esp8266
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
This file is part of the ESP8266WebServer library for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
upload the contents of the data folder with MkSPIFFS Tool ("ESP8266 Sketch Data Upload" in Tools menu in Arduino IDE)
or you can upload the contents of a folder if you CD in that folder and run the following command:
for file in `ls -A1`; do curl -F "file=@$PWD/$file" esp8266fs.local/edit; done
access the sample web page at http://esp8266fs.local
edit the page by going to http://esp8266fs.local/edit
*/
6 years ago
#if defined(ARDUINO_ARCH_ESP8266)
7 years ago
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <FS.h>
6 years ago
#elif defined(ARDUINO_ARCH_ESP32)
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <SPIFFS.h>
#endif
7 years ago
//Add a below line for AutoConnect.
#include <AutoConnect.h>
#define DBG_OUTPUT_PORT Serial
const char* ssid = "wifi-ssid";
const char* password = "wifi-password";
6 years ago
#if defined(ARDUINO_ARCH_ESP8266)
7 years ago
const char* host = "esp8266fs";
ESP8266WebServer server(80);
6 years ago
#elif defined(ARDUINO_ARCH_ESP32)
const char* host = "esp32fs";
WebServer server(80);
#endif
7 years ago
//Add a below line for AutoConnect.
AutoConnect portal(server);
AutoConnectConfig config;
AutoConnectAux FSBedit("/edit", "Edit");
AutoConnectAux FSBlist("/list?dir=\"/\"", "List");
7 years ago
//holds the current upload
File fsUploadFile;
//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";
}
7 years ago
return "text/plain";
}
bool handleFileRead(String path) {
7 years ago
DBG_OUTPUT_PORT.println("handleFileRead: " + path);
if (path.endsWith("/")) {
path += "index.htm";
}
7 years ago
String contentType = getContentType(path);
String pathWithGz = path + ".gz";
if (SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) {
if (SPIFFS.exists(pathWithGz)) {
7 years ago
path += ".gz";
}
7 years ago
File file = SPIFFS.open(path, "r");
server.streamFile(file, contentType);
7 years ago
file.close();
return true;
}
return false;
}
void handleFileUpload() {
if (server.uri() != "/edit") {
return;
}
7 years ago
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
7 years ago
String filename = upload.filename;
if (!filename.startsWith("/")) {
filename = "/" + filename;
}
7 years ago
DBG_OUTPUT_PORT.print("handleFileUpload Name: "); DBG_OUTPUT_PORT.println(filename);
fsUploadFile = SPIFFS.open(filename, "w");
filename = String();
} else if (upload.status == UPLOAD_FILE_WRITE) {
7 years ago
//DBG_OUTPUT_PORT.print("handleFileUpload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize);
if (fsUploadFile) {
7 years ago
fsUploadFile.write(upload.buf, upload.currentSize);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (fsUploadFile) {
7 years ago
fsUploadFile.close();
}
7 years ago
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");
}
7 years ago
String path = server.arg(0);
DBG_OUTPUT_PORT.println("handleFileDelete: " + path);
if (path == "/") {
7 years ago
return server.send(500, "text/plain", "BAD PATH");
}
if (!SPIFFS.exists(path)) {
7 years ago
return server.send(404, "text/plain", "FileNotFound");
}
7 years ago
SPIFFS.remove(path);
server.send(200, "text/plain", "");
path = String();
}
void handleFileCreate() {
if (server.args() == 0) {
7 years ago
return server.send(500, "text/plain", "BAD ARGS");
}
7 years ago
String path = server.arg(0);
DBG_OUTPUT_PORT.println("handleFileCreate: " + path);
if (path == "/") {
7 years ago
return server.send(500, "text/plain", "BAD PATH");
}
if (SPIFFS.exists(path)) {
7 years ago
return server.send(500, "text/plain", "FILE EXISTS");
}
7 years ago
File file = SPIFFS.open(path, "w");
if (file) {
7 years ago
file.close();
} else {
7 years ago
return server.send(500, "text/plain", "CREATE FAILED");
}
7 years ago
server.send(200, "text/plain", "");
path = String();
}
void handleFileList() {
if (!server.hasArg("dir")) {
server.send(500, "text/plain", "BAD ARGS");
return;
}
7 years ago
String path = server.arg("dir");
DBG_OUTPUT_PORT.println("handleFileList: " + path);
6 years ago
#if defined(ARDUINO_ARCH_ESP8266)
7 years ago
Dir dir = SPIFFS.openDir(path);
6 years ago
#elif defined(ARDUINO_ARCH_ESP32)
File root = SPIFFS.open(path);
#endif
7 years ago
path = String();
String output = "[";
6 years ago
#if defined(ARDUINO_ARCH_ESP8266)
while (dir.next()) {
7 years ago
File entry = dir.openFile("r");
if (output != "[") {
output += ',';
}
7 years ago
bool isDir = false;
output += "{\"type\":\"";
output += (isDir) ? "dir" : "file";
7 years ago
output += "\",\"name\":\"";
output += String(entry.name()).substring(1);
output += "\"}";
entry.close();
}
6 years ago
#elif defined(ARDUINO_ARCH_ESP32)
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();
}
}
#endif
7 years ago
output += "]";
server.send(200, "text/json", output);
}
void setup(void){
DBG_OUTPUT_PORT.begin(115200);
DBG_OUTPUT_PORT.print("\n");
DBG_OUTPUT_PORT.setDebugOutput(true);
SPIFFS.begin();
{
6 years ago
#if defined(ARDUINO_ARCH_ESP8266)
7 years ago
Dir dir = SPIFFS.openDir("/");
while (dir.next()) {
7 years ago
String fileName = dir.fileName();
size_t fileSize = dir.fileSize();
DBG_OUTPUT_PORT.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
}
6 years ago
#elif defined(ARDUINO_ARCH_ESP32)
File root = SPIFFS.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();
}
#endif
7 years ago
DBG_OUTPUT_PORT.printf("\n");
}
//WIFI INIT
DBG_OUTPUT_PORT.printf("Connecting to %s\n", ssid);
//Comment out as follows to make AutoConnect recognition.
//if (String(WiFi.SSID()) != String(ssid)) {
// WiFi.mode(WIFI_STA);
// WiFi.begin(ssid, password);
//}
//while (WiFi.status() != WL_CONNECTED) {
// delay(500);
// DBG_OUTPUT_PORT.print(".");
//}
//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");
}
7 years ago
});
//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);
7 years ago
//called when the url is not defined here
//use it to load content from SPIFFS
//Replacement as follows to make AutoConnect recognition.
//server.onNotFound([](){
portal.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));
6 years ago
#if defined(ARDUINO_ARCH_ESP8266)
7 years ago
json += ", \"gpio\":"+String((uint32_t)(((GPI | GPO) & 0xFFFF) | ((GP16I & 0x01) << 16)));
6 years ago
#elif defined(ARDUINO_ARCH_ESP32)
json += ", \"gpio\":" + String((uint32_t)(0));
#endif
7 years ago
json += "}";
server.send(200, "text/json", json);
json = String();
});
//Set menu title
config.title = "FSBrowser";
portal.config(config);
//Register AutoConnect menu
portal.join({ FSBedit, FSBlist });
7 years ago
//Replacement as follows to make AutoConnect recognition.
//server.begin();
portal.begin();
DBG_OUTPUT_PORT.println("HTTP server started");
//Relocation as follows to make AutoConnect recognition.
DBG_OUTPUT_PORT.println("");
DBG_OUTPUT_PORT.print("Connected! IP address: ");
DBG_OUTPUT_PORT.println(WiFi.localIP());
//Relocation as follows to make AutoConnect recognition.
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");
}
void loop(void){
//Replacement as follows to make AutoConnect recognition.
//server.handleClient();
portal.handleClient();
#ifdef ARDUINO_ARCH_ESP8266
MDNS.update();
#endif
7 years ago
}