commit 979f2ad
default
·
2024-05-08 14:43:02 +0000 UTC
parent 34c8968
Rewritten content_search() to read from both timelines.
M
data.c
+63,
-14
1@@ -2490,23 +2490,35 @@ void notify_clear(snac *snac)
2
3 /** searches **/
4
5-xs_list *content_search(snac *user, const xs_list *timeline,
6- const char *regex, int max_secs, int *timeout)
7+xs_list *content_search(snac *user, const char *regex, int priv, int max_secs, int *timeout)
8 /* returns a list of posts which content matches the regex */
9 {
10- xs_list *r = xs_list_new();
11+ xs_set seen;
12+
13+ xs_set_init(&seen);
14
15 if (max_secs == 0)
16 max_secs = 3;
17
18- int c = 0;
19- char *v;
20-
21 time_t t = time(NULL) + max_secs;
22 *timeout = 0;
23
24- while (xs_list_next(timeline, &v, &c)) {
25- xs *post = NULL;
26+ /* iterate both timelines simultaneously */
27+ xs *pub_tl = timeline_simple_list(user, "public", 0, XS_ALL);
28+ int pub_c = 0;
29+ char *pub_md5 = NULL;
30+
31+ xs *priv_tl = priv ? timeline_simple_list(user, "private", 0, XS_ALL) : xs_list_new();
32+ int priv_c = 0;
33+ char *priv_md5 = NULL;
34+
35+ /* first positioning */
36+ xs_list_next(pub_tl, &pub_md5, &pub_c);
37+ xs_list_next(priv_tl, &priv_md5, &priv_c);
38+
39+ for (;;) {
40+ char *md5 = NULL;
41+ enum { NONE, PUBLIC, PRIVATE } from = NONE;
42
43 /* timeout? */
44 if (time(NULL) > t) {
45@@ -2514,11 +2526,48 @@ xs_list *content_search(snac *user, const xs_list *timeline,
46 break;
47 }
48
49- /* if from a user, must be in any timeline */
50- if (user && !timeline_here(user, v))
51- continue;
52+ if (pub_md5 == NULL) {
53+ /* out of both lists? done */
54+ if (priv_md5 == NULL)
55+ break;
56
57- if (!valid_status(object_get_by_md5(v, &post)))
58+ /* out of public: take element from the private timeline and advance */
59+ from = PRIVATE;
60+ }
61+ else
62+ if (priv_md5 == NULL) {
63+ /* out of private: take element from the public timeline and advance */
64+ from = PUBLIC;
65+ }
66+ else {
67+ /* candidates from both: choose one from the file dates */
68+ xs *pub_fn = xs_fmt("%s/public/%s.json", user->basedir, pub_md5);
69+ xs *priv_fn = xs_fmt("%s/private/%s.json", user->basedir, priv_md5);
70+
71+ if (mtime(pub_fn) < mtime(priv_fn))
72+ from = PRIVATE;
73+ else
74+ from = PUBLIC;
75+ }
76+
77+ if (from == PUBLIC) { /* public */
78+ md5 = pub_md5;
79+ if (!xs_list_next(pub_tl, &pub_md5, &pub_c))
80+ pub_md5 = NULL;
81+ }
82+ else
83+ if (from == PRIVATE) { /* private */
84+ md5 = priv_md5;
85+ if (!xs_list_next(priv_tl, &priv_md5, &priv_c))
86+ priv_md5 = NULL;
87+ }
88+
89+ if (md5 == NULL)
90+ break;
91+
92+ xs *post = NULL;
93+
94+ if (!valid_status(timeline_get_by_md5(user, md5, &post)))
95 continue;
96
97 /* must be a Note */
98@@ -2539,10 +2588,10 @@ xs_list *content_search(snac *user, const xs_list *timeline,
99 xs *l = xs_regex_select_n(c, regex, 1);
100
101 if (xs_list_len(l))
102- r = xs_list_append(r, v);
103+ xs_set_add(&seen, md5);
104 }
105
106- return r;
107+ return xs_set_result(&seen);
108 }
109
110
M
main.c
+1,
-21
1@@ -376,30 +376,10 @@ int main(int argc, char *argv[])
2 }
3
4 if (strcmp(cmd, "search") == 0) { /** **/
5- xs *tl = timeline_simple_list(&snac, "private", 0, XS_ALL);
6 int to;
7
8 /* 'url' contains the regex */
9- xs *r = content_search(&snac, tl, url, 10, &to);
10-
11- int c = 0;
12- char *v;
13-
14- /* print results as standalone links */
15- while (xs_list_next(r, &v, &c)) {
16- printf("%s/admin/p/%s\n", snac.actor, v);
17- }
18-
19- return 0;
20- }
21-
22- if (strcmp(cmd, "search2") == 0) { /** **/
23- /* undocumented (for testing only) */
24- xs *tl = timeline_simple_list(&snac, "public", 0, XS_ALL);
25- int to;
26-
27- /* 'url' contains the regex */
28- xs *r = content_search(&snac, tl, url, 10, &to);
29+ xs *r = content_search(&snac, url, 1, 10, &to);
30
31 int c = 0;
32 char *v;
M
snac.h
+1,
-2
1@@ -179,8 +179,7 @@ xs_list *list_timeline(snac *user, const char *list, int skip, int show);
2 xs_val *list_content(snac *user, const char *list_id, const char *actor_md5, int op);
3 void list_distribute(snac *user, const char *who, const xs_dict *post);
4
5-xs_list *content_search(snac *user, const xs_list *timeline,
6- const char *regex, int max_secs, int *timeout);
7+xs_list *content_search(snac *user, const char *regex, int priv, int max_secs, int *timeout);
8
9 int actor_add(const char *actor, xs_dict *msg);
10 int actor_get(const char *actor, xs_dict **data);