Browse Source

every note associated with it's pid now

master
Christian Mueller 12 years ago
parent
commit
953ad3a01e
  1. 5
      API.md
  2. 1
      messages
  3. 5
      src/NoteHub/api.clj
  4. 39
      src/NoteHub/storage.clj
  5. 12
      src/NoteHub/views/pages.clj
  6. 1
      test/NoteHub/test/api.clj
  7. 8
      test/NoteHub/test/storage.clj
  8. 2
      test/NoteHub/test/views/pages.clj

5
API.md

@ -1,6 +1,6 @@
# NoteHub API # NoteHub API
**Version 1.0, status: released.** **Version 1.1, status: released.**
## Prerequisites ## Prerequisites
@ -42,7 +42,8 @@ Example:
status: { status: {
success: true, success: true,
comment: "some server message" comment: "some server message"
} },
publisher: "Publisher Description"
} }
Hence, the status of the request can be evaluated by reading of the property `status.success`. The field `status.comment`might contain an error message, a warning or any other comments from the server. Hence, the status of the request can be evaluated by reading of the property `status.success`. The field `status.comment`might contain an error message, a warning or any other comments from the server.

1
messages

@ -16,6 +16,7 @@ enter-passwd = Password
publish = Publish publish = Publish
update = Save update = Save
published = Published published = Published
publisher = Publisher
edited = Edited edited = Edited
article-views = Article Views article-views = Article Views
statistics = Statistics statistics = Statistics

5
src/NoteHub/api.clj

