#pragma once #include #include #include #include "rapidjson/document.h" #include "Base64.hpp" #include "Utils.hpp" #include "Constants.h" namespace khofmann { /// /// Exclude . and .. directory /// /// Entry to check /// TRUE if not . or .., FALSE otherwise static int excludeDotDirs(const struct dirent* entry) { return strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0; } /// /// Read a file and return file contents /// /// Path of BASE64 encoded File /// Allocator /// File contents static rapidjson::Value readFile(const char* path, rapidjson::Document::AllocatorType& alloc) { FILE* file = fopen(path, "r"); if (file) { fseek(file, 0, SEEK_END); long fsize = ftell(file); fseek(file, 0, SEEK_SET); char* string = (char*)calloc(sizeof(char), fsize + 1); fread(string, fsize, 1, file); fclose(file); return rapidjson::Value(string, alloc); } return rapidjson::Value("", alloc); } /// /// Enumerate a directory and return list of directories. /// Return tumbnail as BASE64 and page count if present. /// /// Path of directory /// Pointer to files value object /// Allocator /// Offset into file list /// Total numbers of directories static int enumerateDir(const char* path, rapidjson::Value *files, rapidjson::Document::AllocatorType& alloc, int offset) { int count = 0; int numDirs = 0; DIR* d = opendir(path); if (d) { struct dirent **dir; numDirs = scandir(path, &dir, excludeDotDirs, alphasort); if (numDirs == -1) { log(stdout, "Error: %i", (void*)errno); } for (int i = 0; i < numDirs; i++) { if (i >= offset && i < offset + MAX_LIST) { std::string dirPath(path); dirPath += dir[i]->d_name; std::string thumb(dirPath); thumb += "/thumb.bjpg"; FILE* check = fopen(thumb.c_str(), "r"); if (check) { fclose(check); DIR* f; struct dirent* file; f = opendir(dirPath.c_str()); if (f) { log(stdout, "Found file %s\n", dir[i]->d_name); while ((file = readdir(f)) != NULL) { if (file->d_type == DT_REG) { count++; } } rapidjson::Value entry; entry.SetObject(); entry.AddMember("name", rapidjson::Value(dir[i]->d_name, alloc).Move(), alloc); entry.AddMember("pages", count - 1, alloc); entry.AddMember("thumb", readFile(thumb.c_str(), alloc).Move(), alloc); entry.AddMember("type", "file", alloc); files->PushBack(entry.Move(), alloc); } closedir(f); } else { log(stdout, "Found directory %s\n", dir[i]->d_name); rapidjson::Value entry; entry.SetObject(); entry.AddMember("name", rapidjson::Value(dir[i]->d_name, alloc).Move(), alloc); entry.AddMember("type", "directory", alloc); files->PushBack(entry.Move(), alloc); } } free(dir[i]->d_name); } free(dir); } closedir(d); return numDirs; } }