diff --git a/plip_voice/main/net.c b/plip_voice/main/net.c index a8d8f53..bb2bb1f 100644 --- a/plip_voice/main/net.c +++ b/plip_voice/main/net.c @@ -281,6 +281,44 @@ static esp_err_t handle_file_post(httpd_req_t *req) return send_json(req, "200 OK", resp); } +/* ── DELETE /game/file?path=... (remove a staged file; SD or SPIFFS) ─────── */ +/* Same path routing as the POST handler (sd/ prefix → /sdcard, else /spiffs). + * Lets the host clean stale clips when regenerating the SD voice pack. */ +static esp_err_t handle_file_delete(httpd_req_t *req) +{ + char query[128] = {0}, fpath[128] = {0}; + httpd_req_get_url_query_str(req, query, sizeof(query)); + if (httpd_query_key_value(query, "path", fpath, sizeof(fpath)) != ESP_OK) + return send_json(req, "400 Bad Request", "{\"error\":\"missing path param\"}"); + + const char *base, *rel = fpath; + bool to_sd = false; + if (strncmp(fpath, "sd/", 3) == 0) { rel = fpath + 3; to_sd = true; } + else if (strncmp(fpath, "sdcard/", 7) == 0) { rel = fpath + 7; to_sd = true; } + else if (strncmp(fpath, "/sdcard/", 8) == 0) { rel = fpath + 8; to_sd = true; } + + if (to_sd) { + if (!audio_ensure_sd()) + return send_json(req, "503 Service Unavailable", "{\"error\":\"no sd card\"}"); + base = PLIP_SD_MOUNT; + } else { + ensure_spiffs(); + base = SPIFFS_BASE; + } + while (*rel == '/') rel++; + + char full[192]; + snprintf(full, sizeof(full), "%s/%s", base, rel); + if (remove(full) != 0) { + ESP_LOGW(TAG, "remove %s failed: errno=%d", full, errno); + return send_json(req, "404 Not Found", "{\"error\":\"remove failed\"}"); + } + ESP_LOGI(TAG, "file removed: %s", full); + char resp[256]; + snprintf(resp, sizeof(resp), "{\"status\":\"ok\",\"removed\":\"%s\"}", full); + return send_json(req, "200 OK", resp); +} + /* ── POST /voice/capture ──────────────────────────────────────────────────── */ #define CAP_MAX_MS_DEFAULT 5000 @@ -842,7 +880,7 @@ esp_err_t net_init(void) /* Start HTTP server. */ httpd_config_t hcfg = HTTPD_DEFAULT_CONFIG(); hcfg.server_port = 80; - hcfg.max_uri_handlers = 17; + hcfg.max_uri_handlers = 18; hcfg.stack_size = 8192; esp_err_t ret = httpd_start(&s_httpd, &hcfg); @@ -863,6 +901,10 @@ esp_err_t net_init(void) .uri = "/game/file", .method = HTTP_POST, .handler = handle_file_post, .user_ctx = NULL, }; + static const httpd_uri_t uri_file_delete = { + .uri = "/game/file", .method = HTTP_DELETE, + .handler = handle_file_delete, .user_ctx = NULL, + }; static const httpd_uri_t uri_cmd = { .uri = "/game/cmd", .method = HTTP_POST, .handler = handle_cmd_post, .user_ctx = NULL, @@ -918,6 +960,7 @@ esp_err_t net_init(void) httpd_register_uri_handler(s_httpd, &uri_status); httpd_register_uri_handler(s_httpd, &uri_scenario); httpd_register_uri_handler(s_httpd, &uri_file); + httpd_register_uri_handler(s_httpd, &uri_file_delete); httpd_register_uri_handler(s_httpd, &uri_cmd); httpd_register_uri_handler(s_httpd, &uri_capture); httpd_register_uri_handler(s_httpd, &uri_debug_regs);