going somewhere

This commit is contained in:
didier amyot committed 2018-10-22 09:19:48 -04:00
1 parent 6e266c787b
commit 440206e924
15 files changed
+289 -46

No files matched your search

+20 -1
View File
@@ -41,9 +41,28 @@
(catch [:error-type :5XX] e (build-response request e)))))
(defn get-all-users [conn]
(fn [{{email :email} :route-params :as request}]
(try+
(timbre/info "getting user with email" email)
(let [db (d/db conn)
emails (d/q '[:find ?email
:where [_ :skirmish.broker.user/email ?email]] db)
xf (comp cat (map #(hash-map :email % :url (str "/api/1/users/" %))))]
(build-response request
(doall ((sequence xf emails)))))
(catch [:error-type :4XX] e (build-response request e))
(catch [:error-type :5XX] e (build-response request e)))))
(defn get-account [conn]
(fn [email account]))
(defn create-routes [conn]
(routes
(context "/api/1" []
(POST "/users" [] (create-user conn))
(GET "/users/:email" [email] (get-user conn)))
(GET "/users" [] (get-all-users conn))
(GET "/users/:email" [email] (get-user conn))
(GET "/users/:email/accounts/:account" [email account] (get-account conn)))
not-found-resp))
+13 -7
View File
@@ -47,30 +47,36 @@
:db/valueType :db.type/keyword
:db/cardinality :db.cardinality/one
:db/unique :db.unique/identity
:db/doc "The sec id."}
:db/doc "The security id."}
{
:db/ident :skirmish.security/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/doc "The usual name of the security."}
{
:db/ident :skirmish.security/type
:db/valueType :db.type/keyword
:db/cardinality :db.cardinality/one
:db/unique :db.unique/identity
:db/doc "The type of security. For instance :equity or :currency."}
{
:db/ident :skirmish.security/description
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/unique :db.unique/identity
:db/doc "The description of the currency. Please be verbose."}
{
:db/ident :skirmish.security/emitter
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/unique :db.unique/identity
:db/doc "The public key of the emmiter. This is not yet supported."}
{
:db/ident :skirmish.security/number-of-decimal
:db/valueType :db.type/long
:db/cardinality :db.cardinality/one
:db/doc "The number of decimal to show in the pretty printing."}
{
:db/ident :skirmish.security/symbol
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/unique :db.unique/identity
:db/doc "The symbol of the security for pretty printing."}
{
:db/ident :skirmish.security/interest-rate
@@ -108,7 +114,7 @@
(defn create-connection [uri]
(let [new-db? (d/create-database uri)
conn (d/connect uri)]
(when new-db?
@(d/transact conn schema))
;(when new-db?
@(d/transact conn schema)
conn))
+36 -14
View File
@@ -5,7 +5,7 @@
[slingshot.slingshot :refer [try+ throw+]]
[compojure.route :refer [not-found]]
[skirmish.exchange-gateway.exchange-gateway :refer [create-routes-for-exchange]]
[skirmish.rest.util :refer [build-response get-body]]
[skirmish.rest.util :refer [build-response get-body cors-middleware]]
[skirmish.ledger.accounts]
[datomic.api :as d]
[taoensso.timbre :as timbre]
@@ -21,7 +21,7 @@
(defn get-account-body [request account sec]
(if (nil? sec)
(build-response request {:status 404})
(let [sec-url (str "/api/1/securities/" (-> sec :skirmish.security/sec-id name))
(let [sec-url (str "/api/1/ledger/securities/" (-> sec :skirmish.security/sec-id name))
beautify-account { :amount (:skirmish.ledger/amount account)
:sec-id (:skirmish.security/sec-id sec)
:account-public-key (:skirmish.ledger/owner-public-key account)}
@@ -63,21 +63,38 @@
raw-securities
(throw+ {:error-type :4XX :status 400 :body {:error "Invalid security format."}})))
(defn get-security-from-db [conn sec-id]
(let [db (d/db conn)
e (d/pull db '[*] [:skirmish.security/sec-id sec-id])
{interest-rate :skirmish.security/interest-rate
(defn prettify-security [e db]
(let [{interest-rate :skirmish.security/interest-rate
description :skirmish.security/description
id :db/id
sec-id :skirmish.security/sec-id
symbol :skirmish.security/symbol
name :skirmish.security/name
number-of-decimal :skirmish.security/number-of-decimal
type_ :skirmish.security/type} e
volume (d/q '[:find (sum ?a) .
:where [?e :skirmish.ledger/amount ?a]
[?e :skirmish.ledger/owner-public-key ?pk]]
db)
ret {:sec-id sec-id :interest-rate interest-rate :volume volume :type type_ :description description}]
(if (nil? id)
volume (d/q '[:find (sum ?amount) .
:in $ ?id
:where [?e :skirmish.ledger/sec ?id]
[?e :skirmish.ledger/amount ?amount]]
db id)]
{:sec-id sec-id
:interest-rate interest-rate
:volume (or volume 0)
:name name
:symbol symbol
:number-of-decimal number-of-decimal
:type type_
:description description}))
(defn get-security-from-db [conn sec-id]
(let [db (d/db conn)
e (d/pull db '[*] [:skirmish.security/sec-id sec-id])]
(println (str e))
(if (-> e :db/id nil?)
(throw+ {:error-type :4XX :status 404 :body {:error "Security not found."}})
ret)))
(prettify-security e db))))
(defn create-security [conn]
"Create a fresh new security."
@@ -156,11 +173,13 @@
(let [securities (d/q '[:find ?pk :where [?e :skirmish.ledger/owner-public-key ?pk]] (d/db conn))]
(build-response request (get-available-accounts-body securities)))))
(defn get-api-description [request]
(let [body [{:url "ledger/accounts" :name "accounts"}
{:url "ledger/securities" :name "securities"}]]
(build-response request body)))
(defn create-routes-for-ledger [securities conn]
(routes
(context "/api/1/ledger" []
@@ -181,4 +200,7 @@
api-routes (create-routes-for-ledger (:securities config) conn)]
(timbre/info "Running skirmish.ledger.core server with config: " ledger-config)
(run-server (api api-routes) ledger-config)))
(run-server
(-> api-routes api cors-middleware)
ledger-config)))
+47
View File
@@ -0,0 +1,47 @@
(ns skirmish.routes)
(defn get-app-for [all-routes k]
"An app consists on a name, a prefix and some routes."
(let [app-name (-> k namespace keyword)
app (first (filter #(= app-name (:name %)) all-routes))]
app))
(defn- get-route-for [all-routes k]
(let [app (get-app-for all-routes k)
route-name (-> k name keyword)
route (first (filter #(= route-name (:name %)) (:routes app)))]
route))
(defn get-compojure-path [all-routes k]
"Returns what compojure expects to have."
(->> k (get-route-for all-routes) :path))
(defn replace-part [part params]
(if (clojure.string/starts-with? part ":")
(-> part (subs 1) keyword params)
part))
(defn path-for [p params]
(let [parts (clojure.string/split p #"/")]
(clojure.string/join "/" (map #(replace-part % params) parts))))
(defn get-context [all-routes c]
(let [get-app #(get-app-for all-routes %)]
(-> c
name
(keyword "some-name")
get-app
:path)))
(defn get-path-for
"Returns a link to a location by name."
([all-routes k]
(get-path-for all-routes k {}))
([all-routes k params]
(let [app (get-app-for all-routes k)
route (get-route-for all-routes k)
p (str (:path app) (:path route))]
(path-for p params))))
+3
View File
@@ -0,0 +1,3 @@
(ns skirmish.wui-util)
(defn pp-number [n])
@@ -0,0 +1,6 @@
(ns skirmish.wui.components.face-value
(:require [skirmish.wui.components.secunit :refer [secunit]]))
(defn face-value [amount sec-id]
(when (= sec-id :dapm)
(secunit amount sec-id)))
@@ -1,24 +1,35 @@
(ns skirmish.wui.components.portfolio-page
(:require [reagent.core :refer [atom]]
[cljs-http.client :as http]
[skirmish.wui.components.face-value :refer [face-value]]
[cljs.core.async :refer [<!] :refer-macros [go] :as async]
[skirmish.wui.components.secunit :refer [secunit]]))
(defn make-portfolio-summary-table [portfolio]
[:table
[:thead
[:tr [:th "Security"] [:th "Amount"] [:th "Face Value"]]]
[:tbody
(for [sec-summary portfolio]
[:tr {:key (:id sec-summary)}
(for [{sec-summary :account} portfolio]
[:tr {:key (:account-public-key sec-summary)}
[:td (:sec-id sec-summary)]
[:td [secunit (:sec-id sec-summary) (:amount sec-summary)]]
[:td [secunit :dapm (:face-value sec-summary)]]])]])
[:td [secunit (:amount sec-summary) (-> sec-summary :sec-id keyword)]]
[:td [face-value (:amount sec-summary) (-> sec-summary :sec-id keyword)]]])]])
(defn get-accounts-information [urls a-accounts]
(go
(let [ar (async/merge (map #(http/get % {:with-credentials? false}) urls))
accounts (map :body (<! (async/into [] ar)))]
(reset! a-accounts accounts))))
(defn shit [urls accounts]
[:div.content
[make-portfolio-summary-table accounts]])
(defn page [{{accounts :skirmish.broker.user/accounts} :user}]
(let [porfolio [{:id 12 :sec-id :foo :amount 100 :face-value 1265}
{:id 54 :sec-id :toto :amount 100 :face-value 1265}
{:id 66 :sec-id :foo :amount 100 :face-value 1265}]]
[:div.content
[:pre (str accounts)]
(make-portfolio-summary-table porfolio)]))
(let [urls (map :skirmish.broker.account/url accounts)
a-accounts (atom [])]
(get-accounts-information urls a-accounts)
#(shit urls @a-accounts)))
+24 -4
View File
@@ -1,5 +1,25 @@
(ns skirmish.wui.components.secunit)
(ns skirmish.wui.components.secunit
(:require [reagent.core :refer [atom]]
[skirmish.wui.util :refer [pp-int]]
[cljs-http.client :as http]
[cljs.core.async :refer [<!] :refer-macros [go] :as async]))
(defn secunit [sec-id amount]
(let [href (str "/securities/" sec-id)]
[:a {:href href} (str amount)]))
(defn get-security-definition [sec sec-id]
(go
(let [url (str "http://localhost:1604/api/1/ledger/securities/" (name sec-id))
resp (<! (http/get url {:with-credentials? false}))]
(reset! sec (:body resp)))))
(defn- pp-amount [amount sec]
(when (seq sec)
(let [{sec-id :sec-id number-of-decimal :number-of-decimal symbol :symbol} sec
href (str "/securities/" sec-id)]
[:a {:href href} (pp-int amount (or number-of-decimal 0)) " "
(or symbol "")])))
(defn secunit [amount sec-id]
(let [sec (atom {})]
(get-security-definition sec sec-id)
#(pp-amount amount @sec)))
@@ -1,4 +1,41 @@
(ns skirmish.wui.components.security-page)
(ns skirmish.wui.components.security-page
(:require [skirmish.wui.util :refer [pp-int]]
[reagent.core :refer [atom]]
[cljs-http.client :as http]
[cljs.core.async :refer [<!] :refer-macros [go]]))
(defn get-ledget-information [sec-info sec-id]
(go
(let [url (str "http://localhost:1604/api/1/ledger/securities/" (name sec-id))
resp (<! (http/get url {:with-credentials? false}))]
(reset! sec-info (:body resp)))))
(defn create-ledger-table [sec-info]
[:div
[:h1 (:name sec-info)]
[:cite (:description sec-info)]
[:table
[:tbody
[:tr
[:td "Security ID"] [:td (:sec-id sec-info)]]
[:tr
[:td "Type"] [:td (:type sec-info)]]
[:tr
[:td "Symbol"] [:td (:symbol sec-info)]]
[:tr
[:td "Interest Rate"] [:td (:interest-rate sec-info)]]
[:tr
[:td "Total Volume"] [:td (-> sec-info :volume (pp-int (:number-of-decimal sec-info)))]]]]])
(defn ledger-table [sec-id]
(let [sec-info (atom {})]
(get-ledget-information sec-info sec-id)
#(create-ledger-table @sec-info)))
(defn page [state]
[:h1 (str "this is a security page for " (:sec-id state))])
[:div.content
[ledger-table (:sec-id state)]])
@@ -19,9 +19,16 @@
[:li done "add the notion of 'accounts' in the server. An
user should have many accounts; one for each security
he owns"]
[:li on-it "make the " [:a {:href "/portfolio"} "portfolio"] " page representing the use accounts"]
[:li done "make the " [:a {:href "/portfolio"} "portfolio"] " page representing the use accounts"]
[:li done "make a somewhat pretty " [:a {:href "/securities/dapm"} "security"] " page"]
[:li done "create two stocks"]
[:li on-it "add stocks to didier@gmail.com"]
[:li on-it "make something for urls on the backend"]
[:li "add a little bit of professionalism on top of the broker api"]
[:li "make the api support transit and edn"]
[:li "implements interest rate in ledger."]
[:li "Make sure the ledger can have accounts"]
[:li "when a new user logs in, he should receive some sort of money"]
[:li "when a new user signs in, he should receive some sort of money"]
[:li "\u22EE"]
[:li "implement buy/sell securities."]]]
@@ -34,7 +41,6 @@
[:ol
[:li "Use ledger as source of through in each sub server."]
[:li "Update web ui for integrating securities with ledger."]
[:li "Create a basic broker that supports..."]
[:li "Ledger should compute interest rate."]
[:li "implement transactions in ledger."]
[:li "implement escrow."]]]]])
+29
View File
@@ -0,0 +1,29 @@
(ns skirmish.wui.util)
(defn right-pad [s o n]
"right pad s with o until length is greater or
equal to n."
(if (<= n (count s))
s
(recur (str s o) o n)))
(defn left-pad [s o n]
"left pad s with o until length is greater or
equal to n."
(if (<= n (count s))
s
(recur (str o s) o n)))
(defn pp-int
"returns the string representing n with the spaces at
the proper place."
([n]
(cond
(neg? n) (str "-" (pp-int (- n)))
(< n 1000) (str n)
:else (str (pp-int (quot n 1000)) " " (left-pad (str (mod n 1000)) "0" 3))))
([n dec]
(if (<= dec 0)
(pp-int n)
(let [i (int (Math/pow 10 dec))]
(str (pp-int (quot n i)) "," (right-pad (str (mod n i)) "0" dec))))))