summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.md14
-rw-r--r--activitypub.c20
-rw-r--r--data.c2
-rw-r--r--doc/snac.52
-rw-r--r--html.c4
-rw-r--r--httpd.c14
-rw-r--r--main.c6
-rw-r--r--mastoapi.c24
-rw-r--r--snac.h1
9 files changed, 69 insertions, 18 deletions
diff --git a/TODO.md b/TODO.md
index 619364c..0f2cbd0 100644
--- a/TODO.md
+++ b/TODO.md
@@ -16,10 +16,6 @@ Important: deleting a follower should do more that just delete the object, see h
16 16
17## Wishlist 17## Wishlist
18 18
19Implement Proxying for Media Links to Enhance User Privacy (see https://codeberg.org/grunfink/snac2/issues/219 for more information).
20
21Consider showing only posts by the account owner (not full trees) (see https://codeberg.org/grunfink/snac2/issues/217 for more information).
22
23Add support for subscribing and posting to relays (see https://codeberg.org/grunfink/snac2/issues/216 for more information). 19Add support for subscribing and posting to relays (see https://codeberg.org/grunfink/snac2/issues/216 for more information).
24 20
25The instance timeline should also show boosts from users. 21The instance timeline should also show boosts from users.
@@ -357,3 +353,13 @@ Fix a crash when posting from the links browser (2.63, 2024-11-08T15:57:25+0100)
357Fix some repeated images in Lemmy posts (2.63, 2024-11-08T15:57:25+0100). 353Fix some repeated images in Lemmy posts (2.63, 2024-11-08T15:57:25+0100).
358 354
359Fix a crash when posting an image from the tooot mobile app (2.63, 2024-11-11T19:42:11+0100). 355Fix a crash when posting an image from the tooot mobile app (2.63, 2024-11-11T19:42:11+0100).
356
357Fix some URL proxying (2.64, 2024-11-16T07:26:23+0100).
358
359Allow underscores in hashtags (2.64, 2024-11-16T07:26:23+0100).
360
361Add a pidfile (2.64, 2024-11-17T10:21:29+0100).
362
363Implement Proxying for Media Links to Enhance User Privacy (see https://codeberg.org/grunfink/snac2/issues/219 for more information) (2024-11-18T20:36:39+0100).
364
365Consider showing only posts by the account owner (not full trees) (see https://codeberg.org/grunfink/snac2/issues/217 for more information) (2024-11-18T20:36:39+0100).
diff --git a/activitypub.c b/activitypub.c
index 0b2fc6a..473675d 100644
--- a/activitypub.c
+++ b/activitypub.c
@@ -183,6 +183,18 @@ const char *get_atto(const xs_dict *msg)
183} 183}
184 184
185 185
186const char *get_in_reply_to(const xs_dict *msg)
187/* gets the inReplyTo id */
188{
189 const xs_val *in_reply_to = xs_dict_get(msg, "inReplyTo");
190
191 if (xs_type(in_reply_to) == XSTYPE_DICT)
192 in_reply_to = xs_dict_get(in_reply_to, "id");
193
194 return in_reply_to;
195}
196
197
186xs_list *get_attachments(const xs_dict *msg) 198xs_list *get_attachments(const xs_dict *msg)
187/* unify the garbage fire that are the attachments */ 199/* unify the garbage fire that are the attachments */
188{ 200{
@@ -373,7 +385,7 @@ int timeline_request(snac *snac, const char **id, xs_str **wrk, int level)
373 } 385 }
374 386
375 /* does it have an ancestor? */ 387 /* does it have an ancestor? */
376 const char *in_reply_to = xs_dict_get(object, "inReplyTo"); 388 const char *in_reply_to = get_in_reply_to(object);
377 389
378 /* store */ 390 /* store */
379 timeline_add(snac, nid, object); 391 timeline_add(snac, nid, object);
@@ -671,7 +683,7 @@ int is_msg_for_me(snac *snac, const xs_dict *c_msg)
671 return 3; 683 return 3;
672 684
673 /* is this message a reply to another? */ 685 /* is this message a reply to another? */
674 const char *irt = xs_dict_get(msg, "inReplyTo"); 686 const char *irt = get_in_reply_to(msg);
675 if (!xs_is_null(irt)) { 687 if (!xs_is_null(irt)) {
676 xs *r_msg = NULL; 688 xs *r_msg = NULL;
677 689
@@ -724,7 +736,7 @@ xs_str *process_tags(snac *snac, const char *content, xs_list **tag)
724 /* use this same server */ 736 /* use this same server */
725 def_srv = xs_dup(xs_dict_get(srv_config, "host")); 737 def_srv = xs_dup(xs_dict_get(srv_config, "host"));
726 738
727 split = xs_regex_split(content, "(@[A-Za-z0-9_]+(@[A-Za-z0-9\\.-]+)?|&#[0-9]+;|#[^[:punct:][:space:]]+)"); 739 split = xs_regex_split(content, "(@[A-Za-z0-9_]+(@[A-Za-z0-9\\.-]+)?|&#[0-9]+;|#(_|[^[:punct:][:space:]])+)");
728 740
729 p = split; 741 p = split;
730 while (xs_list_iter(&p, &v)) { 742 while (xs_list_iter(&p, &v)) {
@@ -1957,7 +1969,7 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req)
1957 1969
1958 if (xs_match(utype, "Note|Article")) { /** **/ 1970 if (xs_match(utype, "Note|Article")) { /** **/
1959 const char *id = xs_dict_get(object, "id"); 1971 const char *id = xs_dict_get(object, "id");
1960 const char *in_reply_to = xs_dict_get(object, "inReplyTo"); 1972 const char *in_reply_to = get_in_reply_to(object);
1961 const char *atto = get_atto(object); 1973 const char *atto = get_atto(object);
1962 xs *wrk = NULL; 1974 xs *wrk = NULL;
1963 1975
diff --git a/data.c b/data.c
index 54099db..6f93098 100644
--- a/data.c
+++ b/data.c
@@ -762,7 +762,7 @@ int _object_add(const char *id, const xs_dict *obj, int ow)
762 fclose(f); 762 fclose(f);
763 763
764 /* does this object has a parent? */ 764 /* does this object has a parent? */
765 const char *in_reply_to = xs_dict_get(obj, "inReplyTo"); 765 const char *in_reply_to = get_in_reply_to(obj);
766 766
767 if (!xs_is_null(in_reply_to) && *in_reply_to) { 767 if (!xs_is_null(in_reply_to) && *in_reply_to) {
768 /* update the children index of the parent */ 768 /* update the children index of the parent */
diff --git a/doc/snac.5 b/doc/snac.5
index 1b28d25..0168430 100644
--- a/doc/snac.5
+++ b/doc/snac.5
@@ -209,6 +209,8 @@ web interface.
209.It Pa history/ 209.It Pa history/
210This directory contains generated HTML files. They may be snapshots of the 210This directory contains generated HTML files. They may be snapshots of the
211local timeline in previous months or other cached data. 211local timeline in previous months or other cached data.
212.It Pa server.pid
213This file stores the server PID in a single text line.
212.El 214.El
213.Sh SEE ALSO 215.Sh SEE ALSO
214.Xr snac 1 , 216.Xr snac 1 ,
diff --git a/html.c b/html.c
index 3a2b14f..74de47d 100644
--- a/html.c
+++ b/html.c
@@ -1670,7 +1670,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only,
1670 if (strcmp(type, "Note") == 0) { 1670 if (strcmp(type, "Note") == 0) {
1671 if (level == 0) { 1671 if (level == 0) {
1672 /* is the parent not here? */ 1672 /* is the parent not here? */
1673 const char *parent = xs_dict_get(msg, "inReplyTo"); 1673 const char *parent = get_in_reply_to(msg);
1674 1674
1675 if (user && !xs_is_null(parent) && *parent && !timeline_here(user, parent)) { 1675 if (user && !xs_is_null(parent) && *parent && !timeline_here(user, parent)) {
1676 xs_html_add(post_header, 1676 xs_html_add(post_header,
@@ -2329,7 +2329,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only,
2329 2329
2330 /* is this message a non-public reply? */ 2330 /* is this message a non-public reply? */
2331 if (user != NULL && !is_msg_public(msg)) { 2331 if (user != NULL && !is_msg_public(msg)) {
2332 const char *irt = xs_dict_get(msg, "inReplyTo"); 2332 const char *irt = get_in_reply_to(msg);
2333 2333
2334 /* is it a reply to something not in the storage? */ 2334 /* is it a reply to something not in the storage? */
2335 if (!xs_is_null(irt) && !object_here(irt)) { 2335 if (!xs_is_null(irt) && !object_here(irt)) {
diff --git a/httpd.c b/httpd.c
index 1613e1f..81d2f9e 100644
--- a/httpd.c
+++ b/httpd.c
@@ -774,6 +774,7 @@ void httpd(void)
774 xs *sem_name = NULL; 774 xs *sem_name = NULL;
775 xs *shm_name = NULL; 775 xs *shm_name = NULL;
776 sem_t anon_job_sem; 776 sem_t anon_job_sem;
777 xs *pidfile = xs_fmt("%s/server.pid", srv_basedir);
777 778
778 address = xs_dict_get(srv_config, "address"); 779 address = xs_dict_get(srv_config, "address");
779 780
@@ -809,6 +810,17 @@ void httpd(void)
809 srv_log(xs_fmt("httpd%s start %s %s", p_state->use_fcgi ? " (FastCGI)" : "", 810 srv_log(xs_fmt("httpd%s start %s %s", p_state->use_fcgi ? " (FastCGI)" : "",
810 full_address, USER_AGENT)); 811 full_address, USER_AGENT));
811 812
813 {
814 FILE *f;
815
816 if ((f = fopen(pidfile, "w")) != NULL) {
817 fprintf(f, "%d\n", getpid());
818 fclose(f);
819 }
820 else
821 srv_log(xs_fmt("Cannot create %s: %s", pidfile, strerror(errno)));
822 }
823
812 /* show the number of usable file descriptors */ 824 /* show the number of usable file descriptors */
813 struct rlimit r; 825 struct rlimit r;
814 getrlimit(RLIMIT_NOFILE, &r); 826 getrlimit(RLIMIT_NOFILE, &r);
@@ -894,4 +906,6 @@ void httpd(void)
894 srv_log(xs_fmt("httpd%s stop %s (run time: %s)", 906 srv_log(xs_fmt("httpd%s stop %s (run time: %s)",
895 p_state->use_fcgi ? " (FastCGI)" : "", 907 p_state->use_fcgi ? " (FastCGI)" : "",
896 full_address, uptime)); 908 full_address, uptime));
909
910 unlink(pidfile);
897} 911}
diff --git a/main.c b/main.c
index c6fff5f..c285fac 100644
--- a/main.c
+++ b/main.c
@@ -558,7 +558,11 @@ int main(int argc, char *argv[])
558 if (data != NULL) { 558 if (data != NULL) {
559 xs_json_dump(data, 4, stdout); 559 xs_json_dump(data, 4, stdout);
560 enqueue_actor_refresh(&snac, xs_dict_get(data, "attributedTo"), 0); 560 enqueue_actor_refresh(&snac, xs_dict_get(data, "attributedTo"), 0);
561 timeline_add(&snac, url, data); 561
562 if (!timeline_here(&snac, url))
563 timeline_add(&snac, url, data);
564 else
565 printf("Post %s already here\n", url);
562 } 566 }
563 567
564 return 0; 568 return 0;
diff --git a/mastoapi.c b/mastoapi.c
index c9d71b9..1dd91dc 100644
--- a/mastoapi.c
+++ b/mastoapi.c
@@ -171,7 +171,7 @@ const char *login_page = ""
171"<body><h1>%s OAuth identify</h1>\n" 171"<body><h1>%s OAuth identify</h1>\n"
172"<div style=\"background-color: red; color: white\">%s</div>\n" 172"<div style=\"background-color: red; color: white\">%s</div>\n"
173"<form method=\"post\" action=\"%s:/" "/%s/%s\">\n" 173"<form method=\"post\" action=\"%s:/" "/%s/%s\">\n"
174"<p>Login: <input type=\"text\" name=\"login\"></p>\n" 174"<p>Login: <input type=\"text\" name=\"login\" autocapitalize=\"off\"></p>\n"
175"<p>Password: <input type=\"password\" name=\"passwd\"></p>\n" 175"<p>Password: <input type=\"password\" name=\"passwd\"></p>\n"
176"<input type=\"hidden\" name=\"redir\" value=\"%s\">\n" 176"<input type=\"hidden\" name=\"redir\" value=\"%s\">\n"
177"<input type=\"hidden\" name=\"cid\" value=\"%s\">\n" 177"<input type=\"hidden\" name=\"cid\" value=\"%s\">\n"
@@ -1024,7 +1024,7 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
1024 st = xs_dict_append(st, "in_reply_to_id", xs_stock(XSTYPE_NULL)); 1024 st = xs_dict_append(st, "in_reply_to_id", xs_stock(XSTYPE_NULL));
1025 st = xs_dict_append(st, "in_reply_to_account_id", xs_stock(XSTYPE_NULL)); 1025 st = xs_dict_append(st, "in_reply_to_account_id", xs_stock(XSTYPE_NULL));
1026 1026
1027 tmp = xs_dict_get(msg, "inReplyTo"); 1027 tmp = get_in_reply_to(msg);
1028 if (!xs_is_null(tmp)) { 1028 if (!xs_is_null(tmp)) {
1029 xs *irto = NULL; 1029 xs *irto = NULL;
1030 1030
@@ -1727,11 +1727,11 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1727 if (logged_in) { 1727 if (logged_in) {
1728 xs *l = notify_list(&snac1, 0, 64); 1728 xs *l = notify_list(&snac1, 0, 64);
1729 xs *out = xs_list_new(); 1729 xs *out = xs_list_new();
1730 xs_list *p = l;
1731 const xs_dict *v; 1730 const xs_dict *v;
1732 const xs_list *excl = xs_dict_get(args, "exclude_types[]"); 1731 const xs_list *excl = xs_dict_get(args, "exclude_types[]");
1732 const char *max_id = xs_dict_get(args, "max_id");
1733 1733
1734 while (xs_list_iter(&p, &v)) { 1734 xs_list_foreach(l, v) {
1735 xs *noti = notify_get(&snac1, v); 1735 xs *noti = notify_get(&snac1, v);
1736 1736
1737 if (noti == NULL) 1737 if (noti == NULL)
@@ -1740,6 +1740,8 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1740 const char *type = xs_dict_get(noti, "type"); 1740 const char *type = xs_dict_get(noti, "type");
1741 const char *utype = xs_dict_get(noti, "utype"); 1741 const char *utype = xs_dict_get(noti, "utype");
1742 const char *objid = xs_dict_get(noti, "objid"); 1742 const char *objid = xs_dict_get(noti, "objid");
1743 const char *id = xs_dict_get(noti, "id");
1744 xs *fid = xs_replace(id, ".", "");
1743 xs *actor = NULL; 1745 xs *actor = NULL;
1744 xs *entry = NULL; 1746 xs *entry = NULL;
1745 1747
@@ -1752,6 +1754,13 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1752 if (is_hidden(&snac1, objid)) 1754 if (is_hidden(&snac1, objid))
1753 continue; 1755 continue;
1754 1756
1757 if (max_id) {
1758 if (strcmp(fid, max_id) == 0)
1759 max_id = NULL;
1760
1761 continue;
1762 }
1763
1755 /* convert the type */ 1764 /* convert the type */
1756 if (strcmp(type, "Like") == 0 || strcmp(type, "EmojiReact") == 0) 1765 if (strcmp(type, "Like") == 0 || strcmp(type, "EmojiReact") == 0)
1757 type = "favourite"; 1766 type = "favourite";
@@ -1778,12 +1787,15 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1778 1787
1779 mn = xs_dict_append(mn, "type", type); 1788 mn = xs_dict_append(mn, "type", type);
1780 1789
1781 xs *id = xs_replace(xs_dict_get(noti, "id"), ".", ""); 1790 mn = xs_dict_append(mn, "id", fid);
1782 mn = xs_dict_append(mn, "id", id);
1783 1791
1784 mn = xs_dict_append(mn, "created_at", xs_dict_get(noti, "date")); 1792 mn = xs_dict_append(mn, "created_at", xs_dict_get(noti, "date"));
1785 1793
1786 xs *acct = mastoapi_account(&snac1, actor); 1794 xs *acct = mastoapi_account(&snac1, actor);
1795
1796 if (acct == NULL)
1797 continue;
1798
1787 mn = xs_dict_append(mn, "account", acct); 1799 mn = xs_dict_append(mn, "account", acct);
1788 1800
1789 if (strcmp(type, "follow") != 0 && !xs_is_null(objid)) { 1801 if (strcmp(type, "follow") != 0 && !xs_is_null(objid)) {
diff --git a/snac.h b/snac.h
index ba84420..ff02539 100644
--- a/snac.h
+++ b/snac.h
@@ -298,6 +298,7 @@ const char *default_avatar_base64(void);
298xs_str *process_tags(snac *snac, const char *content, xs_list **tag); 298xs_str *process_tags(snac *snac, const char *content, xs_list **tag);
299 299
300const char *get_atto(const xs_dict *msg); 300const char *get_atto(const xs_dict *msg);
301const char *get_in_reply_to(const xs_dict *msg);
301xs_list *get_attachments(const xs_dict *msg); 302xs_list *get_attachments(const xs_dict *msg);
302 303
303xs_dict *msg_admiration(snac *snac, const char *object, const char *type); 304xs_dict *msg_admiration(snac *snac, const char *object, const char *type);