Browse Source

Filebrowser: Move to CP437 encoding support

master
grch101 4 years ago
committed by Torsten Stauder
parent
commit
9caddc80fc
  1. 10
      html/management.html
  2. 2
      platformio.ini
  3. 11
      src/HTMLmanagement.h
  4. 134
      src/main.cpp

10
html/management.html

@ -156,7 +156,7 @@
<div class="filetree demo" id="explorerTree"></div> <div class="filetree demo" id="explorerTree"></div>
</div> </div>
<div> <div>
<form id="explorerUploadForm" method="POST" enctype="multipart/form-data" action="/explorer" accept-charset="iso-8859-1">
<form id="explorerUploadForm" method="POST" enctype="multipart/form-data" action="/explorer">
<input id="explorerUploadedFiles" type="file" class="form-control-file" name="explorerUploadFiles" multiple> <input type="submit" class="btn btn-primary" id="submit" value="Hochladen"> <input id="explorerUploadedFiles" type="file" class="form-control-file" name="explorerUploadFiles" multiple> <input type="submit" class="btn btn-primary" id="submit" value="Hochladen">
<progress id="explorerUploadProgress" value="0" max="100"></progress> <span id="explorerUploadPercent"></span> <progress id="explorerUploadProgress" value="0" max="100"></progress> <span id="explorerUploadPercent"></span>
</form> </form>
@ -485,9 +485,9 @@
function doRest(path, callback, obj) { function doRest(path, callback, obj) {
obj.url = path; obj.url = path;
obj.dataType = "json"; obj.dataType = "json";
obj.contentType= "application/json;charset=iso-8859-1",
obj.scriptCharset= "iso-8859-1",
obj.success = function(data, textStatus, jqXHR) {
obj.contentType= "application/json;charset=IBM437",
obj.scriptCharset= "IBM437",
obj.success = function(data, textStatus, jqXHR) {
if (callback) { if (callback) {
callback(data); callback(data);
} }
@ -771,7 +771,7 @@
/* Delete */ /* Delete */
items.delete = { items.delete = {
label: "Loeschen",
label: "Löschen",
action: function(x) { action: function(x) {
handleDeleteData(nodeId); handleDeleteData(nodeId);
refreshNode(ref.get_parent(nodeId)); refreshNode(ref.get_parent(nodeId));

2
platformio.ini

@ -13,7 +13,7 @@ lib_deps_builtin =
SPI SPI
Wire Wire
lib_deps_external = lib_deps_external =
https://github.com/schreibfaul1/ESP32-audioI2S.git#a816a19 ; currently not master-version as commit a816a19 not compatible with latest stable ESP32-Arduino
https://github.com/grch87/ESP32-audioI2S.git
https://github.com/madhephaestus/ESP32Encoder.git https://github.com/madhephaestus/ESP32Encoder.git
https://github.com/knolleary/pubsubclient.git https://github.com/knolleary/pubsubclient.git
https://github.com/biologist79/ESP32FTPServer https://github.com/biologist79/ESP32FTPServer

11
src/HTMLmanagement.h

@ -156,11 +156,10 @@ static const char management_HTML[] PROGMEM = "<!DOCTYPE html>\
<div class=\"filetree demo\" id=\"explorerTree\"></div>\ <div class=\"filetree demo\" id=\"explorerTree\"></div>\
</div>\ </div>\
<div>\ <div>\
<form id=\"explorerUploadForm\" method=\"POST\" enctype=\"multipart/form-data\" action=\"/explorer\" accept-charset=\"iso-8859-1\">\
<form id=\"explorerUploadForm\" method=\"POST\" enctype=\"multipart/form-data\" action=\"/explorer\">\
<input id=\"explorerUploadedFiles\" type=\"file\" class=\"form-control-file\" name=\"explorerUploadFiles\" multiple> <input type=\"submit\" class=\"btn btn-primary\" id=\"submit\" value=\"Hochladen\">\ <input id=\"explorerUploadedFiles\" type=\"file\" class=\"form-control-file\" name=\"explorerUploadFiles\" multiple> <input type=\"submit\" class=\"btn btn-primary\" id=\"submit\" value=\"Hochladen\">\
<progress id=\"explorerUploadProgress\" value=\"0\" max=\"100\"></progress> <span id=\"explorerUploadPercent\"></span>\ <progress id=\"explorerUploadProgress\" value=\"0\" max=\"100\"></progress> <span id=\"explorerUploadPercent\"></span>\
</form>\ </form>\
\
</div>\ </div>\
</fieldset>\ </fieldset>\
</div>\ </div>\
@ -485,9 +484,9 @@ static const char management_HTML[] PROGMEM = "<!DOCTYPE html>\
function doRest(path, callback, obj) {\ function doRest(path, callback, obj) {\
obj.url = path;\ obj.url = path;\
obj.dataType = \"json\";\ obj.dataType = \"json\";\
obj.contentType= \"application/json;charset=iso-8859-1\",\
obj.scriptCharset= \"iso-8859-1\",\
obj.success = function(data, textStatus, jqXHR) {\
obj.contentType= \"application/json;charset=IBM437\",\
obj.scriptCharset= \"IBM437\",\
obj.success = function(data, textStatus, jqXHR) {\
if (callback) {\ if (callback) {\
callback(data);\ callback(data);\
}\ }\
@ -771,7 +770,7 @@ static const char management_HTML[] PROGMEM = "<!DOCTYPE html>\
\ \
/* Delete */\ /* Delete */\
items.delete = {\ items.delete = {\
label: \"Loeschen\",\
label: \"Löschen\",\
action: function(x) {\ action: function(x) {\
handleDeleteData(nodeId);\ handleDeleteData(nodeId);\
refreshNode(ref.get_parent(nodeId));\ refreshNode(ref.get_parent(nodeId));\

134
src/main.cpp

@ -362,6 +362,7 @@ void freeMultiCharArray(char **arr, const uint32_t cnt);
uint8_t getRepeatMode(void); uint8_t getRepeatMode(void);
bool getWifiEnableStatusFromNVS(void); bool getWifiEnableStatusFromNVS(void);
void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final); void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final);
void convertAsciiToUtf8(String asciiString, char *utf8String);
void convertUtf8ToAscii(String utf8String, char *asciiString); void convertUtf8ToAscii(String utf8String, char *asciiString);
void explorerHandleFileUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final); void explorerHandleFileUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final);
void explorerHandleFileStorageTask(void *parameter); void explorerHandleFileStorageTask(void *parameter);
@ -3593,25 +3594,62 @@ void webserverStart(void) {
return true; return true;
} }
// Conversion routine for http UTF-8 strings
// Conversion routine
void convertAsciiToUtf8(String asciiString, char *utf8String) {
int k=0;
for (int i=0; i<asciiString.length(); i++)
{
switch (asciiString[i]) {
case 0x8e: utf8String[k++]=0xc3; utf8String[k++]=0x84; break; // Ä
case 0x84: utf8String[k++]=0xc3; utf8String[k++]=0xa4; break; // ä
case 0x9a: utf8String[k++]=0xc3; utf8String[k++]=0x9c; break; // Ü
case 0x81: utf8String[k++]=0xc3; utf8String[k++]=0xbc; break; // ü
case 0x99: utf8String[k++]=0xc3; utf8String[k++]=0x96; break; // Ö
case 0x94: utf8String[k++]=0xc3; utf8String[k++]=0xb6; break; // ö
case 0xe1: utf8String[k++]=0xc3; utf8String[k++]=0x9f; break; // ß
default: utf8String[k++]=asciiString[i];
}
}
utf8String[k]=0;
}
void convertUtf8ToAscii(String utf8String, char *asciiString) { void convertUtf8ToAscii(String utf8String, char *asciiString) {
uint16_t i = 0, j=0;
bool f_C3_seen = false;
while(utf8String[i] != 0) { // convert UTF8 to ASCII
if(utf8String[i] == 195){ // C3
i++;
f_C3_seen = true;
continue;
}
asciiString[j] = utf8String[i];
if(asciiString[j] > 128 && asciiString[j] < 189 && f_C3_seen == true) {
asciiString[j] = asciiString[j] + 64; // found a related ASCII sign
f_C3_seen = false;
int k=0;
bool f_C3_seen = false;
for (int i=0; i<utf8String.length(); i++)
{
if(utf8String[i] == 195){ // C3
f_C3_seen = true;
continue;
} else {
if (f_C3_seen == true) {
f_C3_seen = false;
switch (utf8String[i]) {
case 0x84: asciiString[k++]=0x8e; break; // Ä
case 0xa4: asciiString[k++]=0x84; break; // ä
case 0x9c: asciiString[k++]=0x9a; break; // Ü
case 0xbc: asciiString[k++]=0x81; break; // ü
case 0x96: asciiString[k++]=0x99; break; // Ö
case 0xb6: asciiString[k++]=0x94; break; // ö
case 0x9f: asciiString[k++]=0xe1; break; // ß
default: asciiString[k++]=0xdb; // Unknow...
} }
i++; j++;
} else {
asciiString[k++]=utf8String[i];
}
} }
asciiString[j] = 0;
}
asciiString[k]=0;
} }
@ -3624,7 +3662,7 @@ void explorerHandleFileUpload(AsyncWebServerRequest *request, String filename, s
// New File // New File
if (!index) { if (!index) {
String utf8FilePath; String utf8FilePath;
static char asciiFilePath[256];
static char filePath[256];
if (request->hasParam("path")) { if (request->hasParam("path")) {
AsyncWebParameter *param = request->getParam("path"); AsyncWebParameter *param = request->getParam("path");
utf8FilePath = param->value() + "/" + filename; utf8FilePath = param->value() + "/" + filename;
@ -3632,7 +3670,11 @@ void explorerHandleFileUpload(AsyncWebServerRequest *request, String filename, s
} else { } else {
utf8FilePath = "/" + filename; utf8FilePath = "/" + filename;
} }
convertUtf8ToAscii(utf8FilePath, asciiFilePath);
convertUtf8ToAscii(utf8FilePath, filePath);
snprintf(logBuf, serialLoglength, "%s: %s", (char *) FPSTR(writingFile), utf8FilePath.c_str());
loggerNl(serialDebug, logBuf, LOGLEVEL_INFO);
// Create Ringbuffer for upload // Create Ringbuffer for upload
if(explorerFileUploadRingBuffer == NULL) { if(explorerFileUploadRingBuffer == NULL) {
@ -3649,7 +3691,7 @@ void explorerHandleFileUpload(AsyncWebServerRequest *request, String filename, s
explorerHandleFileStorageTask, /* Function to implement the task */ explorerHandleFileStorageTask, /* Function to implement the task */
"fileStorageTask", /* Name of the task */ "fileStorageTask", /* Name of the task */
4000, /* Stack size in words */ 4000, /* Stack size in words */
asciiFilePath, /* Task input parameter */
filePath, /* Task input parameter */
2 | portPRIVILEGE_BIT, /* Priority of the task */ 2 | portPRIVILEGE_BIT, /* Priority of the task */
&fileStorageTaskHandle /* Task handle. */ &fileStorageTaskHandle /* Task handle. */
); );
@ -3685,9 +3727,6 @@ void explorerHandleFileStorageTask(void *parameter) {
uploadFile = FSystem.open((char *)parameter, "w"); uploadFile = FSystem.open((char *)parameter, "w");
snprintf(logBuf, serialLoglength, "%s: %s", (char *) FPSTR(writingFile), (char *) parameter);
loggerNl(serialDebug, logBuf, LOGLEVEL_INFO);
for(;;) { for(;;) {
esp_task_wdt_reset(); esp_task_wdt_reset();
@ -3718,13 +3757,13 @@ void explorerHandleListRequest(AsyncWebServerRequest *request) {
//StaticJsonDocument<4096> jsonBuffer; //StaticJsonDocument<4096> jsonBuffer;
String serializedJsonString; String serializedJsonString;
AsyncWebParameter *param; AsyncWebParameter *param;
char asciiFilePath[256];
char filePath[256];
JsonArray obj = jsonBuffer.createNestedArray(); JsonArray obj = jsonBuffer.createNestedArray();
File root; File root;
if(request->hasParam("path")){ if(request->hasParam("path")){
param = request->getParam("path"); param = request->getParam("path");
convertUtf8ToAscii(param->value(), asciiFilePath);
root = FSystem.open(asciiFilePath);
convertUtf8ToAscii(param->value(), filePath);
root = FSystem.open(filePath);
} else { } else {
root = FSystem.open("/"); root = FSystem.open("/");
} }
@ -3745,7 +3784,8 @@ void explorerHandleListRequest(AsyncWebServerRequest *request) {
while(file) { while(file) {
JsonObject entry = obj.createNestedObject(); JsonObject entry = obj.createNestedObject();
std::string path = file.name();
convertAsciiToUtf8(file.name(), filePath);
std::string path = filePath;
std::string fileName = path.substr(path.find_last_of("/") + 1); std::string fileName = path.substr(path.find_last_of("/") + 1);
entry["name"] = fileName; entry["name"] = fileName;
@ -3758,7 +3798,7 @@ void explorerHandleListRequest(AsyncWebServerRequest *request) {
} }
serializeJson(obj, serializedJsonString); serializeJson(obj, serializedJsonString);
request->send(200, "application/json; charset=iso-8859-1", serializedJsonString);
request->send(200, "application/json; charset=utf-8", serializedJsonString);
} }
bool explorerDeleteDirectory(File dir) { bool explorerDeleteDirectory(File dir) {
@ -3786,31 +3826,31 @@ bool explorerDeleteDirectory(File dir) {
void explorerHandleDeleteRequest(AsyncWebServerRequest *request) { void explorerHandleDeleteRequest(AsyncWebServerRequest *request) {
File file; File file;
AsyncWebParameter *param; AsyncWebParameter *param;
char asciiFilePath[256];
char filePath[256];
if(request->hasParam("path")){ if(request->hasParam("path")){
param = request->getParam("path"); param = request->getParam("path");
convertUtf8ToAscii(param->value(), asciiFilePath);
if(FSystem.exists(asciiFilePath)) {
file = FSystem.open(asciiFilePath);
convertUtf8ToAscii(param->value(), filePath);
if(FSystem.exists(filePath)) {
file = FSystem.open(filePath);
if(file.isDirectory()) { if(file.isDirectory()) {
if(explorerDeleteDirectory(file)) { if(explorerDeleteDirectory(file)) {
snprintf(logBuf, serialLoglength, "DELETE: %s deleted", asciiFilePath);
snprintf(logBuf, serialLoglength, "DELETE: %s deleted", param->value().c_str());
loggerNl(serialDebug, logBuf, LOGLEVEL_INFO); loggerNl(serialDebug, logBuf, LOGLEVEL_INFO);
} else { } else {
snprintf(logBuf, serialLoglength, "DELETE: Cannot delete %s", asciiFilePath);
snprintf(logBuf, serialLoglength, "DELETE: Cannot delete %s", param->value().c_str());
loggerNl(serialDebug, logBuf, LOGLEVEL_ERROR); loggerNl(serialDebug, logBuf, LOGLEVEL_ERROR);
} }
} else { } else {
if(FSystem.remove(asciiFilePath)) {
snprintf(logBuf, serialLoglength, "DELETE: %s deleted", asciiFilePath);
if(FSystem.remove(filePath)) {
snprintf(logBuf, serialLoglength, "DELETE: %s deleted", param->value().c_str());
loggerNl(serialDebug, logBuf, LOGLEVEL_INFO); loggerNl(serialDebug, logBuf, LOGLEVEL_INFO);
} else { } else {
snprintf(logBuf, serialLoglength, "DELETE: Cannot delete %s", asciiFilePath);
snprintf(logBuf, serialLoglength, "DELETE: Cannot delete %s", param->value().c_str());
loggerNl(serialDebug, logBuf, LOGLEVEL_ERROR); loggerNl(serialDebug, logBuf, LOGLEVEL_ERROR);
} }
} }
} else { } else {
snprintf(logBuf, serialLoglength, "DELETE: Path %s does not exist", asciiFilePath);
snprintf(logBuf, serialLoglength, "DELETE: Path %s does not exist", param->value().c_str());
loggerNl(serialDebug, logBuf, LOGLEVEL_ERROR); loggerNl(serialDebug, logBuf, LOGLEVEL_ERROR);
} }
} else { } else {
@ -3824,15 +3864,15 @@ void explorerHandleDeleteRequest(AsyncWebServerRequest *request) {
// requires a GET parameter path to the new directory // requires a GET parameter path to the new directory
void explorerHandleCreateRequest(AsyncWebServerRequest *request) { void explorerHandleCreateRequest(AsyncWebServerRequest *request) {
AsyncWebParameter *param; AsyncWebParameter *param;
char asciiFilePath[256];
char filePath[256];
if(request->hasParam("path")){ if(request->hasParam("path")){
param = request->getParam("path"); param = request->getParam("path");
convertUtf8ToAscii(param->value(), asciiFilePath);
if(FSystem.mkdir(asciiFilePath)) {
snprintf(logBuf, serialLoglength, "CREATE: %s created", asciiFilePath);
convertUtf8ToAscii(param->value(), filePath);
if(FSystem.mkdir(filePath)) {
snprintf(logBuf, serialLoglength, "CREATE: %s created", param->value().c_str());
loggerNl(serialDebug, logBuf, LOGLEVEL_INFO); loggerNl(serialDebug, logBuf, LOGLEVEL_INFO);
} else { } else {
snprintf(logBuf, serialLoglength, "CREATE: Cannot create %s", asciiFilePath);
snprintf(logBuf, serialLoglength, "CREATE: Cannot create %s", param->value().c_str());
loggerNl(serialDebug, logBuf, LOGLEVEL_ERROR); loggerNl(serialDebug, logBuf, LOGLEVEL_ERROR);
} }
} else { } else {
@ -3856,14 +3896,14 @@ void explorerHandleRenameRequest(AsyncWebServerRequest *request) {
convertUtf8ToAscii(dstPath->value(), dstFullFilePath); convertUtf8ToAscii(dstPath->value(), dstFullFilePath);
if(FSystem.exists(srcFullFilePath)) { if(FSystem.exists(srcFullFilePath)) {
if(FSystem.rename(srcFullFilePath, dstFullFilePath)) { if(FSystem.rename(srcFullFilePath, dstFullFilePath)) {
snprintf(logBuf, serialLoglength, "RENAME: %s renamed to %s", srcFullFilePath, dstFullFilePath);
snprintf(logBuf, serialLoglength, "RENAME: %s renamed to %s", srcPath->value().c_str(), dstPath->value().c_str());
loggerNl(serialDebug, logBuf, LOGLEVEL_INFO); loggerNl(serialDebug, logBuf, LOGLEVEL_INFO);
} else { } else {
snprintf(logBuf, serialLoglength, "RENAME: Cannot rename %s", srcFullFilePath);
snprintf(logBuf, serialLoglength, "RENAME: Cannot rename %s", srcPath->value().c_str());
loggerNl(serialDebug, logBuf, LOGLEVEL_ERROR); loggerNl(serialDebug, logBuf, LOGLEVEL_ERROR);
} }
} else { } else {
snprintf(logBuf, serialLoglength, "RENAME: Path %s does not exist", srcFullFilePath);
snprintf(logBuf, serialLoglength, "RENAME: Path %s does not exist", srcPath->value().c_str());
loggerNl(serialDebug, logBuf, LOGLEVEL_ERROR); loggerNl(serialDebug, logBuf, LOGLEVEL_ERROR);
} }
} else { } else {
@ -3880,15 +3920,15 @@ void explorerHandleAudioRequest(AsyncWebServerRequest *request) {
AsyncWebParameter *param; AsyncWebParameter *param;
String playModeString; String playModeString;
uint32_t playMode; uint32_t playMode;
char asciiFilePath[256];
char filePath[256];
if(request->hasParam("path") && request->hasParam("playmode")) { if(request->hasParam("path") && request->hasParam("playmode")) {
param = request->getParam("path"); param = request->getParam("path");
convertUtf8ToAscii(param->value(), asciiFilePath);
convertUtf8ToAscii(param->value(), filePath);
param = request->getParam("playmode"); param = request->getParam("playmode");
playModeString = param->value(); playModeString = param->value();
playMode = atoi(playModeString.c_str()); playMode = atoi(playModeString.c_str());
trackQueueDispatcher(asciiFilePath,0,playMode,0);
trackQueueDispatcher(filePath,0,playMode,0);
} else { } else {
loggerNl(serialDebug, "AUDIO: No path variable set", LOGLEVEL_ERROR); loggerNl(serialDebug, "AUDIO: No path variable set", LOGLEVEL_ERROR);
} }

Loading…
Cancel
Save