Return list of dirs and files from OPDS request
This commit is contained in:
57
src/main.c
57
src/main.c
@@ -25,6 +25,27 @@ static enum MHD_Result send_response(struct MHD_Connection *connection, int stat
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool is_dir;
|
||||||
|
SV name;
|
||||||
|
} Library_Entry;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Library_Entry *elems;
|
||||||
|
size_t count;
|
||||||
|
size_t capacity;
|
||||||
|
} Library_Entries;
|
||||||
|
|
||||||
|
int compare_library_entries(const void *a, const void *b) {
|
||||||
|
Library_Entry lea = *(Library_Entry*)a;
|
||||||
|
Library_Entry leb = *(Library_Entry*)b;
|
||||||
|
|
||||||
|
if (lea.is_dir && !leb.is_dir) return -1;
|
||||||
|
if (!lea.is_dir && leb.is_dir) return 1;
|
||||||
|
|
||||||
|
return noh_sv_compare(lea.name, leb.name);
|
||||||
|
}
|
||||||
|
|
||||||
static enum MHD_Result handle_opds(struct MHD_Connection *connection, SV url, SV base_path, SV username) {
|
static enum MHD_Result handle_opds(struct MHD_Connection *connection, SV url, SV base_path, SV username) {
|
||||||
Noh_String fs_path = {0};
|
Noh_String fs_path = {0};
|
||||||
noh_string_append_sv(&fs_path, base_path);
|
noh_string_append_sv(&fs_path, base_path);
|
||||||
@@ -38,21 +59,49 @@ static enum MHD_Result handle_opds(struct MHD_Connection *connection, SV url, SV
|
|||||||
|
|
||||||
DIR *dir = opendir(fs_path.elems);
|
DIR *dir = opendir(fs_path.elems);
|
||||||
if (dir) {
|
if (dir) {
|
||||||
noh_log(NOH_INFO, "Exists.");
|
Library_Entries list = {0};
|
||||||
|
|
||||||
noh_arena_save(&temp);
|
noh_arena_save(&temp);
|
||||||
struct dirent *entry = noh_arena_alloc(&temp, sizeof(struct dirent));
|
struct dirent *entry = noh_arena_alloc(&temp, sizeof(struct dirent));
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
while ((entry = readdir(dir)) != NULL) {
|
||||||
(void)entry;
|
SV name = sv(entry->d_name);
|
||||||
noh_log(NOH_INFO, "Entry..");
|
int type = entry->d_type;
|
||||||
|
|
||||||
|
if (type != DT_DIR && type != DT_REG) continue;
|
||||||
|
if (noh_sv_eq(name, sv(".")) || noh_sv_eq(name, sv(".."))) continue;
|
||||||
|
if (type == DT_REG && !noh_sv_ends_with_ci(name, sv(".epub"))) continue;
|
||||||
|
|
||||||
|
Library_Entry le = {
|
||||||
|
.is_dir = type == DT_DIR,
|
||||||
|
.name = noh_sv_copy_cstr(&temp, entry->d_name),
|
||||||
|
};
|
||||||
|
noh_da_append(&list, le);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort entries, folders first, then by name.
|
||||||
|
if (list.count > 1)
|
||||||
|
qsort(list.elems, list.count, sizeof(list.elems[0]), compare_library_entries);
|
||||||
|
|
||||||
|
// Print sorted entries.
|
||||||
|
Noh_String response = {0};
|
||||||
|
for (size_t i = 0; i < list.count; i++) {
|
||||||
|
Library_Entry *le = &list.elems[i];
|
||||||
|
noh_string_append_cstr(&response,
|
||||||
|
noh_arena_sprintf(
|
||||||
|
&temp,
|
||||||
|
"Entry: %s '"Nsv_Fmt"'.\n", le->is_dir ? "Dir" : "File", Nsv_Arg(le->name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return send_response(connection, 200, noh_sv_from_string(&response));
|
||||||
|
|
||||||
|
noh_da_free(&list);
|
||||||
noh_arena_reset(&temp);
|
noh_arena_reset(&temp);
|
||||||
|
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
|
||||||
} else if (errno == ENOENT) {
|
} else if (errno == ENOENT) {
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
return send_response(connection, 404, sv("That directory does not exist."));
|
return send_response(connection, 404, sv(""));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
noh_log(NOH_ERROR, "Opening directory failed.");
|
noh_log(NOH_ERROR, "Opening directory failed.");
|
||||||
|
|||||||
Reference in New Issue
Block a user