summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar default2024-05-08 16:43:02 +0200
committerGravatar default2024-05-08 16:43:02 +0200
commit979f2ad1400111bcd36da980ba8f78f25bb5390e (patch)
tree1a2e4d76bf54633fad3beb307bf2612991eac8e3
parentMinor tweaks to content_search(). (diff)
downloadpenes-snac2-979f2ad1400111bcd36da980ba8f78f25bb5390e.tar.gz
penes-snac2-979f2ad1400111bcd36da980ba8f78f25bb5390e.tar.xz
penes-snac2-979f2ad1400111bcd36da980ba8f78f25bb5390e.zip
Rewritten content_search() to read from both timelines.
-rw-r--r--data.c77
-rw-r--r--main.c22
-rw-r--r--snac.h3
3 files changed, 65 insertions, 37 deletions
diff --git a/data.c b/data.c
index 1421f17..d9449d8 100644
--- a/data.c
+++ b/data.c
@@ -2490,23 +2490,35 @@ void notify_clear(snac *snac)
2490 2490
2491/** searches **/ 2491/** searches **/
2492 2492
2493xs_list *content_search(snac *user, const xs_list *timeline, 2493xs_list *content_search(snac *user, const char *regex, int priv, int max_secs, int *timeout)
2494 const char *regex, int max_secs, int *timeout)
2495/* returns a list of posts which content matches the regex */ 2494/* returns a list of posts which content matches the regex */
2496{ 2495{
2497 xs_list *r = xs_list_new(); 2496 xs_set seen;
2497
2498 xs_set_init(&seen);
2498 2499
2499 if (max_secs == 0) 2500 if (max_secs == 0)
2500 max_secs = 3; 2501 max_secs = 3;
2501 2502
2502 int c = 0;
2503 char *v;
2504
2505 time_t t = time(NULL) + max_secs; 2503 time_t t = time(NULL) + max_secs;
2506 *timeout = 0; 2504 *timeout = 0;
2507 2505
2508 while (xs_list_next(timeline, &v, &c)) { 2506 /* iterate both timelines simultaneously */
2509 xs *post = NULL; 2507 xs *pub_tl = timeline_simple_list(user, "public", 0, XS_ALL);
2508 int pub_c = 0;
2509 char *pub_md5 = NULL;
2510
2511 xs *priv_tl = priv ? timeline_simple_list(user, "private", 0, XS_ALL) : xs_list_new();
2512 int priv_c = 0;
2513 char *priv_md5 = NULL;
2514
2515 /* first positioning */
2516 xs_list_next(pub_tl, &pub_md5, &pub_c);
2517 xs_list_next(priv_tl, &priv_md5, &priv_c);
2518
2519 for (;;) {
2520 char *md5 = NULL;
2521 enum { NONE, PUBLIC, PRIVATE } from = NONE;
2510 2522
2511 /* timeout? */ 2523 /* timeout? */
2512 if (time(NULL) > t) { 2524 if (time(NULL) > t) {
@@ -2514,11 +2526,48 @@ xs_list *content_search(snac *user, const xs_list *timeline,
2514 break; 2526 break;
2515 } 2527 }
2516 2528
2517 /* if from a user, must be in any timeline */ 2529 if (pub_md5 == NULL) {
2518 if (user && !timeline_here(user, v)) 2530 /* out of both lists? done */
2519 continue; 2531 if (priv_md5 == NULL)
2532 break;
2520 2533
2521 if (!valid_status(object_get_by_md5(v, &post))) 2534 /* out of public: take element from the private timeline and advance */
2535 from = PRIVATE;
2536 }
2537 else
2538 if (priv_md5 == NULL) {
2539 /* out of private: take element from the public timeline and advance */
2540 from = PUBLIC;
2541 }
2542 else {
2543 /* candidates from both: choose one from the file dates */
2544 xs *pub_fn = xs_fmt("%s/public/%s.json", user->basedir, pub_md5);
2545 xs *priv_fn = xs_fmt("%s/private/%s.json", user->basedir, priv_md5);
2546
2547 if (mtime(pub_fn) < mtime(priv_fn))
2548 from = PRIVATE;
2549 else
2550 from = PUBLIC;
2551 }
2552
2553 if (from == PUBLIC) { /* public */
2554 md5 = pub_md5;
2555 if (!xs_list_next(pub_tl, &pub_md5, &pub_c))
2556 pub_md5 = NULL;
2557 }
2558 else
2559 if (from == PRIVATE) { /* private */
2560 md5 = priv_md5;
2561 if (!xs_list_next(priv_tl, &priv_md5, &priv_c))
2562 priv_md5 = NULL;
2563 }
2564
2565 if (md5 == NULL)
2566 break;
2567
2568 xs *post = NULL;
2569
2570 if (!valid_status(timeline_get_by_md5(user, md5, &post)))
2522 continue; 2571 continue;
2523 2572
2524 /* must be a Note */ 2573 /* must be a Note */
@@ -2539,10 +2588,10 @@ xs_list *content_search(snac *user, const xs_list *timeline,
2539 xs *l = xs_regex_select_n(c, regex, 1); 2588 xs *l = xs_regex_select_n(c, regex, 1);
2540 2589
2541 if (xs_list_len(l)) 2590 if (xs_list_len(l))
2542 r = xs_list_append(r, v); 2591 xs_set_add(&seen, md5);
2543 } 2592 }
2544 2593
2545 return r; 2594 return xs_set_result(&seen);
2546} 2595}
2547 2596
2548 2597
diff --git a/main.c b/main.c
index 240e02e..bd52b19 100644
--- a/main.c
+++ b/main.c
@@ -376,30 +376,10 @@ int main(int argc, char *argv[])
376 } 376 }
377 377
378 if (strcmp(cmd, "search") == 0) { /** **/ 378 if (strcmp(cmd, "search") == 0) { /** **/
379 xs *tl = timeline_simple_list(&snac, "private", 0, XS_ALL);
380 int to; 379 int to;
381 380
382 /* 'url' contains the regex */ 381 /* 'url' contains the regex */
383 xs *r = content_search(&snac, tl, url, 10, &to); 382 xs *r = content_search(&snac, url, 1, 10, &to);
384
385 int c = 0;
386 char *v;
387
388 /* print results as standalone links */
389 while (xs_list_next(r, &v, &c)) {
390 printf("%s/admin/p/%s\n", snac.actor, v);
391 }
392
393 return 0;
394 }
395
396 if (strcmp(cmd, "search2") == 0) { /** **/
397 /* undocumented (for testing only) */
398 xs *tl = timeline_simple_list(&snac, "public", 0, XS_ALL);
399 int to;
400
401 /* 'url' contains the regex */
402 xs *r = content_search(&snac, tl, url, 10, &to);
403 383
404 int c = 0; 384 int c = 0;
405 char *v; 385 char *v;
diff --git a/snac.h b/snac.h
index e3b76f6..e04dc65 100644
--- a/snac.h
+++ b/snac.h
@@ -179,8 +179,7 @@ xs_list *list_timeline(snac *user, const char *list, int skip, int show);
179xs_val *list_content(snac *user, const char *list_id, const char *actor_md5, int op); 179xs_val *list_content(snac *user, const char *list_id, const char *actor_md5, int op);
180void list_distribute(snac *user, const char *who, const xs_dict *post); 180void list_distribute(snac *user, const char *who, const xs_dict *post);
181 181
182xs_list *content_search(snac *user, const xs_list *timeline, 182xs_list *content_search(snac *user, const char *regex, int priv, int max_secs, int *timeout);
183 const char *regex, int max_secs, int *timeout);
184 183
185int actor_add(const char *actor, xs_dict *msg); 184int actor_add(const char *actor, xs_dict *msg);
186int actor_get(const char *actor, xs_dict **data); 185int actor_get(const char *actor, xs_dict **data);