~williewillus/r16

602ad8fceb0ea4d0021e579aaec31a7559a457fa — Vincent Lee 2 years ago 34f472b
Make all frontends store trick creation time as integer unix timestamp

Before, this was inconsistent between Discord (iso8601 string timestamp)
and http (unix time in string form).
A script is provided to migrate old files created by the Discord frontend before
this change.
5 files changed, 40 insertions(+), 3 deletions(-)

M frontends/discord.rkt
M frontends/http.rkt
M interface.rkt
A scripts/migrate_timestamps.rkt
A timestamp.rkt
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))