#include "playlist_manager.h" #include #include "spi_master.h" #include PlaylistManager::PlaylistManager() { SPIMaster::select_sd(); File root = SD.open("/"); File entry; while (entry = root.openNextFile()) { String foldername = entry.name(); if (!entry.isDirectory() || foldername.startsWith("/.")) continue; // Remove trailing slash foldername.remove(foldername.length()); DEBUG(" Checking %s...\n", foldername.c_str()); bool non_ascii_chars = false; for(int i=0; i= 0x7F) { non_ascii_chars = true; break; } } if (non_ascii_chars) { ERROR("WARNING: Folder '%s' contains non-ascii chars!\n", foldername.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(); entry.close(); } root.close(); SPIMaster::select_sd(false); } Playlist* PlaylistManager::get_playlist_for_id(String id) { if (!_map.count(id)) return NULL; String folder = _map[id]; return get_playlist_for_folder(folder); } Playlist* PlaylistManager::get_playlist_for_folder(String folder) { if (!_playlists.count(folder)) { _playlists[folder] = new Playlist(folder); } return _playlists[folder]; } void PlaylistManager::dump_ids() { for (std::map::iterator it = _map.begin(); it!=_map.end(); it++) { INFO(" %s -> %s\n", it->first.c_str(), it->second.c_str()); } } String PlaylistManager::json() { DynamicJsonDocument json(10240); json["_type"] = "playlist_manager"; JsonObject folders = json.createNestedObject("folders"); for (std::map::iterator it = _map.begin(); it!=_map.end(); it++) { folders[it->second] = folders[it->first]; } JsonArray started = json.createNestedArray("started"); for (std::map::iterator it = _playlists.begin(); it!=_playlists.end(); it++) { if (it->second->is_fresh()) continue; started.add(it->first); } JsonArray unmapped = json.createNestedArray("unmapped"); for(String folder : _unmapped_folders) { unmapped.add(folder); } return json.as(); } bool PlaylistManager::add_mapping(String id, String folder) { 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; return true; }