WIP: service and broken partitions

This commit is contained in:
2025-09-15 20:33:15 +02:00
parent 089f938796
commit 98fdc3e1ae
13 changed files with 807 additions and 300 deletions

View File

@@ -3,6 +3,7 @@
#include "spore/services/NetworkService.h"
#include "spore/services/ClusterService.h"
#include "spore/services/TaskService.h"
#include "spore/services/StaticFileService.h"
#include <Arduino.h>
Spore::Spore() : ctx(), network(ctx), taskManager(ctx), cluster(ctx, taskManager),
@@ -119,12 +120,14 @@ void Spore::registerCoreServices() {
auto networkService = std::make_shared<NetworkService>(network);
auto clusterService = std::make_shared<ClusterService>(ctx);
auto taskService = std::make_shared<TaskService>(taskManager);
auto staticFileService = std::make_shared<StaticFileService>(ctx, apiServer);
// Add to services list
services.push_back(nodeService);
services.push_back(networkService);
services.push_back(clusterService);
services.push_back(taskService);
services.push_back(staticFileService);
Serial.println("[Spore] Core services registered");
}

View File

@@ -0,0 +1,109 @@
#include "spore/services/StaticFileService.h"
#include <Arduino.h>
const String StaticFileService::name = "StaticFileService";
StaticFileService::StaticFileService(NodeContext& ctx, ApiServer& apiServer)
: ctx(ctx), apiServer(apiServer) {
}
void StaticFileService::registerEndpoints(ApiServer& api) {
// Initialize LittleFS
if (!LittleFS.begin()) {
Serial.println("[StaticFileService] LittleFS Mount Failed");
return;
}
Serial.println("[StaticFileService] LittleFS mounted successfully");
// Root endpoint - serve index.html
api.addEndpoint("/", HTTP_GET,
[this](AsyncWebServerRequest* request) { handleRootRequest(request); },
std::vector<ParamSpec>{});
// Static file serving for any path
api.addEndpoint("/*", HTTP_GET,
[this](AsyncWebServerRequest* request) { handleStaticFileRequest(request); },
std::vector<ParamSpec>{});
}
void StaticFileService::handleRootRequest(AsyncWebServerRequest* request) {
// Serve index.html from root
String path = "/index.html";
if (!fileExists(path)) {
request->send(404, "text/plain", "File not found");
return;
}
File file = LittleFS.open(path, "r");
if (!file) {
request->send(500, "text/plain", "Failed to open file");
return;
}
String contentType = getContentType(path);
request->send(LittleFS, path, contentType);
file.close();
}
void StaticFileService::handleStaticFileRequest(AsyncWebServerRequest* request) {
String path = request->url();
// Remove leading slash for LittleFS path
if (path.startsWith("/")) {
path = path.substring(1);
}
// If path is empty or just "/", serve index.html
if (path.isEmpty() || path == "/") {
path = "index.html";
}
// Check if file exists
if (!fileExists("/" + path)) {
request->send(404, "text/plain", "File not found: " + path);
return;
}
String contentType = getContentType(path);
request->send(LittleFS, "/" + path, contentType);
}
void StaticFileService::handleNotFound(AsyncWebServerRequest* request) {
// Try to serve index.html as fallback
if (fileExists("/index.html")) {
request->send(LittleFS, "/index.html", "text/html");
} else {
request->send(404, "text/plain", "Not found");
}
}
String StaticFileService::getContentType(const String& filename) {
if (filename.endsWith(".html") || filename.endsWith(".htm")) {
return "text/html";
} else if (filename.endsWith(".css")) {
return "text/css";
} else if (filename.endsWith(".js")) {
return "application/javascript";
} else if (filename.endsWith(".json")) {
return "application/json";
} else if (filename.endsWith(".png")) {
return "image/png";
} else if (filename.endsWith(".jpg") || filename.endsWith(".jpeg")) {
return "image/jpeg";
} else if (filename.endsWith(".gif")) {
return "image/gif";
} else if (filename.endsWith(".svg")) {
return "image/svg+xml";
} else if (filename.endsWith(".ico")) {
return "image/x-icon";
} else if (filename.endsWith(".txt")) {
return "text/plain";
} else {
return "application/octet-stream";
}
}
bool StaticFileService::fileExists(const String& path) {
return LittleFS.exists(path);
}