From 24c7965d9d0aaf27985d29c5cbb12a4e08ac7d9c Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Sat, 11 Jul 2020 14:04:25 -0400 Subject: Factor out "scope" of pages Use this to keep the search query around and hide network and context from the search results if the scope is already limited. --- contexts.c | 14 +++++++------- events.c | 21 +++++++++------------ html.c | 35 +++++++++++++++++++---------------- networks.c | 4 +++- search.c | 26 +++++++++----------------- server.h | 22 ++++++++++++++++++---- 6 files changed, 65 insertions(+), 57 deletions(-) diff --git a/contexts.c b/contexts.c index d8eb4fd..e17ccfe 100644 --- a/contexts.c +++ b/contexts.c @@ -46,22 +46,22 @@ const char *ContextsQuery = SQL( ); enum kcgi_err pageContexts(struct kreq *req) { - if (!req->fieldmap[Network]) return httpFail(req, KHTTP_400); + struct Scope scope = htmlScope(req); + if (!scope.network) return httpFail(req, KHTTP_400); + enum kcgi_err error = httpHead(req, KHTTP_200, KMIME_TEXT_HTML); if (req->method == KMETHOD_HEAD) return error; - const char *network = req->fieldmap[Network]->parsed.s; - struct khtmlreq html; error = error || khttp_body(req) || khtml_open(&html, req, KHTML_PRETTY) - || htmlHead(&html, network) - || htmlNav(&html, network, NULL); + || htmlHead(&html, scope.network) + || htmlNav(&html, scope); if (error) return error; dbBindInt(stmt.contexts, ":recent", pageRecent); - dbBindText(stmt.contexts, ":network", network); + dbBindText(stmt.contexts, ":network", scope.network); if (pagePublic) dbBindInt(stmt.contexts, ":query", false); enum State { @@ -92,7 +92,7 @@ enum kcgi_err pageContexts(struct kreq *req) { char *href = khttp_urlpart( NULL, NULL, Pages[Events], - Keys[Network].name, network, + Keys[Network].name, scope.network, Keys[Context].name, context, NULL ); diff --git a/events.c b/events.c index 32e94c2..5e332a3 100644 --- a/events.c +++ b/events.c @@ -70,11 +70,8 @@ const char *EventsBeforeQuery = SQL( ); enum kcgi_err pageEvents(struct kreq *req) { - if (!req->fieldmap[Network] || !req->fieldmap[Context]) { - return httpFail(req, KHTTP_400); - } - const char *network = req->fieldmap[Network]->parsed.s; - const char *context = req->fieldmap[Context]->parsed.s; + struct Scope scope = htmlScope(req); + if (!scope.network || !scope.context) return httpFail(req, KHTTP_400); if (!req->fieldmap[After] && !req->fieldmap[Before]) { struct tm *tm = gmtime(&(time_t) { time(NULL) }); @@ -85,8 +82,8 @@ enum kcgi_err pageEvents(struct kreq *req) { char *url = khttp_urlpart( NULL, NULL, Pages[Events], - Keys[Network].name, network, - Keys[Context].name, context, + Keys[Network].name, scope.network, + Keys[Context].name, scope.context, Keys[Before].name, time, NULL ); @@ -106,16 +103,16 @@ enum kcgi_err pageEvents(struct kreq *req) { error = error || khttp_body(req) || khtml_open(&html, req, KHTML_PRETTY) - || htmlHead(&html, context) - || htmlNav(&html, network, context) + || htmlHead(&html, scope.context) + || htmlNav(&html, scope) || khtml_elem(&html, KELEM_TABLE); if (error) return error; sqlite3_stmt *events = stmt.eventsAfter; if (req->fieldmap[Before]) events = stmt.eventsBefore; - dbBindText(events, ":network", network); - dbBindText(events, ":context", context); + dbBindText(events, ":network", scope.network); + dbBindText(events, ":context", scope.context); if (pagePublic) dbBindInt(events, ":query", false); dbBindText(events, ":time", time); dbBindInt(events, ":limit", pageLimit); @@ -132,7 +129,7 @@ enum kcgi_err pageEvents(struct kreq *req) { .target = (const char *)sqlite3_column_text(events, 6), .message = (const char *)sqlite3_column_text(events, 7), }; - error = htmlEvent(&html, event); + error = htmlEvent(&html, scope, event); if (error) break; } if (result != SQLITE_DONE) errx(EX_SOFTWARE, "%s", sqlite3_errmsg(db)); diff --git a/html.c b/html.c index 9386205..562f909 100644 --- a/html.c +++ b/html.c @@ -49,7 +49,7 @@ enum kcgi_err htmlHead(struct khtmlreq *html, const char *title) { } enum kcgi_err -htmlNav(struct khtmlreq *html, const char *network, const char *context) { +htmlNav(struct khtmlreq *html, struct Scope scope) { enum kcgi_err error = 0 || khtml_elem(html, KELEM_NAV) || khtml_elem(html, KELEM_OL) @@ -59,33 +59,33 @@ htmlNav(struct khtmlreq *html, const char *network, const char *context) { || khtml_closeelem(html, 2); if (error) return error; - if (network) { + if (scope.network) { char *href = khttp_urlpart( NULL, NULL, Pages[Contexts], - Keys[Network].name, network, + Keys[Network].name, scope.network, NULL ); if (!href) err(EX_OSERR, "khttp_urlpart"); error = 0 || khtml_elem(html, KELEM_LI) || khtml_attr(html, KELEM_A, KATTR_HREF, href, KATTR__MAX) - || khtml_puts(html, network) + || khtml_puts(html, scope.network) || khtml_closeelem(html, 2); if (error) return error; } - if (network && context) { + if (scope.network && scope.context) { char *href = khttp_urlpart( NULL, NULL, Pages[Events], - Keys[Network].name, network, - Keys[Context].name, context, + Keys[Network].name, scope.network, + Keys[Context].name, scope.context, NULL ); if (!href) err(EX_OSERR, "khttp_urlpart"); error = 0 || khtml_elem(html, KELEM_LI) || khtml_attr(html, KELEM_A, KATTR_HREF, href, KATTR__MAX) - || khtml_puts(html, context) + || khtml_puts(html, scope.context) || khtml_closeelem(html, 2); if (error) return error; } @@ -93,7 +93,8 @@ htmlNav(struct khtmlreq *html, const char *network, const char *context) { char label[256]; snprintf( label, sizeof(label), "Search%s%s", - (network ? " " : ""), (context ? context : network ? network : "") + (scope.network ? " " : ""), + (scope.context ? scope.context : scope.network ? scope.network : "") ); error = 0 @@ -108,6 +109,7 @@ htmlNav(struct khtmlreq *html, const char *network, const char *context) { html, KELEM_INPUT, KATTR_TYPE, "search", KATTR_NAME, Keys[Query].name, + KATTR_VALUE, (scope.query ? scope.query : ""), KATTR__MAX ) || khtml_attr( @@ -118,23 +120,23 @@ htmlNav(struct khtmlreq *html, const char *network, const char *context) { ); if (error) return error; - if (network) { + if (scope.network) { error = khtml_attr( html, KELEM_INPUT, KATTR_TYPE, "hidden", KATTR_NAME, Keys[Network].name, - KATTR_VALUE, network, + KATTR_VALUE, scope.network, KATTR__MAX ); if (error) return error; } - if (context) { + if (scope.context) { error = khtml_attr( html, KELEM_INPUT, KATTR_TYPE, "hidden", KATTR_NAME, Keys[Context].name, - KATTR_VALUE, context, + KATTR_VALUE, scope.context, KATTR__MAX ); if (error) return error; @@ -284,7 +286,8 @@ static const char *Types[TypesLen] = { #undef X }; -enum kcgi_err htmlEvent(struct khtmlreq *html, struct Event event) { +enum kcgi_err +htmlEvent(struct khtmlreq *html, struct Scope scope, struct Event event) { const char *type = (event.type < TypesLen ? Types[event.type] : "unknown"); return 0 || khtml_attrx( @@ -294,8 +297,8 @@ enum kcgi_err htmlEvent(struct khtmlreq *html, struct Event event) { KATTR__MAX ) || eventTime(html, event) - || eventNetwork(html, event) - || eventContext(html, event) + || (scope.network ? 0 : eventNetwork(html, event)) + || (scope.context ? 0 : eventContext(html, event)) || eventNick(html, event) || eventMessage(html, event) || khtml_closeelem(html, 1); diff --git a/networks.c b/networks.c index 7f974c4..74b9ea2 100644 --- a/networks.c +++ b/networks.c @@ -44,6 +44,8 @@ const char *NetworksQuery = SQL( ); enum kcgi_err pageNetworks(struct kreq *req) { + struct Scope scope = {0}; + enum kcgi_err error = httpHead(req, KHTTP_200, KMIME_TEXT_HTML); if (req->method == KMETHOD_HEAD) return error; @@ -52,7 +54,7 @@ enum kcgi_err pageNetworks(struct kreq *req) { || khttp_body(req) || khtml_open(&html, req, KHTML_PRETTY) || htmlHead(&html, "Litterbox") - || htmlNav(&html, NULL, NULL); + || htmlNav(&html, scope); if (error) return error; dbBindInt(stmt.networks, ":recent", pageRecent); diff --git a/search.c b/search.c index 767081b..6fba589 100644 --- a/search.c +++ b/search.c @@ -46,20 +46,12 @@ const char *SearchQuery = SQL( ); enum kcgi_err pageSearch(struct kreq *req) { - if (!req->fieldmap[Query]) { - return httpFail(req, KHTTP_400); - } - if (req->fieldmap[Context] && !req->fieldmap[Network]) { - return httpFail(req, KHTTP_400); - } - const char *query = req->fieldmap[Query]->parsed.s; + struct Scope scope = htmlScope(req); + if (!scope.query) return httpFail(req, KHTTP_400); + if (scope.context && !scope.network) return httpFail(req, KHTTP_400); int64_t offset = 0; - const char *network = NULL; - const char *context = NULL; if (req->fieldmap[Offset]) offset = req->fieldmap[Offset]->parsed.i; - if (req->fieldmap[Network]) network = req->fieldmap[Network]->parsed.s; - if (req->fieldmap[Context]) context = req->fieldmap[Context]->parsed.s; enum kcgi_err error = httpHead(req, KHTTP_200, KMIME_TEXT_HTML); if (req->method == KMETHOD_HEAD) return error; @@ -68,16 +60,16 @@ enum kcgi_err pageSearch(struct kreq *req) { error = error || khttp_body(req) || khtml_open(&html, req, KHTML_PRETTY) - || htmlHead(&html, query) - || htmlNav(&html, network, context) + || htmlHead(&html, scope.query) + || htmlNav(&html, scope) || khtml_elem(&html, KELEM_TABLE); if (error) return error; dbBindText(stmt.search, ":highlight", "\26"); - dbBindText(stmt.search, ":network", network); - dbBindText(stmt.search, ":context", context); + dbBindText(stmt.search, ":network", scope.network); + dbBindText(stmt.search, ":context", scope.context); if (pagePublic) dbBindInt(stmt.search, ":query", false); - dbBindText(stmt.search, ":search", query); + dbBindText(stmt.search, ":search", scope.query); dbBindInt(stmt.search, ":limit", pageLimit); dbBindInt(stmt.search, ":offset", offset); @@ -95,7 +87,7 @@ enum kcgi_err pageSearch(struct kreq *req) { .target = (const char *)sqlite3_column_text(stmt.search, 8), .message = (const char *)sqlite3_column_text(stmt.search, 9), }; - error = htmlEvent(&html, event); + error = htmlEvent(&html, scope, event); if (error) break; } if (result != SQLITE_DONE) errx(EX_SOFTWARE, "%s", sqlite3_errmsg(db)); diff --git a/server.h b/server.h index 502e228..318d103 100644 --- a/server.h +++ b/server.h @@ -171,10 +171,24 @@ static inline enum kcgi_err httpFail(struct kreq *req, enum khttp http) { || khttp_printf(req, "%s\n", khttps[http]); } +struct Scope { + const char *network; + const char *context; + const char *query; +}; + +static inline struct Scope htmlScope(struct kreq *req) { + struct Scope s = {0}; + if (req->fieldmap[Network]) s.network = req->fieldmap[Network]->parsed.s; + if (req->fieldmap[Context]) s.context = req->fieldmap[Context]->parsed.s; + if (req->fieldmap[Query]) s.query = req->fieldmap[Query]->parsed.s; + return s; +} + extern const char *htmlStylesheet; enum kcgi_err htmlHead(struct khtmlreq *html, const char *title); -enum kcgi_err htmlNav( - struct khtmlreq *html, const char *network, const char *context -); +enum kcgi_err htmlNav(struct khtmlreq *html, struct Scope scope); enum kcgi_err htmlFooter(struct khtmlreq *html); -enum kcgi_err htmlEvent(struct khtmlreq *html, struct Event event); +enum kcgi_err htmlEvent( + struct khtmlreq *html, struct Scope scope, struct Event event +); -- cgit 1.4.1