From 85a1f20681b4f28b7e5230ef64c2b59e178ce638 Mon Sep 17 00:00:00 2001 From: Michael McVady Date: Fri, 12 Jan 2024 17:26:24 -0600 Subject: Flesh out search ... --- assets/footer.html | 9 ---- assets/header.html | 12 ----- assets/html_footer.html | 9 ++++ assets/html_header.html | 12 +++++ assets/index_footer.html | 1 - assets/index_header.html | 3 -- assets/index_row.html | 1 - assets/table_footer.html | 1 + assets/table_header.html | 1 + assets/table_row.html | 1 + conf/clog.conf | 9 ++++ src/clog.c | 123 +++++++++++++++++++++++++++++++++++++++-------- src/queries.h | 4 +- 13 files changed, 137 insertions(+), 49 deletions(-) delete mode 100644 assets/footer.html delete mode 100644 assets/header.html create mode 100644 assets/html_footer.html create mode 100644 assets/html_header.html delete mode 100644 assets/index_footer.html delete mode 100644 assets/index_header.html delete mode 100644 assets/index_row.html create mode 100644 assets/table_footer.html create mode 100644 assets/table_header.html create mode 100644 assets/table_row.html diff --git a/assets/footer.html b/assets/footer.html deleted file mode 100644 index 6131a40..0000000 --- a/assets/footer.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/assets/header.html b/assets/header.html deleted file mode 100644 index 0ff3660..0000000 --- a/assets/header.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - -bunkergate.org - - - - - diff --git a/assets/html_footer.html b/assets/html_footer.html new file mode 100644 index 0000000..6131a40 --- /dev/null +++ b/assets/html_footer.html @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/assets/html_header.html b/assets/html_header.html new file mode 100644 index 0000000..0ff3660 --- /dev/null +++ b/assets/html_header.html @@ -0,0 +1,12 @@ + + + + + + +bunkergate.org + + + + + diff --git a/assets/index_footer.html b/assets/index_footer.html deleted file mode 100644 index 000ca4b..0000000 --- a/assets/index_footer.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/assets/index_header.html b/assets/index_header.html deleted file mode 100644 index a768089..0000000 --- a/assets/index_header.html +++ /dev/null @@ -1,3 +0,0 @@ -

clog.bunkergate.org

