diff options
| author | 2024-12-05 17:16:57 +0100 | |
|---|---|---|
| committer | 2024-12-05 17:16:57 +0100 | |
| commit | 7e743e8918e0a4d058217ec33ab745b1f1a97335 (patch) | |
| tree | 9aaed93dff31ccfbc63b4302dd8531a47c11f9bf /data.c | |
| parent | Merge remote-tracking branch 'upstream/master' (diff) | |
| parent | Updated RELEASE_NOTES. (diff) | |
| download | snac2-7e743e8918e0a4d058217ec33ab745b1f1a97335.tar.gz snac2-7e743e8918e0a4d058217ec33ab745b1f1a97335.tar.xz snac2-7e743e8918e0a4d058217ec33ab745b1f1a97335.zip | |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'data.c')
| -rw-r--r-- | data.c | 119 |
1 files changed, 119 insertions, 0 deletions
| @@ -299,6 +299,35 @@ int user_persist(snac *snac, int publish) | |||
| 299 | xs *bfn = xs_fmt("%s.bak", fn); | 299 | xs *bfn = xs_fmt("%s.bak", fn); |
| 300 | FILE *f; | 300 | FILE *f; |
| 301 | 301 | ||
| 302 | if (publish) { | ||
| 303 | /* check if any of the relevant fields have really changed */ | ||
| 304 | if ((f = fopen(fn, "r")) != NULL) { | ||
| 305 | xs *old = xs_json_load(f); | ||
| 306 | fclose(f); | ||
| 307 | |||
| 308 | if (old != NULL) { | ||
| 309 | int nw = 0; | ||
| 310 | const char *fields[] = { "header", "avatar", "name", "bio", "metadata", NULL }; | ||
| 311 | |||
| 312 | for (int n = 0; fields[n]; n++) { | ||
| 313 | const char *of = xs_dict_get(old, fields[n]); | ||
| 314 | const char *nf = xs_dict_get(snac->config, fields[n]); | ||
| 315 | |||
| 316 | if (of == NULL && nf == NULL) | ||
| 317 | continue; | ||
| 318 | |||
| 319 | if (xs_type(of) != XSTYPE_STRING || xs_type(nf) != XSTYPE_STRING || strcmp(of, nf)) { | ||
| 320 | nw = 1; | ||
| 321 | break; | ||
| 322 | } | ||
| 323 | } | ||
| 324 | |||
| 325 | if (!nw) | ||
| 326 | publish = 0; | ||
| 327 | } | ||
| 328 | } | ||
| 329 | } | ||
| 330 | |||
| 302 | rename(fn, bfn); | 331 | rename(fn, bfn); |
| 303 | 332 | ||
| 304 | if ((f = fopen(fn, "w")) != NULL) { | 333 | if ((f = fopen(fn, "w")) != NULL) { |
| @@ -1139,6 +1168,96 @@ xs_list *follower_list(snac *snac) | |||
| 1139 | } | 1168 | } |
| 1140 | 1169 | ||
| 1141 | 1170 | ||
| 1171 | /** pending followers **/ | ||
| 1172 | |||
| 1173 | int pending_add(snac *user, const char *actor, const xs_dict *msg) | ||
| 1174 | /* stores the follow message for later confirmation */ | ||
| 1175 | { | ||
| 1176 | xs *dir = xs_fmt("%s/pending", user->basedir); | ||
| 1177 | xs *md5 = xs_md5_hex(actor, strlen(actor)); | ||
| 1178 | xs *fn = xs_fmt("%s/%s.json", dir, md5); | ||
| 1179 | FILE *f; | ||
| 1180 | |||
| 1181 | mkdirx(dir); | ||
| 1182 | |||
| 1183 | if ((f = fopen(fn, "w")) == NULL) | ||
| 1184 | return -1; | ||
| 1185 | |||
| 1186 | xs_json_dump(msg, 4, f); | ||
| 1187 | fclose(f); | ||
| 1188 | |||
| 1189 | return 0; | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | |||
| 1193 | int pending_check(snac *user, const char *actor) | ||
| 1194 | /* checks if there is a pending follow confirmation for the actor */ | ||
| 1195 | { | ||
| 1196 | xs *md5 = xs_md5_hex(actor, strlen(actor)); | ||
| 1197 | xs *fn = xs_fmt("%s/pending/%s.json", user->basedir, md5); | ||
| 1198 | |||
| 1199 | return mtime(fn) != 0; | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | |||
| 1203 | xs_dict *pending_get(snac *user, const char *actor) | ||
| 1204 | /* returns the pending follow confirmation for the actor */ | ||
| 1205 | { | ||
| 1206 | xs *md5 = xs_md5_hex(actor, strlen(actor)); | ||
| 1207 | xs *fn = xs_fmt("%s/pending/%s.json", user->basedir, md5); | ||
| 1208 | xs_dict *msg = NULL; | ||
| 1209 | FILE *f; | ||
| 1210 | |||
| 1211 | if ((f = fopen(fn, "r")) != NULL) { | ||
| 1212 | msg = xs_json_load(f); | ||
| 1213 | fclose(f); | ||
| 1214 | } | ||
| 1215 | |||
| 1216 | return msg; | ||
| 1217 | } | ||
| 1218 | |||
| 1219 | |||
| 1220 | void pending_del(snac *user, const char *actor) | ||
| 1221 | /* deletes a pending follow confirmation for the actor */ | ||
| 1222 | { | ||
| 1223 | xs *md5 = xs_md5_hex(actor, strlen(actor)); | ||
| 1224 | xs *fn = xs_fmt("%s/pending/%s.json", user->basedir, md5); | ||
| 1225 | |||
| 1226 | unlink(fn); | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | |||
| 1230 | xs_list *pending_list(snac *user) | ||
| 1231 | /* returns a list of pending follow confirmations */ | ||
| 1232 | { | ||
| 1233 | xs *spec = xs_fmt("%s/pending/""*.json", user->basedir); | ||
| 1234 | xs *l = xs_glob(spec, 0, 0); | ||
| 1235 | xs_list *r = xs_list_new(); | ||
| 1236 | const char *v; | ||
| 1237 | |||
| 1238 | xs_list_foreach(l, v) { | ||
| 1239 | FILE *f; | ||
| 1240 | xs *msg = NULL; | ||
| 1241 | |||
| 1242 | if ((f = fopen(v, "r")) == NULL) | ||
| 1243 | continue; | ||
| 1244 | |||
| 1245 | msg = xs_json_load(f); | ||
| 1246 | fclose(f); | ||
| 1247 | |||
| 1248 | if (msg == NULL) | ||
| 1249 | continue; | ||
| 1250 | |||
| 1251 | const char *actor = xs_dict_get(msg, "actor"); | ||
| 1252 | |||
| 1253 | if (xs_type(actor) == XSTYPE_STRING) | ||
| 1254 | r = xs_list_append(r, actor); | ||
| 1255 | } | ||
| 1256 | |||
| 1257 | return r; | ||
| 1258 | } | ||
| 1259 | |||
| 1260 | |||
| 1142 | /** timeline **/ | 1261 | /** timeline **/ |
| 1143 | 1262 | ||
| 1144 | double timeline_mtime(snac *snac) | 1263 | double timeline_mtime(snac *snac) |