version manager; new API signatures; new noteID format
This commit is contained in:
+13
-16
@@ -11,7 +11,7 @@
|
||||
[hiccup.util :as util]
|
||||
[notehub.storage :as storage]))
|
||||
|
||||
(def version "1.1")
|
||||
(def version "1.2")
|
||||
|
||||
(def domain
|
||||
(get-setting
|
||||
@@ -33,8 +33,8 @@
|
||||
; Concatenates all fields to a string
|
||||
(defn build-key
|
||||
"Returns a storage-key for the given note coordinates"
|
||||
[[year month day] title]
|
||||
(print-str year month day title))
|
||||
[year month day title]
|
||||
(apply str (interpose "/" [year month day title])))
|
||||
|
||||
(defn derive-title [md-text]
|
||||
(sreplace (first (split-lines md-text))
|
||||
@@ -46,20 +46,20 @@
|
||||
(map #(+ (second %) (.get (Calendar/getInstance) (first %)))
|
||||
{Calendar/YEAR 0, Calendar/MONTH 1, Calendar/DAY_OF_MONTH 0}))
|
||||
|
||||
(defn- create-response
|
||||
([success] { :success success })
|
||||
(defn create-response
|
||||
([success] {:success success})
|
||||
([success message & params]
|
||||
(assoc (create-response success) :message (apply format message params))))
|
||||
|
||||
(defn- get-path [token & [description]]
|
||||
(if (= :url description)
|
||||
(str domain "/" token)
|
||||
(let [[year month day title] (split token #" ")]
|
||||
(let [[year month day title] (split token #"/")]
|
||||
(if description
|
||||
(str domain "/" (storage/create-short-url token {:year year :month month :day day :title title}))
|
||||
(str domain (url year month day title))))))
|
||||
|
||||
(defn get-note [noteID]
|
||||
(defn get-note [{:keys [noteID]}]
|
||||
(if (storage/note-exists? noteID)
|
||||
(let [note (storage/get-note noteID)]
|
||||
{:note note
|
||||
@@ -72,8 +72,7 @@
|
||||
(create-response false "noteID '%s' unknown" noteID)))
|
||||
|
||||
(defn post-note
|
||||
([note pid signature] (post-note note pid signature {}))
|
||||
([note pid signature opts]
|
||||
[{:keys [note pid signature password] :as params}]
|
||||
;(log "post-note: %s" {:pid pid :signature signature :password password :note note})
|
||||
(let [errors (filter identity
|
||||
[(when-not (storage/valid-publisher? pid) "pid invalid")
|
||||
@@ -82,17 +81,15 @@
|
||||
(when (blank? note) "note is empty")])]
|
||||
(if (empty? errors)
|
||||
(let [[year month day] (map str (get-date))
|
||||
password (opts :password)
|
||||
params (opts :params {})
|
||||
params (dissoc params :note :pid :signature :password)
|
||||
raw-title (filter #(or (= \- %) (Character/isLetterOrDigit %))
|
||||
(-> note derive-title trim (sreplace " " "-") lower-case))
|
||||
max-length (get-setting :max-title-length #(Integer/parseInt %) 80)
|
||||
proposed-title (apply str (take max-length raw-title))
|
||||
date [year month day]
|
||||
title (first (drop-while #(storage/note-exists? (build-key date %))
|
||||
title (first (drop-while #(storage/note-exists? (build-key year month day %))
|
||||
(cons proposed-title
|
||||
(map #(str proposed-title "-" (+ 2 %)) (range)))))
|
||||
noteID (build-key date title)
|
||||
noteID (build-key year month day title)
|
||||
new-params (assoc params :year year :month month :day day :title title)
|
||||
short-url (get-path (storage/create-short-url noteID new-params) :url)
|
||||
long-url (get-path noteID)]
|
||||
@@ -102,10 +99,10 @@
|
||||
:longURL (if (empty? params) long-url (str (util/url long-url params)))
|
||||
:shortURL short-url
|
||||
:status (create-response true)}))
|
||||
{:status (create-response false (first errors))}))))
|
||||
{:status (create-response false (first errors))})))
|
||||
|
||||
|
||||
(defn update-note [noteID note pid signature password]
|
||||
(defn update-note [{:keys [noteID note pid signature password]}]
|
||||
;(log "update-note: %s" {:pid pid :noteID noteID :signature signature :password password :note note})
|
||||
(let [errors (filter identity
|
||||
[(when-not (storage/valid-publisher? pid) "pid invalid")
|
||||
|
||||
+30
-25
@@ -90,25 +90,27 @@
|
||||
{:headers {"Content-Type" ctype}
|
||||
:body content})
|
||||
|
||||
(defn version-manager [f params]
|
||||
(generate-string
|
||||
(if-let [version (:version params)]
|
||||
(f (if (and (:noteID params) (< (Float/parseFloat version) 1.3))
|
||||
(assoc params :noteID (sreplace (params :noteID) #" " "/"))
|
||||
params))
|
||||
(api/create-response false "API version expected"))))
|
||||
|
||||
(defroutes api-routes
|
||||
|
||||
(GET "/" [] (layout (get-message :api-title)
|
||||
(md-node :article (slurp "API.md"))))
|
||||
|
||||
(GET "/note" [version noteID]
|
||||
(generate-string (api/get-note noteID)))
|
||||
(GET "/note" {params :params}
|
||||
(version-manager api/get-note params))
|
||||
|
||||
(POST "/note" {params :params}
|
||||
(generate-string
|
||||
(api/post-note
|
||||
(:note params)
|
||||
(:pid params)
|
||||
(:signature params)
|
||||
{:params (dissoc params :version :note :pid :signature :password)
|
||||
:password (:password params)})))
|
||||
(version-manager api/post-note params))
|
||||
|
||||
(PUT "/note" [version noteID note pid signature password]
|
||||
(generate-string (api/update-note noteID note pid signature password))))
|
||||
(PUT "/note" {params :params}
|
||||
(version-manager api/update-note params)))
|
||||
|
||||
(defroutes app-routes
|
||||
(context "/api" [] api-routes)
|
||||
@@ -127,11 +129,11 @@
|
||||
(md-node :div.centered.helvetica (get-message :footer))))
|
||||
|
||||
(GET "/:year/:month/:day/:title/export" [year month day title]
|
||||
(when-let [md-text (:note (api/get-note (api/build-key [year month day] title)))]
|
||||
(when-let [md-text (:note (api/get-note {:noteID (api/build-key year month day title)}))]
|
||||
(return-content-type "text/plain; charset=utf-8" md-text)))
|
||||
|
||||
(GET "/:year/:month/:day/:title/stats" [year month day title]
|
||||
(when-let [stats (:statistics (api/get-note (api/build-key [year month day] title)))]
|
||||
(when-let [stats (:statistics (api/get-note {:noteID (api/build-key year month day title)}))]
|
||||
(layout (get-message :statistics)
|
||||
[:table#stats.helvetica.central-element
|
||||
(map
|
||||
@@ -140,10 +142,10 @@
|
||||
[:published :edited :publisher :views])])))
|
||||
|
||||
(GET "/:year/:month/:day/:title/edit" [year month day title]
|
||||
(let [noteID (api/build-key [year month day] title)]
|
||||
(let [noteID (api/build-key year month day title)]
|
||||
(input-form "/update-note" :update
|
||||
(html (hidden-field :noteID noteID))
|
||||
(:note (api/get-note noteID)) :enter-passwd)))
|
||||
(:note (api/get-note {:noteID noteID})) :enter-passwd)))
|
||||
|
||||
(GET "/new" []
|
||||
(input-form "/post-note" :publish
|
||||
@@ -154,9 +156,9 @@
|
||||
(GET "/:year/:month/:day/:title" [year month day title :as params]
|
||||
(let [params (assoc (:query-params params)
|
||||
:year year :month month :day day :title title)
|
||||
noteID (api/build-key [year month day] title)]
|
||||
noteID (api/build-key year month day title)]
|
||||
(when (storage/note-exists? noteID)
|
||||
(let [note (api/get-note noteID)
|
||||
(let [note (api/get-note {:noteID noteID})
|
||||
sanitized-note (sanitize (:note note))]
|
||||
(layout (:title note)
|
||||
(md-node :article.bottom-space sanitized-note)
|
||||
@@ -180,25 +182,28 @@
|
||||
(redirect long-url))))
|
||||
|
||||
|
||||
(POST "/post-note" [session note signature password version]
|
||||
(POST "/post-note" [session note signature password]
|
||||
(if (= signature (storage/sign session note))
|
||||
(let [pid "NoteHub"
|
||||
psk (storage/get-psk pid)]
|
||||
psk (storage/get-psk pid)
|
||||
params {:session session :note note :signature signature
|
||||
:password password :pid pid}]
|
||||
(if (storage/valid-publisher? pid)
|
||||
(let [resp (api/post-note note pid (storage/sign pid psk note) {:password password})]
|
||||
(let [resp (api/post-note (assoc params :signature (storage/sign pid psk note)))]
|
||||
(if (get-in resp [:status :success])
|
||||
(redirect (:longURL resp))
|
||||
(response 400)))
|
||||
(response 500)))
|
||||
(response 400)))
|
||||
|
||||
(POST "/update-note" [noteID note password version]
|
||||
(POST "/update-note" [noteID note password]
|
||||
(let [pid "NoteHub"
|
||||
psk (storage/get-psk pid)]
|
||||
psk (storage/get-psk pid)
|
||||
params {:noteID noteID :note note :password password :pid pid}]
|
||||
(if (storage/valid-publisher? pid)
|
||||
(let [resp (api/update-note noteID note pid
|
||||
(storage/sign pid psk noteID note password)
|
||||
password)]
|
||||
(let [resp (api/update-note (assoc params
|
||||
:signature
|
||||
(storage/sign pid psk noteID note password)))]
|
||||
(if (get-in resp [:status :success])
|
||||
(redirect (:longURL resp))
|
||||
(response 403)))
|
||||
|
||||
Reference in New Issue
Block a user