From c71af590d87ff5e2483b7828f4903153ce956e83 Mon Sep 17 00:00:00 2001 From: ThoNohT Date: Fri, 15 May 2026 11:33:49 +0200 Subject: [PATCH] Load modified time and extract creation of entry --- src/main.c | 50 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/main.c b/src/main.c index f545688..9c497f0 100644 --- a/src/main.c +++ b/src/main.c @@ -28,6 +28,7 @@ static enum MHD_Result send_response(struct MHD_Connection *connection, int stat typedef struct { bool is_dir; SV name; + struct tm modified_at; } Library_Entry; typedef struct { @@ -46,6 +47,34 @@ int compare_library_entries(const void *a, const void *b) { return noh_sv_compare(lea.name, leb.name); } +/** + * Creates a Library entry from a dirent structure. + */ +bool create_entry(struct dirent *dir_entry, const char *parent_path, Library_Entry *result) { + SV name = sv(dir_entry->d_name); + int type = dir_entry->d_type; + + // Check if the entry is relevant. + if (type != DT_DIR && type != DT_REG) return false; + if (noh_sv_eq(name, sv(".")) || noh_sv_eq(name, sv(".."))) return false; + if (type == DT_REG && !noh_sv_ends_with_ci(name, sv(".epub"))) return false; + + // Allocate and populate library entry. + result->is_dir = type == DT_DIR; + result->name = noh_sv_copy_cstr(&temp, dir_entry->d_name); + + // Load modified time. + struct stat attr; + if (stat(noh_arena_sprintf(&temp, "%s/"Nsv_Fmt, parent_path, Nsv_Arg(name)), &attr) == 0) { + struct tm *timeinfo = localtime(&attr.st_mtime); + result->modified_at = *timeinfo; + } else { + result->modified_at = (struct tm){0}; + } + + return true; +} + static enum MHD_Result handle_opds(struct MHD_Connection *connection, SV url, SV base_path, SV username) { Noh_String fs_path = {0}; noh_string_append_sv(&fs_path, base_path); @@ -64,32 +93,23 @@ static enum MHD_Result handle_opds(struct MHD_Connection *connection, SV url, SV noh_arena_save(&temp); struct dirent *entry = noh_arena_alloc(&temp, sizeof(struct dirent)); while ((entry = readdir(dir)) != NULL) { - SV name = sv(entry->d_name); - 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); + Library_Entry result = {0}; + if (create_entry(entry, fs_path.elems, &result)) noh_da_append(&list, result); } // Sort entries, folders first, then by name. - if (list.count > 1) - qsort(list.elems, list.count, sizeof(list.elems[0]), compare_library_entries); + if (list.count > 1) qsort(list.elems, list.count, sizeof(list.elems[0]), compare_library_entries); // Print sorted entries. Noh_String response = {0}; + char *time_buffer = noh_arena_alloc(&temp, 80); for (size_t i = 0; i < list.count; i++) { Library_Entry *le = &list.elems[i]; + strftime(time_buffer, 80, "%Y-%m-%d %H:%M:%S", &le->modified_at); noh_string_append_cstr(&response, noh_arena_sprintf( &temp, - "Entry: %s '"Nsv_Fmt"'.\n", le->is_dir ? "Dir" : "File", Nsv_Arg(le->name))); + "Entry: %s '"Nsv_Fmt"' (modified at %s).\n", le->is_dir ? "Dir" : "File", Nsv_Arg(le->name), time_buffer)); } return send_response(connection, 200, noh_sv_from_string(&response));