fixed some crashes, html..
This commit is contained in:
parent
571a1c5c39
commit
a1d486dd2d
|
|
@ -119,7 +119,10 @@ void DirectoryNode::buildDirectoryTree(const char *currentPath)
|
|||
}
|
||||
else if (String(entry.name()).endsWith(".mp3")||String(entry.name()).endsWith(".MP3"))
|
||||
{
|
||||
mp3Files.push_back(entry.name());
|
||||
String fullPath = String(currentPath);
|
||||
if (!fullPath.endsWith("/")) fullPath += "/";
|
||||
fullPath += entry.name();
|
||||
mp3Files.push_back(fullPath);
|
||||
ids.push_back(getNextId());
|
||||
}
|
||||
entry.close();
|
||||
|
|
@ -182,8 +185,7 @@ void DirectoryNode::advanceToFirstMP3InThisNode()
|
|||
|
||||
DirectoryNode *DirectoryNode::advanceToMP3(const uint16_t id)
|
||||
{
|
||||
|
||||
|
||||
// First check MP3 files in this directory
|
||||
for (size_t i = 0; i < ids.size(); i++)
|
||||
{
|
||||
if (id == ids[i])
|
||||
|
|
@ -195,62 +197,85 @@ DirectoryNode *DirectoryNode::advanceToMP3(const uint16_t id)
|
|||
}
|
||||
}
|
||||
|
||||
// Recursively search subdirectories
|
||||
for (auto subdir : subdirectories)
|
||||
{
|
||||
// Check if the ID matches a subdirectory ID
|
||||
if (subdir->getId() == id)
|
||||
{
|
||||
subdir->advanceToFirstMP3InThisNode();
|
||||
return subdir;
|
||||
}
|
||||
|
||||
// Have each subdirectory advance its song
|
||||
for (size_t i = 0; i < subdir->ids.size(); i++)
|
||||
// Recursively search in subdirectory
|
||||
DirectoryNode* result = subdir->advanceToMP3(id);
|
||||
if (result != nullptr && result->getCurrentPlaying() != nullptr)
|
||||
{
|
||||
if (id == subdir->ids[i])
|
||||
{
|
||||
// Found the current MP3 file
|
||||
subdir->currentPlaying = &subdir->mp3Files[i];
|
||||
subdir->currentPlayingId = id;
|
||||
return subdir;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, there were no MP3 files or subdirectories left to check
|
||||
currentPlaying = nullptr;
|
||||
Serial.println("no more nodes found");
|
||||
return this;
|
||||
// If we get here, no song with this ID was found
|
||||
Serial.println("advanceToMP3: No song found for ID: " + String(id));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DirectoryNode *DirectoryNode::advanceToMP3(const String *currentGlobal)
|
||||
{
|
||||
if (currentGlobal == nullptr) {
|
||||
Serial.println("advanceToMP3: currentGlobal is null");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Check if the input is an absolute path (starts with '/') or just a filename
|
||||
bool isAbsolutePath = currentGlobal->startsWith("/");
|
||||
|
||||
// First, check MP3 files in this directory
|
||||
for (size_t i = 0; i < mp3Files.size(); i++)
|
||||
{
|
||||
if (isAbsolutePath) {
|
||||
// For absolute paths, do exact match
|
||||
if (*currentGlobal == mp3Files[i])
|
||||
{
|
||||
setCurrentPlaying(&mp3Files[i]);
|
||||
return this;
|
||||
}
|
||||
} else {
|
||||
// For filenames, extract filename from full path and compare
|
||||
String filename = mp3Files[i];
|
||||
int lastSlash = filename.lastIndexOf('/');
|
||||
if (lastSlash != -1) {
|
||||
filename = filename.substring(lastSlash + 1);
|
||||
}
|
||||
if (*currentGlobal == filename)
|
||||
{
|
||||
setCurrentPlaying(&mp3Files[i]);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively search subdirectories
|
||||
for (auto subdir : subdirectories)
|
||||
{
|
||||
if (subdir->getName() == *currentGlobal)
|
||||
// Check if the string matches a directory name (only for non-absolute paths)
|
||||
if (!isAbsolutePath && subdir->getName() == *currentGlobal)
|
||||
{
|
||||
subdir->advanceToFirstMP3InThisNode();
|
||||
return subdir;
|
||||
}
|
||||
|
||||
// Have each subdirectory advance its song
|
||||
for (size_t i = 0; i < subdir->mp3Files.size(); i++)
|
||||
// Recursively search in subdirectory
|
||||
DirectoryNode* result = subdir->advanceToMP3(currentGlobal);
|
||||
if (result != nullptr && result->getCurrentPlaying() != nullptr)
|
||||
{
|
||||
if (*currentGlobal == subdir->mp3Files[i])
|
||||
{
|
||||
// Found the current MP3 file
|
||||
if (i < subdir->mp3Files.size() - 1)
|
||||
{
|
||||
subdir->setCurrentPlaying(&subdir->mp3Files[i]);
|
||||
return subdir;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, there were no MP3 files or subdirectories left to check
|
||||
currentPlaying = nullptr;
|
||||
Serial.println("no more nodes found");
|
||||
return this;
|
||||
// If we get here, no matching song was found
|
||||
Serial.println("advanceToMP3: No song found for: " + *currentGlobal);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -466,16 +491,7 @@ String DirectoryNode::getCurrentPlayingFilePath() const
|
|||
{
|
||||
if (currentPlaying != nullptr)
|
||||
{
|
||||
String filePath = name;
|
||||
if (!filePath.startsWith("/")) {
|
||||
filePath = "/"+filePath;
|
||||
}
|
||||
if (!filePath.endsWith("/"))
|
||||
{
|
||||
filePath += "/";
|
||||
}
|
||||
filePath += *currentPlaying;
|
||||
return filePath;
|
||||
return *currentPlaying;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
|
|
|||
122
src/main.cpp
122
src/main.cpp
|
|
@ -303,24 +303,41 @@ void playSongById(uint16_t id, uint32_t continueSeconds = 0)
|
|||
currentNode = rootNode.advanceToMP3(id);
|
||||
|
||||
if (currentNode == nullptr) {
|
||||
Serial.println("No node found for ID: " + String(id));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the current playing song is valid
|
||||
if (currentNode->getCurrentPlaying() == nullptr) {
|
||||
currentNode = nullptr;
|
||||
Serial.println("No song found for ID: " + String(id));
|
||||
return;
|
||||
}
|
||||
|
||||
String mp3File = currentNode->getCurrentPlayingFilePath();
|
||||
Serial.print("playing by id: ");
|
||||
Serial.print(id);Serial.print(" ");Serial.println(continueSeconds);
|
||||
|
||||
Serial.println(mp3File.c_str());
|
||||
deactivateRFID();
|
||||
activateSD();
|
||||
|
||||
if (currentNode != nullptr && currentNode->getCurrentPlaying()==nullptr) {
|
||||
if (mp3File.length() == 0) {
|
||||
currentNode = nullptr;
|
||||
Serial.println("no node by id found, exiting playSongById");
|
||||
Serial.println("Empty file path for ID: " + String(id));
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Playing by ID: ");
|
||||
Serial.print(id);
|
||||
Serial.print(" ");
|
||||
Serial.println(continueSeconds);
|
||||
Serial.println(mp3File.c_str());
|
||||
|
||||
deactivateRFID();
|
||||
activateSD();
|
||||
|
||||
if (!playFile(mp3File.c_str())) {
|
||||
Serial.println("Failed to play file: " + mp3File);
|
||||
currentNode = nullptr;
|
||||
activateRFID();
|
||||
deactivateSD();
|
||||
return;
|
||||
}
|
||||
|
||||
playFile(mp3File.c_str());
|
||||
if (continueSeconds != 0) {
|
||||
audio.setAudioPlayPosition(continueSeconds);
|
||||
}
|
||||
|
|
@ -330,12 +347,45 @@ void playSongById(uint16_t id, uint32_t continueSeconds = 0)
|
|||
|
||||
void playSongByName(String song)
|
||||
{
|
||||
if (song.length() == 0) {
|
||||
Serial.println("Empty song name provided");
|
||||
return;
|
||||
}
|
||||
|
||||
currentNode = rootNode.advanceToMP3(&song);
|
||||
if (currentNode == nullptr) {
|
||||
Serial.println("No node found for song: " + song);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the current playing song is valid
|
||||
if (currentNode->getCurrentPlaying() == nullptr) {
|
||||
currentNode = nullptr;
|
||||
Serial.println("No song found for name: " + song);
|
||||
return;
|
||||
}
|
||||
|
||||
String mp3File = currentNode->getCurrentPlayingFilePath();
|
||||
Serial.println(mp3File.c_str());
|
||||
if (mp3File.length() == 0) {
|
||||
currentNode = nullptr;
|
||||
Serial.println("Empty file path for song: " + song);
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.println("Playing song: " + mp3File);
|
||||
deactivateRFID();
|
||||
activateSD();
|
||||
playFile(mp3File.c_str());
|
||||
|
||||
if (!playFile(mp3File.c_str())) {
|
||||
Serial.println("Failed to play file: " + mp3File);
|
||||
currentNode = nullptr;
|
||||
activateRFID();
|
||||
deactivateSD();
|
||||
return;
|
||||
}
|
||||
|
||||
activateRFID();
|
||||
deactivateSD();
|
||||
}
|
||||
|
||||
void playSongByPath(String path)
|
||||
|
|
@ -345,13 +395,23 @@ void playSongByPath(String path)
|
|||
|
||||
void playSongByRFID(String id)
|
||||
{
|
||||
auto songit = rfid_map.find(id);
|
||||
if (songit==rfid_map.end()) {
|
||||
Serial.println("song for uid not found.");
|
||||
if (id.length() == 0) {
|
||||
Serial.println("Empty RFID ID provided");
|
||||
return;
|
||||
}
|
||||
Serial.println("searching for ");
|
||||
Serial.println(songit->second);
|
||||
|
||||
auto songit = rfid_map.find(id);
|
||||
if (songit == rfid_map.end()) {
|
||||
Serial.println("Song for UID not found: " + id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (songit->second.length() == 0) {
|
||||
Serial.println("Empty song name mapped to RFID: " + id);
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.println("Searching for song: " + songit->second);
|
||||
playSongByName(songit->second);
|
||||
}
|
||||
|
||||
|
|
@ -517,7 +577,7 @@ void editMapping(AsyncWebServerRequest *request) {
|
|||
}
|
||||
}
|
||||
|
||||
std::map<String, String> readDataFromFile(const char *filename) {
|
||||
std::map<String, String> readDataFromFile(String filename) {
|
||||
|
||||
File file = SD.open(filename);
|
||||
|
||||
|
|
@ -530,6 +590,7 @@ std::map<String, String> readDataFromFile(const char *filename) {
|
|||
// Extract key and value
|
||||
String key = line.substring(0, separatorIndex).c_str();
|
||||
String value = line.substring(separatorIndex + 1).c_str();
|
||||
Serial.println("found rfid mapping for "+value);
|
||||
// Add key-value pair to the map
|
||||
rfid_map[key] = value;
|
||||
}
|
||||
|
|
@ -549,6 +610,29 @@ String processor(const String &var)
|
|||
{
|
||||
return rootNode.getDirectoryStructureHTML();
|
||||
}
|
||||
|
||||
if (var == "MAPPING") {
|
||||
auto htmlEscape = [](const String& s) -> String {
|
||||
String out;
|
||||
for (size_t i = 0; i < s.length(); ++i) {
|
||||
char c = s[i];
|
||||
if (c == '&') out += "&";
|
||||
else if (c == '<') out += "";
|
||||
else if (c == '>') out += "";
|
||||
else if (c == '"') out += "";
|
||||
else if (c == '\'') out += "";
|
||||
else out += c;
|
||||
}
|
||||
return out;
|
||||
};
|
||||
String html = "<table style='width:100%;border-collapse:collapse;'><tr><th style='border:1px solid #ccc;padding:4px;'>RFID</th><th style='border:1px solid #ccc;padding:4px;'>Song</th></tr>";
|
||||
for (const auto& pair : rfid_map) {
|
||||
html += "<tr><td style='border:1px solid #ccc;padding:4px;'>" + htmlEscape(pair.first) + "</td><td style='border:1px solid #ccc;padding:4px;'>" + htmlEscape(pair.second) + "</td></tr>";
|
||||
}
|
||||
html += "</table>";
|
||||
return html;
|
||||
}
|
||||
|
||||
return String(); // Return empty string instead of creating new String
|
||||
}
|
||||
|
||||
|
|
@ -747,7 +831,7 @@ void setup()
|
|||
rootNode.buildDirectoryTree("/");
|
||||
rootNode.printDirectoryTree();
|
||||
|
||||
readDataFromFile(mapping_file.c_str());
|
||||
readDataFromFile(getSysDir(mapping_file));
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,7 @@
|
|||
<body>
|
||||
<h1>🎵 HannaBox 🎵</h1>
|
||||
<span id="state"></span><br/><br/>
|
||||
<span id="voltage"></span><br/>
|
||||
<span id="uid"></span><br/>
|
||||
<span id="heap"></span><br/>
|
||||
|
||||
|
||||
<div>
|
||||
<button class="prev-button" onclick="simpleGetCall('previous');"></button>
|
||||
|
|
@ -42,11 +40,13 @@
|
|||
|
||||
|
||||
|
||||
<button id="toggleFileManagerButton" class="action-btn" onclick="toggleFileManager()">Toggle File Manager</button>
|
||||
<button id="toggleFileManagerButton" class="action-btn" onclick="toggleFileManager()">Toggle Manager</button>
|
||||
|
||||
<div id="fileManager" style="display:none; margin-top:20px;">
|
||||
<h2>File Manager</h2>
|
||||
|
||||
<h2>Manager</h2>
|
||||
<span id="voltage"></span><br/>
|
||||
<span id="uid"></span><br/>
|
||||
<span id="heap"></span><br/>
|
||||
<h3>Upload File</h3>
|
||||
<form id="uploadForm" class="form" method="POST" action="/upload" enctype="multipart/form-data">
|
||||
<input type="file" name="data" id="uploadFile" accept=".mp3,.wav,.flac,.m4a,.ogg"/>
|
||||
|
|
@ -56,11 +56,13 @@
|
|||
<div class="progress-bar">
|
||||
<div class="progress-fill" id="progressFill"></div>
|
||||
</div>
|
||||
<span id="progressText">0%</span>
|
||||
<span id="progressText">0</span>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h3>Edit RFID Mapping</h3>
|
||||
Hint: Use a folder or filename, not the absolute file path!
|
||||
<div class="form">%MAPPING%</div>
|
||||
<form id="editMappingForm" class="form">
|
||||
<label for="rfid">RFID:</label>
|
||||
<input type="text" id="rfid" name="rfid" required><br>
|
||||
|
|
@ -77,8 +79,9 @@
|
|||
<input type="text" id="moveTo" placeholder="/newname.mp3"/>
|
||||
<button type="button" class="action-btn" onclick="moveFile()">Move/Rename</button>
|
||||
</form>
|
||||
<form class="form">
|
||||
|
||||
<h3>Delete File</h3>
|
||||
<form class="form">
|
||||
<label for="deleteFileName">Filename:</label>
|
||||
<input type="text" id="deleteFileName" placeholder="/song.mp3"/>
|
||||
<button type="button" class="action-btn" onclick="deleteFileOnServer()">Delete</button>
|
||||
|
|
|
|||
Loading…
Reference in New Issue