- - diff --git a/assets/index_row.html b/assets/index_row.html deleted file mode 100644 index c9b9c68..0000000 --- a/assets/index_row.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/assets/table_footer.html b/assets/table_footer.html new file mode 100644 index 0000000..000ca4b --- /dev/null +++ b/assets/table_footer.html @@ -0,0 +1 @@ +
titlecreatedupdated
%s%s%s
diff --git a/assets/table_header.html b/assets/table_header.html new file mode 100644 index 0000000..eded2a7 --- /dev/null +++ b/assets/table_header.html @@ -0,0 +1 @@ + diff --git a/assets/table_row.html b/assets/table_row.html new file mode 100644 index 0000000..c9b9c68 --- /dev/null +++ b/assets/table_row.html @@ -0,0 +1 @@ + diff --git a/conf/clog.conf b/conf/clog.conf index 89e9880..cf870b1 100644 --- a/conf/clog.conf +++ b/conf/clog.conf @@ -35,9 +35,18 @@ domain * { methods get } + route ^/search$ { + handler search_entries + methods get + + validate qs:get query v_text + } + route ^/entries/search$ { handler search_entries methods get + + validate qs:get query v_text } route ^/entries/[a-z0-9\-]+$ { diff --git a/src/clog.c b/src/clog.c index feedd98..5111b06 100644 --- a/src/clog.c +++ b/src/clog.c @@ -35,6 +35,7 @@ struct entry { struct entry_query { char *id; + char *query; struct entry **entries; int num_entries; @@ -52,7 +53,7 @@ static const char * const error_msg[] = { [HTTP_STATUS_INTERNAL_ERROR] = "There was an error processing the request.", // 500 }; -void entry_query_init(struct entry_query *eq, const char *id); +void entry_query_init(struct entry_query *eq, const char *id, const char *query); void entry_query_cleanup(struct entry_query *eq); int validate_uuid(const char *uuid); @@ -77,12 +78,22 @@ int sql_update(const char *id, const char *title, const char *body); static void process_md_output(const MD_CHAR *html, MD_SIZE size, void *buf); static int render_md(const char *in, struct kore_buf *out); -void entry_query_init(struct entry_query *eq, const char *id) { - if (id != NULL) +void entry_query_init(struct entry_query *eq, const char *id, const char *query) { + if (id != NULL) { eq->id = kore_strdup(id); - else + } + else { eq->id = NULL; + } + if (query != NULL) { + eq->query = kore_strdup(query); + } + else { + eq->query = NULL; + } + + // FIXME: define MAX_ENTRIES and LIMIT queries with it. eq->entries = kore_malloc(sizeof(struct entry *) * 100); eq->num_entries = 0; @@ -90,10 +101,16 @@ void entry_query_init(struct entry_query *eq, const char *id) { } void entry_query_cleanup(struct entry_query *eq) { - if (eq->id != NULL) + if (eq->id != NULL) { kore_free((void *) eq->id); + } eq->id = NULL; + if (eq->query != NULL) { + kore_free((void *) eq->query); + } + eq->query = NULL; + for (int i = 0; i < eq->num_entries; i++) { if (eq->entries[i]->id != NULL) kore_free((void *) eq->entries[i]->id); @@ -108,6 +125,7 @@ void entry_query_cleanup(struct entry_query *eq) { kore_free((void *) eq->entries[i]); } kore_free((void *) eq->entries); + eq->entries = NULL; } int validate_uuid(const char *uuid) { @@ -135,7 +153,7 @@ int validate_uuid(const char *uuid) { } int validate_text(struct http_request *req, char *data) { - kore_log(LOG_NOTICE, "v_example_func called %s", data); + kore_log(LOG_NOTICE, "validate_text called with data '%s'", data); return KORE_RESULT_OK; } @@ -148,9 +166,9 @@ int http_ok_resp( const char *body = kore_buf_stringify(content, NULL); http_response_header(req, "content-type", "text/html; charset=utf-8"); - kore_buf_append(resp_buf, asset_header_html, asset_len_header_html); + kore_buf_append(resp_buf, asset_html_header_html, asset_len_html_header_html); kore_buf_append(resp_buf, body, strlen(body)); - kore_buf_append(resp_buf, asset_footer_html, asset_len_footer_html); + kore_buf_append(resp_buf, asset_html_footer_html, asset_len_html_footer_html); http_response(req, status, resp_buf->data, resp_buf->offset); @@ -166,9 +184,9 @@ int http_err_resp( struct kore_buf *resp_buf = kore_buf_alloc(0); http_response_header(req, "content-type", "text/html; charset=utf-8"); - kore_buf_append(resp_buf, asset_header_html, asset_len_header_html); + kore_buf_append(resp_buf, asset_html_header_html, asset_len_html_header_html); kore_buf_appendf(resp_buf, (const char *) asset_error_html, error_msg[status]); - kore_buf_append(resp_buf, asset_footer_html, asset_len_footer_html); + kore_buf_append(resp_buf, asset_html_footer_html, asset_len_html_footer_html); http_response(req, status, resp_buf->data, resp_buf->offset); @@ -192,7 +210,7 @@ int get_index(struct http_request *req) { content = kore_buf_alloc(0); - entry_query_init(&eq, NULL); + entry_query_init(&eq, NULL, NULL); (void) sql_select(&eq); if (eq.status != QUERY_STATUS_OK) { @@ -200,21 +218,24 @@ int get_index(struct http_request *req) { goto out; } + // Write header. + kore_buf_append(content, asset_header_html, asset_len_header_html); + // Write table header. - kore_buf_append(content, asset_index_header_html, asset_len_index_header_html); + kore_buf_append(content, asset_table_header_html, asset_len_table_header_html); // Iterate over entries and render them. for (row = 0; row < eq.num_entries; row++) { // Append rendered MD entry. kore_buf_appendf( content, - (const char *) asset_index_row_html, + (const char *) asset_table_row_html, eq.entries[row]->id, eq.entries[row]->title, eq.entries[row]->created_at, eq.entries[row]->updated_at ); } // Write table footer. - kore_buf_append(content, asset_index_footer_html, asset_len_index_footer_html); + kore_buf_append(content, asset_table_footer_html, asset_len_table_footer_html); http_ok_resp(req, HTTP_STATUS_OK, content); @@ -238,7 +259,7 @@ int get_entry(struct http_request *req) { content = kore_buf_alloc(0); rendered_body = kore_buf_alloc(0); - entry_query_init(&eq, req->path + strlen("/entries/")); + entry_query_init(&eq, req->path + strlen("/entries/"), NULL); // Check for valid resource UUID kore_log(LOG_DEBUG, "Resource id /entries/%s.", eq.id); @@ -300,7 +321,7 @@ int edit_entry(struct http_request *req) { id = kore_strdup(req->path + strlen("/entries/")); id[strlen(id) - strlen("/edit")] = '\0'; - entry_query_init(&eq, (const char*) id); + entry_query_init(&eq, (const char*) id, NULL); // Check for valid resource UUID kore_log(LOG_DEBUG, "Resource id /entries/%s.", eq.id); @@ -410,13 +431,64 @@ out: ; int search_entries(struct http_request *req) { - // int err = 0; + int err = 0; - kore_log(LOG_INFO, "search ...."); + int row = 0; - http_err_resp(req, HTTP_STATUS_OK); + char *query = NULL; -// out: ; + struct entry_query eq; + + struct kore_buf *content = NULL; + + content = kore_buf_alloc(0); + + http_populate_get(req); + + err = http_argument_get_string(req, "query", &query); + if (err == KORE_RESULT_OK) { + kore_log(LOG_INFO, "query string: '%s'", query); + } + + entry_query_init(&eq, NULL, query); + + (void) sql_select(&eq); + if (eq.status != QUERY_STATUS_OK) { + http_err_resp(req, HTTP_STATUS_INTERNAL_ERROR); + goto out; + } + + // Write header. + kore_buf_append(content, asset_header_html, asset_len_header_html); + + // Write search form. + kore_buf_append(content, asset_search_html, asset_len_search_html); + + if (eq.num_entries > 0) { + // Write table header. + kore_buf_append(content, asset_table_header_html, asset_len_table_header_html); + + // Iterate over entries and render them. + for (row = 0; row < eq.num_entries; row++) { + // Append rendered MD entry. + kore_buf_appendf( + content, + (const char *) asset_table_row_html, + eq.entries[row]->id, eq.entries[row]->title, eq.entries[row]->created_at, eq.entries[row]->updated_at + ); + } + + // Write table footer. + kore_buf_append(content, asset_table_footer_html, asset_len_table_footer_html); + } + + http_ok_resp(req, HTTP_STATUS_OK, content); + +out: ; + + entry_query_cleanup(&eq); + + kore_free(content); return KORE_RESULT_OK; } @@ -449,7 +521,16 @@ int sql_select(struct entry_query *eq) { 1, // param count KORE_PGSQL_PARAM_TEXT(eq->id) ); - } else { + } + else if (eq->query != NULL) { + err = kore_pgsql_query_params(&sql, q_search_entries, + 0, // return string data + 2, // param count + KORE_PGSQL_PARAM_TEXT(eq->query), + KORE_PGSQL_PARAM_TEXT(eq->query) + ); + } + else { // Query for index. err = kore_pgsql_query(&sql, q_select_entries); } diff --git a/src/queries.h b/src/queries.h index a55fafb..7fbe898 100644 --- a/src/queries.h +++ b/src/queries.h @@ -11,13 +11,13 @@ const char *q_select_entries = const char *q_search_entries = "WITH query AS " "( " -" SELECT id, title, created_at::DATE, updated_at::DATE, " +" SELECT id, title, created_at::DATE, updated_at::DATE, body, " " TS_RANK(search_vector, TO_TSQUERY('english', $1)) AS rank " " FROM entries " " WHERE search_vector @@ TO_TSQUERY('english', $2) " " ORDER BY rank DESC " ") " -"SELECT id, title, created_at::DATE, updated_at::DATE FROM query;"; +"SELECT id, title, created_at::DATE, updated_at::DATE, body FROM query;"; const char *q_update_entry = "UPDATE entries " -- cgit v1.2.3
titlecreatedupdated
%s%s%s