mirror of
https://codeberg.org/grunfink/snac2.git
synced 2024-11-25 14:35:04 +00:00
Rewritten content_search() to read from both timelines.
This commit is contained in:
parent
34c8968cfb
commit
979f2ad140
3 changed files with 65 additions and 37 deletions
77
data.c
77
data.c
|
@ -2490,23 +2490,35 @@ void notify_clear(snac *snac)
|
||||||
|
|
||||||
/** searches **/
|
/** searches **/
|
||||||
|
|
||||||
xs_list *content_search(snac *user, const xs_list *timeline,
|
xs_list *content_search(snac *user, const char *regex, int priv, int max_secs, int *timeout)
|
||||||
const char *regex, int max_secs, int *timeout)
|
|
||||||
/* returns a list of posts which content matches the regex */
|
/* returns a list of posts which content matches the regex */
|
||||||
{
|
{
|
||||||
xs_list *r = xs_list_new();
|
xs_set seen;
|
||||||
|
|
||||||
|
xs_set_init(&seen);
|
||||||
|
|
||||||
if (max_secs == 0)
|
if (max_secs == 0)
|
||||||
max_secs = 3;
|
max_secs = 3;
|
||||||
|
|
||||||
int c = 0;
|
|
||||||
char *v;
|
|
||||||
|
|
||||||
time_t t = time(NULL) + max_secs;
|
time_t t = time(NULL) + max_secs;
|
||||||
*timeout = 0;
|
*timeout = 0;
|
||||||
|
|
||||||
while (xs_list_next(timeline, &v, &c)) {
|
/* iterate both timelines simultaneously */
|
||||||
xs *post = NULL;
|
xs *pub_tl = timeline_simple_list(user, "public", 0, XS_ALL);
|
||||||
|
int pub_c = 0;
|
||||||
|
char *pub_md5 = NULL;
|
||||||
|
|
||||||
|
xs *priv_tl = priv ? timeline_simple_list(user, "private", 0, XS_ALL) : xs_list_new();
|
||||||
|
int priv_c = 0;
|
||||||
|
char *priv_md5 = NULL;
|
||||||
|
|
||||||
|
/* first positioning */
|
||||||
|
xs_list_next(pub_tl, &pub_md5, &pub_c);
|
||||||
|
xs_list_next(priv_tl, &priv_md5, &priv_c);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
char *md5 = NULL;
|
||||||
|
enum { NONE, PUBLIC, PRIVATE } from = NONE;
|
||||||
|
|
||||||
/* timeout? */
|
/* timeout? */
|
||||||
if (time(NULL) > t) {
|
if (time(NULL) > t) {
|
||||||
|
@ -2514,11 +2526,48 @@ xs_list *content_search(snac *user, const xs_list *timeline,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if from a user, must be in any timeline */
|
if (pub_md5 == NULL) {
|
||||||
if (user && !timeline_here(user, v))
|
/* out of both lists? done */
|
||||||
continue;
|
if (priv_md5 == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
if (!valid_status(object_get_by_md5(v, &post)))
|
/* out of public: take element from the private timeline and advance */
|
||||||
|
from = PRIVATE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (priv_md5 == NULL) {
|
||||||
|
/* out of private: take element from the public timeline and advance */
|
||||||
|
from = PUBLIC;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* candidates from both: choose one from the file dates */
|
||||||
|
xs *pub_fn = xs_fmt("%s/public/%s.json", user->basedir, pub_md5);
|
||||||
|
xs *priv_fn = xs_fmt("%s/private/%s.json", user->basedir, priv_md5);
|
||||||
|
|
||||||
|
if (mtime(pub_fn) < mtime(priv_fn))
|
||||||
|
from = PRIVATE;
|
||||||
|
else
|
||||||
|
from = PUBLIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (from == PUBLIC) { /* public */
|
||||||
|
md5 = pub_md5;
|
||||||
|
if (!xs_list_next(pub_tl, &pub_md5, &pub_c))
|
||||||
|
pub_md5 = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (from == PRIVATE) { /* private */
|
||||||
|
md5 = priv_md5;
|
||||||
|
if (!xs_list_next(priv_tl, &priv_md5, &priv_c))
|
||||||
|
priv_md5 = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (md5 == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
xs *post = NULL;
|
||||||
|
|
||||||
|
if (!valid_status(timeline_get_by_md5(user, md5, &post)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* must be a Note */
|
/* must be a Note */
|
||||||
|
@ -2539,10 +2588,10 @@ xs_list *content_search(snac *user, const xs_list *timeline,
|
||||||
xs *l = xs_regex_select_n(c, regex, 1);
|
xs *l = xs_regex_select_n(c, regex, 1);
|
||||||
|
|
||||||
if (xs_list_len(l))
|
if (xs_list_len(l))
|
||||||
r = xs_list_append(r, v);
|
xs_set_add(&seen, md5);
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return xs_set_result(&seen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
22
main.c
22
main.c
|
@ -376,30 +376,10 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(cmd, "search") == 0) { /** **/
|
if (strcmp(cmd, "search") == 0) { /** **/
|
||||||
xs *tl = timeline_simple_list(&snac, "private", 0, XS_ALL);
|
|
||||||
int to;
|
int to;
|
||||||
|
|
||||||
/* 'url' contains the regex */
|
/* 'url' contains the regex */
|
||||||
xs *r = content_search(&snac, tl, url, 10, &to);
|
xs *r = content_search(&snac, url, 1, 10, &to);
|
||||||
|
|
||||||
int c = 0;
|
|
||||||
char *v;
|
|
||||||
|
|
||||||
/* print results as standalone links */
|
|
||||||
while (xs_list_next(r, &v, &c)) {
|
|
||||||
printf("%s/admin/p/%s\n", snac.actor, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(cmd, "search2") == 0) { /** **/
|
|
||||||
/* undocumented (for testing only) */
|
|
||||||
xs *tl = timeline_simple_list(&snac, "public", 0, XS_ALL);
|
|
||||||
int to;
|
|
||||||
|
|
||||||
/* 'url' contains the regex */
|
|
||||||
xs *r = content_search(&snac, tl, url, 10, &to);
|
|
||||||
|
|
||||||
int c = 0;
|
int c = 0;
|
||||||
char *v;
|
char *v;
|
||||||
|
|
3
snac.h
3
snac.h
|
@ -179,8 +179,7 @@ xs_list *list_timeline(snac *user, const char *list, int skip, int show);
|
||||||
xs_val *list_content(snac *user, const char *list_id, const char *actor_md5, int op);
|
xs_val *list_content(snac *user, const char *list_id, const char *actor_md5, int op);
|
||||||
void list_distribute(snac *user, const char *who, const xs_dict *post);
|
void list_distribute(snac *user, const char *who, const xs_dict *post);
|
||||||
|
|
||||||
xs_list *content_search(snac *user, const xs_list *timeline,
|
xs_list *content_search(snac *user, const char *regex, int priv, int max_secs, int *timeout);
|
||||||
const char *regex, int max_secs, int *timeout);
|
|
||||||
|
|
||||||
int actor_add(const char *actor, xs_dict *msg);
|
int actor_add(const char *actor, xs_dict *msg);
|
||||||
int actor_get(const char *actor, xs_dict **data);
|
int actor_get(const char *actor, xs_dict **data);
|
||||||
|
|
Loading…
Reference in a new issue