From 7312f4ce51100d4ed98988cb3af0ab06e4fba53c Mon Sep 17 00:00:00 2001 From: iwojim0 Date: Sat, 9 Mar 2024 14:37:54 +0000 Subject: Ability to federate with hidden networks #93 (update for v2.49) --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index 59fd6c9..46ef735 100644 --- a/html.c +++ b/html.c @@ -783,7 +783,7 @@ static xs_html *html_user_body(snac *user, int read_only) while (xs_dict_next(metadata, &k, &v, &c)) { xs_html *value; - if (xs_startswith(v, "https:/" "/")) { + if (xs_startswith(v, "http")) { /* is this link validated? */ xs *verified_link = NULL; xs_number *val_time = xs_dict_get(val_links, v); -- cgit v1.2.3 From 2e31253ba8de74e073fd104785bde78510c843c1 Mon Sep 17 00:00:00 2001 From: default Date: Wed, 17 Apr 2024 06:45:19 +0200 Subject: Don't skip orphan private posts that are for us. --- html.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index f50fb7d..59ada61 100644 --- a/html.c +++ b/html.c @@ -2055,8 +2055,13 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, char *irt = xs_dict_get(msg, "inReplyTo"); if (!xs_is_null(irt) && !object_here(irt)) { - snac_debug(user, 1, xs_fmt("skipping non-public reply to an unknown post %s", v)); - continue; + /* is it for me? */ + xs_list *to = xs_dict_get(msg, "to"); + + if (xs_type(to) == XSTYPE_LIST && xs_list_in(to, user->actor) == -1) { + snac_debug(user, 1, xs_fmt("skipping non-public reply to an unknown post %s", v)); + continue; + } } } -- cgit v1.2.3 From 44d126e0f96748f7f5e0c8a95ed8b3f5f69cd0f0 Mon Sep 17 00:00:00 2001 From: default Date: Wed, 17 Apr 2024 08:09:05 +0200 Subject: Improved non-public reply check. --- html.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 59ada61..0fca601 100644 --- a/html.c +++ b/html.c @@ -2054,11 +2054,13 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, if (user != NULL && !is_msg_public(msg)) { char *irt = xs_dict_get(msg, "inReplyTo"); + /* is it a reply to something not in the storage? */ if (!xs_is_null(irt) && !object_here(irt)) { /* is it for me? */ - xs_list *to = xs_dict_get(msg, "to"); + xs_list *to = xs_dict_get_def(msg, "to", xs_stock(XSTYPE_LIST)); + xs_list *cc = xs_dict_get_def(msg, "cc", xs_stock(XSTYPE_LIST)); - if (xs_type(to) == XSTYPE_LIST && xs_list_in(to, user->actor) == -1) { + if (xs_list_in(to, user->actor) == -1 && xs_list_in(cc, user->actor) == -1) { snac_debug(user, 1, xs_fmt("skipping non-public reply to an unknown post %s", v)); continue; } -- cgit v1.2.3 From 26840e0dc0e7322b2041c21b4e44ed9a34afff4b Mon Sep 17 00:00:00 2001 From: default Date: Thu, 18 Apr 2024 17:13:31 +0200 Subject: Some tweaks to previous patch. --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index a251e21..d52ef03 100644 --- a/html.c +++ b/html.c @@ -813,7 +813,7 @@ static xs_html *html_user_body(snac *user, int read_only) while (xs_dict_next(metadata, &k, &v, &c)) { xs_html *value; - if (xs_startswith(v, "http")) { + if (xs_startswith(v, "https:/") || xs_startswith(v, "http:/")) { /* is this link validated? */ xs *verified_link = NULL; xs_number *val_time = xs_dict_get(val_links, v); -- cgit v1.2.3 From ebf6a4bd8e97e434d1502ddead4690aca3dd6d33 Mon Sep 17 00:00:00 2001 From: default Date: Mon, 22 Apr 2024 05:46:56 +0200 Subject: URLs like {srv_baseurl}/{user}/admin/p/{md5} are valid. But only if {md5} is in the user's timeline. --- html.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'html.c') diff --git a/html.c b/html.c index d52ef03..fdc0975 100644 --- a/html.c +++ b/html.c @@ -2586,6 +2586,25 @@ int html_get_handler(const xs_dict *req, const char *q_path, } } else + if (xs_startswith(p_path, "admin/p/")) { /** unique post by md5 **/ + if (!login(&snac, req)) { + *body = xs_dup(uid); + status = 401; + } + else { + xs *l = xs_split(p_path, "/"); + char *md5 = xs_list_get(l, -1); + + if (md5 && *md5 && timeline_here(&snac, md5)) { + xs *list = xs_list_append(xs_list_new(), md5); + + *body = html_timeline(&snac, list, 0, 0, 0, 0, NULL, "/admin", 1); + *b_size = strlen(*body); + status = 200; + } + } + } + else if (strcmp(p_path, "people") == 0) { /** the list of people **/ if (!login(&snac, req)) { *body = xs_dup(uid); -- cgit v1.2.3 From 2f499e9421bd67299d4fc1981f350f80efc2772b Mon Sep 17 00:00:00 2001 From: default Date: Sun, 5 May 2024 01:06:34 +0200 Subject: Fixed Pleroma polls. --- html.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index fdc0975..fa8253f 100644 --- a/html.c +++ b/html.c @@ -1653,20 +1653,27 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, xs_list *p; xs_dict *v; int closed = 0; + char *f_closed = NULL; xs_html *poll = xs_html_tag("div", NULL); if (read_only) closed = 1; /* non-identified page; show as closed */ else - if (xs_dict_get(msg, "closed")) - closed = 2; - else if (user && xs_startswith(id, user->actor)) closed = 1; /* we questioned; closed for us */ else if (user && was_question_voted(user, id)) closed = 1; /* we already voted; closed for us */ + else + if ((f_closed = xs_dict_get(msg, "closed")) != NULL) { + /* it has a closed date... but is it in the past? */ + time_t t0 = time(NULL); + time_t t1 = xs_parse_iso_date(f_closed, 0); + + if (t1 < t0) + closed = 2; + } /* get the appropriate list of options */ p = oo != NULL ? oo : ao; @@ -1756,6 +1763,12 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, else { /* show when the poll closes */ char *end_time = xs_dict_get(msg, "endTime"); + + /* Pleroma does not have an endTime field; + it has a closed time in the future */ + if (xs_is_null(end_time)) + end_time = xs_dict_get(msg, "closed"); + if (!xs_is_null(end_time)) { time_t t0 = time(NULL); time_t t1 = xs_parse_iso_date(end_time, 0); -- cgit v1.2.3 From 7ea57485c70e9a55045f14bd81d7aea73fff4fb1 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 5 May 2024 01:21:07 +0200 Subject: More Pleroma poll tweaks. --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index fa8253f..45c665c 100644 --- a/html.c +++ b/html.c @@ -1665,7 +1665,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, else if (user && was_question_voted(user, id)) closed = 1; /* we already voted; closed for us */ - else + if ((f_closed = xs_dict_get(msg, "closed")) != NULL) { /* it has a closed date... but is it in the past? */ time_t t0 = time(NULL); -- cgit v1.2.3 From be9cf2f5550f68ef4e86b547d7247a0bd498521d Mon Sep 17 00:00:00 2001 From: default Date: Sun, 5 May 2024 01:58:27 +0200 Subject: Enqueue an object request for closed polls. It seems that Pleroma does not send poll updates on close (or never). --- html.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'html.c') diff --git a/html.c b/html.c index 45c665c..9de1cca 100644 --- a/html.c +++ b/html.c @@ -3300,6 +3300,25 @@ int html_post_handler(const xs_dict *req, const char *q_path, timeline_add(&snac, xs_dict_get(msg, "id"), msg); } + { + /* get the poll object */ + xs *poll = NULL; + + if (valid_status(object_get(irt, &poll))) { + char *date = xs_dict_get(poll, "endTime"); + if (xs_is_null(date)) + date = xs_dict_get(poll, "closed"); + + if (!xs_is_null(date)) { + time_t t = xs_parse_iso_date(date, 0) - time(NULL); + + /* request the poll when it's closed; + Pleroma does not send and update when the poll closes */ + enqueue_object_request(&snac, irt, t + 2); + } + } + } + status = 303; } -- cgit v1.2.3 From 45357b8e6e36f973fc09c0a82a633e2d08b34eda Mon Sep 17 00:00:00 2001 From: default Date: Sun, 5 May 2024 11:00:29 +0200 Subject: New function timeline_to_rss(). --- html.c | 111 ++++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 62 insertions(+), 49 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 9de1cca..fe070c1 100644 --- a/html.c +++ b/html.c @@ -2728,55 +2728,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, xs_dict_get(srv_config, "host")); xs *rss_link = xs_fmt("%s.rss", snac.actor); - xs_html *rss = xs_html_tag("rss", - xs_html_attr("version", "0.91")); - - xs_html *channel = xs_html_tag("channel", - xs_html_tag("title", - xs_html_text(rss_title)), - xs_html_tag("language", - xs_html_text("en")), - xs_html_tag("link", - xs_html_text(rss_link)), - xs_html_tag("description", - xs_html_text(bio))); - - xs_html_add(rss, channel); - - xs_list *p = elems; - char *v; - - while (xs_list_iter(&p, &v)) { - xs *msg = NULL; - - if (!valid_status(timeline_get_by_md5(&snac, v, &msg))) - continue; - - char *id = xs_dict_get(msg, "id"); - char *content = xs_dict_get(msg, "content"); - - if (!xs_startswith(id, snac.actor)) - continue; - - /* create a title with the first line of the content */ - xs *es_title = xs_replace(content, "
", "\n"); - xs *title = xs_str_new(NULL); - int i; - - for (i = 0; es_title[i] && es_title[i] != '\n' && es_title[i] != '&' && i < 50; i++) - title = xs_append_m(title, &es_title[i], 1); - - xs_html_add(channel, - xs_html_tag("item", - xs_html_tag("title", - xs_html_text(title)), - xs_html_tag("link", - xs_html_text(id)), - xs_html_tag("description", - xs_html_text(content)))); - } - - *body = xs_html_render_s(rss, "\n"); + *body = timeline_to_rss(&snac, elems, rss_title, rss_link, bio); *b_size = strlen(*body); *ctype = "application/rss+xml; charset=utf-8"; status = 200; @@ -3336,3 +3288,64 @@ int html_post_handler(const xs_dict *req, const char *q_path, return status; } + + +xs_str *timeline_to_rss(snac *user, const xs_list *timeline, char *title, char *link, char *desc) +/* converts a timeline to rss */ +{ + xs_html *rss = xs_html_tag("rss", + xs_html_attr("version", "0.91")); + + xs_html *channel = xs_html_tag("channel", + xs_html_tag("title", + xs_html_text(title)), + xs_html_tag("language", + xs_html_text("en")), + xs_html_tag("link", + xs_html_text(link)), + xs_html_tag("description", + xs_html_text(desc))); + + xs_html_add(rss, channel); + + int c = 0; + char *v; + + while (xs_list_next(timeline, &v, &c)) { + xs *msg = NULL; + + if (user) { + if (!valid_status(timeline_get_by_md5(user, v, &msg))) + continue; + } + else { + if (!valid_status(object_get_by_md5(v, &msg))) + continue; + } + + char *id = xs_dict_get(msg, "id"); + char *content = xs_dict_get(msg, "content"); + + if (user && !xs_startswith(id, user->actor)) + continue; + + /* create a title with the first line of the content */ + xs *es_title = xs_replace(content, "
", "\n"); + xs *title = xs_str_new(NULL); + int i; + + for (i = 0; es_title[i] && es_title[i] != '\n' && es_title[i] != '&' && i < 50; i++) + title = xs_append_m(title, &es_title[i], 1); + + xs_html_add(channel, + xs_html_tag("item", + xs_html_tag("title", + xs_html_text(title)), + xs_html_tag("link", + xs_html_text(id)), + xs_html_tag("description", + xs_html_text(content)))); + } + + return xs_html_render_s(rss, "\n"); +} -- cgit v1.2.3 From c31a4ae73e9759cebda2a9cf8a34b352dc246314 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 5 May 2024 11:27:24 +0200 Subject: Minor RSS title beautifying. --- html.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index fe070c1..ee5c2cd 100644 --- a/html.c +++ b/html.c @@ -3330,12 +3330,19 @@ xs_str *timeline_to_rss(snac *user, const xs_list *timeline, char *title, char * continue; /* create a title with the first line of the content */ - xs *es_title = xs_replace(content, "
", "\n"); - xs *title = xs_str_new(NULL); + xs *title = xs_replace(content, "
", "\n"); + title = xs_regex_replace_i(title, "<[^>]+>", " "); + title = xs_regex_replace_i(title, "&[^;]+;", " "); int i; - for (i = 0; es_title[i] && es_title[i] != '\n' && es_title[i] != '&' && i < 50; i++) - title = xs_append_m(title, &es_title[i], 1); + for (i = 0; title[i] && title[i] != '\n' && i < 50; i++); + + if (title[i] != '\0') { + title[i] = '\0'; + title = xs_str_cat(title, "..."); + } + + title = xs_strip_i(title); xs_html_add(channel, xs_html_tag("item", -- cgit v1.2.3 From 6b1721c977294ee28f54150579c36514aa3ee62a Mon Sep 17 00:00:00 2001 From: default Date: Tue, 7 May 2024 19:40:28 +0200 Subject: List timelines can now be (manually) navigated from the web UI. URLs are {srv_baseurl}/{user}/list/{list_id} (you must know the list id). --- html.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'html.c') diff --git a/html.c b/html.c index ee5c2cd..b34fc81 100644 --- a/html.c +++ b/html.c @@ -2658,6 +2658,29 @@ int html_get_handler(const xs_dict *req, const char *q_path, } } else + if (xs_startswith(p_path, "list/")) { /** list timelines **/ + if (!login(&snac, req)) { + *body = xs_dup(uid); + status = 401; + } + else { + xs *l = xs_split(p_path, "/"); + char *lid = xs_list_get(l, -1); + + xs *list = list_timeline(&snac, lid, skip, show); + xs *next = list_timeline(&snac, lid, skip + show, 1); + + if (list != NULL) { + xs *base = xs_fmt("/list/%s", lid); + + *body = html_timeline(&snac, list, 0, skip, show, + xs_list_len(next), NULL, base, 0); + *b_size = strlen(*body); + status = 200; + } + } + } + else if (xs_startswith(p_path, "p/")) { /** a timeline with just one entry **/ if (xs_type(xs_dict_get(snac.config, "private")) == XSTYPE_TRUE) return 403; -- cgit v1.2.3 From b57409a9590c737da66c0aaa679a47c2c947fbf8 Mon Sep 17 00:00:00 2001 From: default Date: Tue, 7 May 2024 19:45:10 +0200 Subject: Fixed typo. --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index b34fc81..536879c 100644 --- a/html.c +++ b/html.c @@ -2674,7 +2674,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, xs *base = xs_fmt("/list/%s", lid); *body = html_timeline(&snac, list, 0, skip, show, - xs_list_len(next), NULL, base, 0); + xs_list_len(next), NULL, base, 1); *b_size = strlen(*body); status = 200; } -- cgit v1.2.3 From 82ec4ea95cb1040c5b9b983ec649dbde024d20f8 Mon Sep 17 00:00:00 2001 From: default Date: Tue, 7 May 2024 20:32:13 +0200 Subject: Minor "Back to top" "More..." link refactoring. --- html.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 536879c..bd3179d 100644 --- a/html.c +++ b/html.c @@ -509,7 +509,7 @@ xs_html *html_instance_head(void) } -static xs_html *html_instance_body(char *tag) +static xs_html *html_instance_body(char *title) { char *host = xs_dict_get(srv_config, "host"); char *sdesc = xs_dict_get(srv_config, "short_description"); @@ -560,14 +560,11 @@ static xs_html *html_instance_body(char *tag) xs_html_text(handle))))); } - { - xs *l = tag ? xs_fmt(L("Search results for #%s"), tag) : - xs_dup(L("Recent posts by users in this instance")); - + if (title != NULL) { xs_html_add(body, xs_html_tag("h2", xs_html_attr("class", "snac-header"), - xs_html_text(l))); + xs_html_text(title))); } return body; @@ -1996,7 +1993,7 @@ xs_html *html_footer(void) xs_str *html_timeline(snac *user, const xs_list *list, int read_only, int skip, int show, int show_more, - char *tag, char *page, int utl) + char *title, char *page, int utl) /* returns the HTML for the timeline */ { xs_list *p = (xs_list *)list; @@ -2026,7 +2023,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, } else { head = html_instance_head(); - body = html_instance_body(tag); + body = html_instance_body(title); } xs_html *html = xs_html_tag("html", @@ -2126,25 +2123,22 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, } if (show_more) { - xs *t = NULL; xs *m = NULL; xs *ss = xs_fmt("skip=%d&show=%d", skip + show, show); - xs *url = page == NULL || user == NULL ? - xs_dup(srv_baseurl) : xs_fmt("%s%s", user->actor, page); + xs *url = xs_dup(user == NULL ? srv_baseurl : user->actor); - if (tag) { - t = xs_fmt("%s?t=%s", url, tag); - m = xs_fmt("%s&%s", t, ss); - } - else { - t = xs_dup(url); - m = xs_fmt("%s?%s", t, ss); - } + if (page != NULL) + url = xs_str_cat(url, page); + + if (xs_str_in(url, "?") != -1) + m = xs_fmt("%s&%s", url, ss); + else + m = xs_fmt("%s?%s", url, ss); xs_html *more_links = xs_html_tag("p", xs_html_tag("a", - xs_html_attr("href", t), + xs_html_attr("href", url), xs_html_attr("name", "snac-more"), xs_html_text(L("Back to top"))), xs_html_text(" - "), -- cgit v1.2.3 From d3cdbf170251db70121b2162513a6cfa2addd8c4 Mon Sep 17 00:00:00 2001 From: default Date: Tue, 7 May 2024 20:51:43 +0200 Subject: Added a title to list timelines. --- html.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index bd3179d..86cb2f5 100644 --- a/html.c +++ b/html.c @@ -2034,6 +2034,13 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, xs_html_add(body, html_top_controls(user)); + if (user && title) { + xs_html_add(body, + xs_html_tag("h2", + xs_html_attr("class", "snac-header"), + xs_html_text(title))); + } + xs_html_add(body, xs_html_tag("a", xs_html_attr("name", "snac-posts"))); @@ -2666,9 +2673,11 @@ int html_get_handler(const xs_dict *req, const char *q_path, if (list != NULL) { xs *base = xs_fmt("/list/%s", lid); + xs *name = list_maint(&snac, lid, 3); + xs *title = xs_fmt(L("Showing timeline for list %s"), name); *body = html_timeline(&snac, list, 0, skip, show, - xs_list_len(next), NULL, base, 1); + xs_list_len(next), title, base, 1); *b_size = strlen(*body); status = 200; } -- cgit v1.2.3 From 2322de4900312653d04ec19e8ee2850e0f5d4ac4 Mon Sep 17 00:00:00 2001 From: default Date: Tue, 7 May 2024 20:53:58 +0200 Subject: Added a title to the instance timeline. --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index 86cb2f5..5521a9f 100644 --- a/html.c +++ b/html.c @@ -2653,7 +2653,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, xs *next = timeline_instance_list(skip + show, 1); *body = html_timeline(&snac, list, 0, skip, show, - xs_list_len(next), NULL, "/instance", 0); + xs_list_len(next), L("Showing instance timeline"), "/instance", 0); *b_size = strlen(*body); status = 200; } -- cgit v1.2.3 From fa8b40192757a2022da1cc945e4d0c3c1dc014b2 Mon Sep 17 00:00:00 2001 From: default Date: Wed, 8 May 2024 04:15:36 +0200 Subject: More HTML simplification. --- html.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 5521a9f..27fc713 100644 --- a/html.c +++ b/html.c @@ -509,7 +509,7 @@ xs_html *html_instance_head(void) } -static xs_html *html_instance_body(char *title) +static xs_html *html_instance_body(void) { char *host = xs_dict_get(srv_config, "host"); char *sdesc = xs_dict_get(srv_config, "short_description"); @@ -560,13 +560,6 @@ static xs_html *html_instance_body(char *title) xs_html_text(handle))))); } - if (title != NULL) { - xs_html_add(body, - xs_html_tag("h2", - xs_html_attr("class", "snac-header"), - xs_html_text(title))); - } - return body; } @@ -2023,7 +2016,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, } else { head = html_instance_head(); - body = html_instance_body(title); + body = html_instance_body(); } xs_html *html = xs_html_tag("html", @@ -2034,7 +2027,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, xs_html_add(body, html_top_controls(user)); - if (user && title) { + if (title) { xs_html_add(body, xs_html_tag("h2", xs_html_attr("class", "snac-header"), -- cgit v1.2.3 From d27a60dfe7a440ad76540b826d9105a82711f70b Mon Sep 17 00:00:00 2001 From: khm Date: Tue, 7 May 2024 23:28:51 -0700 Subject: allow unboosting your own posts --- html.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index ee5c2cd..018cdc8 100644 --- a/html.c +++ b/html.c @@ -1265,8 +1265,8 @@ xs_html *html_entry_controls(snac *snac, char *actor, const xs_dict *msg, const } if (is_msg_public(msg)) { - if (strcmp(actor, snac->actor) == 0 || xs_list_in(boosts, snac->md5) == -1) { - /* not already boosted or us; add button */ + if (xs_list_in(boosts, snac->md5) == -1) { + /* not already boosted; add button */ xs_html_add(form, html_button("boost", L("Boost"), L("Announce this post to your followers"))); } -- cgit v1.2.3 From be420cae77c6da69a976e15848989a5e52c56403 Mon Sep 17 00:00:00 2001 From: Kelson Vibber Date: Thu, 9 May 2024 04:27:58 +0000 Subject: Set avatars and custom emoji as square (fixes display in Dillo) The minimalist web browser Dillo has recently started up development again. Its CSS implementation only applies the explicitly stated width and height of an image, so avatars were displaying at 2.5 em high, and the full original width. https://dillo-browser.github.io/ --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index ee5c2cd..8bc8cc9 100644 --- a/html.c +++ b/html.c @@ -55,7 +55,7 @@ xs_str *replace_shortnames(xs_str *s, xs_list *tag, int ems) tag_list = xs_dup(tag); } - xs *style = xs_fmt("height: %dem; vertical-align: middle;", ems); + xs *style = xs_fmt("height: %dem; width: %dem; vertical-align: middle;", ems, ems); xs_list *p = tag_list; char *v; -- cgit v1.2.3 From a5766a6c83662efeb9544ab4a14ea4bfa33c5344 Mon Sep 17 00:00:00 2001 From: default Date: Thu, 9 May 2024 10:04:45 +0200 Subject: The /admin page now accepts ?q=regex for a content search. --- html.c | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 4109929..c56f4cb 100644 --- a/html.c +++ b/html.c @@ -2560,35 +2560,48 @@ int html_get_handler(const xs_dict *req, const char *q_path, status = 401; } else { - double t = history_mtime(&snac, "timeline.html_"); + char *q = xs_dict_get(q_vars, "q"); - /* if enabled by admin, return a cached page if its timestamp is: - a) newer than the timeline timestamp - b) newer than the start time of the server - */ - if (cache && t > timeline_mtime(&snac) && t > p_state->srv_start_time) { - snac_debug(&snac, 1, xs_fmt("serving cached timeline")); + if (q && *q) { + /* search by content */ + int to = 0; + xs *tl = content_search(&snac, q, 1, 0, show, &to); - status = history_get(&snac, "timeline.html_", body, b_size, - xs_dict_get(req, "if-none-match"), etag); + *body = html_timeline(&snac, tl, 0, 0, show, 0, NULL, "/admin", 1); + *b_size = strlen(*body); + status = 200; } else { - snac_debug(&snac, 1, xs_fmt("building timeline")); + double t = history_mtime(&snac, "timeline.html_"); - xs *list = timeline_list(&snac, "private", skip, show); - xs *next = timeline_list(&snac, "private", skip + show, 1); + /* if enabled by admin, return a cached page if its timestamp is: + a) newer than the timeline timestamp + b) newer than the start time of the server + */ + if (cache && t > timeline_mtime(&snac) && t > p_state->srv_start_time) { + snac_debug(&snac, 1, xs_fmt("serving cached timeline")); - xs *pins = pinned_list(&snac); - pins = xs_list_cat(pins, list); + status = history_get(&snac, "timeline.html_", body, b_size, + xs_dict_get(req, "if-none-match"), etag); + } + else { + snac_debug(&snac, 1, xs_fmt("building timeline")); - *body = html_timeline(&snac, pins, 0, skip, show, - xs_list_len(next), NULL, "/admin", 1); + xs *list = timeline_list(&snac, "private", skip, show); + xs *next = timeline_list(&snac, "private", skip + show, 1); - *b_size = strlen(*body); - status = 200; + xs *pins = pinned_list(&snac); + pins = xs_list_cat(pins, list); + + *body = html_timeline(&snac, pins, 0, skip, show, + xs_list_len(next), NULL, "/admin", 1); - if (save) - history_add(&snac, "timeline.html_", *body, *b_size, etag); + *b_size = strlen(*body); + status = 200; + + if (save) + history_add(&snac, "timeline.html_", *body, *b_size, etag); + } } } } -- cgit v1.2.3 From 430afe103b9b31c321c13d510250877b1361c965 Mon Sep 17 00:00:00 2001 From: default Date: Thu, 9 May 2024 22:57:08 +0200 Subject: Added a title to search results. --- html.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index c56f4cb..505f41a 100644 --- a/html.c +++ b/html.c @@ -2566,8 +2566,14 @@ int html_get_handler(const xs_dict *req, const char *q_path, /* search by content */ int to = 0; xs *tl = content_search(&snac, q, 1, 0, show, &to); + xs *title = NULL; - *body = html_timeline(&snac, tl, 0, 0, show, 0, NULL, "/admin", 1); + if (xs_list_len(tl)) + title = xs_fmt(L("Search results for '%s'"), q); + else + title = xs_fmt(L("Nothing found for '%s'"), q); + + *body = html_timeline(&snac, tl, 0, 0, show, 0, title, "/admin", 1); *b_size = strlen(*body); status = 200; } -- cgit v1.2.3 From 2b27a0d772cd294cfe1db67bbfdb2b58df585130 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 10 May 2024 11:02:59 +0200 Subject: Some tweaks to web ui search. --- html.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 505f41a..9eefeec 100644 --- a/html.c +++ b/html.c @@ -2565,15 +2565,18 @@ int html_get_handler(const xs_dict *req, const char *q_path, if (q && *q) { /* search by content */ int to = 0; - xs *tl = content_search(&snac, q, 1, 0, show, &to); + xs *tl = content_search(&snac, q, 1, skip ? 10 : 0, skip + show, &to); xs *title = NULL; + xs *page = xs_fmt("/admin?q=%s", q); + int tl_len = xs_list_len(tl); - if (xs_list_len(tl)) + if (tl_len) title = xs_fmt(L("Search results for '%s'"), q); else title = xs_fmt(L("Nothing found for '%s'"), q); - *body = html_timeline(&snac, tl, 0, 0, show, 0, title, "/admin", 1); + *body = html_timeline(&snac, tl, 0, 0, tl_len, + (to || tl_len == skip + show), title, page, 1); *b_size = strlen(*body); status = 200; } -- cgit v1.2.3 From 1531e81a310311656d06c9ee0d31da31493e6de2 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 10 May 2024 11:29:18 +0200 Subject: Added a skip argument to content_search(). --- html.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 9eefeec..d50333a 100644 --- a/html.c +++ b/html.c @@ -2563,20 +2563,22 @@ int html_get_handler(const xs_dict *req, const char *q_path, char *q = xs_dict_get(q_vars, "q"); if (q && *q) { - /* search by content */ + /** search by content **/ int to = 0; - xs *tl = content_search(&snac, q, 1, skip ? 10 : 0, skip + show, &to); + xs *tl = content_search(&snac, q, 1, skip, show, skip ? 10 : 0, &to); xs *title = NULL; xs *page = xs_fmt("/admin?q=%s", q); int tl_len = xs_list_len(tl); if (tl_len) title = xs_fmt(L("Search results for '%s'"), q); + else + if (skip) + title = xs_fmt(L("No more matches for '%s'"), q); else title = xs_fmt(L("Nothing found for '%s'"), q); - *body = html_timeline(&snac, tl, 0, 0, tl_len, - (to || tl_len == skip + show), title, page, 1); + *body = html_timeline(&snac, tl, 0, skip, show, tl_len > 0, title, page, 1); *b_size = strlen(*body); status = 200; } -- cgit v1.2.3 From 5d1577af3ceaad8e3e89cf53a1c523e6a5c710a6 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 10 May 2024 11:55:45 +0200 Subject: More web ui search tweaks baaaaah I'm boring. --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index d50333a..8bcfab3 100644 --- a/html.c +++ b/html.c @@ -2578,7 +2578,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, else title = xs_fmt(L("Nothing found for '%s'"), q); - *body = html_timeline(&snac, tl, 0, skip, show, tl_len > 0, title, page, 1); + *body = html_timeline(&snac, tl, 0, skip, tl_len, tl_len > 0, title, page, 1); *b_size = strlen(*body); status = 200; } -- cgit v1.2.3 From c2c0f3b39b8d893b9041907df375fa20654ad3e2 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 10 May 2024 12:44:26 +0200 Subject: More search tweaks la la la la. --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index 8bcfab3..8139d68 100644 --- a/html.c +++ b/html.c @@ -2578,7 +2578,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, else title = xs_fmt(L("Nothing found for '%s'"), q); - *body = html_timeline(&snac, tl, 0, skip, tl_len, tl_len > 0, title, page, 1); + *body = html_timeline(&snac, tl, 0, skip, tl_len, tl_len == show, title, page, 1); *b_size = strlen(*body); status = 200; } -- cgit v1.2.3 From 767c2d98d519c9bde43788336d269adf353e573f Mon Sep 17 00:00:00 2001 From: default Date: Fri, 10 May 2024 12:49:03 +0200 Subject: Also add the 'More...' link if there was a search timeout. --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index 8139d68..3d378d1 100644 --- a/html.c +++ b/html.c @@ -2578,7 +2578,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, else title = xs_fmt(L("Nothing found for '%s'"), q); - *body = html_timeline(&snac, tl, 0, skip, tl_len, tl_len == show, title, page, 1); + *body = html_timeline(&snac, tl, 0, skip, tl_len, to || tl_len == show, title, page, 1); *b_size = strlen(*body); status = 200; } -- cgit v1.2.3 From f2a33727e781a9f7338d8321b3d5b504ca4dab8e Mon Sep 17 00:00:00 2001 From: default Date: Fri, 10 May 2024 17:54:15 +0200 Subject: Added a search box. --- html.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index 3d378d1..a0a9cf7 100644 --- a/html.c +++ b/html.c @@ -739,7 +739,17 @@ static xs_html *html_user_body(snac *user, int read_only) xs_html_text(" - "), xs_html_tag("a", xs_html_attr("href", instance_url), - xs_html_text(L("instance")))); + xs_html_text(L("instance"))), + xs_html_text(" "), + xs_html_tag("form", + xs_html_attr("style", "display: inline!important"), + xs_html_attr("class", "snac-search-box"), + xs_html_attr("action", admin_url), + xs_html_sctag("input", + xs_html_attr("type", "text"), + xs_html_attr("name", "q"), + xs_html_attr("title", L("Search posts by content (regular expression)")), + xs_html_attr("placeholder", L("Content search"))))); } xs_html_add(body, -- cgit v1.2.3 From 1762e0f1459599524b54aabfd470e171e1d6e592 Mon Sep 17 00:00:00 2001 From: default Date: Sat, 11 May 2024 09:29:38 +0200 Subject: Added an incremental max seconds value to every content search page. --- html.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index a0a9cf7..0cdb608 100644 --- a/html.c +++ b/html.c @@ -2525,7 +2525,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, int skip = 0; int show = xs_number_get(xs_dict_get(srv_config, "max_timeline_entries")); - char *q_vars = xs_dict_get(req, "q_vars"); + xs_dict *q_vars = xs_dict_get(req, "q_vars"); if ((v = xs_dict_get(q_vars, "skip")) != NULL) skip = atoi(v), cache = 0, save = 0; if ((v = xs_dict_get(q_vars, "show")) != NULL) @@ -2575,9 +2575,10 @@ int html_get_handler(const xs_dict *req, const char *q_path, if (q && *q) { /** search by content **/ int to = 0; - xs *tl = content_search(&snac, q, 1, skip, show, skip ? 10 : 0, &to); + int msecs = atoi(xs_dict_get_def(q_vars, "msecs", "0")); + xs *tl = content_search(&snac, q, 1, skip, show, msecs, &to); xs *title = NULL; - xs *page = xs_fmt("/admin?q=%s", q); + xs *page = xs_fmt("/admin?q=%s&msecs=%d", q, msecs + 10); int tl_len = xs_list_len(tl); if (tl_len) -- cgit v1.2.3 From e1ce85debd5b192b5dc56a4e9810839cc52b0f8b Mon Sep 17 00:00:00 2001 From: default Date: Sat, 11 May 2024 18:46:15 +0200 Subject: Unified post-like object type match. --- html.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 0cdb608..12dba6b 100644 --- a/html.c +++ b/html.c @@ -256,7 +256,7 @@ xs_html *html_msg_icon(snac *user, char *actor_id, const xs_dict *msg) int priv = 0; const char *type = xs_dict_get(msg, "type"); - if (xs_match(type, "Note|Question|Page|Article|Video")) + if (xs_match(type, POSTLIKE_OBJECT_TYPE)) url = xs_dict_get(msg, "id"); priv = !is_msg_public(msg); @@ -1405,7 +1405,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, html_msg_icon(read_only ? NULL : user, xs_dict_get(msg, "actor"), msg))); } else - if (!xs_match(type, "Note|Question|Page|Article|Video")) { + if (!xs_match(type, POSTLIKE_OBJECT_TYPE)) { /* skip oddities */ return NULL; } -- cgit v1.2.3 From 6f3763f452ba55ee6ddd9f63f5bc523807e7288f Mon Sep 17 00:00:00 2001 From: default Date: Sat, 11 May 2024 19:15:18 +0200 Subject: Show 'Event' object types as Notes. --- html.c | 1 + 1 file changed, 1 insertion(+) (limited to 'html.c') diff --git a/html.c b/html.c index 12dba6b..201456e 100644 --- a/html.c +++ b/html.c @@ -1407,6 +1407,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, else if (!xs_match(type, POSTLIKE_OBJECT_TYPE)) { /* skip oddities */ + snac_debug(user, 1, xs_fmt("html_entry: ignoring object type '%s' %s", type, id)); return NULL; } -- cgit v1.2.3 From 9acba489fb37f0d3daca45aad17df96a6360efe5 Mon Sep 17 00:00:00 2001 From: default Date: Sat, 11 May 2024 19:35:33 +0200 Subject: Add some special treatment to Event object display. --- html.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 201456e..10b1427 100644 --- a/html.c +++ b/html.c @@ -1374,6 +1374,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, char *type = xs_dict_get(msg, "type"); char *actor; char *v; + int has_title = 0; /* do not show non-public messages in the public timeline */ if ((read_only || !user) && !is_msg_public(msg)) @@ -1484,6 +1485,14 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, } } + if (strcmp(type, "Event") == 0) { + /* add the calendar emoji */ + xs_html_add(score, + xs_html_tag("span", + xs_html_attr("title", L("Event")), + xs_html_raw(" 📅 "))); + } + /* if it's a user from this same instance, add the score */ if (xs_startswith(id, srv_baseurl)) { int n_likes = object_likes_len(id); @@ -1575,11 +1584,13 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, xs_html_add(entry, snac_content_wrap); - if (!xs_is_null(v = xs_dict_get(msg, "name"))) { + if (!has_title && !xs_is_null(v = xs_dict_get(msg, "name"))) { xs_html_add(snac_content_wrap, xs_html_tag("h3", xs_html_attr("class", "snac-entry-title"), xs_html_text(v))); + + has_title = 1; } xs_html *snac_content = NULL; @@ -1604,12 +1615,15 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, } else { /* print the summary as a header (sites like e.g. Friendica can contain one) */ - if (!xs_is_null(v) && *v) + if (!has_title && !xs_is_null(v) && *v) { xs_html_add(snac_content_wrap, xs_html_tag("h3", xs_html_attr("class", "snac-entry-title"), xs_html_text(v))); + has_title = 1; + } + snac_content = xs_html_tag("div", NULL); } -- cgit v1.2.3 From 281f934f74c662d3c2e58db556f3046a736a2f00 Mon Sep 17 00:00:00 2001 From: default Date: Tue, 14 May 2024 05:17:33 +0200 Subject: content_search() also searches the instance timeline. --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index 10b1427..2b0436e 100644 --- a/html.c +++ b/html.c @@ -2604,7 +2604,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, else title = xs_fmt(L("Nothing found for '%s'"), q); - *body = html_timeline(&snac, tl, 0, skip, tl_len, to || tl_len == show, title, page, 1); + *body = html_timeline(&snac, tl, 0, skip, tl_len, to || tl_len == show, title, page, 0); *b_size = strlen(*body); status = 200; } -- cgit v1.2.3 From 34311714ce725da9fae9fea3b29a4988977c79bd Mon Sep 17 00:00:00 2001 From: default Date: Wed, 15 May 2024 05:57:21 +0200 Subject: User search can also be done by tag. --- html.c | 57 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 19 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 2b0436e..6351823 100644 --- a/html.c +++ b/html.c @@ -748,7 +748,7 @@ static xs_html *html_user_body(snac *user, int read_only) xs_html_sctag("input", xs_html_attr("type", "text"), xs_html_attr("name", "q"), - xs_html_attr("title", L("Search posts by content (regular expression)")), + xs_html_attr("title", L("Search posts by content (regular expression) or #tag")), xs_html_attr("placeholder", L("Content search"))))); } @@ -2588,25 +2588,44 @@ int html_get_handler(const xs_dict *req, const char *q_path, char *q = xs_dict_get(q_vars, "q"); if (q && *q) { - /** search by content **/ - int to = 0; - int msecs = atoi(xs_dict_get_def(q_vars, "msecs", "0")); - xs *tl = content_search(&snac, q, 1, skip, show, msecs, &to); - xs *title = NULL; - xs *page = xs_fmt("/admin?q=%s&msecs=%d", q, msecs + 10); - int tl_len = xs_list_len(tl); - - if (tl_len) - title = xs_fmt(L("Search results for '%s'"), q); - else - if (skip) - title = xs_fmt(L("No more matches for '%s'"), q); - else - title = xs_fmt(L("Nothing found for '%s'"), q); + if (*q == '#') { + /** search by tag **/ + xs *tl = tag_search(q, skip, show + 1); + int more = 0; + if (xs_list_len(tl) >= show + 1) { + /* drop the last one */ + tl = xs_list_del(tl, -1); + more = 1; + } - *body = html_timeline(&snac, tl, 0, skip, tl_len, to || tl_len == show, title, page, 0); - *b_size = strlen(*body); - status = 200; + xs *page = xs_fmt("/admin?q=%%23%s", q + 1); + xs *title = xs_fmt(L("Search results for tag %s"), q); + + *body = html_timeline(&snac, tl, 0, skip, show, more, title, page, 0); + *b_size = strlen(*body); + status = 200; + } + else { + /** search by content **/ + int to = 0; + int msecs = atoi(xs_dict_get_def(q_vars, "msecs", "0")); + xs *tl = content_search(&snac, q, 1, skip, show, msecs, &to); + xs *title = NULL; + xs *page = xs_fmt("/admin?q=%s&msecs=%d", q, msecs + 10); + int tl_len = xs_list_len(tl); + + if (tl_len) + title = xs_fmt(L("Search results for '%s'"), q); + else + if (skip) + title = xs_fmt(L("No more matches for '%s'"), q); + else + title = xs_fmt(L("Nothing found for '%s'"), q); + + *body = html_timeline(&snac, tl, 0, skip, tl_len, to || tl_len == show, title, page, 0); + *b_size = strlen(*body); + status = 200; + } } else { double t = history_mtime(&snac, "timeline.html_"); -- cgit v1.2.3 From 4777fc86cb962917a8f34afb3bfa40f26290815d Mon Sep 17 00:00:00 2001 From: default Date: Tue, 21 May 2024 14:12:15 +0200 Subject: Added const everywhere. --- html.c | 278 +++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 143 insertions(+), 135 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 6351823..6521726 100644 --- a/html.c +++ b/html.c @@ -41,7 +41,7 @@ int login(snac *snac, const xs_dict *headers) } -xs_str *replace_shortnames(xs_str *s, xs_list *tag, int ems) +xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems) /* replaces all the :shortnames: with the emojis in tag */ { if (!xs_is_null(tag)) { @@ -57,18 +57,18 @@ xs_str *replace_shortnames(xs_str *s, xs_list *tag, int ems) xs *style = xs_fmt("height: %dem; width: %dem; vertical-align: middle;", ems, ems); - xs_list *p = tag_list; char *v; + int c = 0; - while (xs_list_iter(&p, &v)) { - char *t = xs_dict_get(v, "type"); + while (xs_list_next(tag_list, &v, &c)) { + const char *t = xs_dict_get(v, "type"); if (t && strcmp(t, "Emoji") == 0) { - char *n = xs_dict_get(v, "name"); - char *i = xs_dict_get(v, "icon"); + const char *n = xs_dict_get(v, "name"); + const char *i = xs_dict_get(v, "icon"); if (n && i) { - char *u = xs_dict_get(i, "url"); + const char *u = xs_dict_get(i, "url"); xs_html *img = xs_html_sctag("img", xs_html_attr("loading", "lazy"), xs_html_attr("src", u), @@ -88,7 +88,7 @@ xs_str *replace_shortnames(xs_str *s, xs_list *tag, int ems) xs_str *actor_name(xs_dict *actor) /* gets the actor name */ { - char *v; + const char *v; if (xs_is_null((v = xs_dict_get(actor, "name"))) || *v == '\0') { if (xs_is_null(v = xs_dict_get(actor, "preferredUsername")) || *v == '\0') { @@ -106,7 +106,7 @@ xs_html *html_actor_icon(snac *user, xs_dict *actor, const char *date, xs_html *actor_icon = xs_html_tag("p", NULL); xs *avatar = NULL; - char *v; + const char *v; int fwing = 0; int fwer = 0; @@ -125,7 +125,7 @@ xs_html *html_actor_icon(snac *user, xs_dict *actor, const char *date, if (avatar == NULL) avatar = xs_fmt("data:image/png;base64, %s", default_avatar_base64()); - char *actor_id = xs_dict_get(actor, "id"); + const char *actor_id = xs_dict_get(actor, "id"); xs *href = NULL; if (user) { @@ -216,7 +216,7 @@ xs_html *html_actor_icon(snac *user, xs_dict *actor, const char *date, } { - char *username, *id; + const char *username, *id; if (xs_is_null(username = xs_dict_get(actor, "preferredUsername")) || *username == '\0') { /* This should never be reached */ @@ -244,15 +244,15 @@ xs_html *html_actor_icon(snac *user, xs_dict *actor, const char *date, } -xs_html *html_msg_icon(snac *user, char *actor_id, const xs_dict *msg) +xs_html *html_msg_icon(snac *user, const char *actor_id, const xs_dict *msg) { xs *actor = NULL; xs_html *actor_icon = NULL; if (actor_id && valid_status(actor_get_refresh(user, actor_id, &actor))) { - char *date = NULL; - char *udate = NULL; - char *url = NULL; + const char *date = NULL; + const char *udate = NULL; + const char *url = NULL; int priv = 0; const char *type = xs_dict_get(msg, "type"); @@ -271,14 +271,14 @@ xs_html *html_msg_icon(snac *user, char *actor_id, const xs_dict *msg) } -xs_html *html_note(snac *user, char *summary, - char *div_id, char *form_id, - char *ta_plh, char *ta_content, - char *edit_id, char *actor_id, - xs_val *cw_yn, char *cw_text, - xs_val *mnt_only, char *redir, - char *in_reply_to, int poll, - char *att_file, char *att_alt_text) +xs_html *html_note(snac *user, const char *summary, + const char *div_id, const char *form_id, + const char *ta_plh, const char *ta_content, + const char *edit_id, const char *actor_id, + const xs_val *cw_yn, const char *cw_text, + const xs_val *mnt_only, const char *redir, + const char *in_reply_to, int poll, + const char *att_file, const char *att_alt_text) { xs *action = xs_fmt("%s/admin/note", user->actor); @@ -460,9 +460,11 @@ static xs_html *html_base_head(void) /* add server CSS and favicon */ xs *f; f = xs_fmt("%s/favicon.ico", srv_baseurl); - xs_list *p = xs_dict_get(srv_config, "cssurls"); + const xs_list *p = xs_dict_get(srv_config, "cssurls"); char *v; - while (xs_list_iter(&p, &v)) { + int c = 0; + + while (xs_list_next(p, &v, &c)) { xs_html_add(head, xs_html_sctag("link", xs_html_attr("rel", "stylesheet"), @@ -498,8 +500,8 @@ xs_html *html_instance_head(void) } } - char *host = xs_dict_get(srv_config, "host"); - char *title = xs_dict_get(srv_config, "title"); + const char *host = xs_dict_get(srv_config, "host"); + const char *title = xs_dict_get(srv_config, "title"); xs_html_add(head, xs_html_tag("title", @@ -511,10 +513,10 @@ xs_html *html_instance_head(void) static xs_html *html_instance_body(void) { - char *host = xs_dict_get(srv_config, "host"); - char *sdesc = xs_dict_get(srv_config, "short_description"); - char *email = xs_dict_get(srv_config, "admin_email"); - char *acct = xs_dict_get(srv_config, "admin_account"); + const char *host = xs_dict_get(srv_config, "host"); + const char *sdesc = xs_dict_get(srv_config, "short_description"); + const char *email = xs_dict_get(srv_config, "admin_email"); + const char *acct = xs_dict_get(srv_config, "admin_account"); xs *blurb = xs_replace(snac_blurb, "%host%", host); @@ -760,7 +762,7 @@ static xs_html *html_user_body(snac *user, int read_only) xs_html_attr("class", "h-card snac-top-user")); if (read_only) { - char *header = xs_dict_get(user->config, "header"); + const char *header = xs_dict_get(user->config, "header"); if (header && *header) { xs_html_add(top_user, xs_html_tag("div", @@ -797,7 +799,7 @@ static xs_html *html_user_body(snac *user, int read_only) xs_html_add(top_user, top_user_bio); - xs_dict *metadata = xs_dict_get(user->config, "metadata"); + const xs_dict *metadata = xs_dict_get(user->config, "metadata"); if (xs_type(metadata) == XSTYPE_DICT) { xs_str *k; xs_str *v; @@ -816,7 +818,7 @@ static xs_html *html_user_body(snac *user, int read_only) if (xs_startswith(v, "https:/") || xs_startswith(v, "http:/")) { /* is this link validated? */ xs *verified_link = NULL; - xs_number *val_time = xs_dict_get(val_links, v); + const xs_number *val_time = xs_dict_get(val_links, v); if (xs_type(val_time) == XSTYPE_NUMBER) { time_t t = xs_number_get(val_time); @@ -928,7 +930,7 @@ xs_html *html_top_controls(snac *snac) /** user settings **/ - char *email = "[disabled by admin]"; + const char *email = "[disabled by admin]"; if (xs_type(xs_dict_get(srv_config, "disable_email_notifications")) != XSTYPE_TRUE) { email = xs_dict_get(snac->config_o, "email"); @@ -940,38 +942,38 @@ xs_html *html_top_controls(snac *snac) } } - char *cw = xs_dict_get(snac->config, "cw"); + const char *cw = xs_dict_get(snac->config, "cw"); if (xs_is_null(cw)) cw = ""; - char *telegram_bot = xs_dict_get(snac->config, "telegram_bot"); + const char *telegram_bot = xs_dict_get(snac->config, "telegram_bot"); if (xs_is_null(telegram_bot)) telegram_bot = ""; - char *telegram_chat_id = xs_dict_get(snac->config, "telegram_chat_id"); + const char *telegram_chat_id = xs_dict_get(snac->config, "telegram_chat_id"); if (xs_is_null(telegram_chat_id)) telegram_chat_id = ""; - char *ntfy_server = xs_dict_get(snac->config, "ntfy_server"); + const char *ntfy_server = xs_dict_get(snac->config, "ntfy_server"); if (xs_is_null(ntfy_server)) ntfy_server = ""; - char *ntfy_token = xs_dict_get(snac->config, "ntfy_token"); + const char *ntfy_token = xs_dict_get(snac->config, "ntfy_token"); if (xs_is_null(ntfy_token)) ntfy_token = ""; - char *purge_days = xs_dict_get(snac->config, "purge_days"); + const char *purge_days = xs_dict_get(snac->config, "purge_days"); if (!xs_is_null(purge_days) && xs_type(purge_days) == XSTYPE_NUMBER) purge_days = (char *)xs_number_str(purge_days); else purge_days = "0"; - xs_val *d_dm_f_u = xs_dict_get(snac->config, "drop_dm_from_unknown"); - xs_val *bot = xs_dict_get(snac->config, "bot"); - xs_val *a_private = xs_dict_get(snac->config, "private"); + const xs_val *d_dm_f_u = xs_dict_get(snac->config, "drop_dm_from_unknown"); + const xs_val *bot = xs_dict_get(snac->config, "bot"); + const xs_val *a_private = xs_dict_get(snac->config, "private"); xs *metadata = xs_str_new(NULL); - xs_dict *md = xs_dict_get(snac->config, "metadata"); + const xs_dict *md = xs_dict_get(snac->config, "metadata"); xs_str *k; xs_str *v; @@ -1158,13 +1160,14 @@ xs_str *build_mentions(snac *snac, const xs_dict *msg) /* returns a string with the mentions in msg */ { xs_str *s = xs_str_new(NULL); - char *list = xs_dict_get(msg, "tag"); + const char *list = xs_dict_get(msg, "tag"); char *v; + int c = 0; - while (xs_list_iter(&list, &v)) { - char *type = xs_dict_get(v, "type"); - char *href = xs_dict_get(v, "href"); - char *name = xs_dict_get(v, "name"); + while (xs_list_next(list, &v, &c)) { + const char *type = xs_dict_get(v, "type"); + const char *href = xs_dict_get(v, "href"); + const char *name = xs_dict_get(v, "name"); if (type && strcmp(type, "Mention") == 0 && href && strcmp(href, snac->actor) != 0 && name) { @@ -1208,10 +1211,11 @@ xs_str *build_mentions(snac *snac, const xs_dict *msg) } -xs_html *html_entry_controls(snac *snac, char *actor, const xs_dict *msg, const char *md5) +xs_html *html_entry_controls(snac *snac, const char *actor, + const xs_dict *msg, const char *md5) { - char *id = xs_dict_get(msg, "id"); - char *group = xs_dict_get(msg, "audience"); + const char *id = xs_dict_get(msg, "id"); + const char *group = xs_dict_get(msg, "audience"); xs *likes = object_likes(id); xs *boosts = object_announces(id); @@ -1310,7 +1314,7 @@ xs_html *html_entry_controls(snac *snac, char *actor, const xs_dict *msg, const html_button("delete", L("Delete"), L("Delete this post")), html_button("hide", L("Hide"), L("Hide this post and its children"))); - char *prev_src = xs_dict_get(msg, "sourceContent"); + const char *prev_src = xs_dict_get(msg, "sourceContent"); if (!xs_is_null(prev_src) && strcmp(actor, snac->actor) == 0) { /** edit **/ /* post can be edited */ @@ -1318,13 +1322,13 @@ xs_html *html_entry_controls(snac *snac, char *actor, const xs_dict *msg, const xs *form_id = xs_fmt("%s_edit_form", md5); xs *redir = xs_fmt("%s_entry", md5); - char *att_file = ""; - char *att_alt_text = ""; - xs_list *att_list = xs_dict_get(msg, "attachment"); + const char *att_file = ""; + const char *att_alt_text = ""; + const xs_list *att_list = xs_dict_get(msg, "attachment"); /* does it have an attachment? */ if (xs_type(att_list) == XSTYPE_LIST && xs_list_len(att_list)) { - xs_dict *d = xs_list_get(att_list, 0); + const xs_dict *d = xs_list_get(att_list, 0); if (xs_type(d) == XSTYPE_DICT) { att_file = xs_dict_get_def(d, "url", ""); @@ -1370,10 +1374,10 @@ xs_html *html_entry_controls(snac *snac, char *actor, const xs_dict *msg, const xs_html *html_entry(snac *user, xs_dict *msg, int read_only, int level, char *md5, int hide_children) { - char *id = xs_dict_get(msg, "id"); - char *type = xs_dict_get(msg, "type"); - char *actor; - char *v; + const char *id = xs_dict_get(msg, "id"); + const char *type = xs_dict_get(msg, "type"); + const char *actor; + const char *v; int has_title = 0; /* do not show non-public messages in the public timeline */ @@ -1509,7 +1513,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, if (xs_list_len(boosts)) { /* if somebody boosted this, show as origin */ - char *p = xs_list_get(boosts, -1); + const char *p = xs_list_get(boosts, -1); xs *actor_r = NULL; if (user && xs_list_in(boosts, user->md5) != -1) { @@ -1529,7 +1533,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, if (!xs_is_null(name)) { xs *href = NULL; - char *id = xs_dict_get(actor_r, "id"); + const char *id = xs_dict_get(actor_r, "id"); int fwers = 0; int fwing = 0; @@ -1558,7 +1562,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, if (strcmp(type, "Note") == 0) { if (level == 0) { /* is the parent not here? */ - char *parent = xs_dict_get(msg, "inReplyTo"); + const char *parent = xs_dict_get(msg, "inReplyTo"); if (user && !xs_is_null(parent) && *parent && !timeline_here(user, parent)) { xs_html_add(post_header, @@ -1603,7 +1607,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, v = "..."; /* only show it when not in the public timeline and the config setting is "open" */ - char *cw = xs_dict_get(user->config, "cw"); + const char *cw = xs_dict_get(user->config, "cw"); if (xs_is_null(cw) || read_only) cw = ""; @@ -1632,7 +1636,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, { /** build the content string **/ - char *content = xs_dict_get(msg, "content"); + const char *content = xs_dict_get(msg, "content"); xs *c = sanitize(xs_is_null(content) ? "" : content); @@ -1650,7 +1654,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, c = replace_shortnames(c, xs_dict_get(msg, "tag"), 2); /* Peertube videos content is in markdown */ - char *mtype = xs_dict_get(msg, "mediaType"); + const char *mtype = xs_dict_get(msg, "mediaType"); if (xs_type(mtype) == XSTYPE_STRING && strcmp(mtype, "text/markdown") == 0) { /* a full conversion could be better */ c = xs_replace_i(c, "\r", ""); @@ -1663,12 +1667,12 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, } if (strcmp(type, "Question") == 0) { /** question content **/ - xs_list *oo = xs_dict_get(msg, "oneOf"); - xs_list *ao = xs_dict_get(msg, "anyOf"); - xs_list *p; + const xs_list *oo = xs_dict_get(msg, "oneOf"); + const xs_list *ao = xs_dict_get(msg, "anyOf"); + const xs_list *p; xs_dict *v; int closed = 0; - char *f_closed = NULL; + const char *f_closed = NULL; xs_html *poll = xs_html_tag("div", NULL); @@ -1697,10 +1701,11 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, /* closed poll */ xs_html *poll_result = xs_html_tag("table", xs_html_attr("class", "snac-poll-result")); + int c = 0; - while (xs_list_iter(&p, &v)) { - char *name = xs_dict_get(v, "name"); - xs_dict *replies = xs_dict_get(v, "replies"); + while (xs_list_next(p, &v, &c)) { + const char *name = xs_dict_get(v, "name"); + const xs_dict *replies = xs_dict_get(v, "replies"); if (name && replies) { char *ti = (char *)xs_number_str(xs_dict_get(replies, "totalItems")); @@ -1737,9 +1742,10 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, xs_html_attr("name", "irt"), xs_html_attr("value", id)))); - while (xs_list_iter(&p, &v)) { - char *name = xs_dict_get(v, "name"); - xs_dict *replies = xs_dict_get(v, "replies"); + int c = 0; + while (xs_list_next(p, &v, &c)) { + const char *name = xs_dict_get(v, "name"); + const xs_dict *replies = xs_dict_get(v, "replies"); if (name) { char *ti = (char *)xs_number_str(xs_dict_get(replies, "totalItems")); @@ -1777,7 +1783,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, } else { /* show when the poll closes */ - char *end_time = xs_dict_get(msg, "endTime"); + const char *end_time = xs_dict_get(msg, "endTime"); /* Pleroma does not have an endTime field; it has a closed time in the future */ @@ -1820,12 +1826,12 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, xs_html_add(snac_content, content_attachments); - xs_list *p = attach; - - while (xs_list_iter(&p, &v)) { - char *type = xs_dict_get(v, "type"); - char *href = xs_dict_get(v, "href"); - char *name = xs_dict_get(v, "name"); + int c = 0; + xs_dict *a; + while (xs_list_next(attach, &a, &c)) { + const char *type = xs_dict_get(a, "type"); + const char *href = xs_dict_get(a, "href"); + const char *name = xs_dict_get(a, "name"); if (xs_startswith(type, "image/") || strcmp(type, "Image") == 0) { xs_html_add(content_attachments, @@ -1889,7 +1895,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, } /* has this message an audience (i.e., comes from a channel or community)? */ - char *audience = xs_dict_get(msg, "audience"); + const char *audience = xs_dict_get(msg, "audience"); if (strcmp(type, "Page") == 0 && !xs_is_null(audience)) { xs_html *au_tag = xs_html_tag("p", xs_html_text("("), @@ -2023,11 +2029,12 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, if (xs_list_len(list) == 1) { /* only one element? pick the description from the source */ - char *id = xs_list_get(list, 0); + const char *id = xs_list_get(list, 0); xs *d = NULL; object_get_by_md5(id, &d); - if (d && (v = xs_dict_get(d, "sourceContent")) != NULL) - desc = xs_dup(v); + const char *sc = xs_dict_get(d, "sourceContent"); + if (d && sc != NULL) + desc = xs_dup(sc); alternate = xs_dup(xs_dict_get(d, "id")); } @@ -2087,13 +2094,13 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, /* is this message a non-public reply? */ if (user != NULL && !is_msg_public(msg)) { - char *irt = xs_dict_get(msg, "inReplyTo"); + const char *irt = xs_dict_get(msg, "inReplyTo"); /* is it a reply to something not in the storage? */ if (!xs_is_null(irt) && !object_here(irt)) { /* is it for me? */ - xs_list *to = xs_dict_get_def(msg, "to", xs_stock(XSTYPE_LIST)); - xs_list *cc = xs_dict_get_def(msg, "cc", xs_stock(XSTYPE_LIST)); + const xs_list *to = xs_dict_get_def(msg, "to", xs_stock(XSTYPE_LIST)); + const xs_list *cc = xs_dict_get_def(msg, "cc", xs_stock(XSTYPE_LIST)); if (xs_list_in(to, user->actor) == -1 && xs_list_in(cc, user->actor) == -1) { snac_debug(user, 1, xs_fmt("skipping non-public reply to an unknown post %s", v)); @@ -2212,7 +2219,7 @@ xs_html *html_people_list(snac *snac, xs_list *list, char *header, char *t) html_actor_icon(snac, actor, xs_dict_get(actor, "published"), NULL, NULL, 0, 1))); /* content (user bio) */ - char *c = xs_dict_get(actor, "summary"); + const char *c = xs_dict_get(actor, "summary"); if (!xs_is_null(c)) { xs *sc = sanitize(c); @@ -2364,10 +2371,10 @@ xs_str *html_notifications(snac *user, int skip, int show) continue; xs *obj = NULL; - char *type = xs_dict_get(noti, "type"); - char *utype = xs_dict_get(noti, "utype"); - char *id = xs_dict_get(noti, "objid"); - char *date = xs_dict_get(noti, "date"); + const char *type = xs_dict_get(noti, "type"); + const char *utype = xs_dict_get(noti, "utype"); + const char *id = xs_dict_get(noti, "objid"); + const char *date = xs_dict_get(noti, "date"); if (xs_is_null(id) || !valid_status(object_get(id, &obj))) continue; @@ -2375,14 +2382,14 @@ xs_str *html_notifications(snac *user, int skip, int show) if (is_hidden(user, id)) continue; - char *actor_id = xs_dict_get(noti, "actor"); + const char *actor_id = xs_dict_get(noti, "actor"); xs *actor = NULL; if (!valid_status(actor_get(actor_id, &actor))) continue; xs *a_name = actor_name(actor); - char *label = type; + const char *label = type; if (strcmp(type, "Create") == 0) label = L("Mention"); @@ -2494,14 +2501,14 @@ xs_str *html_notifications(snac *user, int skip, int show) int html_get_handler(const xs_dict *req, const char *q_path, char **body, int *b_size, char **ctype, xs_str **etag) { - char *accept = xs_dict_get(req, "accept"); + const char *accept = xs_dict_get(req, "accept"); int status = 404; snac snac; xs *uid = NULL; - char *p_path; + const char *p_path; int cache = 1; int save = 1; - char *v; + const char *v; xs *l = xs_split_n(q_path, "/", 2); v = xs_list_get(l, 1); @@ -2540,7 +2547,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, int skip = 0; int show = xs_number_get(xs_dict_get(srv_config, "max_timeline_entries")); - xs_dict *q_vars = xs_dict_get(req, "q_vars"); + const xs_dict *q_vars = xs_dict_get(req, "q_vars"); if ((v = xs_dict_get(q_vars, "skip")) != NULL) skip = atoi(v), cache = 0, save = 0; if ((v = xs_dict_get(q_vars, "show")) != NULL) @@ -2585,7 +2592,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, status = 401; } else { - char *q = xs_dict_get(q_vars, "q"); + const char *q = xs_dict_get(q_vars, "q"); if (q && *q) { if (*q == '#') { @@ -2669,7 +2676,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, } else { xs *l = xs_split(p_path, "/"); - char *md5 = xs_list_get(l, -1); + const char *md5 = xs_list_get(l, -1); if (md5 && *md5 && timeline_here(&snac, md5)) { xs *list = xs_list_append(xs_list_new(), md5); @@ -2728,7 +2735,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, } else { xs *l = xs_split(p_path, "/"); - char *lid = xs_list_get(l, -1); + const char *lid = xs_list_get(l, -1); xs *list = list_timeline(&snac, lid, skip, show); xs *next = list_timeline(&snac, lid, skip + show, 1); @@ -2767,7 +2774,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, else if (xs_startswith(p_path, "s/")) { /** a static file **/ xs *l = xs_split(p_path, "/"); - char *id = xs_list_get(l, 1); + const char *id = xs_list_get(l, 1); int sz; if (id && *id) { @@ -2788,8 +2795,8 @@ int html_get_handler(const xs_dict *req, const char *q_path, if (xs_type(xs_dict_get(srv_config, "disable_history")) == XSTYPE_TRUE) return 403; - xs *l = xs_split(p_path, "/"); - char *id = xs_list_get(l, 1); + xs *l = xs_split(p_path, "/"); + const char *id = xs_list_get(l, 1); if (id && *id) { if (xs_endswith(id, "timeline.html_")) { @@ -2845,8 +2852,9 @@ int html_post_handler(const xs_dict *req, const char *q_path, int status = 0; snac snac; - char *uid, *p_path; - xs_dict *p_vars; + const char *uid; + const char *p_path; + const xs_dict *p_vars; xs *l = xs_split_n(q_path, "/", 2); @@ -2874,15 +2882,15 @@ int html_post_handler(const xs_dict *req, const char *q_path, if (p_path && strcmp(p_path, "admin/note") == 0) { /** **/ /* post note */ - xs_str *content = xs_dict_get(p_vars, "content"); - xs_str *in_reply_to = xs_dict_get(p_vars, "in_reply_to"); - xs_str *attach_url = xs_dict_get(p_vars, "attach_url"); - xs_list *attach_file = xs_dict_get(p_vars, "attach"); - xs_str *to = xs_dict_get(p_vars, "to"); - xs_str *sensitive = xs_dict_get(p_vars, "sensitive"); - xs_str *summary = xs_dict_get(p_vars, "summary"); - xs_str *edit_id = xs_dict_get(p_vars, "edit_id"); - xs_str *alt_text = xs_dict_get(p_vars, "alt_text"); + const xs_str *content = xs_dict_get(p_vars, "content"); + const xs_str *in_reply_to = xs_dict_get(p_vars, "in_reply_to"); + const xs_str *attach_url = xs_dict_get(p_vars, "attach_url"); + const xs_list *attach_file = xs_dict_get(p_vars, "attach"); + const xs_str *to = xs_dict_get(p_vars, "to"); + const xs_str *sensitive = xs_dict_get(p_vars, "sensitive"); + const xs_str *summary = xs_dict_get(p_vars, "summary"); + const xs_str *edit_id = xs_dict_get(p_vars, "edit_id"); + const xs_str *alt_text = xs_dict_get(p_vars, "alt_text"); int priv = !xs_is_null(xs_dict_get(p_vars, "mentioned_only")); xs *attach_list = xs_list_new(); @@ -2902,7 +2910,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, /* is attach_file set? */ if (!xs_is_null(attach_file) && xs_type(attach_file) == XSTYPE_LIST) { - char *fn = xs_list_get(attach_file, 0); + const char *fn = xs_list_get(attach_file, 0); if (*fn != '\0') { char *ext = strrchr(fn, '.'); @@ -2978,7 +2986,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, int n; for (n = 0; fields[n]; n++) { - char *v = xs_dict_get(p_msg, fields[n]); + const char *v = xs_dict_get(p_msg, fields[n]); msg = xs_dict_set(msg, fields[n], v); } @@ -3007,10 +3015,10 @@ int html_post_handler(const xs_dict *req, const char *q_path, else if (p_path && strcmp(p_path, "admin/action") == 0) { /** **/ /* action on an entry */ - char *id = xs_dict_get(p_vars, "id"); - char *actor = xs_dict_get(p_vars, "actor"); - char *action = xs_dict_get(p_vars, "action"); - char *group = xs_dict_get(p_vars, "group"); + const char *id = xs_dict_get(p_vars, "id"); + const char *actor = xs_dict_get(p_vars, "actor"); + const char *action = xs_dict_get(p_vars, "action"); + const char *group = xs_dict_get(p_vars, "group"); if (action == NULL) return 404; @@ -3134,7 +3142,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, } else if (strcmp(action, L("Delete")) == 0) { /** **/ - char *actor_form = xs_dict_get(p_vars, "actor-form"); + const char *actor_form = xs_dict_get(p_vars, "actor-form"); if (actor_form != NULL) { /* delete follower */ if (valid_status(follower_del(&snac, actor))) @@ -3178,8 +3186,8 @@ int html_post_handler(const xs_dict *req, const char *q_path, else if (p_path && strcmp(p_path, "admin/user-setup") == 0) { /** **/ /* change of user data */ - char *v; - char *p1, *p2; + const char *v; + const char *p1, *p2; if ((v = xs_dict_get(p_vars, "name")) != NULL) snac.config = xs_dict_set(snac.config, "name", v); @@ -3245,7 +3253,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, for (n = 0; uploads[n]; n++) { xs *var_name = xs_fmt("%s_file", uploads[n]); - xs_list *uploaded_file = xs_dict_get(p_vars, var_name); + const xs_list *uploaded_file = xs_dict_get(p_vars, var_name); if (xs_type(uploaded_file) == XSTYPE_LIST) { const char *fn = xs_list_get(uploaded_file, 0); @@ -3310,7 +3318,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, } else if (p_path && strcmp(p_path, "admin/vote") == 0) { /** **/ - char *irt = xs_dict_get(p_vars, "irt"); + const char *irt = xs_dict_get(p_vars, "irt"); const char *opt = xs_dict_get(p_vars, "question"); const char *actor = xs_dict_get(p_vars, "actor"); @@ -3345,7 +3353,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, xs *poll = NULL; if (valid_status(object_get(irt, &poll))) { - char *date = xs_dict_get(poll, "endTime"); + const char *date = xs_dict_get(poll, "endTime"); if (xs_is_null(date)) date = xs_dict_get(poll, "closed"); @@ -3363,7 +3371,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, } if (status == 303) { - char *redir = xs_dict_get(p_vars, "redir"); + const char *redir = xs_dict_get(p_vars, "redir"); if (xs_is_null(redir)) redir = "top"; @@ -3411,8 +3419,8 @@ xs_str *timeline_to_rss(snac *user, const xs_list *timeline, char *title, char * continue; } - char *id = xs_dict_get(msg, "id"); - char *content = xs_dict_get(msg, "content"); + const char *id = xs_dict_get(msg, "id"); + const char *content = xs_dict_get(msg, "content"); if (user && !xs_startswith(id, user->actor)) continue; -- cgit v1.2.3 From 8cf7559a7e21c5757455b948814d61e6e96f08f1 Mon Sep 17 00:00:00 2001 From: default Date: Thu, 23 May 2024 10:01:37 +0200 Subject: Added more const. --- html.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index 6521726..11fe4bf 100644 --- a/html.c +++ b/html.c @@ -57,7 +57,7 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems) xs *style = xs_fmt("height: %dem; width: %dem; vertical-align: middle;", ems, ems); - char *v; + const char *v; int c = 0; while (xs_list_next(tag_list, &v, &c)) { @@ -461,7 +461,7 @@ static xs_html *html_base_head(void) xs *f; f = xs_fmt("%s/favicon.ico", srv_baseurl); const xs_list *p = xs_dict_get(srv_config, "cssurls"); - char *v; + const char *v; int c = 0; while (xs_list_next(p, &v, &c)) { @@ -801,8 +801,8 @@ static xs_html *html_user_body(snac *user, int read_only) const xs_dict *metadata = xs_dict_get(user->config, "metadata"); if (xs_type(metadata) == XSTYPE_DICT) { - xs_str *k; - xs_str *v; + const xs_str *k; + const xs_str *v; xs_dict *val_links = user->links; if (xs_is_null(val_links)) @@ -974,8 +974,8 @@ xs_html *html_top_controls(snac *snac) xs *metadata = xs_str_new(NULL); const xs_dict *md = xs_dict_get(snac->config, "metadata"); - xs_str *k; - xs_str *v; + const xs_str *k; + const xs_str *v; int c = 0; while (xs_dict_next(md, &k, &v, &c)) { @@ -1161,7 +1161,7 @@ xs_str *build_mentions(snac *snac, const xs_dict *msg) { xs_str *s = xs_str_new(NULL); const char *list = xs_dict_get(msg, "tag"); - char *v; + const char *v; int c = 0; while (xs_list_next(list, &v, &c)) { @@ -1372,7 +1372,7 @@ xs_html *html_entry_controls(snac *snac, const char *actor, xs_html *html_entry(snac *user, xs_dict *msg, int read_only, - int level, char *md5, int hide_children) + int level, const char *md5, int hide_children) { const char *id = xs_dict_get(msg, "id"); const char *type = xs_dict_get(msg, "type"); @@ -1670,7 +1670,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, const xs_list *oo = xs_dict_get(msg, "oneOf"); const xs_list *ao = xs_dict_get(msg, "anyOf"); const xs_list *p; - xs_dict *v; + const xs_dict *v; int closed = 0; const char *f_closed = NULL; @@ -1827,7 +1827,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, content_attachments); int c = 0; - xs_dict *a; + const xs_dict *a; while (xs_list_next(attach, &a, &c)) { const char *type = xs_dict_get(a, "type"); const char *href = xs_dict_get(a, "href"); @@ -1945,7 +1945,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, } xs_list *p = children; - char *cmd5; + const char *cmd5; int cnt = 0; int o_cnt = 0; @@ -2021,7 +2021,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, /* returns the HTML for the timeline */ { xs_list *p = (xs_list *)list; - char *v; + const char *v; double t = ftime(); xs *desc = NULL; @@ -2130,7 +2130,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, xs *list = history_list(user); xs_list *p = list; - char *v; + const char *v; while (xs_list_iter(&p, &v)) { xs *fn = xs_replace(v, ".html", ""); @@ -2203,7 +2203,7 @@ xs_html *html_people_list(snac *snac, xs_list *list, char *header, char *t) xs_html_text("...")))); xs_list *p = list; - char *actor_id; + const char *actor_id; while (xs_list_iter(&p, &actor_id)) { xs *md5 = xs_md5_hex(actor_id, strlen(actor_id)); @@ -2363,7 +2363,7 @@ xs_str *html_notifications(snac *user, int skip, int show) xs_html *noti_seen = NULL; xs_list *p = n_list; - xs_str *v; + const xs_str *v; while (xs_list_iter(&p, &v)) { xs *noti = notify_get(user, v); @@ -3232,7 +3232,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, xs_dict *md = xs_dict_new(); xs *l = xs_split(v, "\n"); xs_list *p = l; - xs_str *kp; + const xs_str *kp; while (xs_list_iter(&p, &kp)) { xs *kpl = xs_split_n(kp, "=", 1); @@ -3333,7 +3333,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, } xs_list *p = ls; - xs_str *v; + const xs_str *v; while (xs_list_iter(&p, &v)) { xs *msg = msg_note(&snac, "", actor, irt, NULL, 1); @@ -3405,7 +3405,7 @@ xs_str *timeline_to_rss(snac *user, const xs_list *timeline, char *title, char * xs_html_add(rss, channel); int c = 0; - char *v; + const char *v; while (xs_list_next(timeline, &v, &c)) { xs *msg = NULL; -- cgit v1.2.3 From a787c818b2c52b5bf30d13bb8f3490a92dd8bdcb Mon Sep 17 00:00:00 2001 From: default Date: Fri, 24 May 2024 12:12:03 +0200 Subject: Added links to the lists in html_timeline(). --- html.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'html.c') diff --git a/html.c b/html.c index 11fe4bf..a9b82da 100644 --- a/html.c +++ b/html.c @@ -2066,6 +2066,31 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, xs_html_text(title))); } + /* show links to the available lists */ + { + xs *lists = list_maint(user, NULL, 0); /* get list of lists */ + + if (xs_list_len(lists)) { + int ct = 0; + const char *v; + + xs_html *lol = xs_html_tag("ul", + xs_html_attr("class", "snac-list-of-lists")); + xs_html_add(body, lol); + + while (xs_list_next(lists, &v, &ct)) { + xs *url = xs_fmt("%s/list/%s", user->actor, xs_list_get(v, 0)); + + xs_html_add(lol, + xs_html_tag("li", + xs_html_tag("a", + xs_html_attr("href", url), + xs_html_attr("class", "snac-list-link"), + xs_html_text(xs_list_get(v, 1))))); + } + } + } + xs_html_add(body, xs_html_tag("a", xs_html_attr("name", "snac-posts"))); -- cgit v1.2.3 From 8ebad8d536dfdcec568e3a926e3c8796a0305ab5 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 24 May 2024 12:24:23 +0200 Subject: Minor list show tweaks. --- html.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'html.c') diff --git a/html.c b/html.c index a9b82da..e77771f 100644 --- a/html.c +++ b/html.c @@ -2059,13 +2059,6 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, xs_html_add(body, html_top_controls(user)); - if (title) { - xs_html_add(body, - xs_html_tag("h2", - xs_html_attr("class", "snac-header"), - xs_html_text(title))); - } - /* show links to the available lists */ { xs *lists = list_maint(user, NULL, 0); /* get list of lists */ @@ -2091,6 +2084,13 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, } } + if (title) { + xs_html_add(body, + xs_html_tag("h2", + xs_html_attr("class", "snac-header"), + xs_html_text(title))); + } + xs_html_add(body, xs_html_tag("a", xs_html_attr("name", "snac-posts"))); @@ -2768,7 +2768,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, if (list != NULL) { xs *base = xs_fmt("/list/%s", lid); xs *name = list_maint(&snac, lid, 3); - xs *title = xs_fmt(L("Showing timeline for list %s"), name); + xs *title = xs_fmt(L("Showing timeline for list '%s'"), name); *body = html_timeline(&snac, list, 0, skip, show, xs_list_len(next), title, base, 1); -- cgit v1.2.3 From bd4511e7c50cc92739d2762cd9d69ebc8d0b8e94 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 24 May 2024 12:31:41 +0200 Subject: Show 'Nothing found for tag' message. --- html.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index e77771f..4e29bd7 100644 --- a/html.c +++ b/html.c @@ -2631,7 +2631,8 @@ int html_get_handler(const xs_dict *req, const char *q_path, } xs *page = xs_fmt("/admin?q=%%23%s", q + 1); - xs *title = xs_fmt(L("Search results for tag %s"), q); + xs *title = xs_fmt(xs_list_len(tl) ? + L("Search results for tag %s") : L("Nothing found for tag %s"), q); *body = html_timeline(&snac, tl, 0, skip, show, more, title, page, 0); *b_size = strlen(*body); -- cgit v1.2.3 From a727bb29f6a4b1e66a4ad0664e4557f69d1e2ac4 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 24 May 2024 12:36:08 +0200 Subject: Don't show list links in read only timelines. --- html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index 4e29bd7..e89fdfb 100644 --- a/html.c +++ b/html.c @@ -2060,7 +2060,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, html_top_controls(user)); /* show links to the available lists */ - { + if (user && !read_only) { xs *lists = list_maint(user, NULL, 0); /* get list of lists */ if (xs_list_len(lists)) { -- cgit v1.2.3 From f631fc5ed22cb49d9d9f6a481f4a5d227c180246 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 24 May 2024 19:06:39 +0200 Subject: Added a 'title' to each list timeline. --- html.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'html.c') diff --git a/html.c b/html.c index e89fdfb..f97c45d 100644 --- a/html.c +++ b/html.c @@ -2072,14 +2072,17 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, xs_html_add(body, lol); while (xs_list_next(lists, &v, &ct)) { + const char *lname = xs_list_get(v, 1); xs *url = xs_fmt("%s/list/%s", user->actor, xs_list_get(v, 0)); + xs *ttl = xs_fmt(L("Timeline for list '%s'"), lname); xs_html_add(lol, xs_html_tag("li", xs_html_tag("a", xs_html_attr("href", url), xs_html_attr("class", "snac-list-link"), - xs_html_text(xs_list_get(v, 1))))); + xs_html_attr("title", ttl), + xs_html_text(lname)))); } } } -- cgit v1.2.3