@ -58,7 +58,8 @@
:longURL (get-path noteID) :longURL (get-path noteID)
:shortURL (get-path noteID :short) :shortURL (get-path noteID :short)
:statistics (storage/get-note-statistics noteID) :statistics (storage/get-note-statistics noteID)
:status (create-response true)} :status (create-response true)
:publisher (storage/get-publisher noteID)}
(create-response false "noteID '%s' unknown" noteID))) (create-response false "noteID '%s' unknown" noteID)))
(defn post-note (defn post-note
@ -85,7 +86,7 @@
(map #(str proposed-title "-" (+ 2 %)) (range))))) (map #(str proposed-title "-" (+ 2 %)) (range)))))
noteID (build-key date title)] noteID (build-key date title)]
(do (do
(storage/add-note noteID note password) (storage/add-note noteID note pid password)
(storage/create-short-url noteID) (storage/create-short-url noteID)
{:noteID noteID {:noteID noteID
:longURL (get-path noteID) :longURL (get-path noteID)

39
src/NoteHub/storage.clj

@ -5,8 +5,8 @@
[noir.options :only [dev-mode?]]) [noir.options :only [dev-mode?]])
(:require [clj-redis.client :as redis])) (:require [clj-redis.client :as redis]))
; Initialize the data base ; Initialize the data base
(def db (def db
(redis/init (redis/init
(when-not (dev-mode?) (when-not (dev-mode?)
{:url (get-setting :db-url)}))) {:url (get-setting :db-url)})))
@ -23,22 +23,23 @@
(def sessions "sessions") (def sessions "sessions")
(def short-url "short-url") (def short-url "short-url")
(def publisher "publisher") (def publisher "publisher")
(def publisher-key "publisher-key")
(defn valid-publisher? [pid] (defn valid-publisher? [pid]
(redis/hexists db publisher pid)) (redis/hexists db publisher-key pid))
(defn register-publisher [pid] (defn register-publisher [pid]
"Returns nil if given PID exists or a PSK otherwise" "Returns nil if given PID exists or a PSK otherwise"
(when (not (valid-publisher? pid)) (when (not (valid-publisher? pid))
(let [psk (encrypt (str (rand-int Integer/MAX_VALUE) pid)) (let [psk (encrypt (str (rand-int Integer/MAX_VALUE) pid))
_ (redis/hset db publisher pid psk)] _ (redis/hset db publisher-key pid psk)]
psk))) psk)))
(defn revoke-publisher [pid] (defn revoke-publisher [pid]
(redis/hdel db publisher pid)) (redis/hdel db publisher-key pid))
(defn get-psk [pid] (defn get-psk [pid]
(redis/hget db publisher pid)) (redis/hget db publisher-key pid))
(defn create-session [] (defn create-session []
(let [token (encrypt (str (rand-int Integer/MAX_VALUE)))] (let [token (encrypt (str (rand-int Integer/MAX_VALUE)))]
@ -59,11 +60,12 @@
(redis/hset db note noteID text))) (redis/hset db note noteID text)))
(defn add-note (defn add-note
([noteID text] (add-note noteID text nil)) ([noteID text pid] (add-note noteID text pid nil))
([noteID text passwd] ([noteID text pid passwd]
(do (do
(redis/hset db note noteID text) (redis/hset db note noteID text)
(redis/hset db published noteID (get-current-date)) (redis/hset db published noteID (get-current-date))
(redis/hset db publisher noteID pid)
(when (not (blank? passwd)) (when (not (blank? passwd))
(redis/hset db password noteID passwd))))) (redis/hset db password noteID passwd)))))
@ -79,16 +81,21 @@
(redis/hincrby db views noteID 1) (redis/hincrby db views noteID 1)
text)))) text))))
(defn get-note-views (defn get-note-views
[noteID] [noteID]
(redis/hget db views noteID)) (redis/hget db views noteID))
(defn get-publisher
[noteID]
(redis/hget db publisher noteID))
(defn get-note-statistics (defn get-note-statistics
"Return views, publishing and editing timestamp" "Return views, publishing and editing timestamp"
[noteID] [noteID]
{ :views (redis/hget db views noteID) {:views (get-note-views noteID)
:published (redis/hget db published noteID) :published (redis/hget db published noteID)
:edited (redis/hget db edited noteID) }) :edited (redis/hget db edited noteID)
:publisher (get-publisher noteID)})
(defn note-exists? (defn note-exists?
[noteID] [noteID]
@ -96,7 +103,7 @@
(defn delete-note (defn delete-note
[noteID] [noteID]
(doseq [kw [password views note published edited]] (doseq [kw [password views note published edited publisher]]
; TODO: delete short url by looking for the title ; TODO: delete short url by looking for the title
(redis/hdel db kw noteID))) (redis/hdel db kw noteID)))
@ -112,7 +119,7 @@
"Resolves short url by providing all metadata of the request" "Resolves short url by providing all metadata of the request"
[url] [url]
(let [value (redis/hget db short-url url)] (let [value (redis/hget db short-url url)]
(when value (when value
(read-string value)))) (read-string value))))
(defn delete-short-url (defn delete-short-url
@ -132,14 +139,14 @@
(redis/hget db short-url key) (redis/hget db short-url key)
(let [hash-stream (partition 5 (repeatedly #(rand-int 36))) (let [hash-stream (partition 5 (repeatedly #(rand-int 36)))
hash-to-string (fn [hash] hash-to-string (fn [hash]
(apply str (apply str
; map first 10 numbers to digits ; map first 10 numbers to digits
; and the rest to chars ; and the rest to chars
(map #(char (+ (if (< 9 %) 87 48) %)) hash))) (map #(char (+ (if (< 9 %) 87 48) %)) hash)))
url (first url (first
(remove short-url-exists? (remove short-url-exists?
(map hash-to-string hash-stream)))] (map hash-to-string hash-stream)))]
(do (do
; we create two mappings: key params -> short url and back, ; we create two mappings: key params -> short url and back,
; s.t. we can later easily check whether a short url already exists ; s.t. we can later easily check whether a short url already exists
(redis/hset db short-url url key) (redis/hset db short-url url key)

12
src/NoteHub/views/pages.clj

@ -20,8 +20,8 @@
[noir.core :only [defpage defpartial]] [noir.core :only [defpage defpartial]]
[noir.statuses])) [noir.statuses]))
(when-not (storage/valid-publisher? api/domain) (when-not (storage/valid-publisher? "NoteHub")
(storage/register-publisher api/domain)) (storage/register-publisher "NoteHub"))
; Creates the main html layout ; Creates the main html layout
(defpartial generate-layout (defpartial generate-layout
@ -148,6 +148,10 @@
[:tr [:tr
[:td (get-message :edited)] [:td (get-message :edited)]
[:td (:edited stats)]]) [:td (:edited stats)]])
(when (:publisher stats)
[:tr
[:td (get-message :publisher)]
[:td (:publisher stats)]])
[:tr [:tr
[:td (get-message :article-views)] [:td (get-message :article-views)]
[:td (:views stats)]]]))) [:td (:views stats)]]])))
@ -178,7 +182,7 @@
; Creates New Note from Web ; Creates New Note from Web
(defpage [:post "/post-note"] {:keys [session note signature password version]} (defpage [:post "/post-note"] {:keys [session note signature password version]}
(if (= signature (api/get-signature session note)) (if (= signature (api/get-signature session note))
(let [pid api/domain (let [pid "NoteHub"
psk (storage/get-psk pid)] psk (storage/get-psk pid)]
(if (storage/valid-publisher? pid) (if (storage/valid-publisher? pid)
(let [resp (api/post-note note pid (api/get-signature (str pid psk note)) password)] (let [resp (api/post-note note pid (api/get-signature (str pid psk note)) password)]
@ -190,7 +194,7 @@
; Updates a note ; Updates a note
(defpage [:post "/update-note"] {:keys [noteID note password version]} (defpage [:post "/update-note"] {:keys [noteID note password version]}
(let [pid api/domain (let [pid "NoteHub"
psk (storage/get-psk pid)] psk (storage/get-psk pid)]
(if (storage/valid-publisher? pid) (if (storage/valid-publisher? pid)
(let [resp (api/update-note noteID note pid (let [resp (api/update-note noteID note pid

1
test/NoteHub/test/api.clj

@ -45,6 +45,7 @@
(is (= note (:note get-response))) (is (= note (:note get-response)))
(is (= (:longURL post-response) (:longURL get-response) note-url)) (is (= (:longURL post-response) (:longURL get-response) note-url))
(is (= (:shortURL post-response) (:shortURL get-response))) (is (= (:shortURL post-response) (:shortURL get-response)))
(is (= (:publisher get-response) pid))
(is (= "1" (get-in get-response [:statistics :views]))) (is (= "1" (get-in get-response [:statistics :views])))
(isnt (get-in get-response [:statistics :edited])) (isnt (get-in get-response [:statistics :edited]))
(is (= "2" (get-in (get-note (:noteID post-response)) [:statistics :views]))))) (is (= "2" (get-in (get-note (:noteID post-response)) [:statistics :views])))))

8
test/NoteHub/test/storage.clj

@ -23,12 +23,12 @@
(is (short-url-exists? url)) (is (short-url-exists? url))
(is (= url url2)) (is (= url url2))
(is (= metadata (resolve-url url))) (is (= metadata (resolve-url url)))
(is (not (do (is (not (do
(delete-short-url url) (delete-short-url url)
(short-url-exists? url)))))) (short-url-exists? url))))))
(testing "of correct note creation" (testing "of correct note creation"
(is (= (do (is (= (do
(add-note (build-key date test-title) test-note) (add-note (build-key date test-title) test-note "testPID")
(get-note (build-key date test-title))) (get-note (build-key date test-title)))
test-note)) test-note))
(is (= "1" (get-note-views (build-key date test-title)))) (is (= "1" (get-note-views (build-key date test-title))))
@ -38,7 +38,7 @@
"2"))) "2")))
(testing "of note update" (testing "of note update"
(is (= (do (is (= (do
(add-note (build-key date test-title) test-note "12345qwert") (add-note (build-key date test-title) test-note "testPID" "12345qwert")
(get-note (build-key date test-title))) (get-note (build-key date test-title)))
test-note)) test-note))
(is (valid-password? (build-key date test-title) "12345qwert")) (is (valid-password? (build-key date test-title) "12345qwert"))
@ -60,7 +60,7 @@
(testing "of note existence" (testing "of note existence"
(is (note-exists? (build-key date test-title))) (is (note-exists? (build-key date test-title)))
(is (not (do (is (not (do
(delete-note (build-key date test-title)) (delete-note (build-key date test-title))
(note-exists? (build-key date test-title))))) (note-exists? (build-key date test-title)))))
(is (not (note-exists? (build-key [2013 06 03] test-title)))) (is (not (note-exists? (build-key [2013 06 03] test-title))))
(is (not (note-exists? (build-key date "some title"))))))) (is (not (note-exists? (build-key date "some title")))))))

2
test/NoteHub/test/views/pages.clj

@ -11,7 +11,7 @@
(def test-note "# This is a test note.\nHello _world_. Motörhead, тест.") (def test-note "# This is a test note.\nHello _world_. Motörhead, тест.")
(defn create-testnote-fixture [f] (defn create-testnote-fixture [f]
(add-note (build-key date test-title) test-note) (add-note (build-key date test-title) test-note "testPID")
(f) (f)
(delete-note (build-key date test-title))) (delete-note (build-key date test-title)))

Loading…
Cancel
Save