commit 31318c5

grunfink  ·  2026-10-02 07:07:08 +0000 UTC
parents b2ba481, 21c19c0
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
3 files changed,  +35, -7
M data.c
M snac.c
M snac.h
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)) \