diff options
author | June McEnroe <june@causal.agency> | 2020-07-12 12:17:44 -0400 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2020-07-12 12:17:44 -0400 |
commit | 7ff6e16e8ccda2433006f949ffc7b1ee5eaf08cf (patch) | |
tree | 03abf9d87da7810b364d27f97f9e541df9c9e46f /events.c | |
parent | Clean up page error handling (diff) | |
download | scooper-7ff6e16e8ccda2433006f949ffc7b1ee5eaf08cf.tar.gz scooper-7ff6e16e8ccda2433006f949ffc7b1ee5eaf08cf.zip |
Reorganize code and add earlier messages link
Diffstat (limited to 'events.c')
-rw-r--r-- | events.c | 96 |
1 files changed, 56 insertions, 40 deletions
diff --git a/events.c b/events.c index e018087..35e2c5b 100644 --- a/events.c +++ b/events.c @@ -15,6 +15,7 @@ */ #include <err.h> +#include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <sysexits.h> @@ -22,32 +23,21 @@ #include "server.h" -static enum kcgi_err redirect(struct kreq *req, struct Scope scope) { - struct tm *tm = gmtime(&(time_t) { time(NULL) }); - if (!tm) err(EX_OSERR, "gmtime"); - - char time[sizeof("0000-00-00T00:00:00")]; - strftime(time, sizeof(time), "%FT%T", tm); - - char *url = khttp_urlpart( - NULL, NULL, Pages[Events], - Keys[Network].name, scope.network, - Keys[Context].name, scope.context, - Keys[Before].name, time, - NULL - ); - enum kcgi_err error = httpRedirect(req, url); - free(url); - return error; +int eventsGap = 3600; +int eventsOverlap = 15; +int eventsLimit = 50; + +static const char *timestamp(time_t time) { + static char stamp[sizeof("0000-00-00T00:00:00")]; + strftime(stamp, sizeof(stamp), "%FT%T", gmtime(&time)); + return stamp; } static enum kcgi_err dateForm(struct khtmlreq *html, struct Scope scope, const char *_time) { struct tm tm = {0}; if (!strptime(_time, "%F", &tm)) { - struct tm *now = gmtime(&(time_t) { time(NULL) }); - if (!now) err(EX_OSERR, "gmtime"); - tm = *now; + tm = *gmtime(&(time_t) { time(NULL) }); } char date[sizeof("0000-00-00")]; strftime(date, sizeof(date), "%F", &tm); @@ -58,20 +48,7 @@ dateForm(struct khtmlreq *html, struct Scope scope, const char *_time) { KATTR_ACTION, Pages[Events], KATTR__MAX ) - || khtml_attr( - html, KELEM_INPUT, - KATTR_TYPE, "hidden", - KATTR_NAME, Keys[Network].name, - KATTR_VALUE, scope.network, - KATTR__MAX - ) - || khtml_attr( - html, KELEM_INPUT, - KATTR_TYPE, "hidden", - KATTR_NAME, Keys[Context].name, - KATTR_VALUE, scope.context, - KATTR__MAX - ) + || htmlScopeFields(html, scope) || khtml_attr( html, KELEM_INPUT, KATTR_TYPE, "date", @@ -134,12 +111,24 @@ const char *EventsBeforeQuery = SQL( ORDER BY time, event; ); -enum kcgi_err pageEvents(struct kreq *req) { - struct Scope scope = htmlScope(req); +enum kcgi_err eventsPage(struct kreq *req) { + struct Scope scope = pageScope(req); if (!scope.network || !scope.context) return httpFail(req, KHTTP_400); + if (!req->fieldmap[After] && !req->fieldmap[Before]) { - return redirect(req, scope); + char *url = khttp_urlpart( + NULL, NULL, Pages[Events], + Keys[Network].name, scope.network, + Keys[Context].name, scope.context, + Keys[Before].name, timestamp(time(NULL)), + NULL + ); + if (!url) err(EX_OSERR, "khttp_urlpart"); + enum kcgi_err error = httpRedirect(req, url); + free(url); + return error; } + const char *time = req->fieldmap[Before] ? req->fieldmap[Before]->parsed.s : req->fieldmap[After]->parsed.s; @@ -164,11 +153,12 @@ enum kcgi_err pageEvents(struct kreq *req) { dbBindText(events, ":network", scope.network); dbBindText(events, ":context", scope.context); dbBindText(events, ":time", time); - dbBindInt(events, ":public", pagePublic); - dbBindInt(events, ":limit", pageLimit); + dbBindInt(events, ":public", contextsPublic); + dbBindInt(events, ":limit", eventsLimit); + int rows; int result; - while (SQLITE_ROW == (result = sqlite3_step(events))) { + for (rows = 0; SQLITE_ROW == (result = sqlite3_step(events)); ++rows) { int i = 0; struct Event event = {0}; event.event = sqlite3_column_int64(events, i++); @@ -179,6 +169,32 @@ enum kcgi_err pageEvents(struct kreq *req) { event.host = sqlite3_column_text(events, i++); event.target = sqlite3_column_text(events, i++); event.message = sqlite3_column_text(events, i++); + + if (!rows) { + char *base = khttp_urlpart( + NULL, NULL, Pages[Events], + Keys[Network].name, scope.network, + Keys[Context].name, scope.context, + Keys[Before].name, timestamp(event.time + eventsOverlap), + NULL + ); + if (!base) err(EX_OSERR, "khttp_urlpart"); + + char *href = NULL; + asprintf(&href, "%s#%" PRId64, base, event.event); + if (!href) err(EX_OSERR, "asprintf"); + free(base); + + error = 0 + || khtml_elem(&html, KELEM_TR) + || khtml_attr(&html, KELEM_TH, KATTR_COLSPAN, "3", KATTR__MAX) + || khtml_attr(&html, KELEM_A, KATTR_HREF, href, KATTR__MAX) + || khtml_puts(&html, "Earlier messages") + || khtml_closeelem(&html, 3); + free(href); + if (error) return error; + } + error = htmlEvent(&html, scope, event); if (error) return error; } |