M frontends/discord.rkt => frontends/discord.rkt +2 -1
@@ 21,6 21,7 @@
(prefix-in ev: "../evaluator.rkt")
"../interface.rkt"
"../log.rkt"
+ "../timestamp.rkt"
"../utils.rkt")
(provide r16-make-frontend)
@@ 472,7 473,7 @@
(send (current-backend) register
name (strip-backticks body)
(message-author-id (current-message))
- (hash-ref (current-message) 'timestamp)))
+ (discord-timestamp-to-unix (hash-ref (current-message) 'timestamp))))
(list (result-case cdr cadr result)))
(define/command/trick (show-trick name _body)
M frontends/http.rkt => frontends/http.rkt +1 -1
@@ 168,7 168,7 @@
[(cons 'ok msg) (simple-response 200 (string->bytes/utf-8 msg))]
[(list* 'err msg _) (simple-response 400 (string->bytes/utf-8 msg))])]
[else
- (match (send (current-backend) register name code hashed-pass (number->string (current-seconds)))
+ (match (send (current-backend) register name code hashed-pass (current-seconds))
[(cons 'ok _)
(response/full
303 #"See Other"
M interface.rkt => interface.rkt +1 -1
@@ 57,7 57,7 @@
;; register a trick, returning an error or success message
[register (#;trick string? #;code string?
- #;author string? #;timestamp string? . ->m .
+ #;author string? #;timestamp exact-integer? . ->m .
(result/c string?
(error/c (needs-body)
(missing-permissions))))]
A scripts/migrate_timestamps.rkt => scripts/migrate_timestamps.rkt +18 -0
@@ 0,0 1,18 @@
+#lang racket/base
+
+;; This script migrates the timestamps stored in a save data json file from
+;; Discord's ISO8601 variant to unix timestamps. Reads from stdin and outputs to stdout.
+;; Establishes a proper common format in the save data json across frontends
+;; and overall storing numerical timestamps is saner.
+
+(require json "../timestamp.rkt")
+
+(define (main)
+ (define blob (read-json))
+ (define updated-blob
+ (for/hash ([(name trick) (in-hash blob)])
+ (values name (hash-update trick 'created discord-timestamp-to-unix))))
+ (write-json updated-blob))
+
+(module* main #f
+ (main))
A timestamp.rkt => timestamp.rkt +18 -0
@@ 0,0 1,18 @@
+#lang racket/base
+
+(require
+ (only-in racket/date date->seconds)
+ racket/string
+ (only-in srfi/19 string->date))
+
+(provide discord-timestamp-to-unix)
+
+;; Discord timestamps are in the format 2022-02-22T14:42:15.223333+00:00.
+;; We assume and verify that the zone is always UTC, then strip it off,
+;; as srfi-19 cannot parse it.
+(define (discord-timestamp-to-unix s)
+ (unless (string-suffix? s "+00:00")
+ (raise (exn:fail "Expect timestamps with UTC zone" (current-continuation-marks))))
+ ;; Anything extra in the string that is not specified in the template
+ ;; (aka the subsecond precision and +00:00 zone) is ignored by string->date
+ (date->seconds (string->date s "~Y-~m-~dT~H:~M:~S") #f))