From: Art Cancro Date: Sun, 27 Dec 2020 23:34:20 +0000 (-0500) Subject: Moved the defunct server-side renderer into another file to keep as a reference. X-Git-Tag: v939~176 X-Git-Url: https://code.citadel.org/?a=commitdiff_plain;h=3233523d9abe658ca1d9e63ce41a732aff1de214;p=citadel.git Moved the defunct server-side renderer into another file to keep as a reference. --- diff --git a/webcit-ng/README.txt b/webcit-ng/README.txt index 82c0a93cc..435df81a1 100644 --- a/webcit-ng/README.txt +++ b/webcit-ng/README.txt @@ -29,3 +29,8 @@ REST format URIs will generally take the form of: /ctdl/objectClass/[container/]object[/operation] +We are using: + +* libcitadel for information about the Citadel server, some string handling, and the JSON encoder +* Expat for DAV handling +* OpenSSL for TLS diff --git a/webcit-ng/forum_view.c b/webcit-ng/forum_view.c index 6cd4f01f5..a0300064a 100644 --- a/webcit-ng/forum_view.c +++ b/webcit-ng/forum_view.c @@ -37,276 +37,6 @@ void setup_for_forum_view(struct ctdlsession *c) } -#if 0 -// Renderer for one message in the threaded view -// (This will probably work for the flat view too.) -// -void forum_render_one_message(struct ctdlsession *c, StrBuf * sj, long msgnum) -{ - StrBuf *raw_msg = NULL; - StrBuf *sanitized_msg = NULL; - char buf[1024]; - char content_transfer_encoding[1024] = { 0 }; - char content_type[1024] = { 0 }; - char author[128] = { 0 }; - char datetime[128] = { 0 }; - - ctdl_printf(c, "MSG4 %ld", msgnum); - ctdl_readline(c, buf, sizeof(buf)); - if (buf[0] != '1') { - StrBufAppendPrintf(sj, "
ERROR CONDITION FIXME WRITE A BOX
"); - return; - } - - while ((ctdl_readline(c, buf, sizeof(buf)) >= 0) && (strcmp(buf, "text")) && (strcmp(buf, "000"))) { - // citadel header parsing here - if (!strncasecmp(buf, "from=", 5)) { - safestrncpy(author, &buf[5], sizeof author); - } - if (!strncasecmp(buf, "time=", 5)) { - time_t tt; - struct tm tm; - tt = atol(&buf[5]); - localtime_r(&tt, &tm); - strftime(datetime, sizeof datetime, "%c", &tm); - } - } - - if (!strcmp(buf, "text")) { - while ((ctdl_readline(c, buf, sizeof(buf)) >= 0) && (strcmp(buf, "")) && (strcmp(buf, "000"))) { - // rfc822 header parsing here - if (!strncasecmp(buf, "Content-transfer-encoding:", 26)) { - strcpy(content_transfer_encoding, &buf[26]); - striplt(content_transfer_encoding); - } - if (!strncasecmp(buf, "Content-type:", 13)) { - strcpy(content_type, &buf[13]); - striplt(content_type); - } - } - raw_msg = ctdl_readtextmsg(c); - } else { - raw_msg = NULL; - } - - // begin output - - StrBufAppendPrintf(sj, "
"); // begin message wrapper - StrBufAppendPrintf(sj, "
"); // begin avatar FIXME move the style to a stylesheet - StrBufAppendPrintf(sj, " "); // FIXME temporary avatar - StrBufAppendPrintf(sj, "
"); // end avatar - StrBufAppendPrintf(sj, "
"); // begin content - StrBufAppendPrintf(sj, "
"); // begin header - StrBufAppendPrintf(sj, "%s ", author); // FIXME link to user profile or whatever - StrBufAppendPrintf(sj, "%s ", datetime); - StrBufAppendPrintf(sj, "
"); // end header - StrBufAppendPrintf(sj, "
"); // begin body - - if (raw_msg) { - - // These are the encodings we know how to handle. Decode in-place. - - if (!strcasecmp(content_transfer_encoding, "base64")) { - StrBufDecodeBase64(raw_msg); - } - if (!strcasecmp(content_transfer_encoding, "quoted-printable")) { - StrBufDecodeQP(raw_msg); - } - // At this point, raw_msg contains the decoded message. - // Now run through the renderers we have available. - - if (!strncasecmp(content_type, "text/html", 9)) { - sanitized_msg = html2html("UTF-8", 0, c->room, msgnum, raw_msg); - } else if (!strncasecmp(content_type, "text/plain", 10)) { - sanitized_msg = text2html("UTF-8", 0, c->room, msgnum, raw_msg); - } else if (!strncasecmp(content_type, "text/x-citadel-variformat", 25)) { - sanitized_msg = variformat2html(raw_msg); - } else { - sanitized_msg = NewStrBufPlain(HKEY("No renderer for this content type
")); - } - FreeStrBuf(&raw_msg); - - // If sanitized_msg is not NULL, we have rendered the message and can output it. - - if (sanitized_msg) { - StrBufAppendBuf(sj, sanitized_msg, 0); - FreeStrBuf(&sanitized_msg); - } - } - - StrBufAppendPrintf(sj, "
"); // end body - StrBufAppendPrintf(sj, "
"); // end content - StrBufAppendPrintf(sj, "
"); // end wrapper -} - - -// This code implements the thread display code. The thread sorting algorithm is working nicely but we're trying -// not to do rendering in the C server of webcit. Maybe move it into the server as "MSGS threaded" or something like that? - -// Threaded view (recursive section) -// -void thread_o_print(struct ctdlsession *c, StrBuf * sj, struct mthread *m, int num_msgs, int where_parent_is, int nesting_level) -{ - int i = 0; - int j = 0; - int num_printed = 0; - - for (i = 0; i < num_msgs; ++i) { - if (m[i].parent == where_parent_is) { - - if (++num_printed == 1) { - StrBufAppendPrintf(sj, ""); - } -} - - -// Threaded view (entry point) -// -void threaded_view(struct http_transaction *h, struct ctdlsession *c, char *which) -{ - int num_msgs = 0; - int num_alloc = 0; - struct mthread *m; - char buf[1024]; - char refs[1024]; - int i, j, k; - - ctdl_printf(c, "MSGS ALL|||9"); // 9 == headers + thread references - ctdl_readline(c, buf, sizeof(buf)); - if (buf[0] != '1') { - do_404(h); - return; - } - - StrBuf *sj = NewStrBuf(); - StrBufAppendPrintf(sj, "\r\n"); - - while (ctdl_readline(c, buf, sizeof buf), strcmp(buf, "000")) { - - ++num_msgs; - if (num_msgs > num_alloc) { - if (num_alloc == 0) { - num_alloc = 100; - m = malloc(num_alloc * sizeof(struct mthread)); - } else { - num_alloc *= 2; - m = realloc(m, (num_alloc * sizeof(struct mthread))); - } - } - - memset(&m[num_msgs - 1], 0, sizeof(struct mthread)); - m[num_msgs - 1].msgnum = extract_long(buf, 0); - m[num_msgs - 1].datetime = extract_long(buf, 1); - extract_token(m[num_msgs - 1].from, buf, 2, '|', sizeof m[num_msgs - 1].from); - m[num_msgs - 1].threadhash = extract_int(buf, 6); - extract_token(refs, buf, 7, '|', sizeof refs); - - char *t; - char *r = refs; - i = 0; - while ((t = strtok_r(r, ",", &r))) { - if (i == 0) { - m[num_msgs - 1].refhashes[0] = atoi(t); // always keep the first one - } else { - memcpy(&m[num_msgs - 1].refhashes[1], &m[num_msgs - 1].refhashes[2], sizeof(int) * 8); // shift the rest - m[num_msgs - 1].refhashes[9] = atoi(t); - } - ++i; - } - - } - - // Sort by thread. I did read jwz's sorting algorithm and it looks pretty good, but jwz is a self-righteous asshole so we do it our way. - for (i = 0; i < num_msgs; ++i) { - for (j = 9; (j >= 0) && (m[i].parent == 0); --j) { - for (k = 0; (k < num_msgs) && (m[i].parent == 0); ++k) { - if (m[i].refhashes[j] == m[k].threadhash) { - m[i].parent = k; - } - } - } - } - - // Now render it - setup_for_forum_view(c); - thread_o_print(c, sj, m, num_msgs, 0, 0); // Render threads recursively and recursively - - // Garbage collection is for people who aren't smart enough to manage their own memory. - if (num_msgs > 0) { - free(m); - } - - StrBufAppendPrintf(sj, "\r\n"); - - add_response_header(h, strdup("Content-type"), strdup("text/html; charset=utf-8")); - h->response_code = 200; - h->response_string = strdup("OK"); - h->response_body_length = StrLength(sj); - h->response_body = SmashStrBuf(&sj); - return; -} - - -// flat view (entry point) -// -void flat_view(struct http_transaction *h, struct ctdlsession *c, char *which) -{ - StrBuf *sj = NewStrBuf(); - StrBufAppendPrintf(sj, "\r\n"); - - setup_for_forum_view(c); - long *msglist = get_msglist(c, "ALL"); - if (msglist) { - int i; - for (i = 0; (msglist[i] > 0); ++i) { - forum_render_one_message(c, sj, msglist[i]); - } - free(msglist); - } - - StrBufAppendPrintf(sj, "\r\n"); - - add_response_header(h, strdup("Content-type"), strdup("text/html; charset=utf-8")); - h->response_code = 200; - h->response_string = strdup("OK"); - h->response_body_length = StrLength(sj); - h->response_body = SmashStrBuf(&sj); - return; -} - - -// render one message (entire transaction) FIXME EXTERMINATE -// -void html_render_one_message(struct http_transaction *h, struct ctdlsession *c, long msgnum) -{ - StrBuf *sj = NewStrBuf(); - StrBufAppendPrintf(sj, "\r\n"); - setup_for_forum_view(c); // FIXME way too inefficient to do this for every message !!!!!!!!!!!!! - forum_render_one_message(c, sj, msgnum); - StrBufAppendPrintf(sj, "\r\n"); - add_response_header(h, strdup("Content-type"), strdup("text/html; charset=utf-8")); - h->response_code = 200; - h->response_string = strdup("OK"); - h->response_body_length = StrLength(sj); - h->response_body = SmashStrBuf(&sj); - return; -} - -#endif - // Fetch a single message and return it in JSON format for client-side rendering // void json_render_one_message(struct http_transaction *h, struct ctdlsession *c, long msgnum) diff --git a/webcit-ng/old_threaded_view_save_for_reference.c b/webcit-ng/old_threaded_view_save_for_reference.c new file mode 100644 index 000000000..03f7a1f7e --- /dev/null +++ b/webcit-ng/old_threaded_view_save_for_reference.c @@ -0,0 +1,285 @@ +/* + * This is some older code for the forum view that does server-side rendering. + * We're keeping it around as a reference. + * + * Copyright (c) 1996-2018 by the citadel.org team + * + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#if 0 +// Renderer for one message in the threaded view +// (This will probably work for the flat view too.) +// +void forum_render_one_message(struct ctdlsession *c, StrBuf * sj, long msgnum) +{ + StrBuf *raw_msg = NULL; + StrBuf *sanitized_msg = NULL; + char buf[1024]; + char content_transfer_encoding[1024] = { 0 }; + char content_type[1024] = { 0 }; + char author[128] = { 0 }; + char datetime[128] = { 0 }; + + ctdl_printf(c, "MSG4 %ld", msgnum); + ctdl_readline(c, buf, sizeof(buf)); + if (buf[0] != '1') { + StrBufAppendPrintf(sj, "
ERROR CONDITION FIXME WRITE A BOX
"); + return; + } + + while ((ctdl_readline(c, buf, sizeof(buf)) >= 0) && (strcmp(buf, "text")) && (strcmp(buf, "000"))) { + // citadel header parsing here + if (!strncasecmp(buf, "from=", 5)) { + safestrncpy(author, &buf[5], sizeof author); + } + if (!strncasecmp(buf, "time=", 5)) { + time_t tt; + struct tm tm; + tt = atol(&buf[5]); + localtime_r(&tt, &tm); + strftime(datetime, sizeof datetime, "%c", &tm); + } + } + + if (!strcmp(buf, "text")) { + while ((ctdl_readline(c, buf, sizeof(buf)) >= 0) && (strcmp(buf, "")) && (strcmp(buf, "000"))) { + // rfc822 header parsing here + if (!strncasecmp(buf, "Content-transfer-encoding:", 26)) { + strcpy(content_transfer_encoding, &buf[26]); + striplt(content_transfer_encoding); + } + if (!strncasecmp(buf, "Content-type:", 13)) { + strcpy(content_type, &buf[13]); + striplt(content_type); + } + } + raw_msg = ctdl_readtextmsg(c); + } else { + raw_msg = NULL; + } + + // begin output + + StrBufAppendPrintf(sj, "
"); // begin message wrapper + StrBufAppendPrintf(sj, "
"); // begin avatar FIXME move the style to a stylesheet + StrBufAppendPrintf(sj, " "); // FIXME temporary avatar + StrBufAppendPrintf(sj, "
"); // end avatar + StrBufAppendPrintf(sj, "
"); // begin content + StrBufAppendPrintf(sj, "
"); // begin header + StrBufAppendPrintf(sj, "%s ", author); // FIXME link to user profile or whatever + StrBufAppendPrintf(sj, "%s ", datetime); + StrBufAppendPrintf(sj, "
"); // end header + StrBufAppendPrintf(sj, "
"); // begin body + + if (raw_msg) { + + // These are the encodings we know how to handle. Decode in-place. + + if (!strcasecmp(content_transfer_encoding, "base64")) { + StrBufDecodeBase64(raw_msg); + } + if (!strcasecmp(content_transfer_encoding, "quoted-printable")) { + StrBufDecodeQP(raw_msg); + } + // At this point, raw_msg contains the decoded message. + // Now run through the renderers we have available. + + if (!strncasecmp(content_type, "text/html", 9)) { + sanitized_msg = html2html("UTF-8", 0, c->room, msgnum, raw_msg); + } else if (!strncasecmp(content_type, "text/plain", 10)) { + sanitized_msg = text2html("UTF-8", 0, c->room, msgnum, raw_msg); + } else if (!strncasecmp(content_type, "text/x-citadel-variformat", 25)) { + sanitized_msg = variformat2html(raw_msg); + } else { + sanitized_msg = NewStrBufPlain(HKEY("No renderer for this content type
")); + } + FreeStrBuf(&raw_msg); + + // If sanitized_msg is not NULL, we have rendered the message and can output it. + + if (sanitized_msg) { + StrBufAppendBuf(sj, sanitized_msg, 0); + FreeStrBuf(&sanitized_msg); + } + } + + StrBufAppendPrintf(sj, "
"); // end body + StrBufAppendPrintf(sj, "
"); // end content + StrBufAppendPrintf(sj, "
"); // end wrapper +} + + +// This code implements the thread display code. The thread sorting algorithm is working nicely but we're trying +// not to do rendering in the C server of webcit. Maybe move it into the server as "MSGS threaded" or something like that? + +// Threaded view (recursive section) +// +void thread_o_print(struct ctdlsession *c, StrBuf * sj, struct mthread *m, int num_msgs, int where_parent_is, int nesting_level) +{ + int i = 0; + int j = 0; + int num_printed = 0; + + for (i = 0; i < num_msgs; ++i) { + if (m[i].parent == where_parent_is) { + + if (++num_printed == 1) { + StrBufAppendPrintf(sj, ""); + } +} + + +// Threaded view (entry point) +// +void threaded_view(struct http_transaction *h, struct ctdlsession *c, char *which) +{ + int num_msgs = 0; + int num_alloc = 0; + struct mthread *m; + char buf[1024]; + char refs[1024]; + int i, j, k; + + ctdl_printf(c, "MSGS ALL|||9"); // 9 == headers + thread references + ctdl_readline(c, buf, sizeof(buf)); + if (buf[0] != '1') { + do_404(h); + return; + } + + StrBuf *sj = NewStrBuf(); + StrBufAppendPrintf(sj, "\r\n"); + + while (ctdl_readline(c, buf, sizeof buf), strcmp(buf, "000")) { + + ++num_msgs; + if (num_msgs > num_alloc) { + if (num_alloc == 0) { + num_alloc = 100; + m = malloc(num_alloc * sizeof(struct mthread)); + } else { + num_alloc *= 2; + m = realloc(m, (num_alloc * sizeof(struct mthread))); + } + } + + memset(&m[num_msgs - 1], 0, sizeof(struct mthread)); + m[num_msgs - 1].msgnum = extract_long(buf, 0); + m[num_msgs - 1].datetime = extract_long(buf, 1); + extract_token(m[num_msgs - 1].from, buf, 2, '|', sizeof m[num_msgs - 1].from); + m[num_msgs - 1].threadhash = extract_int(buf, 6); + extract_token(refs, buf, 7, '|', sizeof refs); + + char *t; + char *r = refs; + i = 0; + while ((t = strtok_r(r, ",", &r))) { + if (i == 0) { + m[num_msgs - 1].refhashes[0] = atoi(t); // always keep the first one + } else { + memcpy(&m[num_msgs - 1].refhashes[1], &m[num_msgs - 1].refhashes[2], sizeof(int) * 8); // shift the rest + m[num_msgs - 1].refhashes[9] = atoi(t); + } + ++i; + } + + } + + // Sort by thread. I did read jwz's sorting algorithm and it looks pretty good, but jwz is a self-righteous asshole so we do it our way. + for (i = 0; i < num_msgs; ++i) { + for (j = 9; (j >= 0) && (m[i].parent == 0); --j) { + for (k = 0; (k < num_msgs) && (m[i].parent == 0); ++k) { + if (m[i].refhashes[j] == m[k].threadhash) { + m[i].parent = k; + } + } + } + } + + // Now render it + setup_for_forum_view(c); + thread_o_print(c, sj, m, num_msgs, 0, 0); // Render threads recursively and recursively + + // Garbage collection is for people who aren't smart enough to manage their own memory. + if (num_msgs > 0) { + free(m); + } + + StrBufAppendPrintf(sj, "\r\n"); + + add_response_header(h, strdup("Content-type"), strdup("text/html; charset=utf-8")); + h->response_code = 200; + h->response_string = strdup("OK"); + h->response_body_length = StrLength(sj); + h->response_body = SmashStrBuf(&sj); + return; +} + + +// flat view (entry point) +// +void flat_view(struct http_transaction *h, struct ctdlsession *c, char *which) +{ + StrBuf *sj = NewStrBuf(); + StrBufAppendPrintf(sj, "\r\n"); + + setup_for_forum_view(c); + long *msglist = get_msglist(c, "ALL"); + if (msglist) { + int i; + for (i = 0; (msglist[i] > 0); ++i) { + forum_render_one_message(c, sj, msglist[i]); + } + free(msglist); + } + + StrBufAppendPrintf(sj, "\r\n"); + + add_response_header(h, strdup("Content-type"), strdup("text/html; charset=utf-8")); + h->response_code = 200; + h->response_string = strdup("OK"); + h->response_body_length = StrLength(sj); + h->response_body = SmashStrBuf(&sj); + return; +} + + +// render one message (entire transaction) FIXME EXTERMINATE +// +void html_render_one_message(struct http_transaction *h, struct ctdlsession *c, long msgnum) +{ + StrBuf *sj = NewStrBuf(); + StrBufAppendPrintf(sj, "\r\n"); + setup_for_forum_view(c); // FIXME way too inefficient to do this for every message !!!!!!!!!!!!! + forum_render_one_message(c, sj, msgnum); + StrBufAppendPrintf(sj, "\r\n"); + add_response_header(h, strdup("Content-type"), strdup("text/html; charset=utf-8")); + h->response_code = 200; + h->response_string = strdup("OK"); + h->response_body_length = StrLength(sj); + h->response_body = SmashStrBuf(&sj); + return; +} + +#endif diff --git a/webcit-ng/static/js/views.js b/webcit-ng/static/js/views.js index 1a30a2aae..b7eaa1bc3 100644 --- a/webcit-ng/static/js/views.js +++ b/webcit-ng/static/js/views.js @@ -70,7 +70,6 @@ function forum_readmessages(target_div, gt_msg, lt_msg) response = await fetch(url); msgs = await(response.json()); if (response.ok) { - msgs = JSON.parse(this.responseText); document.getElementById(target_div).innerHTML = "" ; // If we were given an explicit starting point, by all means start there. @@ -160,9 +159,8 @@ function forum_render_messages(msgs, prefix, scroll_to) function forum_render_one(div, msgnum, scroll_to) { fetch_message = async() => { response = await fetch("/ctdl/r/" + escapeHTMLURI(current_room) + "/" + msgs[i] + "/json"); - msg = response.json()); + msg = await response.json(); if (response.ok) { - msg = JSON.parse(this.responseText); document.getElementById(div).innerHTML = "
" // begin message wrapper