diff options
| -rw-r--r-- | data.c | 37 | ||||
| -rw-r--r-- | html.c | 71 | ||||
| -rw-r--r-- | httpd.c | 10 | ||||
| -rw-r--r-- | mastoapi.c | 2 | ||||
| -rw-r--r-- | snac.h | 3 |
5 files changed, 87 insertions, 36 deletions
| @@ -1830,12 +1830,42 @@ xs_val *list_maint(snac *user, const char *list, int op) | |||
| 1830 | } | 1830 | } |
| 1831 | 1831 | ||
| 1832 | break; | 1832 | break; |
| 1833 | |||
| 1834 | case 3: /** get list name **/ | ||
| 1835 | if (xs_is_hex(list)) { | ||
| 1836 | FILE *f; | ||
| 1837 | xs *fn = xs_fmt("%s/list/%s.id", user->basedir, list); | ||
| 1838 | |||
| 1839 | if ((f = fopen(fn, "r")) != NULL) { | ||
| 1840 | l = xs_strip_i(xs_readline(f)); | ||
| 1841 | fclose(f); | ||
| 1842 | } | ||
| 1843 | } | ||
| 1844 | |||
| 1845 | break; | ||
| 1833 | } | 1846 | } |
| 1834 | 1847 | ||
| 1835 | return l; | 1848 | return l; |
| 1836 | } | 1849 | } |
| 1837 | 1850 | ||
| 1838 | 1851 | ||
| 1852 | xs_list *list_timeline(snac *user, const char *list, int skip, int show) | ||
| 1853 | /* returns the timeline of a list */ | ||
| 1854 | { | ||
| 1855 | xs_list *l = NULL; | ||
| 1856 | |||
| 1857 | if (!xs_is_hex(list)) | ||
| 1858 | return NULL; | ||
| 1859 | |||
| 1860 | xs *fn = xs_fmt("%s/list/%s.idx", user->basedir, list); | ||
| 1861 | |||
| 1862 | if (mtime(fn) > 0.0) | ||
| 1863 | l = index_list_desc(fn, skip, show); | ||
| 1864 | |||
| 1865 | return l; | ||
| 1866 | } | ||
| 1867 | |||
| 1868 | |||
| 1839 | xs_val *list_content(snac *user, const char *list, const char *actor_md5, int op) | 1869 | xs_val *list_content(snac *user, const char *list, const char *actor_md5, int op) |
| 1840 | /* list content management */ | 1870 | /* list content management */ |
| 1841 | { | 1871 | { |
| @@ -1869,11 +1899,8 @@ xs_val *list_content(snac *user, const char *list, const char *actor_md5, int op | |||
| 1869 | 1899 | ||
| 1870 | break; | 1900 | break; |
| 1871 | 1901 | ||
| 1872 | case 3: /** list timeline **/ | 1902 | default: |
| 1873 | fn = xs_replace_i(fn, ".lst", ".idx"); | 1903 | srv_log(xs_fmt("ERROR: list_content: bad op %d", op)); |
| 1874 | |||
| 1875 | l = index_list_desc(fn, 0, 2048); | ||
| 1876 | |||
| 1877 | break; | 1904 | break; |
| 1878 | } | 1905 | } |
| 1879 | 1906 | ||
| @@ -509,7 +509,7 @@ xs_html *html_instance_head(void) | |||
| 509 | } | 509 | } |
| 510 | 510 | ||
| 511 | 511 | ||
| 512 | static xs_html *html_instance_body(char *tag) | 512 | static xs_html *html_instance_body(void) |
| 513 | { | 513 | { |
| 514 | char *host = xs_dict_get(srv_config, "host"); | 514 | char *host = xs_dict_get(srv_config, "host"); |
| 515 | char *sdesc = xs_dict_get(srv_config, "short_description"); | 515 | char *sdesc = xs_dict_get(srv_config, "short_description"); |
| @@ -560,16 +560,6 @@ static xs_html *html_instance_body(char *tag) | |||
| 560 | xs_html_text(handle))))); | 560 | xs_html_text(handle))))); |
| 561 | } | 561 | } |
| 562 | 562 | ||
| 563 | { | ||
| 564 | xs *l = tag ? xs_fmt(L("Search results for #%s"), tag) : | ||
| 565 | xs_dup(L("Recent posts by users in this instance")); | ||
| 566 | |||
| 567 | xs_html_add(body, | ||
| 568 | xs_html_tag("h2", | ||
| 569 | xs_html_attr("class", "snac-header"), | ||
| 570 | xs_html_text(l))); | ||
| 571 | } | ||
| 572 | |||
| 573 | return body; | 563 | return body; |
| 574 | } | 564 | } |
| 575 | 565 | ||
| @@ -1996,7 +1986,7 @@ xs_html *html_footer(void) | |||
| 1996 | 1986 | ||
| 1997 | xs_str *html_timeline(snac *user, const xs_list *list, int read_only, | 1987 | xs_str *html_timeline(snac *user, const xs_list *list, int read_only, |
| 1998 | int skip, int show, int show_more, | 1988 | int skip, int show, int show_more, |
| 1999 | char *tag, char *page, int utl) | 1989 | char *title, char *page, int utl) |
| 2000 | /* returns the HTML for the timeline */ | 1990 | /* returns the HTML for the timeline */ |
| 2001 | { | 1991 | { |
| 2002 | xs_list *p = (xs_list *)list; | 1992 | xs_list *p = (xs_list *)list; |
| @@ -2026,7 +2016,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, | |||
| 2026 | } | 2016 | } |
| 2027 | else { | 2017 | else { |
| 2028 | head = html_instance_head(); | 2018 | head = html_instance_head(); |
| 2029 | body = html_instance_body(tag); | 2019 | body = html_instance_body(); |
| 2030 | } | 2020 | } |
| 2031 | 2021 | ||
| 2032 | xs_html *html = xs_html_tag("html", | 2022 | xs_html *html = xs_html_tag("html", |
| @@ -2037,6 +2027,13 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, | |||
| 2037 | xs_html_add(body, | 2027 | xs_html_add(body, |
| 2038 | html_top_controls(user)); | 2028 | html_top_controls(user)); |
| 2039 | 2029 | ||
| 2030 | if (title) { | ||
| 2031 | xs_html_add(body, | ||
| 2032 | xs_html_tag("h2", | ||
| 2033 | xs_html_attr("class", "snac-header"), | ||
| 2034 | xs_html_text(title))); | ||
| 2035 | } | ||
| 2036 | |||
| 2040 | xs_html_add(body, | 2037 | xs_html_add(body, |
| 2041 | xs_html_tag("a", | 2038 | xs_html_tag("a", |
| 2042 | xs_html_attr("name", "snac-posts"))); | 2039 | xs_html_attr("name", "snac-posts"))); |
| @@ -2126,25 +2123,22 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, | |||
| 2126 | } | 2123 | } |
| 2127 | 2124 | ||
| 2128 | if (show_more) { | 2125 | if (show_more) { |
| 2129 | xs *t = NULL; | ||
| 2130 | xs *m = NULL; | 2126 | xs *m = NULL; |
| 2131 | xs *ss = xs_fmt("skip=%d&show=%d", skip + show, show); | 2127 | xs *ss = xs_fmt("skip=%d&show=%d", skip + show, show); |
| 2132 | 2128 | ||
| 2133 | xs *url = page == NULL || user == NULL ? | 2129 | xs *url = xs_dup(user == NULL ? srv_baseurl : user->actor); |
| 2134 | xs_dup(srv_baseurl) : xs_fmt("%s%s", user->actor, page); | ||
| 2135 | 2130 | ||
| 2136 | if (tag) { | 2131 | if (page != NULL) |
| 2137 | t = xs_fmt("%s?t=%s", url, tag); | 2132 | url = xs_str_cat(url, page); |
| 2138 | m = xs_fmt("%s&%s", t, ss); | 2133 | |
| 2139 | } | 2134 | if (xs_str_in(url, "?") != -1) |
| 2140 | else { | 2135 | m = xs_fmt("%s&%s", url, ss); |
| 2141 | t = xs_dup(url); | 2136 | else |
| 2142 | m = xs_fmt("%s?%s", t, ss); | 2137 | m = xs_fmt("%s?%s", url, ss); |
| 2143 | } | ||
| 2144 | 2138 | ||
| 2145 | xs_html *more_links = xs_html_tag("p", | 2139 | xs_html *more_links = xs_html_tag("p", |
| 2146 | xs_html_tag("a", | 2140 | xs_html_tag("a", |
| 2147 | xs_html_attr("href", t), | 2141 | xs_html_attr("href", url), |
| 2148 | xs_html_attr("name", "snac-more"), | 2142 | xs_html_attr("name", "snac-more"), |
| 2149 | xs_html_text(L("Back to top"))), | 2143 | xs_html_text(L("Back to top"))), |
| 2150 | xs_html_text(" - "), | 2144 | xs_html_text(" - "), |
| @@ -2652,12 +2646,37 @@ int html_get_handler(const xs_dict *req, const char *q_path, | |||
| 2652 | xs *next = timeline_instance_list(skip + show, 1); | 2646 | xs *next = timeline_instance_list(skip + show, 1); |
| 2653 | 2647 | ||
| 2654 | *body = html_timeline(&snac, list, 0, skip, show, | 2648 | *body = html_timeline(&snac, list, 0, skip, show, |
| 2655 | xs_list_len(next), NULL, "/instance", 0); | 2649 | xs_list_len(next), L("Showing instance timeline"), "/instance", 0); |
| 2656 | *b_size = strlen(*body); | 2650 | *b_size = strlen(*body); |
| 2657 | status = 200; | 2651 | status = 200; |
| 2658 | } | 2652 | } |
| 2659 | } | 2653 | } |
| 2660 | else | 2654 | else |
| 2655 | if (xs_startswith(p_path, "list/")) { /** list timelines **/ | ||
| 2656 | if (!login(&snac, req)) { | ||
| 2657 | *body = xs_dup(uid); | ||
| 2658 | status = 401; | ||
| 2659 | } | ||
| 2660 | else { | ||
| 2661 | xs *l = xs_split(p_path, "/"); | ||
| 2662 | char *lid = xs_list_get(l, -1); | ||
| 2663 | |||
| 2664 | xs *list = list_timeline(&snac, lid, skip, show); | ||
| 2665 | xs *next = list_timeline(&snac, lid, skip + show, 1); | ||
| 2666 | |||
| 2667 | if (list != NULL) { | ||
| 2668 | xs *base = xs_fmt("/list/%s", lid); | ||
| 2669 | xs *name = list_maint(&snac, lid, 3); | ||
| 2670 | xs *title = xs_fmt(L("Showing timeline for list %s"), name); | ||
| 2671 | |||
| 2672 | *body = html_timeline(&snac, list, 0, skip, show, | ||
| 2673 | xs_list_len(next), title, base, 1); | ||
| 2674 | *b_size = strlen(*body); | ||
| 2675 | status = 200; | ||
| 2676 | } | ||
| 2677 | } | ||
| 2678 | } | ||
| 2679 | else | ||
| 2661 | if (xs_startswith(p_path, "p/")) { /** a timeline with just one entry **/ | 2680 | if (xs_startswith(p_path, "p/")) { /** a timeline with just one entry **/ |
| 2662 | if (xs_type(xs_dict_get(snac.config, "private")) == XSTYPE_TRUE) | 2681 | if (xs_type(xs_dict_get(snac.config, "private")) == XSTYPE_TRUE) |
| 2663 | return 403; | 2682 | return 403; |
| @@ -200,14 +200,18 @@ int server_get_handler(xs_dict *req, const char *q_path, | |||
| 200 | *body = timeline_to_rss(NULL, tl, link, link, link); | 200 | *body = timeline_to_rss(NULL, tl, link, link, link); |
| 201 | *ctype = "application/rss+xml; charset=utf-8"; | 201 | *ctype = "application/rss+xml; charset=utf-8"; |
| 202 | } | 202 | } |
| 203 | else | 203 | else { |
| 204 | *body = html_timeline(NULL, tl, 0, skip, show, more, t, NULL, 0); | 204 | xs *page = xs_fmt("?t=%s", t); |
| 205 | xs *title = xs_fmt(L("Search results for #%s"), t); | ||
| 206 | *body = html_timeline(NULL, tl, 0, skip, show, more, title, page, 0); | ||
| 207 | } | ||
| 205 | } | 208 | } |
| 206 | else | 209 | else |
| 207 | if (xs_type(xs_dict_get(srv_config, "show_instance_timeline")) == XSTYPE_TRUE) { | 210 | if (xs_type(xs_dict_get(srv_config, "show_instance_timeline")) == XSTYPE_TRUE) { |
| 208 | /** instance timeline **/ | 211 | /** instance timeline **/ |
| 209 | xs *tl = timeline_instance_list(0, 30); | 212 | xs *tl = timeline_instance_list(0, 30); |
| 210 | *body = html_timeline(NULL, tl, 0, 0, 0, 0, NULL, NULL, 0); | 213 | *body = html_timeline(NULL, tl, 0, 0, 0, 0, |
| 214 | L("Recent posts by users in this instance"), NULL, 0); | ||
| 211 | } | 215 | } |
| 212 | else | 216 | else |
| 213 | *body = greeting_html(); | 217 | *body = greeting_html(); |
| @@ -1669,7 +1669,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, | |||
| 1669 | xs *l = xs_split(cmd, "/"); | 1669 | xs *l = xs_split(cmd, "/"); |
| 1670 | char *list = xs_list_get(l, -1); | 1670 | char *list = xs_list_get(l, -1); |
| 1671 | 1671 | ||
| 1672 | xs *timeline = list_content(&snac1, list, NULL, 3); | 1672 | xs *timeline = list_timeline(&snac1, list, 0, 2048); |
| 1673 | xs *out = xs_list_new(); | 1673 | xs *out = xs_list_new(); |
| 1674 | int c = 0; | 1674 | int c = 0; |
| 1675 | char *md5; | 1675 | char *md5; |
| @@ -175,6 +175,7 @@ void tag_index(const char *id, const xs_dict *obj); | |||
| 175 | xs_list *tag_search(char *tag, int skip, int show); | 175 | xs_list *tag_search(char *tag, int skip, int show); |
| 176 | 176 | ||
| 177 | xs_val *list_maint(snac *user, const char *list, int op); | 177 | xs_val *list_maint(snac *user, const char *list, int op); |
| 178 | xs_list *list_timeline(snac *user, const char *list, int skip, int show); | ||
| 178 | xs_val *list_content(snac *user, const char *list_id, const char *actor_md5, int op); | 179 | xs_val *list_content(snac *user, const char *list_id, const char *actor_md5, int op); |
| 179 | void list_distribute(snac *user, const char *who, const xs_dict *post); | 180 | void list_distribute(snac *user, const char *who, const xs_dict *post); |
| 180 | 181 | ||
| @@ -317,7 +318,7 @@ xs_str *encode_html(const char *str); | |||
| 317 | 318 | ||
| 318 | xs_str *html_timeline(snac *user, const xs_list *list, int read_only, | 319 | xs_str *html_timeline(snac *user, const xs_list *list, int read_only, |
| 319 | int skip, int show, int show_more, | 320 | int skip, int show, int show_more, |
| 320 | char *tag, char *page, int utl); | 321 | char *title, char *page, int utl); |
| 321 | 322 | ||
| 322 | int html_get_handler(const xs_dict *req, const char *q_path, | 323 | int html_get_handler(const xs_dict *req, const char *q_path, |
| 323 | char **body, int *b_size, char **ctype, xs_str **etag); | 324 | char **body, int *b_size, char **ctype, xs_str **etag); |