Просмотр исходного кода

Use Mastodon's RFC3339 format for markers

https://docs.joinmastodon.org/api/datetime-format/#datetime
specifies that datetimes should be a particular variant of
RFC3339.

Fixes #659
Paul Martin 1 месяц назад
Родитель
Сommit
21c19c0e4e
3 измененных файлов с 35 добавлено и 7 удалено
  1. 13 5
      data.c
  2. 18 2
      snac.c
  3. 4 0
      snac.h

+ 13 - 5
data.c

@@ -3493,7 +3493,15 @@ xs_dict *markers_get(snac *snac, const xs_list *markers)
     xs_list_foreach(markers, v) {
         const xs_dict *mark = xs_dict_get(data, v);
         if (!xs_is_null(mark)) {
-            returns = xs_dict_append(returns, v, mark);
+            xs_dict *copy = xs_dup(mark);
+            const xs_val *datetime = xs_dict_get(mark, "updated_at");
+            if (!xs_is_null(datetime) && datetime[0] != '2') {
+                /* fix wrong timestamp format */
+                struct timeval tv;
+                if (sscanf(datetime, "%lu.%lu", &(tv.tv_sec), &(tv.tv_usec))==2)
+                    xs_dict_set(copy, "updated_at", rfctime(0, &tv));
+            }
+            returns = xs_dict_append(returns, v, copy);
         }
     }
     return returns;
@@ -3517,20 +3525,20 @@ xs_dict *markers_set(snac *snac, const char *home_marker, const char *notify_mar
 
     if (!xs_is_null(home_marker)) {
         xs *home = xs_dict_new();
-        xs *s_tid = tid(0);
+        xs *s_datetime = rfctime(0, NULL);
         home = xs_dict_append(home, "last_read_id", home_marker);
         home = xs_dict_append(home, "version", xs_stock(0));
-        home = xs_dict_append(home, "updated_at", s_tid);
+        home = xs_dict_append(home, "updated_at", s_datetime);
         data = xs_dict_set(data, "home", home);
         written = xs_dict_append(written, "home", home);
     }
 
     if (!xs_is_null(notify_marker)) {
         xs *notify = xs_dict_new();
-        xs *s_tid = tid(0);
+        xs *s_datetime = rfctime(0, NULL);
         notify = xs_dict_append(notify, "last_read_id", notify_marker);
         notify = xs_dict_append(notify, "version", xs_stock(0));
-        notify = xs_dict_append(notify, "updated_at", s_tid);
+        notify = xs_dict_append(notify, "updated_at", s_datetime);
         data = xs_dict_set(data, "notifications", notify);
         written = xs_dict_append(written, "notifications", notify);
     }

+ 18 - 2
snac.c

@@ -85,6 +85,22 @@ double ftime(void)
     return atof(ntid);
 }
 
+xs_str *rfctime(int offset, struct timeval *tv)
+/* returns an RFC3339 format (with fractional seconds) compliant with Mastodon datetime */
+{
+    struct timeval tv2;
+
+    if (tv == NULL) {
+        gettimeofday(&tv2, NULL);
+        tv = &tv2;
+    }
+    xs_str *iso_date = xs_str_utctime((long)(*tv).tv_sec + (long)offset, "%Y-%m-%dT%H:%M:%S");
+    xs_str *date_with_ms =xs_fmt("%s.%03ldZ", iso_date, (long)(*tv).tv_usec/1000L);
+    xs_free(iso_date);
+
+    return date_with_ms;
+}
+
 
 int validate_uid(const char *uid)
 /* returns if uid is a valid identifier */
@@ -235,7 +251,7 @@ int strip_media(const char *fn)
         /* Heuristic: find 'user/' in the path to make it relative */
         /* This works for ~/user/..., /var/snac/user/..., etc. */
         const char *r_fn = strstr(fn, "user/");
-        
+
         if (r_fn == NULL) {
             /* Fallback: try to strip ~/ if present */
             if (strncmp(fn, "~/", 2) == 0)
@@ -318,7 +334,7 @@ int strip_media(const char *fn)
                 /* rename tmp file to original */
                 /* use full path for source because it was created relative to basedir */
                 xs *full_tmp_fn = xs_fmt("%s/%s", srv_basedir, tmp_fn);
-                
+
                 if (rename(full_tmp_fn, fn) == 0)
                     srv_debug(1, xs_fmt("strip_media: stripped %s", fn));
                 else

+ 4 - 0
snac.h

@@ -1,6 +1,9 @@
 /* snac - A simple, minimalistic ActivityPub instance */
 /* copyright (c) 2022 - 2026 grunfink et al. / MIT license */
 
+#include <sys/time.h> /* for struct timeval */
+#include "xs.h"       /* for xs_* */
+
 #define VERSION "2.95"
 
 #define USER_AGENT "snac/" VERSION
@@ -49,6 +52,7 @@ int mkdirx(const char *pathname);
 #define valid_status(status) xs_http_valid_status(status)
 xs_str *tid(int offset);
 double ftime(void);
+xs_str *rfctime(int offset, struct timeval *tv);
 
 void srv_log(xs_str *str);
 #define srv_debug(level, str) do { if (dbglevel >= (level)) \