Mercurial > paster
changeset 77:fe78b16c694d
pasterd: refactor json utilities
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 16 Mar 2023 15:05:26 +0100 |
parents | 9643962908ab |
children | 9bfe5ce3cc45 |
files | GNUmakefile html/new.html html/search.html json-util.c json-util.h page-index.c page-new.c page-paste.c page-search.c page-static.c themes/default/style.css util.c util.h |
diffstat | 13 files changed, 230 insertions(+), 100 deletions(-) [+] |
line wrap: on
line diff
--- a/GNUmakefile Thu Mar 16 13:35:17 2023 +0100 +++ b/GNUmakefile Thu Mar 16 15:05:26 2023 +0100 @@ -48,6 +48,7 @@ LIBPASTER_SRCS += config.c LIBPASTER_SRCS += database.c LIBPASTER_SRCS += http.c +LIBPASTER_SRCS += json-util.c LIBPASTER_SRCS += log.c LIBPASTER_SRCS += page-download.c LIBPASTER_SRCS += page-fork.c @@ -116,9 +117,9 @@ pasterd: $(LIBPASTER) clean: - rm -f extern/bcc/bcc + rm -f extern/bcc/bcc extern/bcc/bcc.d rm -f $(LIBPASTER) $(LIBPASTER_OBJS) $(LIBPASTER_DEPS) $(LIBPASTER_HTML_OBJS) - rm -f paster pasterd + rm -f paster pasterd pasterd.d rm -f test.db $(TESTS_OBJS) install-paster:
--- a/html/new.html Thu Mar 16 13:35:17 2023 +0100 +++ b/html/new.html Thu Mar 16 15:05:26 2023 +0100 @@ -41,6 +41,5 @@ </table> <textarea id="code" class="textarea" placeholder="What do you want to share?" rows="10" name="code">{{code}}</textarea> - <br> <input class="submit" type="submit" value="paste" /> </form>
--- a/html/search.html Thu Mar 16 13:35:17 2023 +0100 +++ b/html/search.html Thu Mar 16 15:05:26 2023 +0100 @@ -16,7 +16,9 @@ <td>Language</td> <td> <select name="language"> - <option name="{{value}}">{{value}}</option> + {{#languages}} + <option name="{{name}}">{{name}}</option> + {{/languages}} </select> </td> </tr>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/json-util.c Thu Mar 16 15:05:26 2023 +0100 @@ -0,0 +1,75 @@ +/* + * json-util.c -- utilities for JSON + * + * Copyright (c) 2020-2023 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> +#include <string.h> + +#include "json-util.h" +#include "util.h" +#include "paste.h" + +json_t * +ju_languages(const char *selected) +{ + json_t *array, *obj; + + array = json_array(); + + for (size_t i = 0; i < languagesz; ++i) { + if (selected && strcmp(languages[i], selected) == 0) + obj = json_pack("{ss ss}", + "name", languages[i], + "selected", "selected" + ); + else + obj = json_pack("{ss}", "name", languages[i]); + + json_array_append_new(array, obj); + } + + return array; +} + +json_t * +ju_durations(void) +{ + json_t *array = json_array(); + + for (size_t i = 0; i < durationsz; ++i) + json_array_append_new(array, json_pack("{ss}", + "value", durations[i].title) + ); + + return array; +} + +json_t * +ju_date(const struct paste *paste) +{ + assert(paste); + + return json_string(bstrftime("%c", localtime(&paste->timestamp))); +} + +json_t * +ju_expiration(const struct paste *paste) +{ + assert(paste); + + return json_string(ttl(paste->timestamp, paste->duration)); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/json-util.h Thu Mar 16 15:05:26 2023 +0100 @@ -0,0 +1,98 @@ +/* + * json-util.h -- utilities for JSON + * + * Copyright (c) 2020-2023 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef PASTER_PASTER_JSON_UTIL_H +#define PASTER_PASTER_JSON_UTIL_H + +#include <jansson.h> + +struct paste; + +/** + * Create an array of all possible languages supported by the application. If + * the selected argument is not null it will also add a JSON property selected + * (mostly used when rendering an existing paste). + * + * Example of generated schema: + * + * ```javascript + * [ + * { + * "name": "nohighlight" + * } + * { + * "name": "c", + * "selected": "selected" + * } + * { + * "name": "cpp" + * } + * ] + * ``` + * + * \param selected the current selected language (or NULL if none) + * \return a JSON array of objects + */ +json_t * +ju_languages(const char *selected); + +/** + * Create a list of duration in the form: + * + * ```javascript + * [ + * { + * "value": "day" + * } + * { + * "value": "hour" + * } + * ] + * ``` + * + * \return a JSON array of objects + */ +json_t * +ju_durations(void); + +/** + * Create a convenient ISO date string containing the paste creation date. + * + * \pre paste != NULL + * \param paste this paste + * \return a string with an ISO date + */ +json_t * +ju_date(const struct paste *paste); + +/** + * Create a convenient remaining time for the given paste. + * + * Returns strings in the form: + * + * - `2 day(s)` + * - `3 hours(s)` + * + * \pre paste != NULL + * \param paste this paste + * \return a string containing the expiration time + */ +json_t * +ju_expiration(const struct paste *paste); + +#endif /* !PASTER_PASTER_JSON_UTIL_H */
--- a/page-index.c Thu Mar 16 13:35:17 2023 +0100 +++ b/page-index.c Thu Mar 16 15:05:26 2023 +0100 @@ -19,6 +19,7 @@ #include <assert.h> #include "database.h" +#include "json-util.h" #include "page-index.h" #include "page.h" #include "paste.h" @@ -43,18 +44,6 @@ } static inline json_t * -create_date(const struct paste *paste) -{ - return json_string(bstrftime("%c", localtime(&paste->timestamp))); -} - -static inline json_t * -create_expiration(const struct paste *paste) -{ - return json_string(ttl(paste->timestamp, paste->duration)); -} - -static inline json_t * create_pastes(const struct paste *pastes, size_t pastesz) { json_t *array = json_array(); @@ -67,8 +56,8 @@ "id", paste->id, "author", paste->author, "title", paste->title, - "date", create_date(paste), - "expiration", create_expiration(paste) + "date", ju_date(paste), + "expiration", ju_expiration(paste) )); }
--- a/page-new.c Thu Mar 16 13:35:17 2023 +0100 +++ b/page-new.c Thu Mar 16 15:05:26 2023 +0100 @@ -20,23 +20,14 @@ #include <string.h> #include "database.h" -#include "paste.h" +#include "json-util.h" #include "page-new.h" #include "page.h" +#include "paste.h" #include "util.h" #include "html/new.h" -static const struct { - const char *title; - long long int secs; -} durations[] = { - { "day", PASTE_DURATION_DAY }, - { "hour", PASTE_DURATION_HOUR }, - { "week", PASTE_DURATION_WEEK }, - { "month", PASTE_DURATION_MONTH }, -}; - static const struct paste paste_default = { .id = "", .title = "unknown", @@ -48,7 +39,7 @@ static long long int duration(const char *val) { - for (size_t i = 0; i < NELEM(durations); ++i) + for (size_t i = 0; i < durationsz; ++i) if (strcmp(val, durations[i].title) == 0) return durations[i].secs; @@ -119,39 +110,6 @@ paste_finish(&paste); } -static json_t * -create_languages(const struct paste *paste) -{ - json_t *array, *obj; - - array = json_array(); - - for (size_t i = 0; i < languagesz; ++i) { - if (strcmp(languages[i], paste->language) == 0) - obj = json_pack("{ss ss}", - "name", languages[i], - "selected", "selected" - ); - else - obj = json_pack("{ss}", "name", languages[i]); - - json_array_append_new(array, obj); - } - - return array; -} - -static inline json_t * -create_durations(void) -{ - json_t *array = json_array(); - - for (size_t i = 0; i < NELEM(durations); ++i) - json_array_append_new(array, json_pack("{ss}", "value", durations[i].title)); - - return array; -} - void page_new_render(struct kreq *req, const struct paste *paste) { @@ -163,8 +121,8 @@ page(req, KHTTP_200, html_new, json_pack("{ss ss so so ss}", "pagetitle", "paster -- create new paste", "title", paste->title, - "languages", create_languages(paste), - "durations", create_durations(), + "languages", ju_languages(paste->language), + "durations", ju_durations(), "code", paste->code )); }
--- a/page-paste.c Thu Mar 16 13:35:17 2023 +0100 +++ b/page-paste.c Thu Mar 16 15:05:26 2023 +0100 @@ -19,26 +19,14 @@ #include <assert.h> #include "database.h" -#include "paste.h" +#include "json-util.h" #include "page-paste.h" #include "page.h" +#include "paste.h" #include "util.h" #include "html/paste.h" -// TODO: share this. -static inline json_t * -create_date(const struct paste *paste) -{ - return json_string(bstrftime("%c", localtime(&paste->timestamp))); -} - -static inline json_t * -create_expiration(const struct paste *paste) -{ - return json_string(ttl(paste->timestamp, paste->duration)); -} - static inline json_t * create_pagetitle(const struct paste *paste) { @@ -56,8 +44,8 @@ "language", paste->language, "code", paste->code, "public", paste->visible ? "Yes" : "No", - "date", create_date(paste), - "expiration", create_expiration(paste) + "date", ju_date(paste), + "expiration", ju_expiration(paste) ); }
--- a/page-search.c Thu Mar 16 13:35:17 2023 +0100 +++ b/page-search.c Thu Mar 16 15:05:26 2023 +0100 @@ -20,6 +20,7 @@ #include <string.h> #include "database.h" +#include "json-util.h" #include "page-index.h" #include "page-search.h" #include "page.h" @@ -29,22 +30,11 @@ #include "html/search.h" static inline json_t * -create_languages(void) -{ - json_t *array = json_array(); - - for (size_t i = 0; i < languagesz; ++i) - json_array_append_new(array, json_pack("{ss}", "value", languages[i])); - - return array; -} - -static inline json_t * create_root(void) { return json_pack("{ss so}", "pagetitle", "paster -- search", - "languages", create_languages() + "languages", ju_languages(NULL) ); }
--- a/page-static.c Thu Mar 16 13:35:17 2023 +0100 +++ b/page-static.c Thu Mar 16 15:05:26 2023 +0100 @@ -27,6 +27,18 @@ #include "config.h" #include "page.h" +static inline enum kmime +mimetype(const struct kreq *req) +{ + switch (req->mime) { + case KMIME_TEXT_HTML: + case KMIME_TEXT_CSS: + return req->mime; + default: + return KMIME_APP_OCTET_STREAM; + } +} + static void get(struct kreq *req) { @@ -40,7 +52,7 @@ page_status(req, KHTTP_404); else { khttp_head(req, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]); - khttp_head(req, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[req->mime]); + khttp_head(req, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[mimetype(req)]); khttp_head(req, kresps[KRESP_CONTENT_LENGTH], "%llu", (unsigned long long)(st.st_size)); khttp_body(req);
--- a/themes/default/style.css Thu Mar 16 13:35:17 2023 +0100 +++ b/themes/default/style.css Thu Mar 16 15:05:26 2023 +0100 @@ -111,6 +111,7 @@ border: 0; border-radius: 2px; padding: 0.5em; + margin-top: 1em; font-size: medium; }
--- a/util.c Thu Mar 16 13:35:17 2023 +0100 +++ b/util.c Thu Mar 16 15:05:26 2023 +0100 @@ -2,11 +2,11 @@ * util.c -- various utilities * * Copyright (c) 2020-2023 David Demelier <markand@malikania.fr> - * + * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR @@ -30,7 +30,7 @@ #include "util.h" #include "paste.h" -const char *languages[] = { +const char * const languages[] = { "nohighlight", "1c", "abnf", @@ -212,6 +212,15 @@ const size_t languagesz = NELEM(languages); +const struct duration durations[] = { + { "day", PASTE_DURATION_DAY }, + { "hour", PASTE_DURATION_HOUR }, + { "week", PASTE_DURATION_WEEK }, + { "month", PASTE_DURATION_MONTH } +}; + +const size_t durationsz = NELEM(durations); + void die(const char *fmt, ...) {
--- a/util.h Thu Mar 16 13:35:17 2023 +0100 +++ b/util.h Thu Mar 16 15:05:26 2023 +0100 @@ -2,11 +2,11 @@ * util.h -- various utilities * * Copyright (c) 2020-2023 David Demelier <markand@malikania.fr> - * + * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR @@ -27,9 +27,17 @@ struct tm; struct kreq; -extern const char *languages[]; +struct duration { + const char *title; + long long int secs; +}; + +extern const char * const languages[]; extern const size_t languagesz; +extern const struct duration durations[]; +extern const size_t durationsz; + void die(const char *, ...);