commit 3ab733c

default  ·  2024-05-08 08:20:25 +0000 UTC
parent 5d51928
New function search_by_content().
3 files changed,  +79, -0
M data.c
M main.c
M snac.h
M data.c
+58, -0
 1@@ -2488,6 +2488,64 @@ void notify_clear(snac *snac)
 2 }
 3 
 4 
 5+/** searches **/
 6+
 7+xs_list *search_by_content(snac *user, const xs_list *timeline,
 8+                            const char *regex, int timeout)
 9+/* returns a list of posts which content matches the regex */
10+{
11+    xs_list *r = xs_list_new();
12+
13+    if (timeout == 0)
14+        timeout = 3;
15+
16+    int c = 0;
17+    char *v;
18+
19+    time_t t = time(NULL) + timeout;
20+
21+    while (xs_list_next(timeline, &v, &c)) {
22+        xs *post = NULL;
23+
24+        /* timeout? */
25+        if (time(NULL) > t)
26+            break;
27+
28+        int status;
29+
30+        if (user)
31+            status = timeline_get_by_md5(user, v, &post);
32+        else
33+            status = object_get_by_md5(v, &post);
34+
35+        if (!valid_status(status))
36+            continue;
37+
38+        /* must be a Note */
39+        if (strcmp(xs_dict_get_def(post, "type", ""), "Note"))
40+            continue;
41+
42+        char *content = xs_dict_get(post, "content");
43+
44+        if (xs_is_null(content))
45+            continue;
46+
47+        /* strip HTML */
48+        xs *c = xs_regex_replace(content, "<[^>]+>", " ");
49+        c = xs_regex_replace_i(c, " {2,}", " ");
50+        c = xs_tolower_i(c);
51+
52+        /* apply regex */
53+        xs *l = xs_regex_select_n(c, regex, 1);
54+
55+        if (xs_list_len(l))
56+            r = xs_list_append(r, v);
57+    }
58+
59+    return r;
60+}
61+
62+
63 /** the queue **/
64 
65 static xs_dict *_enqueue_put(const char *fn, xs_dict *msg)
M main.c
+18, -0
 1@@ -44,6 +44,7 @@ int usage(void)
 2     printf("limit {basedir} {uid} {actor}        Limits an actor (drops their announces)\n");
 3     printf("unlimit {basedir} {uid} {actor}      Unlimits an actor\n");
 4     printf("verify_links {basedir} {uid}         Verifies a user's links (in the metadata)\n");
 5+    printf("search {basedir} {uid} {regex}       Searches posts by content\n");
 6 
 7     return 1;
 8 }
 9@@ -374,6 +375,23 @@ int main(int argc, char *argv[])
10         return 0;
11     }
12 
13+    if (strcmp(cmd, "search") == 0) { /** **/
14+        xs *tl = timeline_simple_list(&snac, "private", 0, XS_ALL);
15+
16+        /* 'url' contains the regex */
17+        xs *r = search_by_content(&snac, tl, url, 10);
18+
19+        int c = 0;
20+        char *v;
21+
22+        /* print results as standalone links */
23+        while (xs_list_next(r, &v, &c)) {
24+            printf("%s/admin/p/%s\n", snac.actor, v);
25+        }
26+
27+        return 0;
28+    }
29+
30     if (strcmp(cmd, "ping") == 0) { /** **/
31         xs *actor_o = NULL;
32 
M snac.h
+3, -0
 1@@ -179,6 +179,9 @@ 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 *search_by_content(snac *user, const xs_list *timeline,
 6+                            const char *regex, int timeout);
 7+
 8 int actor_add(const char *actor, xs_dict *msg);
 9 int actor_get(const char *actor, xs_dict **data);
10 int actor_get_refresh(snac *user, const char *actor, xs_dict **data);