commit a221237
Alex Schroeder
·
2022-12-04 20:28:29 +0000 UTC
parent 345f644
Pagination of the public and private page Use the query parameters skip and show to control what you can see, e.g. /alex/admin?skip=0&show=4 Don't use or save the timeline cache if either is set. The following functions were changed from accepting a single max parameter to accepting both skip and show: timeline_simple_list, timeline_list, index_list_desc.
5 files changed,
+46,
-23
+1,
-1
1@@ -1094,7 +1094,7 @@ int activitypub_get_handler(d_char *req, char *q_path,
2 else
3 if (strcmp(p_path, "outbox") == 0) {
4 xs *id = xs_fmt("%s/outbox", snac.actor);
5- xs *elems = timeline_simple_list(&snac, "public", 20);
6+ xs *elems = timeline_simple_list(&snac, "public", 0, 20);
7 xs *list = xs_list_new();
8 msg = msg_collection(&snac, id);
9 char *p, *v;
M
data.c
+10,
-10
1@@ -359,7 +359,7 @@ d_char *index_list(const char *fn, int max)
2 }
3
4
5-d_char *index_list_desc(const char *fn, int max)
6+d_char *index_list_desc(const char *fn, int skip, int show)
7 /* returns an index as a list, in reverse order */
8 {
9 d_char *list = NULL;
10@@ -372,9 +372,9 @@ d_char *index_list_desc(const char *fn, int max)
11 char line[256];
12 list = xs_list_new();
13
14- /* move to the end minus one entry */
15- if (!fseek(f, 0, SEEK_END) && !fseek(f, -33, SEEK_CUR)) {
16- while (n < max && fgets(line, sizeof(line), f) != NULL) {
17+ /* move to the end minus one entry (or more, if skipping entries) */
18+ if (!fseek(f, 0, SEEK_END) && !fseek(f, (skip + 1) * -33, SEEK_CUR)) {
19+ while (n < show && fgets(line, sizeof(line), f) != NULL) {
20 line[32] = '\0';
21 list = xs_list_append(list, line);
22 n++;
23@@ -856,7 +856,7 @@ d_char *timeline_top_level(d_char *list)
24 }
25
26
27-d_char *timeline_simple_list(snac *snac, const char *idx_name, int max)
28+d_char *timeline_simple_list(snac *snac, const char *idx_name, int skip, int show)
29 /* returns a timeline (with all entries) */
30 {
31 int c_max;
32@@ -865,19 +865,19 @@ d_char *timeline_simple_list(snac *snac, const char *idx_name, int max)
33 c_max = xs_number_get(xs_dict_get(srv_config, "max_timeline_entries"));
34
35 /* never more timeline entries than the configured maximum */
36- if (max > c_max)
37- max = c_max;
38+ if (show > c_max)
39+ show = c_max;
40
41 xs *idx = xs_fmt("%s/%s.idx", snac->basedir, idx_name);
42
43- return index_list_desc(idx, max);
44+ return index_list_desc(idx, skip, show);
45 }
46
47
48-d_char *timeline_list(snac *snac, const char *idx_name, int max)
49+d_char *timeline_list(snac *snac, const char *idx_name, int skip, int show)
50 /* returns a timeline (only top level entries) */
51 {
52- xs *list = timeline_simple_list(snac, idx_name, max);
53+ xs *list = timeline_simple_list(snac, idx_name, skip, show);
54
55 return timeline_top_level(list);
56 }
M
html.c
+31,
-8
1@@ -967,6 +967,7 @@ int html_get_handler(d_char *req, char *q_path, char **body, int *b_size, char *
2 xs *uid = NULL;
3 char *p_path;
4 int cache = 1;
5+ int save = 1;
6 char *v;
7
8 xs *l = xs_split_n(q_path, "/", 2);
9@@ -1004,6 +1005,14 @@ int html_get_handler(d_char *req, char *q_path, char **body, int *b_size, char *
10 if ((v = xs_dict_get(srv_config, "disable_cache")) && xs_type(v) == XSTYPE_TRUE)
11 cache = 0;
12
13+ int skip = 0;
14+ int show = 50;
15+ char *q_vars = xs_dict_get(req, "q_vars");
16+ if ((v = xs_dict_get(q_vars, "skip")) != NULL)
17+ skip = atoi(v), cache = 0, save = 0;
18+ if ((v = xs_dict_get(q_vars, "show")) != NULL)
19+ show = atoi(v), cache = 0, save = 0;
20+
21 if (p_path == NULL) {
22 /* public timeline */
23 xs *h = xs_str_localtime(0, "%Y-%m.html");
24@@ -1016,13 +1025,20 @@ int html_get_handler(d_char *req, char *q_path, char **body, int *b_size, char *
25 status = 200;
26 }
27 else {
28- xs *list = timeline_list(&snac, "public", XS_ALL);
29-
30- *body = html_timeline(&snac, list, 1);
31+ xs *list = timeline_list(&snac, "public", skip, show);
32+
33+ *body = html_timeline(&snac, list, 1);
34+ if (xs_list_len(list) == show)
35+ *body = xs_str_cat(
36+ *body, xs_fmt(
37+ "<p>"
38+ "<a href=\"%s?skip=%d&show=%d\" name=\"snac-more\">More…</a>"
39+ "</p>\n", snac.actor, skip + show, show));
40 *b_size = strlen(*body);
41 status = 200;
42
43- history_add(&snac, h, *body, *b_size);
44+ if (save)
45+ history_add(&snac, h, *body, *b_size);
46 }
47 }
48 else
49@@ -1042,13 +1058,20 @@ int html_get_handler(d_char *req, char *q_path, char **body, int *b_size, char *
50 else {
51 snac_debug(&snac, 1, xs_fmt("building timeline"));
52
53- xs *list = timeline_list(&snac, "private", XS_ALL);
54+ xs *list = timeline_list(&snac, "private", skip, show);
55
56 *body = html_timeline(&snac, list, 0);
57+ if (xs_list_len(list) == show)
58+ *body = xs_str_cat(
59+ *body, xs_fmt(
60+ "<p>"
61+ "<a href=\"%s/admin?skip=%d&show=%d\" name=\"snac-more\">More…</a>"
62+ "</p>\n", snac.actor, skip + show, show));
63 *b_size = strlen(*body);
64 status = 200;
65
66- history_add(&snac, "timeline.html_", *body, *b_size);
67+ if (save)
68+ history_add(&snac, "timeline.html_", *body, *b_size);
69 }
70 }
71 }
72@@ -1109,7 +1132,7 @@ int html_get_handler(d_char *req, char *q_path, char **body, int *b_size, char *
73 if (strcmp(p_path, ".rss") == 0) {
74 /* public timeline in RSS format */
75 d_char *rss;
76- xs *elems = timeline_simple_list(&snac, "public", 20);
77+ xs *elems = timeline_simple_list(&snac, "public", 0, 20);
78 xs *bio = not_really_markdown(xs_dict_get(snac.config, "bio"));
79 char *p, *v;
80
81@@ -1202,7 +1225,7 @@ int html_post_handler(d_char *req, char *q_path, d_char *payload, int p_size,
82 uid = xs_list_get(l, 1);
83 if (!uid || !user_open(&snac, uid)) {
84 /* invalid user */
85- srv_log(xs_fmt("html_get_handler bad user %s", uid));
86+ srv_log(xs_fmt("html_post_handler bad user %s", uid));
87 return 404;
88 }
89
M
main.c
+1,
-1
1@@ -159,7 +159,7 @@ int main(int argc, char *argv[])
2 #endif
3
4 xs *idx = xs_fmt("%s/private.idx", snac.basedir);
5- xs *list = index_list_desc(idx, 256);
6+ xs *list = index_list_desc(idx, 0, 256);
7 xs *tl = timeline_top_level(list);
8
9 xs *j = xs_json_dumps_pp(tl, 4);
M
snac.h
+3,
-3
1@@ -58,7 +58,7 @@ int index_add(const char *fn, const char *md5);
2 int index_del(const char *fn, const char *md5);
3 int index_first(const char *fn, char *buf, int size);
4 d_char *index_list(const char *fn, int max);
5-d_char *index_list_desc(const char *fn, int max);
6+d_char *index_list_desc(const char *fn, int skip, int show);
7
8 int object_add(const char *id, d_char *obj);
9 int object_add_ow(const char *id, d_char *obj);
10@@ -85,8 +85,8 @@ d_char *follower_list(snac *snac);
11
12 double timeline_mtime(snac *snac);
13 int timeline_del(snac *snac, char *id);
14-d_char *timeline_simple_list(snac *snac, const char *idx_name, int max);
15-d_char *timeline_list(snac *snac, const char *idx_name, int max);
16+d_char *timeline_simple_list(snac *snac, const char *idx_name, int skip, int show);
17+d_char *timeline_list(snac *snac, const char *idx_name, int skip, int show);
18 int timeline_add(snac *snac, char *id, char *o_msg, char *parent, char *referrer);
19 void timeline_admire(snac *snac, char *o_msg, char *id, char *admirer, int like);
20