commit 31318c5
Merge pull request 'Use Mastodon's RFC3339 format for markers' (#660) from nowster/snac2:markers-rfcdate into master Reviewed-on: https://codeberg.org/grunfink/snac2/pulls/660
M
data.c
+13,
-5
1@@ -3493,7 +3493,15 @@ xs_dict *markers_get(snac *snac, const xs_list *markers)
2 xs_list_foreach(markers, v) {
3 const xs_dict *mark = xs_dict_get(data, v);
4 if (!xs_is_null(mark)) {
5- returns = xs_dict_append(returns, v, mark);
6+ xs_dict *copy = xs_dup(mark);
7+ const xs_val *datetime = xs_dict_get(mark, "updated_at");
8+ if (!xs_is_null(datetime) && datetime[0] != '2') {
9+ /* fix wrong timestamp format */
10+ struct timeval tv;
11+ if (sscanf(datetime, "%lu.%lu", &(tv.tv_sec), &(tv.tv_usec))==2)
12+ xs_dict_set(copy, "updated_at", rfctime(0, &tv));
13+ }
14+ returns = xs_dict_append(returns, v, copy);
15 }
16 }
17 return returns;
18@@ -3517,20 +3525,20 @@ xs_dict *markers_set(snac *snac, const char *home_marker, const char *notify_mar
19
20 if (!xs_is_null(home_marker)) {
21 xs *home = xs_dict_new();
22- xs *s_tid = tid(0);
23+ xs *s_datetime = rfctime(0, NULL);
24 home = xs_dict_append(home, "last_read_id", home_marker);
25 home = xs_dict_append(home, "version", xs_stock(0));
26- home = xs_dict_append(home, "updated_at", s_tid);
27+ home = xs_dict_append(home, "updated_at", s_datetime);
28 data = xs_dict_set(data, "home", home);
29 written = xs_dict_append(written, "home", home);
30 }
31
32 if (!xs_is_null(notify_marker)) {
33 xs *notify = xs_dict_new();
34- xs *s_tid = tid(0);
35+ xs *s_datetime = rfctime(0, NULL);
36 notify = xs_dict_append(notify, "last_read_id", notify_marker);
37 notify = xs_dict_append(notify, "version", xs_stock(0));
38- notify = xs_dict_append(notify, "updated_at", s_tid);
39+ notify = xs_dict_append(notify, "updated_at", s_datetime);
40 data = xs_dict_set(data, "notifications", notify);
41 written = xs_dict_append(written, "notifications", notify);
42 }
M
snac.c
+18,
-2
1@@ -85,6 +85,22 @@ double ftime(void)
2 return atof(ntid);
3 }
4
5+xs_str *rfctime(int offset, struct timeval *tv)
6+/* returns an RFC3339 format (with fractional seconds) compliant with Mastodon datetime */
7+{
8+ struct timeval tv2;
9+
10+ if (tv == NULL) {
11+ gettimeofday(&tv2, NULL);
12+ tv = &tv2;
13+ }
14+ xs_str *iso_date = xs_str_utctime((long)(*tv).tv_sec + (long)offset, "%Y-%m-%dT%H:%M:%S");
15+ xs_str *date_with_ms =xs_fmt("%s.%03ldZ", iso_date, (long)(*tv).tv_usec/1000L);
16+ xs_free(iso_date);
17+
18+ return date_with_ms;
19+}
20+
21
22 int validate_uid(const char *uid)
23 /* returns if uid is a valid identifier */
24@@ -235,7 +251,7 @@ int strip_media(const char *fn)
25 /* Heuristic: find 'user/' in the path to make it relative */
26 /* This works for ~/user/..., /var/snac/user/..., etc. */
27 const char *r_fn = strstr(fn, "user/");
28-
29+
30 if (r_fn == NULL) {
31 /* Fallback: try to strip ~/ if present */
32 if (strncmp(fn, "~/", 2) == 0)
33@@ -318,7 +334,7 @@ int strip_media(const char *fn)
34 /* rename tmp file to original */
35 /* use full path for source because it was created relative to basedir */
36 xs *full_tmp_fn = xs_fmt("%s/%s", srv_basedir, tmp_fn);
37-
38+
39 if (rename(full_tmp_fn, fn) == 0)
40 srv_debug(1, xs_fmt("strip_media: stripped %s", fn));
41 else
M
snac.h
+4,
-0
1@@ -1,6 +1,9 @@
2 /* snac - A simple, minimalistic ActivityPub instance */
3 /* copyright (c) 2022 - 2026 grunfink et al. / MIT license */
4
5+#include <sys/time.h> /* for struct timeval */
6+#include "xs.h" /* for xs_* */
7+
8 #define VERSION "2.95"
9
10 #define USER_AGENT "snac/" VERSION
11@@ -49,6 +52,7 @@ int mkdirx(const char *pathname);
12 #define valid_status(status) xs_http_valid_status(status)
13 xs_str *tid(int offset);
14 double ftime(void);
15+xs_str *rfctime(int offset, struct timeval *tv);
16
17 void srv_log(xs_str *str);
18 #define srv_debug(level, str) do { if (dbglevel >= (level)) \