This commit is contained in:
@@ -3,10 +3,16 @@
|
|||||||
[clojure.tools.logging :as l]
|
[clojure.tools.logging :as l]
|
||||||
[hiccup2.core :as hiccup]
|
[hiccup2.core :as hiccup]
|
||||||
[net.deertopia.doerg.html :as doerg-html]
|
[net.deertopia.doerg.html :as doerg-html]
|
||||||
|
[net.deertopia.publisher.slug :as slug]
|
||||||
[org.httpkit.server :as http]
|
[org.httpkit.server :as http]
|
||||||
|
[reitit.coercion]
|
||||||
|
[reitit.coercion.spec]
|
||||||
[reitit.ring]
|
[reitit.ring]
|
||||||
[ring.util.response :as response]))
|
[ring.util.response :as response]))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Routes
|
||||||
|
|
||||||
(defn hello [req]
|
(defn hello [req]
|
||||||
(-> (hiccup/html {}
|
(-> (hiccup/html {}
|
||||||
[:html
|
[:html
|
||||||
@@ -22,9 +28,27 @@
|
|||||||
response/response
|
response/response
|
||||||
(response/content-type "text/html")))
|
(response/content-type "text/html")))
|
||||||
|
|
||||||
|
(defn node-by-slug [req]
|
||||||
|
(hello req))
|
||||||
|
|
||||||
|
(defn node-by-id [req]
|
||||||
|
(hello req))
|
||||||
|
|
||||||
(def router
|
(def router
|
||||||
(reitit.ring/router
|
(reitit.ring/router
|
||||||
#{["/" {:get hello}]}))
|
#{["/" {:get hello}]
|
||||||
|
["/n/:slug" {:get node-by-slug
|
||||||
|
#_#_#_#_:coercion reitit.coercion.spec/coercion
|
||||||
|
:parameters {:path {:slug ::slug/slug}}}]
|
||||||
|
["/id/:id" {:get node-by-id}]}
|
||||||
|
#_{:compile reitit.coercion/compile-request-coercers}))
|
||||||
|
|
||||||
|
(defn match-by-path-and-coerce! [path]
|
||||||
|
(if-let [match (r/match-by-path router path)]
|
||||||
|
(assoc match :parameters (reitit.coercion/coerce! match))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Server API
|
||||||
|
|
||||||
(def app (reitit.ring/ring-handler router))
|
(def app (reitit.ring/ring-handler router))
|
||||||
|
|
||||||
|
|||||||
66
publisher/src/net/deertopia/publisher/slug.clj
Normal file
66
publisher/src/net/deertopia/publisher/slug.clj
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
(ns net.deertopia.publisher.slug
|
||||||
|
(:require [clojure.spec.alpha :as s])
|
||||||
|
(:import (java.nio ByteBuffer)
|
||||||
|
(java.util Base64 UUID)))
|
||||||
|
|
||||||
|
(defrecord Slug [slug-string]
|
||||||
|
Object
|
||||||
|
(toString [this]
|
||||||
|
(:slug-string this)))
|
||||||
|
|
||||||
|
(defn from-string [s]
|
||||||
|
(try (let [decoder (Base64/getUrlDecoder)]
|
||||||
|
(when (= 16 (count (.decode decoder s)))
|
||||||
|
(Slug. s)))
|
||||||
|
(catch IllegalArgumentException e
|
||||||
|
(when (not= (ex-message e)
|
||||||
|
(str "Input byte[] should at least "
|
||||||
|
"have 2 bytes for base64 bytes"))
|
||||||
|
(throw e)))))
|
||||||
|
|
||||||
|
(defn to-string [s]
|
||||||
|
(str s))
|
||||||
|
|
||||||
|
(defn- coerce-to-uuid [string-or-uuid]
|
||||||
|
(cond (string? string-or-uuid) (UUID/fromString string-or-uuid)
|
||||||
|
(uuid? string-or-uuid) string-or-uuid))
|
||||||
|
|
||||||
|
(defn- uuid->bytes [string-or-uuid]
|
||||||
|
(let [uuid (coerce-to-uuid string-or-uuid)]
|
||||||
|
(.array (doto (ByteBuffer/wrap (byte-array 16))
|
||||||
|
(.putLong (.getMostSignificantBits uuid))
|
||||||
|
(.putLong (.getLeastSignificantBits uuid))))))
|
||||||
|
|
||||||
|
(defn- bytes->uuid [bytes]
|
||||||
|
(when (= (count bytes) 16)
|
||||||
|
(let [bb (ByteBuffer/wrap bytes)
|
||||||
|
high (.getLong bb)
|
||||||
|
low (.getLong bb)]
|
||||||
|
(UUID. high low))))
|
||||||
|
|
||||||
|
(defn from-uuid [string-or-uuid]
|
||||||
|
(let [uuid (coerce-to-uuid string-or-uuid)
|
||||||
|
encoder (.withoutPadding (Base64/getUrlEncoder))]
|
||||||
|
(Slug. (.encodeToString encoder (uuid->bytes uuid)))))
|
||||||
|
|
||||||
|
(defn to-uuid [slug]
|
||||||
|
(let [decoder (Base64/getUrlDecoder)]
|
||||||
|
(bytes->uuid (.decode decoder (str slug)))))
|
||||||
|
|
||||||
|
#_
|
||||||
|
(let [uuid #uuid "f9eab66e-7773-4b87-b854-0bfc8f563809"
|
||||||
|
slug (from-uuid uuid)
|
||||||
|
round-tripped (to-uuid slug)]
|
||||||
|
{:uuid uuid, :slug slug, :round-tripped round-tripped})
|
||||||
|
|
||||||
|
(defn make-slug [string]
|
||||||
|
(assert (try (to-uuid string)
|
||||||
|
(catch Throwable _
|
||||||
|
nil))
|
||||||
|
"invalid slug")
|
||||||
|
(->Slug string))
|
||||||
|
|
||||||
|
(defn slug? [s]
|
||||||
|
(some? (from-string s)))
|
||||||
|
|
||||||
|
(s/def ::slug slug?)
|
||||||
Reference in New Issue
Block a user