summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alex Schroeder2022-12-04 21:28:29 +0100
committerGravatar Alex Schroeder2022-12-06 18:27:33 +0100
commita221237637191d70c2e1d18aec82056501f8140f (patch)
treebf6b3d11feca118e81e8521b19c6456ec72ad341
parentUpdated TODO. (diff)
downloadsnac2-a221237637191d70c2e1d18aec82056501f8140f.tar.gz
snac2-a221237637191d70c2e1d18aec82056501f8140f.tar.xz
snac2-a221237637191d70c2e1d18aec82056501f8140f.zip
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.
-rw-r--r--activitypub.c2
-rw-r--r--data.c20
-rw-r--r--html.c39
-rw-r--r--main.c2
-rw-r--r--snac.h6
5 files changed, 46 insertions, 23 deletions
diff --git a/activitypub.c b/activitypub.c
index 252c084..7017899 100644
--- a/activitypub.c
+++ b/activitypub.c
@@ -1094,7 +1094,7 @@ int activitypub_get_handler(d_char *req, char *q_path,
1094 else 1094 else
1095 if (strcmp(p_path, "outbox") == 0) { 1095 if (strcmp(p_path, "outbox") == 0) {
1096 xs *id = xs_fmt("%s/outbox", snac.actor); 1096 xs *id = xs_fmt("%s/outbox", snac.actor);
1097 xs *elems = timeline_simple_list(&snac, "public", 20); 1097 xs *elems = timeline_simple_list(&snac, "public", 0, 20);
1098 xs *list = xs_list_new(); 1098 xs *list = xs_list_new();
1099 msg = msg_collection(&snac, id); 1099 msg = msg_collection(&snac, id);
1100 char *p, *v; 1100 char *p, *v;
diff --git a/data.c b/data.c
index f36c01d..c545535 100644
--- a/data.c
+++ b/data.c
@@ -359,7 +359,7 @@ d_char *index_list(const char *fn, int max)
359} 359}
360 360
361 361
362d_char *index_list_desc(const char *fn, int max) 362d_char *index_list_desc(const char *fn, int skip, int show)
363/* returns an index as a list, in reverse order */ 363/* returns an index as a list, in reverse order */
364{ 364{
365 d_char *list = NULL; 365 d_char *list = NULL;
@@ -372,9 +372,9 @@ d_char *index_list_desc(const char *fn, int max)
372 char line[256]; 372 char line[256];
373 list = xs_list_new(); 373 list = xs_list_new();
374 374
375 /* move to the end minus one entry */ 375 /* move to the end minus one entry (or more, if skipping entries) */
376 if (!fseek(f, 0, SEEK_END) && !fseek(f, -33, SEEK_CUR)) { 376 if (!fseek(f, 0, SEEK_END) && !fseek(f, (skip + 1) * -33, SEEK_CUR)) {
377 while (n < max && fgets(line, sizeof(line), f) != NULL) { 377 while (n < show && fgets(line, sizeof(line), f) != NULL) {
378 line[32] = '\0'; 378 line[32] = '\0';
379 list = xs_list_append(list, line); 379 list = xs_list_append(list, line);
380 n++; 380 n++;
@@ -856,7 +856,7 @@ d_char *timeline_top_level(d_char *list)
856} 856}
857 857
858 858
859d_char *timeline_simple_list(snac *snac, const char *idx_name, int max) 859d_char *timeline_simple_list(snac *snac, const char *idx_name, int skip, int show)
860/* returns a timeline (with all entries) */ 860/* returns a timeline (with all entries) */
861{ 861{
862 int c_max; 862 int c_max;
@@ -865,19 +865,19 @@ d_char *timeline_simple_list(snac *snac, const char *idx_name, int max)
865 c_max = xs_number_get(xs_dict_get(srv_config, "max_timeline_entries")); 865 c_max = xs_number_get(xs_dict_get(srv_config, "max_timeline_entries"));
866 866
867 /* never more timeline entries than the configured maximum */ 867 /* never more timeline entries than the configured maximum */
868 if (max > c_max) 868 if (show > c_max)
869 max = c_max; 869 show = c_max;
870 870
871 xs *idx = xs_fmt("%s/%s.idx", snac->basedir, idx_name); 871 xs *idx = xs_fmt("%s/%s.idx", snac->basedir, idx_name);
872 872
873 return index_list_desc(idx, max); 873 return index_list_desc(idx, skip, show);
874} 874}
875 875
876 876
877d_char *timeline_list(snac *snac, const char *idx_name, int max) 877d_char *timeline_list(snac *snac, const char *idx_name, int skip, int show)
878/* returns a timeline (only top level entries) */ 878/* returns a timeline (only top level entries) */
879{ 879{
880 xs *list = timeline_simple_list(snac, idx_name, max); 880 xs *list = timeline_simple_list(snac, idx_name, skip, show);
881 881
882 return timeline_top_level(list); 882 return timeline_top_level(list);
883} 883}
diff --git a/html.c b/html.c
index 78c6aed..5614956 100644
--- a/html.c
+++ b/html.c
@@ -967,6 +967,7 @@ int html_get_handler(d_char *req, char *q_path, char **body, int *b_size, char *
967 xs *uid = NULL; 967 xs *uid = NULL;
968 char *p_path; 968 char *p_path;
969 int cache = 1; 969 int cache = 1;
970 int save = 1;
970 char *v; 971 char *v;
971 972
972 xs *l = xs_split_n(q_path, "/", 2); 973 xs *l = xs_split_n(q_path, "/", 2);
@@ -1004,6 +1005,14 @@ int html_get_handler(d_char *req, char *q_path, char **body, int *b_size, char *
1004 if ((v = xs_dict_get(srv_config, "disable_cache")) && xs_type(v) == XSTYPE_TRUE) 1005 if ((v = xs_dict_get(srv_config, "disable_cache")) && xs_type(v) == XSTYPE_TRUE)
1005 cache = 0; 1006 cache = 0;
1006 1007
1008 int skip = 0;
1009 int show = 50;
1010 char *q_vars = xs_dict_get(req, "q_vars");
1011 if ((v = xs_dict_get(q_vars, "skip")) != NULL)
1012 skip = atoi(v), cache = 0, save = 0;
1013 if ((v = xs_dict_get(q_vars, "show")) != NULL)
1014 show = atoi(v), cache = 0, save = 0;
1015
1007 if (p_path == NULL) { 1016 if (p_path == NULL) {
1008 /* public timeline */ 1017 /* public timeline */
1009 xs *h = xs_str_localtime(0, "%Y-%m.html"); 1018 xs *h = xs_str_localtime(0, "%Y-%m.html");
@@ -1016,13 +1025,20 @@ int html_get_handler(d_char *req, char *q_path, char **body, int *b_size, char *
1016 status = 200; 1025 status = 200;
1017 } 1026 }
1018 else { 1027 else {
1019 xs *list = timeline_list(&snac, "public", XS_ALL); 1028 xs *list = timeline_list(&snac, "public", skip, show);
1020 1029
1021 *body = html_timeline(&snac, list, 1); 1030 *body = html_timeline(&snac, list, 1);
1031 if (xs_list_len(list) == show)
1032 *body = xs_str_cat(
1033 *body, xs_fmt(
1034 "<p>"
1035 "<a href=\"%s?skip=%d&show=%d\" name=\"snac-more\">More…</a>"
1036 "</p>\n", snac.actor, skip + show, show));
1022 *b_size = strlen(*body); 1037 *b_size = strlen(*body);
1023 status = 200; 1038 status = 200;
1024 1039
1025 history_add(&snac, h, *body, *b_size); 1040 if (save)
1041 history_add(&snac, h, *body, *b_size);
1026 } 1042 }
1027 } 1043 }
1028 else 1044 else
@@ -1042,13 +1058,20 @@ int html_get_handler(d_char *req, char *q_path, char **body, int *b_size, char *
1042 else { 1058 else {
1043 snac_debug(&snac, 1, xs_fmt("building timeline")); 1059 snac_debug(&snac, 1, xs_fmt("building timeline"));
1044 1060
1045 xs *list = timeline_list(&snac, "private", XS_ALL); 1061 xs *list = timeline_list(&snac, "private", skip, show);
1046 1062
1047 *body = html_timeline(&snac, list, 0); 1063 *body = html_timeline(&snac, list, 0);
1064 if (xs_list_len(list) == show)
1065 *body = xs_str_cat(
1066 *body, xs_fmt(
1067 "<p>"
1068 "<a href=\"%s/admin?skip=%d&show=%d\" name=\"snac-more\">More…</a>"
1069 "</p>\n", snac.actor, skip + show, show));
1048 *b_size = strlen(*body); 1070 *b_size = strlen(*body);
1049 status = 200; 1071 status = 200;
1050 1072
1051 history_add(&snac, "timeline.html_", *body, *b_size); 1073 if (save)
1074 history_add(&snac, "timeline.html_", *body, *b_size);
1052 } 1075 }
1053 } 1076 }
1054 } 1077 }
@@ -1109,7 +1132,7 @@ int html_get_handler(d_char *req, char *q_path, char **body, int *b_size, char *
1109 if (strcmp(p_path, ".rss") == 0) { 1132 if (strcmp(p_path, ".rss") == 0) {
1110 /* public timeline in RSS format */ 1133 /* public timeline in RSS format */
1111 d_char *rss; 1134 d_char *rss;
1112 xs *elems = timeline_simple_list(&snac, "public", 20); 1135 xs *elems = timeline_simple_list(&snac, "public", 0, 20);
1113 xs *bio = not_really_markdown(xs_dict_get(snac.config, "bio")); 1136 xs *bio = not_really_markdown(xs_dict_get(snac.config, "bio"));
1114 char *p, *v; 1137 char *p, *v;
1115 1138
@@ -1202,7 +1225,7 @@ int html_post_handler(d_char *req, char *q_path, d_char *payload, int p_size,
1202 uid = xs_list_get(l, 1); 1225 uid = xs_list_get(l, 1);
1203 if (!uid || !user_open(&snac, uid)) { 1226 if (!uid || !user_open(&snac, uid)) {
1204 /* invalid user */ 1227 /* invalid user */
1205 srv_log(xs_fmt("html_get_handler bad user %s", uid)); 1228 srv_log(xs_fmt("html_post_handler bad user %s", uid));
1206 return 404; 1229 return 404;
1207 } 1230 }
1208 1231
diff --git a/main.c b/main.c
index 7048426..d3a461e 100644
--- a/main.c
+++ b/main.c
@@ -159,7 +159,7 @@ int main(int argc, char *argv[])
159#endif 159#endif
160 160
161 xs *idx = xs_fmt("%s/private.idx", snac.basedir); 161 xs *idx = xs_fmt("%s/private.idx", snac.basedir);
162 xs *list = index_list_desc(idx, 256); 162 xs *list = index_list_desc(idx, 0, 256);
163 xs *tl = timeline_top_level(list); 163 xs *tl = timeline_top_level(list);
164 164
165 xs *j = xs_json_dumps_pp(tl, 4); 165 xs *j = xs_json_dumps_pp(tl, 4);
diff --git a/snac.h b/snac.h
index 6f3899b..a6215b1 100644
--- a/snac.h
+++ b/snac.h
@@ -58,7 +58,7 @@ int index_add(const char *fn, const char *md5);
58int index_del(const char *fn, const char *md5); 58int index_del(const char *fn, const char *md5);
59int index_first(const char *fn, char *buf, int size); 59int index_first(const char *fn, char *buf, int size);
60d_char *index_list(const char *fn, int max); 60d_char *index_list(const char *fn, int max);
61d_char *index_list_desc(const char *fn, int max); 61d_char *index_list_desc(const char *fn, int skip, int show);
62 62
63int object_add(const char *id, d_char *obj); 63int object_add(const char *id, d_char *obj);
64int object_add_ow(const char *id, d_char *obj); 64int object_add_ow(const char *id, d_char *obj);
@@ -85,8 +85,8 @@ d_char *follower_list(snac *snac);
85 85
86double timeline_mtime(snac *snac); 86double timeline_mtime(snac *snac);
87int timeline_del(snac *snac, char *id); 87int timeline_del(snac *snac, char *id);
88d_char *timeline_simple_list(snac *snac, const char *idx_name, int max); 88d_char *timeline_simple_list(snac *snac, const char *idx_name, int skip, int show);
89d_char *timeline_list(snac *snac, const char *idx_name, int max); 89d_char *timeline_list(snac *snac, const char *idx_name, int skip, int show);
90int timeline_add(snac *snac, char *id, char *o_msg, char *parent, char *referrer); 90int timeline_add(snac *snac, char *id, char *o_msg, char *parent, char *referrer);
91void timeline_admire(snac *snac, char *o_msg, char *id, char *admirer, int like); 91void timeline_admire(snac *snac, char *o_msg, char *id, char *admirer, int like);
92 92