diff --git a/data.c b/data.c index 945051e..bde23e1 100644 --- a/data.c +++ b/data.c @@ -381,76 +381,13 @@ d_char *timeline_list(snac *snac) } -void _timeline_parent(snac *snac, char *parent, char *child) -/* add child to parent's children list */ +d_char *_timeline_new_fn(snac *snac, char *id) +/* creates a new filename */ { - /* FIXME: this must be recursive, but *ONLY* for file renaming */ + xs *ntid = tid(0); + xs *md5 = xs_md5_hex(id, strlen(id)); - if (parent != NULL) { - xs *pfn = _timeline_find_fn(snac, parent); - - if (pfn != NULL) { - FILE *f; - - if ((f = fopen(pfn, "r")) != NULL) { - xs *ji, *msg; - - ji = xs_readall(f); - fclose(f); - - msg = xs_json_loads(ji); - - if (msg != NULL) { - xs *meta; - xs *children; - - /* get the children list */ - meta = xs_dup(xs_dict_get(msg, "_snac")); - children = xs_dup(xs_dict_get(meta, "children")); - - /* add */ - children = xs_list_append(children, child); - - /* re-store */ - meta = xs_dict_set(meta, "children", children); - msg = xs_dict_set(msg, "_snac", meta); - - xs *jo = xs_json_dumps_pp(msg, 4); - xs *ntid = tid(0); - xs *md5 = xs_md5_hex(parent, strlen(parent)); - xs *nfn = xs_fmt("%s/timeline/%s-%s.json", snac->basedir, ntid, md5); - - if ((f = fopen(nfn, "w")) != NULL) { - fwrite(jo, strlen(jo), 1, f); - fclose(f); - - snac_debug(snac, 1, - xs_fmt("_timeline_parent updated %s %s", parent, nfn)); - - unlink(pfn); - - /* generated by this user? link to local timeline */ - if (xs_startswith(parent, snac->actor)) { - xs *lfn = xs_replace(nfn, "/timeline/", "/local/"); - xs *olfn = xs_replace(pfn, "/timeline/", "/local/"); - - link(nfn, lfn); - unlink(olfn); - - snac_debug(snac, 1, - xs_fmt("_timeline_parent (local) updated %s %s", parent, lfn)); - } - } - else - snac_log(snac, xs_fmt("_timeline_parent error writing %s %s", parent, nfn)); - } - else - snac_log(snac, xs_fmt("_timeline_parent error reading %s %s", parent, pfn)); - } - else - snac_log(snac, xs_fmt("_timeline_parent error opening %s %s", parent, pfn)); - } - } + return xs_fmt("%s/timeline/%s-%s.json", snac->basedir, ntid, md5); } @@ -466,9 +403,7 @@ void timeline_add(snac *snac, char *id, char *msg, char *parent) } /* build the new filename */ - xs *ntid = tid(0); - xs *md5 = xs_md5_hex(id, strlen(id)); - xs *fn = xs_fmt("%s/timeline/%s-%s.json", snac->basedir, ntid, md5); + xs *fn = _timeline_new_fn(snac, id); xs *md; /* add metadata */ @@ -493,16 +428,113 @@ void timeline_add(snac *snac, char *id, char *msg, char *parent) snac_debug(snac, 1, xs_fmt("timeline_add %s %s", id, fn)); } - /* generated by this user? link to local timeline */ - if (xs_startswith(id, snac->actor)) { + /* related to this user? link to local timeline */ + if (xs_startswith(id, snac->actor) || + (parent != NULL && xs_startswith(parent, snac->actor))) { xs *lfn = xs_replace(fn, "/timeline/", "/local/"); link(fn, lfn); snac_debug(snac, 1, xs_fmt("timeline_add (local) %s %s", id, lfn)); } - /* relink the parent */ - _timeline_parent(snac, parent, id); + if (parent != NULL) { + /* update the parent, adding this id to its children list */ + xs *pfn = _timeline_find_fn(snac, parent); + xs *p_msg = NULL; + + if (pfn != NULL && (f = fopen(pfn, "r")) != NULL) { + xs *j; + + j = xs_readall(f); + fclose(f); + + p_msg = xs_json_loads(j); + } + + if (p_msg == NULL) + return; + + xs *meta = xs_dup(xs_dict_get(p_msg, "_snac")); + xs *children = xs_dup(xs_dict_get(meta, "children")); + + /* add the child */ + children = xs_list_append(children, id); + + /* re-store */ + meta = xs_dict_set(meta, "children", children); + p_msg = xs_dict_set(p_msg, "_snac", meta); + + xs *nfn = _timeline_new_fn(snac, parent); + + if ((f = fopen(nfn, "w")) != NULL) { + xs *j = xs_json_dumps_pp(p_msg, 4); + + fwrite(j, strlen(j), 1, f); + fclose(f); + + unlink(pfn); + + snac_debug(snac, 2, xs_fmt("updated parent %s %s", parent, nfn)); + + /* try to do the same with the local */ + xs *olfn = xs_replace(pfn, "/timeline/", "/local/"); + + if (unlink(olfn) != -1) { + xs *nlfn = xs_replace(nfn, "/timeline/", "/local/"); + + link(nfn, nlfn); + + snac_debug(snac, 2, xs_fmt("updated parent (local) %s %s", parent, nlfn)); + } + } + else + return; + + /* now iterate all parents up, just renaming the files */ + xs *grampa = xs_dup(xs_dict_get(meta, "parent")); + + while (grampa != NULL) { + xs *gofn = _timeline_find_fn(snac, grampa); + + if (gofn == NULL) + break; + + /* create the new filename */ + xs *gnfn = _timeline_new_fn(snac, grampa); + + rename(gofn, gnfn); + + snac_debug(snac, 2, xs_fmt("updated grampa %s %s", grampa, gnfn)); + + /* try to do the same with the local */ + xs *golfn = xs_replace(gofn, "/timeline/", "/local/"); + + if (unlink(golfn) != -1) { + xs *gnlfn = xs_replace(gnfn, "/timeline/", "/local/"); + + link(gnfn, gnlfn); + + snac_debug(snac, 2, xs_fmt("updated grampa (local) %s %s", parent, gnlfn)); + } + + /* now open it and get its own parent */ + if ((f = fopen(gnfn, "r")) != NULL) { + xs *j = xs_readall(f); + fclose(f); + + xs *g_msg = xs_json_loads(j); + xs *meta = xs_dict_get(g_msg, "_snac"); + d_char *p = xs_dict_get(meta, "parent"); + + free(grampa); + + if (p != NULL) + p = xs_dup(p); + + grampa = p; + } + } + } }