Reload folder mappings after modifying a mapping.
This commit is contained in:
parent
b5ec78ab41
commit
e1dd004cf5
@ -57,4 +57,5 @@ public:
|
|||||||
String json();
|
String json();
|
||||||
bool process_message(String m);
|
bool process_message(String m);
|
||||||
void queue_command(String cmd);
|
void queue_command(String cmd);
|
||||||
|
void update_playlist_manager();
|
||||||
};
|
};
|
||||||
|
@ -9,11 +9,14 @@ private:
|
|||||||
std::map<String, String> _map;
|
std::map<String, String> _map;
|
||||||
std::map<String, Playlist*> _playlists;
|
std::map<String, Playlist*> _playlists;
|
||||||
std::vector<String> _unmapped_folders;
|
std::vector<String> _unmapped_folders;
|
||||||
|
void _check_for_special_chars(String s);
|
||||||
|
void _save_mapping();
|
||||||
public:
|
public:
|
||||||
PlaylistManager();
|
PlaylistManager();
|
||||||
Playlist* get_playlist_for_id(String id);
|
Playlist* get_playlist_for_id(String id);
|
||||||
Playlist* get_playlist_for_folder(String folder);
|
Playlist* get_playlist_for_folder(String folder);
|
||||||
void dump_ids();
|
void dump_ids();
|
||||||
|
void scan_files();
|
||||||
String json();
|
String json();
|
||||||
bool add_mapping(String id, String folder);
|
bool add_mapping(String id, String folder);
|
||||||
};
|
};
|
||||||
|
@ -123,7 +123,8 @@ void Controller::_check_rfid() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pl==NULL) {
|
if (pl==NULL) {
|
||||||
INFO("Could not find album for id '%s'.", s_uid.c_str());
|
INFO("Could not find album for id '%s'.\n", s_uid.c_str());
|
||||||
|
send_controller_status();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int index;
|
int index;
|
||||||
@ -412,5 +413,11 @@ void Controller::inform_new_client(AsyncWebSocketClient* client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Controller::queue_command(String s) {
|
void Controller::queue_command(String s) {
|
||||||
|
DEBUG("Enqeueing command '%s'.\n", s.c_str());
|
||||||
_cmd_queue = s;
|
_cmd_queue = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Controller::update_playlist_manager() {
|
||||||
|
_pm->scan_files();
|
||||||
|
send_playlist_manager_status();
|
||||||
|
}
|
@ -4,75 +4,97 @@
|
|||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
PlaylistManager::PlaylistManager() {
|
PlaylistManager::PlaylistManager() {
|
||||||
|
scan_files();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlaylistManager::scan_files() {
|
||||||
SPIMaster::select_sd();
|
SPIMaster::select_sd();
|
||||||
|
std::vector<String> folders;
|
||||||
File root = SD.open("/");
|
File root = SD.open("/");
|
||||||
File entry;
|
File entry;
|
||||||
while (entry = root.openNextFile()) {
|
while (entry = root.openNextFile()) {
|
||||||
String foldername = entry.name();
|
String foldername = entry.name();
|
||||||
if (!entry.isDirectory() || foldername.startsWith("/.")) continue;
|
if (foldername.startsWith("/.")) continue;
|
||||||
// Remove trailing slash
|
|
||||||
foldername.remove(foldername.length());
|
foldername.remove(foldername.length());
|
||||||
DEBUG(" Checking %s...\n", foldername.c_str());
|
folders.push_back(foldername);
|
||||||
bool non_ascii_chars = false;
|
_check_for_special_chars(foldername);
|
||||||
for(int i=0; i<foldername.length(); i++) {
|
entry.close();
|
||||||
char c = foldername.charAt(i);
|
}
|
||||||
if (c < 0x20 || c >= 0x7F) {
|
|
||||||
non_ascii_chars = true;
|
_map.clear();
|
||||||
|
if (!SD.exists("/_mapping.txt\n")) {
|
||||||
|
ERROR("WARNING: File /_mapping.txt not found.\n");
|
||||||
|
} else {
|
||||||
|
File f = SD.open("/_mapping.txt");
|
||||||
|
DEBUG("Reading /_mapping.txt...\n");
|
||||||
|
while (f.available()) {
|
||||||
|
char buffer[512];
|
||||||
|
size_t pos = f.readBytesUntil('\n', buffer, 511);
|
||||||
|
buffer[pos] = '\0';
|
||||||
|
|
||||||
|
String data = buffer;
|
||||||
|
uint8_t eq = data.indexOf('=');
|
||||||
|
if (eq>0 && eq<data.length()-1) {
|
||||||
|
String rfid_id = data.substring(0, eq);
|
||||||
|
String folder = data.substring(eq + 1);
|
||||||
|
TRACE(" Adding mapping: %s=>%s\n", rfid_id.c_str(), folder.c_str());
|
||||||
|
_map[rfid_id] = folder;
|
||||||
|
|
||||||
|
bool found=false;
|
||||||
|
for (String f: folders) {
|
||||||
|
if (f.equals(folder)) {
|
||||||
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (non_ascii_chars) {
|
if (!found) {
|
||||||
ERROR("WARNING: Folder '%s' contains non-ascii chars!\n", foldername.c_str());
|
INFO("WARNING: Found mapping for RFID id %s which maps to non-existing folder %s!\n", rfid_id.c_str(), folder.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!SD.exists(foldername + "/ids.txt")) {
|
|
||||||
TRACE("No ids.txt -> checking for media files...\n");
|
|
||||||
|
|
||||||
File file;
|
|
||||||
bool media_files = false;
|
|
||||||
while(file = entry.openNextFile()) {
|
|
||||||
String filename = file.name();
|
|
||||||
filename = filename.substring(foldername.length() + 1);
|
|
||||||
if (!filename.startsWith(".") && filename.endsWith(".mp3")) {
|
|
||||||
media_files = true;
|
|
||||||
}
|
}
|
||||||
file.close();
|
|
||||||
if (media_files) break;
|
|
||||||
}
|
|
||||||
if (media_files) {
|
|
||||||
_unmapped_folders.push_back(foldername);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
File f = SD.open(foldername + "/ids.txt");
|
|
||||||
String buffer = "";
|
|
||||||
if (f.available()) {
|
|
||||||
do {
|
|
||||||
char c = f.read();
|
|
||||||
if (!f.available() && c!='\n' && c!='\r') {
|
|
||||||
buffer.concat(c);
|
|
||||||
c='\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c=='\n' || c=='\r') {
|
|
||||||
if (buffer.length() > 0) {
|
|
||||||
_map[buffer] = foldername;
|
|
||||||
TRACE(" ID %s", buffer.c_str());
|
|
||||||
buffer="";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
buffer.concat(c);
|
|
||||||
}
|
|
||||||
} while(f.available());
|
|
||||||
}
|
}
|
||||||
f.close();
|
f.close();
|
||||||
entry.close();
|
|
||||||
}
|
}
|
||||||
root.close();
|
root.close();
|
||||||
|
|
||||||
|
_unmapped_folders.clear();
|
||||||
|
for (String folder: folders) {
|
||||||
|
bool found = false;
|
||||||
|
for(std::map<String, String>::iterator it = _map.begin(); it != _map.end(); it++) {
|
||||||
|
if (it->second.equals(folder)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
// Checking folder for media files
|
||||||
|
File dir = SD.open(folder);
|
||||||
|
while (entry = dir.openNextFile()) {
|
||||||
|
String filename = entry.name();
|
||||||
|
filename = filename.substring(folder.length() + 1);
|
||||||
|
if (!filename.startsWith(".") && filename.endsWith(".mp3")) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
entry.close();
|
||||||
|
if (found) break;
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
_unmapped_folders.push_back(folder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
SPIMaster::select_sd(false);
|
SPIMaster::select_sd(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlaylistManager::_check_for_special_chars(String s) {
|
||||||
|
for(int i=0; i<s.length(); i++) {
|
||||||
|
char c = s.charAt(i);
|
||||||
|
if (c < 0x20 || c >= 0x7F) {
|
||||||
|
ERROR("WARNING: Folder / file '%s' contains non-ascii chars!\n", s.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Playlist* PlaylistManager::get_playlist_for_id(String id) {
|
Playlist* PlaylistManager::get_playlist_for_id(String id) {
|
||||||
if (!_map.count(id)) return NULL;
|
if (!_map.count(id)) return NULL;
|
||||||
String folder = _map[id];
|
String folder = _map[id];
|
||||||
@ -97,7 +119,7 @@ String PlaylistManager::json() {
|
|||||||
json["_type"] = "playlist_manager";
|
json["_type"] = "playlist_manager";
|
||||||
JsonObject folders = json.createNestedObject("folders");
|
JsonObject folders = json.createNestedObject("folders");
|
||||||
for (std::map<String, String>::iterator it = _map.begin(); it!=_map.end(); it++) {
|
for (std::map<String, String>::iterator it = _map.begin(); it!=_map.end(); it++) {
|
||||||
folders[it->second] = folders[it->first];
|
folders[it->second] = it->first;
|
||||||
}
|
}
|
||||||
JsonArray started = json.createNestedArray("started");
|
JsonArray started = json.createNestedArray("started");
|
||||||
for (std::map<String, Playlist*>::iterator it = _playlists.begin(); it!=_playlists.end(); it++) {
|
for (std::map<String, Playlist*>::iterator it = _playlists.begin(); it!=_playlists.end(); it++) {
|
||||||
@ -112,17 +134,26 @@ String PlaylistManager::json() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool PlaylistManager::add_mapping(String id, String folder) {
|
bool PlaylistManager::add_mapping(String id, String folder) {
|
||||||
DEBUG("Adding Mapping: '%s'=>'%s'\n", id.c_str(), folder.c_str());
|
DEBUG("Adding mapping: %s=>%s\n", id.c_str(), folder.c_str());
|
||||||
if (!SD.exists(folder)) return false;
|
|
||||||
File ids = SD.open(folder + "/ids.txt", "a");
|
|
||||||
String data = "\n";
|
|
||||||
data += id;
|
|
||||||
data += '\n';
|
|
||||||
char* buffer = new char[data.length()];
|
|
||||||
data.toCharArray(buffer, data.length());
|
|
||||||
ids.write((uint8_t *)buffer, data.length());
|
|
||||||
delete buffer;
|
|
||||||
ids.close();
|
|
||||||
_map[id] = folder;
|
_map[id] = folder;
|
||||||
|
_save_mapping();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlaylistManager::_save_mapping() {
|
||||||
|
SPIMaster::select_sd();
|
||||||
|
File f = SD.open("/_mapping.txt", "w");
|
||||||
|
String s;
|
||||||
|
for(std::map<String, String>::iterator it = _map.begin(); it != _map.end(); it++) {
|
||||||
|
s += it->first;
|
||||||
|
s += "=";
|
||||||
|
s += it->second;
|
||||||
|
s += '\n';
|
||||||
|
}
|
||||||
|
unsigned char* buf = new unsigned char[s.length()];
|
||||||
|
s.getBytes(buf, s.length());
|
||||||
|
f.write(buf, s.length()-1);
|
||||||
|
f.close();
|
||||||
|
SPIMaster::select_sd(false);
|
||||||
|
delete buf;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user