Load modified time and extract creation of entry
This commit is contained in:
50
src/main.c
50
src/main.c
@@ -28,6 +28,7 @@ static enum MHD_Result send_response(struct MHD_Connection *connection, int stat
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
bool is_dir;
|
bool is_dir;
|
||||||
SV name;
|
SV name;
|
||||||
|
struct tm modified_at;
|
||||||
} Library_Entry;
|
} Library_Entry;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -46,6 +47,34 @@ int compare_library_entries(const void *a, const void *b) {
|
|||||||
return noh_sv_compare(lea.name, leb.name);
|
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) {
|
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);
|
||||||
@@ -64,32 +93,23 @@ static enum MHD_Result handle_opds(struct MHD_Connection *connection, SV url, SV
|
|||||||
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) {
|
||||||
SV name = sv(entry->d_name);
|
Library_Entry result = {0};
|
||||||
int type = entry->d_type;
|
if (create_entry(entry, fs_path.elems, &result)) noh_da_append(&list, result);
|
||||||
|
|
||||||
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.
|
// Sort entries, folders first, then by name.
|
||||||
if (list.count > 1)
|
if (list.count > 1) qsort(list.elems, list.count, sizeof(list.elems[0]), compare_library_entries);
|
||||||
qsort(list.elems, list.count, sizeof(list.elems[0]), compare_library_entries);
|
|
||||||
|
|
||||||
// Print sorted entries.
|
// Print sorted entries.
|
||||||
Noh_String response = {0};
|
Noh_String response = {0};
|
||||||
|
char *time_buffer = noh_arena_alloc(&temp, 80);
|
||||||
for (size_t i = 0; i < list.count; i++) {
|
for (size_t i = 0; i < list.count; i++) {
|
||||||
Library_Entry *le = &list.elems[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_string_append_cstr(&response,
|
||||||
noh_arena_sprintf(
|
noh_arena_sprintf(
|
||||||
&temp,
|
&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));
|
return send_response(connection, 200, noh_sv_from_string(&response));
|
||||||
|
|||||||
Reference in New Issue
Block a user