#include "../../plugins/FileManager.hpp" #include "../../include/FileAnalyzer.hpp" #include "../../include/QuickMedia.hpp" namespace QuickMedia { // Returns empty string if no extension static const char* get_ext(const std::filesystem::path &path) { const char *path_c = path.c_str(); int len = strlen(path_c); for(int i = len - 1; i >= 0; --i) { if(path_c[i] == '.') return path_c + i; } return ""; } static std::filesystem::file_time_type file_get_filetime_or(const std::filesystem::directory_entry &path, std::filesystem::file_time_type default_value) { try { return path.last_write_time(); } catch(const std::filesystem::filesystem_error &err) { return default_value; } } PluginResult FileManagerPage::submit(const std::string &title, const std::string &url, std::vector &result_tabs) { (void)url; std::filesystem::path new_path; if(title == "..") new_path = current_dir.parent_path(); else new_path = current_dir / title; if(std::filesystem::is_regular_file(new_path)) { program->select_file(new_path); return PluginResult::OK; } if(!std::filesystem::is_directory(new_path)) return PluginResult::ERR; current_dir = std::move(new_path); BodyItems result_items; PluginResult result = get_files_in_directory(result_items); if(result != PluginResult::OK) return result; auto body = create_body(); body->items = std::move(result_items); result_tabs.push_back(Tab{std::move(body), nullptr, nullptr}); return PluginResult::OK; } bool FileManagerPage::set_current_directory(const std::string &path) { if(!std::filesystem::is_directory(path)) return false; current_dir = path; return true; } PluginResult FileManagerPage::get_files_in_directory(BodyItems &result_items) { std::vector paths; try { for(auto &p : std::filesystem::directory_iterator(current_dir)) { paths.push_back(p); } } catch(const std::filesystem::filesystem_error &err) { fprintf(stderr, "Failed to list files in directory %s, error: %s\n", current_dir.c_str(), err.what()); return PluginResult::ERR; } std::sort(paths.begin(), paths.end(), [](const std::filesystem::directory_entry &path1, std::filesystem::directory_entry &path2) { return file_get_filetime_or(path1, std::filesystem::file_time_type::min()) > file_get_filetime_or(path2, std::filesystem::file_time_type::min()); }); if(current_dir != "/") { auto parent_item = BodyItem::create(".."); result_items.push_back(std::move(parent_item)); } for(auto &p : paths) { auto body_item = BodyItem::create(p.path().filename().string()); // TODO: Check file magic number instead of extension? const char *ext = get_ext(p.path()); if(p.is_regular_file() && (is_image_ext(ext) || is_video_ext(ext))) { body_item->thumbnail_is_local = true; body_item->thumbnail_url = p.path().string(); } result_items.push_back(std::move(body_item)); } return PluginResult::OK; } }