summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar grunfink2026-01-10 21:29:32 +0100
committerGravatar grunfink2026-01-10 21:29:32 +0100
commit99375a7b664750c1288558f1d5c02b833a2e083c (patch)
tree52295802e250d8dacc82bdc49740e3a2c41f5253
parentNew file xs_list_tools.h. (diff)
downloadsnac2-99375a7b664750c1288558f1d5c02b833a2e083c.tar.gz
snac2-99375a7b664750c1288558f1d5c02b833a2e083c.tar.xz
snac2-99375a7b664750c1288558f1d5c02b833a2e083c.zip
New command-line option top_ten.
-rw-r--r--Makefile8
-rw-r--r--Makefile.NetBSD8
-rw-r--r--main.c21
-rw-r--r--snac.h2
-rw-r--r--utils.c72
5 files changed, 102 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index ffeac1a..5614388 100644
--- a/Makefile
+++ b/Makefile
@@ -46,7 +46,7 @@ update-po:
46 xgettext --omit-header -j -o $$a --language=C --keyword=L --from-code=utf-8 *.c ; \ 46 xgettext --omit-header -j -o $$a --language=C --keyword=L --from-code=utf-8 *.c ; \
47 done 47 done
48 48
49activitypub.o: activitypub.c xs.h xs_json.h xs_curl.h xs_mime.h \ 49activitypub.o: activitypub.c xs.h xs_json.h xs_curl.h xs_url.h xs_mime.h \
50 xs_openssl.h xs_regex.h xs_time.h xs_set.h xs_match.h xs_unicode.h \ 50 xs_openssl.h xs_regex.h xs_time.h xs_set.h xs_match.h xs_unicode.h \
51 xs_webmention.h xs_http.h xs_http_codes.h snac.h 51 xs_webmention.h xs_http.h xs_http_codes.h snac.h
52data.o: data.c xs.h xs_hex.h xs_io.h xs_json.h xs_openssl.h xs_glob.h \ 52data.o: data.c xs.h xs_hex.h xs_io.h xs_json.h xs_openssl.h xs_glob.h \
@@ -68,16 +68,16 @@ mastoapi.o: mastoapi.c xs.h xs_hex.h xs_openssl.h xs_json.h xs_io.h \
68 xs_time.h xs_glob.h xs_set.h xs_random.h xs_url.h xs_mime.h xs_match.h \ 68 xs_time.h xs_glob.h xs_set.h xs_random.h xs_url.h xs_mime.h xs_match.h \
69 xs_unicode.h xs_http.h xs_http_codes.h snac.h 69 xs_unicode.h xs_http.h xs_http_codes.h snac.h
70rss.o: rss.c xs.h xs_html.h xs_regex.h xs_time.h xs_match.h xs_curl.h \ 70rss.o: rss.c xs.h xs_html.h xs_regex.h xs_time.h xs_match.h xs_curl.h \
71 xs_openssl.h xs_json.h xs_http.h xs_http_codes.h snac.h 71 xs_openssl.h xs_json.h xs_http.h xs_http_codes.h xs_unicode.h snac.h
72sandbox.o: sandbox.c xs.h snac.h 72sandbox.o: sandbox.c xs.h snac.h
73snac.o: snac.c xs.h xs_hex.h xs_io.h xs_unicode_tbl.h xs_unicode.h \ 73snac.o: snac.c xs.h xs_hex.h xs_io.h xs_unicode_tbl.h xs_unicode.h \
74 xs_json.h xs_curl.h xs_openssl.h xs_socket.h xs_unix_socket.h xs_url.h \ 74 xs_json.h xs_curl.h xs_openssl.h xs_socket.h xs_unix_socket.h xs_url.h \
75 xs_http.h xs_http_codes.h xs_httpd.h xs_mime.h xs_regex.h xs_set.h \ 75 xs_http.h xs_http_codes.h xs_httpd.h xs_mime.h xs_regex.h xs_set.h \
76 xs_time.h xs_glob.h xs_random.h xs_match.h xs_fcgi.h xs_html.h xs_po.h \ 76 xs_time.h xs_glob.h xs_random.h xs_match.h xs_fcgi.h xs_html.h xs_po.h \
77 xs_webmention.h snac.h 77 xs_webmention.h xs_list_tools.h snac.h
78upgrade.o: upgrade.c xs.h xs_io.h xs_json.h xs_glob.h snac.h 78upgrade.o: upgrade.c xs.h xs_io.h xs_json.h xs_glob.h snac.h
79utils.o: utils.c xs.h xs_io.h xs_json.h xs_time.h xs_openssl.h \ 79utils.o: utils.c xs.h xs_io.h xs_json.h xs_time.h xs_openssl.h \
80 xs_random.h xs_glob.h xs_curl.h xs_regex.h xs_http.h xs_http_codes.h \ 80 xs_random.h xs_glob.h xs_curl.h xs_regex.h xs_http.h xs_http_codes.h \
81 snac.h 81 xs_list_tools.h xs_set.h snac.h
82webfinger.o: webfinger.c xs.h xs_json.h xs_curl.h xs_mime.h xs_http.h \ 82webfinger.o: webfinger.c xs.h xs_json.h xs_curl.h xs_mime.h xs_http.h \
83 xs_http_codes.h snac.h 83 xs_http_codes.h snac.h
diff --git a/Makefile.NetBSD b/Makefile.NetBSD
index b5005ee..e752910 100644
--- a/Makefile.NetBSD
+++ b/Makefile.NetBSD
@@ -35,7 +35,7 @@ uninstall:
35 rm $(PREFIX_MAN)/man5/snac.5 35 rm $(PREFIX_MAN)/man5/snac.5
36 rm $(PREFIX_MAN)/man8/snac.8 36 rm $(PREFIX_MAN)/man8/snac.8
37 37
38activitypub.o: activitypub.c xs.h xs_json.h xs_curl.h xs_mime.h \ 38activitypub.o: activitypub.c xs.h xs_json.h xs_curl.h xs_url.h xs_mime.h \
39 xs_openssl.h xs_regex.h xs_time.h xs_set.h xs_match.h xs_unicode.h \ 39 xs_openssl.h xs_regex.h xs_time.h xs_set.h xs_match.h xs_unicode.h \
40 xs_webmention.h xs_http.h xs_http_codes.h snac.h 40 xs_webmention.h xs_http.h xs_http_codes.h snac.h
41data.o: data.c xs.h xs_hex.h xs_io.h xs_json.h xs_openssl.h xs_glob.h \ 41data.o: data.c xs.h xs_hex.h xs_io.h xs_json.h xs_openssl.h xs_glob.h \
@@ -57,16 +57,16 @@ mastoapi.o: mastoapi.c xs.h xs_hex.h xs_openssl.h xs_json.h xs_io.h \
57 xs_time.h xs_glob.h xs_set.h xs_random.h xs_url.h xs_mime.h xs_match.h \ 57 xs_time.h xs_glob.h xs_set.h xs_random.h xs_url.h xs_mime.h xs_match.h \
58 xs_unicode.h xs_http.h xs_http_codes.h snac.h 58 xs_unicode.h xs_http.h xs_http_codes.h snac.h
59rss.o: rss.c xs.h xs_html.h xs_regex.h xs_time.h xs_match.h xs_curl.h \ 59rss.o: rss.c xs.h xs_html.h xs_regex.h xs_time.h xs_match.h xs_curl.h \
60 xs_openssl.h xs_json.h xs_http.h xs_http_codes.h snac.h 60 xs_openssl.h xs_json.h xs_http.h xs_http_codes.h xs_unicode.h snac.h
61sandbox.o: sandbox.c xs.h snac.h 61sandbox.o: sandbox.c xs.h snac.h
62snac.o: snac.c xs.h xs_hex.h xs_io.h xs_unicode_tbl.h xs_unicode.h \ 62snac.o: snac.c xs.h xs_hex.h xs_io.h xs_unicode_tbl.h xs_unicode.h \
63 xs_json.h xs_curl.h xs_openssl.h xs_socket.h xs_unix_socket.h xs_url.h \ 63 xs_json.h xs_curl.h xs_openssl.h xs_socket.h xs_unix_socket.h xs_url.h \
64 xs_http.h xs_http_codes.h xs_httpd.h xs_mime.h xs_regex.h xs_set.h \ 64 xs_http.h xs_http_codes.h xs_httpd.h xs_mime.h xs_regex.h xs_set.h \
65 xs_time.h xs_glob.h xs_random.h xs_match.h xs_fcgi.h xs_html.h xs_po.h \ 65 xs_time.h xs_glob.h xs_random.h xs_match.h xs_fcgi.h xs_html.h xs_po.h \
66 xs_webmention.h snac.h 66 xs_webmention.h xs_list_tools.h snac.h
67upgrade.o: upgrade.c xs.h xs_io.h xs_json.h xs_glob.h snac.h 67upgrade.o: upgrade.c xs.h xs_io.h xs_json.h xs_glob.h snac.h
68utils.o: utils.c xs.h xs_io.h xs_json.h xs_time.h xs_openssl.h \ 68utils.o: utils.c xs.h xs_io.h xs_json.h xs_time.h xs_openssl.h \
69 xs_random.h xs_glob.h xs_curl.h xs_regex.h xs_http.h xs_http_codes.h \ 69 xs_random.h xs_glob.h xs_curl.h xs_regex.h xs_http.h xs_http_codes.h \
70 snac.h 70 xs_list_tools.h xs_set.h snac.h
71webfinger.o: webfinger.c xs.h xs_json.h xs_curl.h xs_mime.h xs_http.h \ 71webfinger.o: webfinger.c xs.h xs_json.h xs_curl.h xs_mime.h xs_http.h \
72 xs_http_codes.h snac.h 72 xs_http_codes.h snac.h
diff --git a/main.c b/main.c
index 29a8a51..4ba9796 100644
--- a/main.c
+++ b/main.c
@@ -76,7 +76,8 @@ int usage(const char *cmd)
76 "list_create {basedir} {uid} {name} Creates a new list\n" 76 "list_create {basedir} {uid} {name} Creates a new list\n"
77 "list_remove {basedir} {uid} {name} Removes an existing list\n" 77 "list_remove {basedir} {uid} {name} Removes an existing list\n"
78 "list_add {basedir} {uid} {name} {acct} Adds an account (@user@host or actor url) to a list\n" 78 "list_add {basedir} {uid} {name} {acct} Adds an account (@user@host or actor url) to a list\n"
79 "list_del {basedir} {uid} {name} {actor} Deletes an actor URL from a list\n"; 79 "list_del {basedir} {uid} {name} {actor} Deletes an actor URL from a list\n"
80 "top_ten {basedir} {uid} [{N}] Prints the most popular posts\n";
80 81
81 if (cmd == NULL) 82 if (cmd == NULL)
82 printf("%s", cmds); 83 printf("%s", cmds);
@@ -350,6 +351,24 @@ int main(int argc, char *argv[])
350 return 0; 351 return 0;
351 } 352 }
352 353
354 if (strcmp(cmd, "top_ten") == 0) { /** **/
355 int count = 10;
356 const char *n = GET_ARGV();
357 if (xs_is_string(n))
358 count = atoi(n);
359
360 xs *l = user_top_ten(&snac, count);
361 const xs_list *i;
362
363 xs_list_foreach(l, i) {
364 printf("%s %ld★ %ld↺\n", xs_list_get(i, 0),
365 xs_number_get_l(xs_list_get(i, 1)),
366 xs_number_get_l(xs_list_get(i, 2)));
367 }
368
369 return 0;
370 }
371
353 if ((url = GET_ARGV()) == NULL) 372 if ((url = GET_ARGV()) == NULL)
354 return usage(cmd); 373 return usage(cmd);
355 374
diff --git a/snac.h b/snac.h
index 2364f72..e5efc0b 100644
--- a/snac.h
+++ b/snac.h
@@ -494,3 +494,5 @@ void rss_to_timeline(snac *user, const char *url);
494void rss_poll_hashtags(void); 494void rss_poll_hashtags(void);
495 495
496void data_fsck(void); 496void data_fsck(void);
497
498xs_list *user_top_ten(snac *user, int count);
diff --git a/utils.c b/utils.c
index 4bdbaaf..fd077f6 100644
--- a/utils.c
+++ b/utils.c
@@ -11,6 +11,8 @@
11#include "xs_curl.h" 11#include "xs_curl.h"
12#include "xs_regex.h" 12#include "xs_regex.h"
13#include "xs_http.h" 13#include "xs_http.h"
14#include "xs_list_tools.h"
15#include "xs_set.h"
14 16
15#include "snac.h" 17#include "snac.h"
16 18
@@ -1002,6 +1004,76 @@ void import_csv(snac *user)
1002 snac_log(user, xs_fmt("Cannot open file %s", fn)); 1004 snac_log(user, xs_fmt("Cannot open file %s", fn));
1003} 1005}
1004 1006
1007
1008static int top_ten_sort(const void *v1, const void *v2)
1009{
1010 const xs_list *l1 = *(const xs_list **)v1;
1011 const xs_list *l2 = *(const xs_list **)v2;
1012
1013 const char *c1 = xs_list_get(l1, 3);
1014 const char *c2 = xs_list_get(l2, 3);
1015
1016 return xs_cmp(c2, c1);
1017}
1018
1019
1020xs_list *user_top_ten(snac *user, int count)
1021/* returns the top ten more popular posts by a user */
1022{
1023 xs *idx = xs_fmt("%s/private.idx", user->basedir);
1024 xs *list = index_list(idx, XS_ALL);
1025 xs *u_list = xs_list_new();
1026 xs_set u;
1027
1028 xs_set_init(&u);
1029
1030 const char *md5;
1031
1032 xs_list_foreach(list, md5) {
1033 xs *obj = NULL;
1034
1035 if (!valid_status(object_get_by_md5(md5, &obj)))
1036 continue;
1037
1038 const char *id = xs_dict_get_def(obj, "id", "-");
1039
1040 if (!is_msg_mine(user, id))
1041 continue;
1042
1043 if (xs_set_add(&u, id) != 1)
1044 continue;
1045
1046 /* get metrics */
1047 int ls = object_likes_len(id);
1048 int as = object_announces_len(id);
1049
1050 /* build the entry and convert to list */
1051 xs *s = xs_fmt("%s\t%d\t%d\t%010d", id, ls, as, ls + as);
1052 xs *l = xs_split(s, "\t");
1053
1054 u_list = xs_list_append(u_list, l);
1055 }
1056
1057 /* sort by the sum of likes and boosts */
1058 xs *s_list = xs_list_sort(u_list, top_ten_sort);
1059
1060 xs_list *r = xs_list_new();
1061 const xs_list *i;
1062
1063 xs_list_foreach(s_list, i) {
1064 r = xs_list_append(r, i);
1065
1066 if (--count <= 0)
1067 break;
1068 }
1069
1070 xs_set_free(&u);
1071
1072 return r;
1073}
1074
1075
1076
1005static const struct { 1077static const struct {
1006 const char *proto; 1078 const char *proto;
1007 unsigned short default_port; 1079 unsigned short default_port;