diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-07-23 00:44:13 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-09-24 11:03:39 +0200 |
| commit | cb9cb0b83dc90aeee6380cdc4d2fb61d1426939c (patch) | |
| tree | 20d6ce0f4896bd5caf7b9a231adece7f4795ee72 /page.c | |
| parent | b9537b1d1164b9f3fbe704512b1e324c2e37beb5 (diff) | |
| download | slcl-cb9cb0b83dc90aeee6380cdc4d2fb61d1426939c.tar.gz | |
Display thumbnails, if available
Diffstat (limited to 'page.c')
| -rw-r--r-- | page.c | 147 |
1 files changed, 136 insertions, 11 deletions
@@ -101,6 +101,67 @@ end: return ret; } +static int prepare_thumbnail(struct html_node *const n, + const struct stat *const sb, const struct page_resource *const pr, + const char *const name, const char *const sep) +{ + int ret = -1; + struct html_node *img; + struct dynstr abs, rel; + struct stat tsb; + + dynstr_init(&abs); + dynstr_init(&rel); + + if (!S_ISREG(sb->st_mode)) + { + ret = 0; + goto end; + } + else if (!pr->adir || !pr->username) + { + ret = 0; + goto end; + } + else if (dynstr_append(&rel, "/thumbnails/%s%s%s%s", + pr->username, pr->dir + strlen("/user"), sep, name)) + { + fprintf(stderr, "%s: dynstr_append rel failed\n", __func__); + goto end; + } + else if (dynstr_append(&abs, "%s%s", pr->adir, rel.str)) + { + fprintf(stderr, "%s: dynstr_append rel failed\n", __func__); + goto end; + } + else if (stat(abs.str, &tsb)) + { + if (errno == ENOENT) + ret = 0; + else + fprintf(stderr, "%s: stat(2): %s\n", __func__, strerror(errno)); + + goto end; + } + else if (!(img = html_node_add_child(n, "img"))) + { + fprintf(stderr, "%s: html_node_add_child failed\n", __func__); + goto end; + } + else if (html_node_add_attr(img, "src", rel.str)) + { + fprintf(stderr, "%s: html_node_add_attr src failed\n", __func__); + goto end; + } + + ret = 0; + +end: + dynstr_free(&abs); + dynstr_free(&rel); + return ret; +} + static int prepare_name(struct html_node *const n, struct stat *const sb, const char *const dir, const char *const name) { @@ -360,19 +421,19 @@ end: return ret; } -static int add_element(struct html_node *const n, const char *const dir, - const char *const res, const char *const name, const bool chbx, - struct element_stats *const st) +static int add_element(struct html_node *const n, + const struct page_resource *const pr, const char *const name, + const bool chbx, struct element_stats *const st) { int ret = -1; - enum {RM_CHECKBOX, NAME, SIZE, DATE, SHARE, PREVIEW, COLUMNS}; + enum {RM_CHECKBOX, THUMBNAIL, NAME, SIZE, DATE, SHARE, PREVIEW, COLUMNS}; struct html_node *tr, *td[COLUMNS]; struct dynstr path; - const char *const sep = res[strlen(res) - 1] != '/' ? "/" : ""; + const char *const sep = pr->res[strlen(pr->res) - 1] != '/' ? "/" : ""; dynstr_init(&path); - if (dynstr_append(&path, "%s%s%s", res, sep, name)) + if (dynstr_append(&path, "%s%s%s", pr->res, sep, name)) { fprintf(stderr, "%s: dynstr_append failed\n", __func__); goto end; @@ -406,7 +467,12 @@ static int add_element(struct html_node *const n, const char *const dir, fprintf(stderr, "%s: prepare_rm_checkbox failed\n", __func__); goto end; } - else if (prepare_name(td[NAME], &sb, dir, name)) + else if (prepare_thumbnail(td[THUMBNAIL], &sb, pr, name, sep)) + { + fprintf(stderr, "%s: prepare_thumbnail failed\n", __func__); + goto end; + } + else if (prepare_name(td[NAME], &sb, pr->dir, name)) { fprintf(stderr, "%s: prepare_name failed\n", __func__); goto end; @@ -421,12 +487,12 @@ static int add_element(struct html_node *const n, const char *const dir, fprintf(stderr, "%s: prepare_date failed\n", __func__); goto end; } - else if (prepare_share(td[SHARE], &sb, dir, name)) + else if (prepare_share(td[SHARE], &sb, pr->dir, name)) { fprintf(stderr, "%s: prepare_date failed\n", __func__); goto end; } - else if (prepare_preview(td[PREVIEW], &sb, dir, name)) + else if (prepare_preview(td[PREVIEW], &sb, pr->dir, name)) { fprintf(stderr, "%s: prepare_date failed\n", __func__); goto end; @@ -1321,7 +1387,7 @@ static int add_elements(const struct page_resource *const pr, if (!strcmp(name, ".") || (!strcmp(name, "..") && !strcmp(pr->root, pr->res))) continue; - else if (add_element(table, pr->dir, pr->res, name, true, st)) + else if (add_element(table, pr, name, true, st)) { fprintf(stderr, "%s: add_element failed\n", __func__); goto end; @@ -2163,8 +2229,15 @@ static int add_search_results(struct html_node *const n, for (size_t i = 0; i < s->n; i++) { const struct page_search_result *const r = &s->results[i]; + const struct page_resource pr = + { + .dir = "/user/", + .adir = s->adir, + .username = s->username, + .res = s->root + }; - if (add_element(table, "/user/", s->root, r->name, false, NULL)) + if (add_element(table, &pr, r->name, false, NULL)) { fprintf(stderr, "%s: add_element failed\n", __func__); return -1; @@ -2580,3 +2653,55 @@ int page_head_resource(struct http_response *const r, const char *const res) return 0; } + +int page_thumbnail(struct http_response *const r, const char *const res) +{ + int ret = -1; + const int fd = open(res, O_RDONLY); + bool fdopened = false; + struct stat sb; + + if (fd < 0) + { + if (errno == ENOENT) + ret = page_not_found(r); + else + fprintf(stderr, "%s: open(2) %s: %s\n", + __func__, res, strerror(errno)); + + goto end; + } + else if (fstat(fd, &sb)) + { + fprintf(stderr, "%s: fstat(2) %s: %s\n", + __func__, res, strerror(errno)); + goto end; + } + + const mode_t m = sb.st_mode; + + if (!S_ISREG(m)) + { + fprintf(stderr, "%s: only regular files are supported\n", __func__); + ret = 1; + goto end; + } + else if (serve_file(r, &sb, res, true, fd, &fdopened)) + { + fprintf(stderr, "%s: serve_file failed\n", __func__); + goto end; + } + + ret = 0; + +end: + + if (!fdopened && fd >= 0 && close(fd)) + { + fprintf(stderr, "%s: close(2) %s: %s\n", + __func__, res, strerror(errno)); + ret = -1; + } + + return ret; +} |
