refine commodity actions test

refine commodity actions test

--- test/clj_money/import/gnucash_test.clj
+++ test/clj_money/import/gnucash_test.clj
@@ -19,6 +19,17 @@
 (def ^:private input
   (io/input-stream "resources/fixtures/budget_sample.gnucash"))

+(def ids
+  {:checking    "ed92489659ab879fb9354a3a050fb65d"
+   :salary      "1b71fd298aeca1a18d35b04a7618e76e"
+   :groceries   "835bfe9b2728976d06e63b90aea8c090"
+   :credit-card "337685830c05f47b2b09734a05a7c1a2"
+   :401k        "fc053b4fc6b94898a5d6fa53ed203bd0"
+   :apple-401k  "77bfb9a7eb53ebfd5dd13b22476f58dd"
+   :ira         "294fd407b010e07e8fb54a4cab3fbd8c"
+   :apple-ira   "d65092fee5cfdacab77e7b37942675bb"
+   :other-inc   "8c62d43a4feee76da698912d7ff3a6ca"})
+
 (def ^:private declarations
   [{:record-type :commodity
     :record-count 2}
@@ -31,25 +42,25 @@

 (def ^:private accounts
   [{:name "Checking"
-    :id "ed92489659ab879fb9354a3a050fb65d"
+    :id (:checking ids)
     :parent-id "d005a139a1aaab6899867923509b96ca"
     :type :asset
     :commodity {:exchange :iso4217
                 :symbol "USD"}}
    {:name "Salary"
-    :id "1b71fd298aeca1a18d35b04a7618e76e"
+    :id (:salary ids)
     :parent-id "dff5746dbbaf805f1a8ac3ceb5d1a234"
     :type :income
     :commodity {:exchange :iso4217
                 :symbol "USD"}}
    {:name "Groceries"
-    :id "835bfe9b2728976d06e63b90aea8c090"
+    :id (:groceries ids)
     :parent-id "abff103816fb2e5cb93778b1ea51ca45"
     :type :expense
     :commodity {:exchange :iso4217
                 :symbol "USD"}}
    {:name "Credit Card"
-    :id "337685830c05f47b2b09734a05a7c1a2"
+    :id (:credit-card ids)
     :parent-id "9ee0484c7788656a0800e28ec8cefaff"
     :type :liability
     :commodity {:exchange :iso4217
@@ -59,61 +70,61 @@
   [{:transaction-date (t/local-date 2015 1 1)
     :description "Paycheck"
     :items [{:action :debit
-             :account-id "ed92489659ab879fb9354a3a050fb65d"
+             :account-id (:checking ids)
              :amount 1000M
              :reconciled false}
             {:action :credit
-             :account-id "1b71fd298aeca1a18d35b04a7618e76e"
+             :account-id (:salary ids)
              :amount 1000M
              :reconciled false}]}
    {:transaction-date (t/local-date 2015 1 4)
     :description "Kroger"
     :items [{:action :debit
-             :account-id "835bfe9b2728976d06e63b90aea8c090"
-             :amount 100M
-             :reconciled false}
-            {:action :credit
-             :account-id "ed92489659ab879fb9354a3a050fb65d"
+             :account-id (:groceries ids)
+             :amount 100M
+             :reconciled false}
+            {:action :credit
+             :account-id (:checking ids)
              :amount 100M
              :reconciled false}]}
    {:transaction-date (t/local-date 2015 1 11)
     :description "Kroger"
     :items [{:action :debit
-             :account-id "835bfe9b2728976d06e63b90aea8c090"
-             :amount 100M
-             :reconciled false}
-            {:action :credit
-             :account-id "ed92489659ab879fb9354a3a050fb65d"
+             :account-id (:groceries ids)
+             :amount 100M
+             :reconciled false}
+            {:action :credit
+             :account-id (:checking ids)
              :amount 100M
              :reconciled false}]}
    {:transaction-date (t/local-date 2015 1 12)
     :description "Kroger"
     :items [{:action :debit
-             :account-id "ed92489659ab879fb9354a3a050fb65d"
+             :account-id (:checking ids)
              :amount 10M
              :reconciled false}
             {:action :credit
-             :account-id "835bfe9b2728976d06e63b90aea8c090"
+             :account-id (:groceries ids)
              :amount 10M
              :reconciled false}]}
    {:transaction-date (t/local-date 2015 1 15)
     :description "Paycheck"
     :items [{:action :debit
-             :account-id "ed92489659ab879fb9354a3a050fb65d"
+             :account-id (:checking ids)
              :amount 1000M
              :reconciled false}
             {:action :credit
-             :account-id "1b71fd298aeca1a18d35b04a7618e76e"
+             :account-id (:salary ids)
              :amount 1000M
              :reconciled false}]}
    {:transaction-date (t/local-date 2015 1 18)
     :description "Kroger"
     :items [{:action :debit
-             :account-id "835bfe9b2728976d06e63b90aea8c090"
-             :amount 100M
-             :reconciled false}
-            {:action :credit
-             :account-id "337685830c05f47b2b09734a05a7c1a2"
+             :account-id (:groceries ids)
+             :amount 100M
+             :reconciled false}
+            {:action :credit
+             :account-id (:credit-card ids)
              :amount 100M
              :reconciled false}]}])

@@ -123,7 +134,7 @@
     :start-date (t/local-date 2017 1 1)
     :period :month
     :period-count 12
-    :items [{:account-id "1b71fd298aeca1a18d35b04a7618e76e"
+    :items [{:account-id (:salary ids)
              :periods #{{:index 0
                          :amount 1000M}
                         {:index 1
@@ -148,7 +159,7 @@
                          :amount 1000M}
                         {:index 11
                          :amount 1000M}}}
-            {:account-id "835bfe9b2728976d06e63b90aea8c090"
+            {:account-id (:groceries ids)
              :periods #{{:index 0
                          :amount 200M}
                         {:index 1
@@ -227,14 +238,14 @@

 (def ^:private accounts-with-commodities
   (-> accounts
-      (concat [{:id "fc053b4fc6b94898a5d6fa53ed203bd0"
+      (concat [{:id (:401k ids)
                 :parent-id "d005a139a1aaab6899867923509b96ca"
                 :name "401k"
                 :type :asset
                 :commodity {:exchange :iso4217
                             :symbol "USD"}}
-               {:id "77bfb9a7eb53ebfd5dd13b22476f58dd"
-                :parent-id "fc053b4fc6b94898a5d6fa53ed203bd0"
+               {:id (:apple-401k ids)
+                :parent-id (:401k ids)
                 :name "Apple, Inc"
                 :type :asset
                 :commodity {:exchange :nasdaq
@@ -258,34 +269,72 @@
 (def ^:private extended-commodities-input
   (io/input-stream "resources/fixtures/sample_with_commodities_ext.gnucash"))

-; IRA        294fd407b010e07e8fb54a4cab3fbd8c
-; Apple IRA  d65092fee5cfdacab77e7b37942675bb
-; 401k       fc053b4fc6b94898a5d6fa53ed203bd0
-; Apple 401k 77bfb9a7eb53ebfd5dd13b22476f58dd
 (deftest read-gnucash-source-with-trading-actions
   (let [found (reduce track-record {} (read-source
                                         :gnucash
                                         extended-commodities-input))
-        expected-transactions [{:transaction-date (t/local-date 2015 1 17)
-                                :description "Purchase 100 shares of AAPL"
-                                :items [{:action :credit
-                                         :account-id "77bfb9a7eb53ebfd5dd13b22476f58dd"
-                                         :amount 100M
-                                         :value 1000M}
+        expected-transactions [{:transaction-date (t/local-date 2015 1 16)
+                                :description "Retirement"
+                                :items [{:action :debit
+                                         :account-id (:401k ids)
+                                         :amount 1000M
+                                         :reconciled false}
+                                        {:action :credit
+                                         :account-id (:checking ids)
+                                         :amount 1000M
+                                         :reconciled false}]}
+                               {:transaction-date (t/local-date 2015 1 17)
+                                :description "Purchase shares AAPL"
+                                :action :buy
+                                :symbol "AAPL"
+                                :exchange :nasdaq
+                                :shares 100M
+                                :account-id (:401k ids)
+                                :commodity-account-id (:apple-401k ids)
+                                :items [{:action :debit
+                                         :account-id (:apple-401k ids)
+                                         :amount 1000M
+                                         :reconciled false}
+                                        {:action :credit
+                                         :account-id (:401k ids)
+                                         :amount 1000M
+                                         :reconciled false}]}
+                               {:transaction-date (t/local-date 2015 3 2)
+                                :description "Transfer shares of AAPL"
+                                :action :transfer
+                                :shares 100M
+                                :from-account-id (:apple-401k ids)
+                                :to-account-id (:ira ids) ; or maybe :apple-ira?
+                                :items [{:action :debit
+                                         :account-id (:apple-ira ids)
+                                         :amount 1000M
+                                         :reconciled false}
+                                        {:action :credit
+                                         :account-id (:apple-401k ids)
+                                         :amount 1000M
+                                         :reconciled false}]}
+                               {:transaction-date (t/local-date 2015 4 1)
+                                :description "Stock Split"
+                                :action :split
+                                :shares-gained 100M
+                                :commodity-account-id (:apple-ira ids)
+                                :items [{:action :debit
+                                         :account-id (:apple-ira ids)
+                                         ; TODO add some shares here
+                                         :amount 0M}
                                         {:action :debit
-                                         :account-id "fc053b4fc6b94898a5d6fa53ed203bd0"
-                                         :amount 1000M
-                                         :value 1000M}]}
-                               {:transaction-date (t/local-date 2015 3 2)
-                                :description "Transfer 100 shares of AAPL"
-                                :items [{:action :credit
-                                         :account-id "77bfb9a7eb53ebfd5dd13b22476f58dd"
-                                         :amount 100M
-                                         :value 1000M}
-                                        {:action :debit
-                                         :account-id "d65092fee5cfdacab77e7b37942675bb"
-                                         :amount 100M
-                                         :value 1000M}]}]]
-    (pprint-diff expected-transactions (:transaction found))
-    (is (= expected-transactions (:transaction found))
+                                         :account-id (:ira ids)
+                                         :amount 1M}
+                                        {:action :credit
+                                         :account-id (:other-inc ids)
+                                         :amount 1M}]}]
+        inv-account-ids (->> [:ira :apple-ira :401k :apple-401k]
+                             (map #(% ids))
+                             set)
+        actual-transactions (filter (fn [transaction]
+                                      (some #(inv-account-ids (:account-id %))
+                                            (:items transaction)))
+                                    (:transaction found))]
+    (pprint-diff expected-transactions actual-transactions)
+    (is (= expected-transactions actual-transactions)
         "The correct transactions are found")))


Cleanup

Cleanup

--- demo/sitetools/core.cljs
+++ demo/sitetools/core.cljs
@@ -165,29 +165,24 @@
 (defn path [] (js/require "path"))

 (defn mkdirs [f]
-  (let [items (as-> f _
-                (.' (path) normalize _)
-                (string/split _ #"/"))]
-    (doseq [d (reductions #(str %1 "/" %2) items)]
-      (when-not (.' (fs) existsSync d)
-        (.' (fs) mkdirSync d)))))
+  (doseq [d (reductions #(str %1 "/" %2)
+                        (-> (.' (path) normalize f)
+                            (string/split #"/")))]
+    (when-not (.' (fs) existsSync d)
+      (.' (fs) mkdirSync d))))

 (defn write-file [f content]
   (mkdirs (.' (path) dirname f))
   (.' (fs) writeFileSync f content))

-(defn read-file [f]
-  (.' (fs) readFileSync f))
-
 (defn path-join [& paths]
   (apply (.' (path) :join) paths))

-(defn read-files [files]
-  (string/join "\n" (map read-file files)))
-
 (defn write-resources [dir {:keys [css-file css-infiles]}]
   (write-file (path-join dir css-file)
-              (read-files css-infiles)))
+              (->> css-infiles
+                   (map #(.' (fs) readFileSync %))
+                   (string/join "\n"))))

 ;;; Main entry points


Added ability to remove metric.

Added ability to remove metric.

--- trackit-core/src/samsara/trackit.clj
+++ trackit-core/src/samsara/trackit.clj
@@ -377,6 +377,11 @@
   ([^MetricRegistry registry name]
    (metric-value name (get (.getMetrics registry) name))))

+(defn remove-metric
+  ([name] (remove-metric *registry* name))
+  ([^MetricRegistry registry name]
+   (let [n-name (namer name)]
+     (m/remove-metric registry n-name))))

 (defn show-stats


[#3157] Fix pie count with data-groups

[#3157] Fix pie count with data-groups

--- backend/src/akvo/lumen/lib/aggregation/pie.clj
+++ backend/src/akvo/lumen/lib/aggregation/pie.clj
@@ -9,8 +9,11 @@
   [tenant-conn {:keys [columns table-name]} query]
   (let [filter-sql    (sql-str columns (:filters query))
         bucket-column (find-column columns (:bucketColumn query))
-        query         (format "SELECT %1$s as x, count(*) FROM %2$s WHERE %3$s GROUP BY x"
-                              (sql-option-bucket-column bucket-column) table-name filter-sql)
+        flow? (some #(= "instance_id" (:columnName %)) columns)
+        query         (format "SELECT %1$s as x, count(%2$s) FROM %3$s WHERE %4$s GROUP BY x"
+                              (sql-option-bucket-column bucket-column)
+                              (if flow? "distinct instance_id" "*")
+                              table-name filter-sql)
         counts        (run-query tenant-conn query)
         max-segments  50]
     (if (> (count counts) max-segments)


Test test-wrong-job-name

Test test-wrong-job-name

--- test/emender_jenkins/rest_api_test.clj
+++ test/emender_jenkins/rest_api_test.clj
@@ -291,3 +291,12 @@
             {:status "error" :jobName nil       :command "create_job" :message "Job does not exist"} (job-does-not-exist-response nil :create-job)
             {:status "error" :jobName nil       :command nil          :message "Job does not exist"} (job-does-not-exist-response nil nil))))

+(deftest test-wrong-job-name
+    "Check the function emender-jenkins.rest-api/wrong-job-name."
+    (testing "the function emender-jenkins.rest-api/wrong-job-name."
+        (are [x y] (= x y)
+            {:status "error" :jobName "jobName" :command "create_job" :message "The name of job is wrong"} (wrong-job-name "jobName" :create-job)
+            {:status "error" :jobName "jobName" :command nil          :message "The name of job is wrong"} (wrong-job-name "jobName" nil)
+            {:status "error" :jobName nil       :command "create_job" :message "The name of job is wrong"} (wrong-job-name nil :create-job)
+            {:status "error" :jobName nil       :command nil          :message "The name of job is wrong"} (wrong-job-name nil nil))))
+


remember-nth uses modulo

remember-nth uses modulo

--- test/push/design_spikes/dsl_macros.clj
+++ test/push/design_spikes/dsl_macros.clj
@@ -213,6 +213,17 @@
   (second integer-munged) => {:int1 6, :int2 5, :third 3}))  ;; 4 *3* 2 1

+(fact "remember-nth stores the nth item of a named stack MODULO its actual length"
+  (let [integer-munged (->  [six-ints {}]
+                            (remember-nth :integer :at 99 :as :99th )
+                            (remember-nth :integer :at -8 :as :minus8th))]
+  (second integer-munged) => {:99th 3, :minus8th 2}
+  (get-stack-from-dslblob integer-munged :integer) => '(6 5 4 3 2 1)
+  (mod 99 6) => 3   ;; 6 5 4 *3* 2 1
+  (mod -8 6) => 4)) ;; 6 5 4 3 *2* 1
+
+
+
 (fact "remember-nth has no effect if :as is not specified"
   (let [integer-munged (-> [six-ints {}]
                         (consume :integer :as :int1)


pop a system object

pop a system object

part of a properly abstracted async/state destructor
mechanism

--- src/deferst/system.cljc
+++ src/deferst/system.cljc
@@ -76,6 +76,32 @@
        (when-not (valid-system-state? st)
          (throw (ex-info "invalid system state" {:state st})))
        (return (filter-system-map st))))))
+
+(defn- pop-obj
+  "pops the most recently put obj, calling it's destructor-fn and
+   removing it from the context"
+  []
+  (with-context config-ctx
+    (mlet [st (get-state)
+           :let [des (:config/destructors st)
+                 [k des-fn] (last des)
+
+                 _ (when (nil? k)
+                     (throw (ex-info "no object to pop" {:state st})))
+
+                 _ (when-not (contains? st k)
+                     (throw (ex-info (str "state key doesn't exist: " k)
+                                     {:state st
+                                      :key k})))]
+           _ (put-state
+              (->> st
+                   (dissoc k)
+                   (assoc :config/desructors
+                          (subvec des 0 (dec (count des))))))
+           st (get-state)]
+      (when-not (valid-system-state? st)
+        (throw (ex-info "invalid system state" {:state st})))
+      (return (filter-system-map st)))))

 (defn- factory-args
   "given args-specs of form


clojurescript unwind

clojurescript unwind

--- src/deferst/system.cljc
+++ src/deferst/system.cljc
@@ -350,7 +350,25 @@
                                :error e}))))))))

      :cljs
-     (-> (run-state system-builder seed))))
+     (p/catch
+         (run-state system-builder seed)
+         (fn [e]
+           (let [{st :state :as xd} (ex-data e)
+                 sd (system-destructor st)]
+             (p/then
+              (p/catch
+                  (run-state sd st)
+                  (fn [ue]
+                    (throw
+                     (ex-info "unwind failed after start-system! failed"
+                              {:state st
+                               :error e
+                               :unwind-error ue}))))
+              (fn [_]
+                (throw
+                 (ex-info "start-system! failed and unwound"
+                          {:state st
+                           :error e})))))))))
 (defn- system-map*
   [system]
   (filter-system-map system))


Minor refactoring of hijack-console!

Minor refactoring of hijack-console!

--- src/devtools/debug.cljs
+++ src/devtools/debug.cljs
@@ -42,17 +42,12 @@
     (set! (.-showRelativeTime formatter) false)
     (set! (.-showLoggerName formatter) true)))

-(defn js-apply [f target args]
-  (.apply f target (into-array args)))
-
-(defn hijack-console!
-  "docstring"
-  []
-  (let [old-log (aget js/console "log")]
+(defn hijack-console! []
+  (let [original-log-fn (aget js/console "log")]
     (aset js/console "log" (fn [& args]
                              (.addSeparator *console*)
                              (apply log (cons (logger "console") args))
-                             (js-apply old-log js/console args)))))
+                             (.apply original-log-fn js/console (into-array args))))))

 (defn init! []
   (init-logger!)


Need to put result in at index

Need to put result in at index

--- src/advent_2016/day_5/part_2.cljs
+++ src/advent_2016/day_5/part_2.cljs
@@ -27,12 +27,12 @@
   [s]
   (loop [seen #{}
          candidates (candidates s)
-         result ""]
+         result (vec (repeat 8 " "))]
     (let [candidate (first candidates)
           ndx (js/parseInt (ndx-str candidate))]
       (if (seen ndx)
         (recur seen (rest candidates) result)
-        (let [result (str result (code-str candidate))]
-          (if (== 8 (count result))
-            result
+        (let [result (assoc result ndx (code-str candidate))]
+          (if (== 8 (count seen))
+            (apply str result)
             (recur (conj seen ndx) (rest candidates) result)))))))


fix problem with uuids

fix problem with uuids

--- src-cljs/frontend/talaria.cljs
+++ src-cljs/frontend/talaria.cljs
@@ -12,13 +12,14 @@
   (:import [goog.net.WebSocket.EventType])
   (:require-macros [cljs.core.async.macros :refer (go go-loop)]))

+(def transit-reader (transit/reader :json {:handlers {"u" cljs.core/uuid}}))
+(def transit-writer (transit/writer :json))
+
 (defn decode-msg [msg]
-  (let [r (transit/reader :json)]
-    (transit/read r msg)))
+  (transit/read transit-reader msg))

 (defn encode-msg [msg]
-  (let [r (transit/writer :json)]
-    (transit/write r msg)))
+  (transit/write transit-writer msg))

 (defrecord AjaxSocket [recv-url send-url csrf-token on-open on-close on-error on-message on-reconnect]
   Object


build-lookup-table works in usual cases - still need to handle cases when data are missing in the lookup

--- src/grafter/tabular.clj
+++ src/grafter/tabular.clj
@@ -334,7 +334,8 @@
          (let [lookup (zipmap (arg->vector key-cols) (arg->vector key-cells))
                value-from-row ((table lookup) value-col)
                ]
-           value-from-row)))))
+           value-from-row)
+         ))))

 (comment


mapc: DONE, works with hashmap of functions or vector of functions

--- src/grafter/tabular.clj
+++ src/grafter/tabular.clj
@@ -273,7 +273,7 @@
                     (zipmap (column-names dataset) fs)
                     fs)
         other-hash (zipmap (vec (clojure.set/difference (set (:column-names dataset))
-                                                        (set (keys fs))))
+                                                        (set (keys fs-hash))))
                            (cycle [identity]))
         functions (conj fs-hash other-hash)]
    (->> dataset
@@ -281,8 +281,7 @@
         (map (fn [row]
                (apply merge (map #(hash-map % ((functions %) (row %)))
                     (keys row)))))
-
-        )))
+        (make-dataset (column-names dataset)))))

 (comment


Remove extra println's.

Remove extra println's.

--- test/ago/test.cljs
+++ test/ago/test.cljs
@@ -14,10 +14,9 @@
     (gevents/listen el type #(put! out %))
     out))

-(defn hello []
-  (println "Hello, World!"))
+; ----------------------------------------------------------

-(hello)
+; Hooked up to buttons to allow interactive tests / demos.

 (defn child [agw in-ch]
   (ago agw
@@ -52,7 +51,6 @@
   (ago agw
        (loop [num-hi 0 num-bye 0]
          (println "num-hi" num-hi "num-bye" num-bye)
-         (println :agw @agw)
          (let [[x ch] (alts! [hi-ch bye-ch])]
            (cond
             (= ch hi-ch)
@@ -86,7 +84,6 @@
   (ago agw
        (loop [num-fie 0]
          (println "num-fie" num-fie)
-         (println :agw @agw)
          (>! ch2 [:fie num-fie])
          (>! ch2 [:foe num-fie])
          (let [x (<! fie-ch)]


wow, I can just use equals :)

wow, I can just use equals :)

--- src/ajax_to_websocket/core.clj
+++ src/ajax_to_websocket/core.clj
@@ -35,13 +35,6 @@
         (when-not (nil? req-map)
           (>! result-chan req-map)))))))

-(defn is-diff? [a-diff]
-  "given the output vector from data/diff, return if different in any way"
-  (if (and (nil? (first a-diff))
-           (nil? (second a-diff)))
-      false
-      true))
-
 (defn send-message
   "Sends a message to the websocket channel, converting it to json"
   [websocket message]
@@ -52,7 +45,7 @@
   [websocket json-res last-state]
   (let [url-name (keyword (:name json-res))
         res      (:body json-res)]
-    (when (is-diff? (data/diff res (url-name @last-state)))
+    (when-not (= res (url-name @last-state))
       (swap! last-state assoc-in [url-name] res)
       (send-message websocket
         {:name (:name json-res),


Refactor lyrics parsing.

Refactor lyrics parsing.

- Data is bad: keys can be different things (sometimes even random strings), their orders have lost (eg charanams, pallavai, citta swarai etc.)

--- src/kosha/app/kriti.clj
+++ src/kosha/app/kriti.clj
@@ -1,54 +1,20 @@
 (ns kosha.app.kriti
-  (:require [clojure.set :as set]
-            [clojure.string :as str]
-            [kosha.db.kriti :as db]
+  (:require [kosha.db.kriti :as db]
             [kosha.app.util :as util]
             [pg-hstore.core :as hs]))

-(defn to-kebab-case
-  "Takes a keyword with spaces and converts it to a kebab-cased keyword."
-  [key-with-spaces]
-  (let [key-string         (name key-with-spaces)
-        kebab-cased-string (str/replace key-string #" " "-")]
-    (keyword kebab-cased-string)))
-
-(defn rename-stanza-keys
-  "Renames keys of stanzas to replace spaces in them, if the lyrics has named stanzas."
-  [content]
-  (let [lyrics-map   (hs/from-hstore content)
-        stanza-keys  (keys lyrics-map)
-        new-names    (into {} (map (juxt identity to-kebab-case) stanza-keys))]
-    (set/rename-keys (hs/from-hstore content) new-names)))
-
-(defn remove-keys
-  "Removes all keys in the given collection from the given map."
-  [map keys-coll]
-  (apply dissoc map keys-coll))
-
-(defn parse-charanams
-  "Parses charanams into a vector under :charanams key if the lyrics has named stanzas"
-  [content]
-  (let [max-charanams          (count (keys content))
-        charanam-key-names     (map #(str "caraNam-" %) (range 1 max-charanams))
-        possible-charanam-keys (concat [:caraNam] (map keyword charanam-key-names))
-        charanams              (into [] (vals (select-keys content possible-charanam-keys)))]
-    (-> content
-        (assoc :charanams charanams)
-        (remove-keys possible-charanam-keys))))
+(defn parse-named-stanzas
+  [{:keys [has-named-stanzas content] :as lyrics}]
+  (if (= "true" has-named-stanzas)
+    (assoc lyrics :content (hs/from-hstore content false))
+    lyrics))

 (defn parse-lyrics
-  "Parses lyrics of a kriti into a clojure map if it has named stanzas."
   [lyrics]
-  (as-> lyrics lyr
-    (when lyr
-      (-> lyr
-          (hs/from-hstore)
-          (update :has-named-stanzas (partial = "true"))))
-    (if (:has-named-stanzas lyr)
-      (-> lyr
-          (update :content rename-stanza-keys)
-          (update :content parse-charanams))
-      lyr)))
+  (when lyrics
+    (-> lyrics
+        hs/from-hstore
+        parse-named-stanzas)))

 (defn handler
   [{:keys [params] :as request}]


Fixed a bug in date display formatting

Fixed a bug in date display formatting

Somehow a time component is stored in the date and the date must
first be converted to local time before it is formatted for display.

--- src/ktra_indexer/db.clj
+++ src/ktra_indexer/db.clj
@@ -4,8 +4,10 @@
             [clojure.java.jdbc :as j]
             [clj-time.format :as f]
             [clj-time.coerce :as c]
+            [clj-time.local :as l]
             [clj-time.jdbc]
-            [ktra-indexer.config :as cfg]))
+            [ktra-indexer.config :as cfg])
+  (:import org.joda.time.format.DateTimeFormat))

 (let [db-host (get (System/getenv)
                    "OPENSHIFT_POSTGRESQL_DB_HOST"
@@ -160,6 +162,14 @@
          {:status "error"
           :cause "general-error"})))))

+(defn format-as-local-date
+  "Format a date from the database as a local date. This avoids problems
+  with timezones."
+  [db-date]
+  (binding [l/*local-formatters* {:local
+                                  (DateTimeFormat/forPattern "d.M.y")}]
+    (l/format-local-time (l/to-local-date-time db-date) :local)))
+
 (defn get-episodes
   "Returns all the episodes in the database. Returns episode number, name
   date."
@@ -169,8 +179,7 @@
                            (kc/order :number :DESC))
         format-date (fn [row]
                       (assoc row :date
-                             (f/unparse date-formatter
-                                        (c/from-sql-date (:date row)))))]
+                             (format-as-local-date (:date row))))]
     (map format-date results)))

 (defn get-episode-basic-data
@@ -183,8 +192,7 @@
                                                episode-number)}))
         format-date (fn [row]
                       (assoc row :date
-                             (f/unparse date-formatter
-                                        (c/from-sql-date (:date row)))))]
+                             (format-as-local-date (:date row))))]
     (first (map format-date results))))

 (defn get-episode-tracks


read-statistic-for-product and read-statistic-for-product-repo

--- src/arachnida/db_interface.clj
+++ src/arachnida/db_interface.clj
@@ -97,6 +97,31 @@
                                  where date between '2015-01-01' and '2015-12-31'
                                  and author=?" author-name])))

+(defn read-statistic-for-product
+    [product-id]
+    (first
+    (jdbc/query db-spec/data-db
+                               ["select count(*) as commits_count,
+                                        sum(files_changed) as files_changed,
+                                        sum(insertions) as insertions,
+                                        sum(deletions) as deletions
+                                 from commits
+                                 where date between '2015-01-01' and '2015-12-31'
+                                 and product=?" product-id])))
+
+(defn read-statistic-for-product-repo
+    [product-id]
+    (jdbc/query db-spec/data-db
+                               ["select count(*) as commits_count,
+                                        (select name from repos where repos.id=commits.repo) as reponame,
+                                        sum(files_changed) as files_changed,
+                                        sum(insertions) as insertions,
+                                        sum(deletions) as deletions
+                                 from commits
+                                 where date between '2015-01-01' and '2015-12-31'
+                                 and product=?
+                                 group by reponame" product-id]))
+
 (defn read-stat-per-weeks-from-db
     [first-day last-day]
     (jdbc/query db-spec/data-db ["select count(*) as commits_count,


dag_unify.core :as u

dag_unify.core :as u

--- src/babel/english/grammar.cljc
+++ src/babel/english/grammar.cljc
@@ -22,7 +22,7 @@
    #?(:clj [clojure.tools.logging :as log])
    #?(:cljs [babel.logjs :as log])
    [clojure.core.cache :as cache]
-   [dag_unify.core :refer [fail? get-in remove-matching-keys strip-refs unify]]))
+   [dag_unify.core :as u :refer [fail? get-in remove-matching-keys strip-refs unify]]))

 (def index-lexicon-on-paths
   [[:synsem :agr :gender]


music is not a place

music is not a place

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -1286,6 +1286,7 @@
             {:synsem {:agr agr
                       :sem {:animate false
                             :pred :name
+                            :place false
                             :physical-object false
                             :subj of}
                       :subcat {:1 {:agr agr


spacing

spacing

--- src/babel/italiano/lexicon.clj
+++ src/babel/italiano/lexicon.clj
@@ -77,19 +77,19 @@
                           :pred :acqua}}})

    "addormentarsi" (let [subject-semantics (atom {:animate true})
-                   subject-agr (atom :top)]
-               {:synsem {:cat :verb
-                         :essere true
-                         :sem {:pred :fall-asleep
-                               :reflexive true
-                               :subj subject-semantics
-                               :obj subject-semantics}
-                         :subcat {:1 {:agr subject-agr
-                                      :sem subject-semantics}
-                                  :2 {:agr subject-agr
-                                      :pronoun true
-                                      :reflexive true
-                                      :sem subject-semantics}}}})
+                         subject-agr (atom :top)]
+                     {:synsem {:cat :verb
+                               :essere true
+                               :sem {:pred :fall-asleep
+                                     :reflexive true
+                                     :subj subject-semantics
+                                     :obj subject-semantics}
+                               :subcat {:1 {:agr subject-agr
+                                            :sem subject-semantics}
+                                        :2 {:agr subject-agr
+                                            :pronoun true
+                                            :reflexive true
+                                            :sem subject-semantics}}}})

    "affolato"
    [;; comparative


fix a bug in push question

fix a bug in push question

--- src/leiningen/utils.clj
+++ src/leiningen/utils.clj
@@ -51,7 +51,8 @@
   (read-line))

 (defn yes-or-no [input]
-  (or (= input "yes") (= input "no")))
+  (or (= input "y")
+      (= input "n")))

 (defn is-number [limit input]
   (let [n (read-string input)]


Tidied up the instruction tracing mechanism

--- src/chip8_clj/instructions.clj
+++ src/chip8_clj/instructions.clj
@@ -5,15 +5,22 @@
             [chip8-clj.state :as state]
             [clojure.tools.logging :as log]))

+(defn- trace
+  [machine-state opcode trace-str & trace-args]
+  (log/info (format "0x%04x 0x%04x %s"
+                    (machine-state/get-pc machine-state) opcode
+                    (apply format trace-str trace-args))))
+
 (defn execute-0NNN
   "Calls RCA 1802 program at address NNN. Not necessary for most ROMs."
   [machine-state opcode]
-  (log/info "execute-0NNN: Error: Not yet implemented")
+  (trace machine-state opcode "0NNN Not yet implemented")
   (System/exit 1))

 (defn execute-00E0
   "Clears the screen."
   [machine-state opcode]
+  (trace machine-state opcode "00E0 cls")
   (-> (reduce ; For each column in the screen buffer.
         (fn [machine-state y]
           (reduce ; For each row in the screen bufer.
@@ -28,21 +35,21 @@
   "Returns from a subroutine."
   [machine-state opcode]
   (let [[machine-state return-addr] (machine-state/pop-stack machine-state)]
-    (log/info (format "0x%04x 00EE 0x%04x ret 0x%04x" (machine-state/get-pc machine-state) opcode return-addr))
+    (trace machine-state opcode "00EE ret 0x%04x" return-addr)
     (machine-state/set-pc machine-state return-addr)))

 (defn execute-1NNN
   "Jumps to address NNN."
   [machine-state opcode]
   (let [imm (utils/get-nnn opcode)]
-    (log/info (format "0x%04x 1NNN 0x%04x jmp 0x%04x" (machine-state/get-pc machine-state) opcode imm))
+    (trace machine-state opcode "1NNN jmp 0x%04x" imm)
     (machine-state/set-pc machine-state imm)))

 (defn execute-2NNN
   "Calls subroutine at NNN."
   [machine-state opcode]
   (let [target-addr (utils/get-nnn opcode)]
-    (log/info (format "0x%04x 2NNN 0x%04x cll 0x%04x" (machine-state/get-pc machine-state) opcode target-addr))
+    (trace machine-state opcode "2NNN cll 0x%04x" target-addr)
     (-> machine-state
         (machine-state/push-stack (+ (machine-state/get-pc machine-state) 2))
         (machine-state/set-pc target-addr))))
@@ -53,8 +60,7 @@
   (let [reg-num (utils/get-nibble1 opcode)
         imm (utils/get-byte1 opcode)
         reg-val (machine-state/get-register machine-state reg-num)]
-    (log/info (format "0x%04x 3XNN 0x%04x skp V[%d](0x%02x) == 0x%02x"
-                       (machine-state/get-pc machine-state) opcode reg-num reg-val imm))
+    (trace machine-state opcode "3XNN skp V[%d](0x%02x) == 0x%02x" reg-num reg-val imm)
     (if (= reg-val imm)
         (machine-state/skip-next-pc machine-state)
         (machine-state/increment-pc machine-state))))
@@ -65,8 +71,7 @@
   (let [reg-num (utils/get-nibble1 opcode)
         imm (utils/get-byte1 opcode)
         reg-val (machine-state/get-register machine-state reg-num)]
-    (log/info (format "0x%04x 4XNN 0x%04x skp V[%d](0x%02x) != 0x%02x"
-                       (machine-state/get-pc machine-state) opcode reg-num reg-val imm))
+    (trace machine-state opcode "4XNN skp V[%d](0x%02x) != 0x%02x" reg-num reg-val imm)
     (if (not= reg-val imm)
         (machine-state/skip-next-pc machine-state)
         (machine-state/increment-pc machine-state))))
@@ -78,8 +83,7 @@
         reg-y-num (utils/get-nibble2 opcode)
         reg-x-val (machine-state/get-register machine-state reg-x-num)
         reg-y-val (machine-state/get-register machine-state reg-y-num)]
-    (log/info (format "0x%04x 5XY0 0x%04x skp V[%d](0x%02x) == V[%d](0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-x-num reg-x-val reg-y-val reg-y-val))
+    (trace machine-state opcode "5XY0 skp V[%d](0x%02x) == V[%d](0x%02x)" reg-x-num reg-x-val reg-y-val reg-y-val)
     (if (= reg-x-val reg-y-val)
         (machine-state/skip-next-pc machine-state)
         (machine-state/increment-pc machine-state))))
@@ -89,8 +93,7 @@
   [machine-state opcode]
   (let [reg (utils/get-nibble1 opcode)
         imm (utils/get-byte1 opcode)]
-    (log/info (format "0x%04x 6XNN 0x%04x set V[%d](0x%02x) = 0x%02x"
-                       (machine-state/get-pc machine-state) opcode reg imm imm))
+    (trace machine-state opcode "6XNN set V[%d](0x%02x) = 0x%02x" reg imm imm)
     (-> machine-state
         (machine-state/set-register reg imm)
         (machine-state/increment-pc))))
@@ -102,8 +105,7 @@
         imm (utils/get-byte1 opcode)
         reg-val (machine-state/get-register machine-state reg-num)
         result (+ reg-val imm)]
-    (log/info (format "0x%04x 7XNN 0x%04x add V[%d](0x%02x) = V[%d](0x%02x) + 0x%02x"
-                       (machine-state/get-pc machine-state) opcode reg-num result reg-num reg-val imm))
+    (trace machine-state opcode "7XNN add V[%d](0x%02x) = V[%d](0x%02x) + 0x%02x" reg-num result reg-num reg-val imm)
     (-> machine-state
         (machine-state/set-register reg-num result)
         (machine-state/increment-pc))))
@@ -114,8 +116,7 @@
   (let [reg-x-num (utils/get-nibble1 opcode)
         reg-y-num (utils/get-nibble2 opcode)
         reg-y-val (machine-state/get-register machine-state reg-y-num)]
-    (log/info (format "0x%04x 8XY4 0x%04x set V[%d](0x%02x) = V[%d](0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-x-num reg-y-val reg-y-num reg-y-val))
+    (trace machine-state opcode "8XY0 set V[%d](0x%02x) = V[%d](0x%02x)" reg-x-num reg-y-val reg-y-num reg-y-val)
     (-> machine-state
         (machine-state/set-register reg-x-num reg-y-val)
         (machine-state/increment-pc))))
@@ -128,8 +129,7 @@
         reg-y-num (utils/get-nibble2 opcode)
         reg-y-val (machine-state/get-register machine-state reg-y-num)
         result (bit-or reg-x-val reg-y-val)]
-    (log/info (format "0x%04x 8XY2 0x%04x bor V[%d](0x%02x) = V[%d](0x%02x) & V[%d](0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-x-num result reg-x-num reg-x-val reg-y-num reg-y-val))
+    (trace machine-state opcode "8XY1 bor V[%d](0x%02x) = V[%d](0x%02x) & V[%d](0x%02x)" reg-x-num result reg-x-num reg-x-val reg-y-num reg-y-val)
     (-> machine-state
         (machine-state/set-register reg-x-num result)
         (machine-state/increment-pc))))
@@ -142,8 +142,7 @@
         reg-y-num (utils/get-nibble2 opcode)
         reg-y-val (machine-state/get-register machine-state reg-y-num)
         result (bit-and reg-x-val reg-y-val)]
-    (log/info (format "0x%04x 8XY2 0x%04x bnd V[%d](0x%02x) = V[%d](0x%02x) & V[%d](0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-x-num result reg-x-num reg-x-val reg-y-num reg-y-val))
+    (trace machine-state opcode "8XY2 bnd V[%d](0x%02x) = V[%d](0x%02x) & V[%d](0x%02x)" reg-x-num result reg-x-num reg-x-val reg-y-num reg-y-val)
     (-> machine-state
         (machine-state/set-register reg-x-num result)
         (machine-state/increment-pc))))
@@ -156,8 +155,7 @@
         reg-y-num (utils/get-nibble2 opcode)
         reg-y-val (machine-state/get-register machine-state reg-y-num)
         result (bit-xor reg-x-val reg-y-val)]
-    (log/info (format "0x%04x 8XY2 0x%04x xor V[%d](0x%02x) = V[%d](0x%02x) & V[%d](0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-x-num result reg-x-num reg-x-val reg-y-num reg-y-val))
+    (trace machine-state opcode "8XY3 xor V[%d](0x%02x) = V[%d](0x%02x) & V[%d](0x%02x)" reg-x-num result reg-x-num reg-x-val reg-y-num reg-y-val)
     (-> machine-state
         (machine-state/set-register reg-x-num result)
         (machine-state/increment-pc))))
@@ -172,8 +170,7 @@
         reg-y-val (machine-state/get-register machine-state reg-y-num)
         result (+ reg-x-val reg-y-val)
         is-carry? (> result 255)]
-    (log/info (format "0x%04x 8XY4 0x%04x add V[%d](0x%02x) = V[%d](0x%02x) + V[%d](0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-x-num result reg-x-num reg-x-val reg-y-num reg-y-val))
+    (trace machine-state opcode "8XY4 add V[%d](0x%02x) = V[%d](0x%02x) + V[%d](0x%02x)" reg-x-num result reg-x-num reg-x-val reg-y-num reg-y-val)
     (-> (if is-carry?
           (machine-state/set-register machine-state 0xF 1)
           (machine-state/set-register machine-state 0xF 0))
@@ -192,8 +189,7 @@
         result (if is-borrow?
                  (+ (- reg-x-val reg-y-val) 256)
                  (- reg-x-val reg-y-val))]
-    (log/info (format "0x%04x 8XY4 0x%04x sb5 V[%d](0x%02x) = V[%d](0x%02x) - V[%d](0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-x-num result reg-x-num reg-x-val reg-y-num reg-y-val))
+    (trace machine-state opcode "8XY5 sb5 V[%d](0x%02x) = V[%d](0x%02x) - V[%d](0x%02x)" reg-x-num result reg-x-num reg-x-val reg-y-num reg-y-val)
     (-> (if is-borrow?
           (machine-state/set-register machine-state 0xF 0)
           (machine-state/set-register machine-state 0xF 1))
@@ -208,8 +204,7 @@
         reg-x-val (machine-state/get-register machine-state reg-x-num)
         result-x (bit-shift-right reg-x-val 1)
         result-f (bit-and reg-x-val 0x1)]
-    (log/info (format "0x%04x 8XY6 0x%04x shr V[%d](0x%02x) = V[%d](0x%02x) >> 1"
-                       (machine-state/get-pc machine-state) opcode reg-x-num result-x reg-x-num reg-x-val))
+    (trace machine-state opcode "8XY6 shr V[%d](0x%02x) = V[%d](0x%02x) >> 1" reg-x-num result-x reg-x-num reg-x-val)
     (-> (machine-state/set-register machine-state 0xF result-f)
         (machine-state/set-register reg-x-num result-x)
         (machine-state/increment-pc))))
@@ -226,8 +221,7 @@
         result (if is-borrow?
                  (+ (- reg-y-val reg-x-val) 256)
                  (- reg-y-val reg-x-val))]
-    (log/info (format "0x%04x 8XY4 0x%04x sb7 V[%d](0x%02x) = V[%d](0x%02x) - V[%d](0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-x-num result reg-y-num reg-y-val reg-x-num reg-x-val))
+    (trace machine-state opcode "8XY7 sb7 V[%d](0x%02x) = V[%d](0x%02x) - V[%d](0x%02x)" reg-x-num result reg-y-num reg-y-val reg-x-num reg-x-val)
     (-> (if is-borrow?
           (machine-state/set-register machine-state 0xF 0)
           (machine-state/set-register machine-state 0xF 1))
@@ -242,8 +236,7 @@
         reg-x-val (machine-state/get-register machine-state reg-x-num)
         result-x (bit-and (bit-shift-left reg-x-val 1) 0xFF)
         result-f (bit-and (bit-shift-right reg-x-val 7) 0x1)]
-    (log/info (format "0x%04x 8XY6 0x%04x shl V[%d](0x%02x) = V[%d](0x%02x) << 1"
-                       (machine-state/get-pc machine-state) opcode reg-x-num result-x reg-x-num reg-x-val))
+    (trace machine-state opcode "8XYE shl V[%d](0x%02x) = V[%d](0x%02x) << 1" reg-x-num result-x reg-x-num reg-x-val)
     (-> (machine-state/set-register machine-state 0xF result-f)
         (machine-state/set-register reg-x-num result-x)
         (machine-state/increment-pc))))
@@ -255,8 +248,7 @@
         reg-x-val (machine-state/get-register machine-state reg-x-num)
         reg-y-num (utils/get-nibble2 opcode)
         reg-y-val (machine-state/get-register machine-state reg-y-num)]
-    (log/info (format "0x%04x 9XY0 0x%04x seq V[%d](0x%02x) == V[%d](0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-x-num reg-x-val reg-y-num reg-y-val))
+    (trace machine-state opcode "9XY0 seq V[%d](0x%02x) == V[%d](0x%02x)" reg-x-num reg-x-val reg-y-num reg-y-val)
     (if (not= reg-x-val reg-y-val)
       (machine-state/skip-next-pc machine-state)
       (machine-state/increment-pc machine-state))))
@@ -265,8 +257,7 @@
   "Sets I to the address NNN."
   [machine-state opcode]
   (let [nnn (utils/get-nnn opcode)]
-    (log/info (format "0x%04x ANNN 0x%04x sti I = 0x%03x"
-                       (machine-state/get-pc machine-state) opcode nnn))
+    (trace machine-state opcode "ANNN sti I = 0x%03x" nnn)
     (-> machine-state
         (machine-state/set-addr-reg nnn)
         (machine-state/increment-pc))))
@@ -277,8 +268,7 @@
   (let [reg-0-val (machine-state/get-register machine-state 0)
         imm (utils/get-nnn opcode)
         dest (+ imm reg-0-val)]
-    (log/info (format "0x%04x BNNN 0x%04x jpa 0x%04x + V0[0x%02x] = 0x%04x"
-                      (machine-state/get-pc machine-state) opcode imm reg-0-val dest))
+    (trace machine-state opcode "BNNN jpa 0x%04x + V0[0x%02x] = 0x%04x" imm reg-0-val dest)
     (machine-state/set-pc machine-state dest)))

 (defn execute-CXNN
@@ -288,8 +278,7 @@
         imm (utils/get-byte1 opcode)
         rnd (rand-int 0xFF)
         result (bit-and imm rnd)]
-    (log/info (format "0x%04x CXNN 0x%04x rnd V[%d](0x%02x) <- rand(0x%02x) & NN(0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-num result rnd imm))
+    (trace machine-state opcode "CXNN rnd V[%d](0x%02x) <- rand(0x%02x) & NN(0x%02x)" reg-num result rnd imm)
     (-> machine-state
         (machine-state/set-register reg-num result)
         (machine-state/increment-pc))))
@@ -308,8 +297,7 @@
         reg-x-val (machine-state/get-register machine-state reg-x-num)
         reg-y-val (machine-state/get-register machine-state reg-y-num)
         addr-reg (machine-state/get-addr-reg machine-state)]
-    (log/info (format "0x%04x DXVN 0x%04x drw V[%d](0x%02x), V[%d](0x%02x), %d, I(0x%04x)"
-                       (machine-state/get-pc machine-state) opcode reg-x-num reg-x-val reg-y-num reg-y-val imm addr-reg))
+    (trace machine-state opcode "DXVN drw V[%d](0x%02x), V[%d](0x%02x), %d, I(0x%04x)" reg-x-num reg-x-val reg-y-num reg-y-val imm addr-reg)

     (as-> machine-state $
       (machine-state/clear-carry-flag $)
@@ -349,8 +337,7 @@
   [machine-state opcode]
   (let [reg-num (utils/get-nibble1 opcode)
         reg-val (machine-state/get-register machine-state reg-num)]
-    (log/info (format "0x%04x EX9E 0x%04x kpt V[%d](0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-num reg-val))
+    (trace machine-state opcode "EX9E kpt V[%d](0x%02x)" reg-num reg-val)
     (if (state/is-key-pressed reg-val)
         (machine-state/skip-next-pc machine-state)
         (machine-state/increment-pc machine-state))))
@@ -360,8 +347,7 @@
   [machine-state opcode]
   (let [reg-num (utils/get-nibble1 opcode)
         reg-val (machine-state/get-register machine-state reg-num)]
-    (log/info (format "0x%04x EXA1 0x%04x kpf V[%d](0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-num reg-val))
+    (trace machine-state opcode "EXA1 kpf V[%d](0x%02x)" reg-num reg-val)
     (if (not (state/is-key-pressed reg-val))
       (machine-state/skip-next-pc machine-state)
       (machine-state/increment-pc machine-state))))
@@ -371,8 +357,7 @@
   [machine-state opcode]
   (let [reg-x-num (utils/get-nibble1 opcode)
         delay-timer-val (state/get-delay-timer)]
-    (log/info (format "0x%04x FX15 0x%04x gdt V[%d](0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-x-num delay-timer-val))
+    (trace machine-state opcode "FX07 gdt V[%d](0x%02x)" reg-x-num delay-timer-val)
     (-> machine-state
         (machine-state/set-register reg-x-num delay-timer-val)
         (machine-state/increment-pc))))
@@ -385,8 +370,7 @@
       (if (= key-pressed nil)
         (recur (state/get-key-pressed))
         (do
-          (log/info (format "0x%04x FX0A 0x%04x wkp V[%d](0x%02x)"
-                            (machine-state/get-pc machine-state) opcode reg-x-num key-pressed))
+          (trace machine-state opcode "FX0A wkp V[%d](0x%02x)" reg-x-num key-pressed)
           (-> machine-state
               (machine-state/set-register reg-x-num key-pressed)
               (machine-state/increment-pc)))))))
@@ -396,8 +380,7 @@
   [machine-state opcode]
   (let [reg-x-num (utils/get-nibble1 opcode)
         reg-x-val (machine-state/get-register machine-state reg-x-num)]
-    (log/info (format "0x%04x FX15 0x%04x sdt V[%d](0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-x-num reg-x-val))
+    (trace machine-state opcode "FX15 sdt V[%d](0x%02x)" reg-x-num reg-x-val)
     (state/set-delay-timer reg-x-val)
     (machine-state/increment-pc machine-state)))

@@ -406,8 +389,7 @@
   [machine-state opcode]
   (let [reg-x-num (utils/get-nibble1 opcode)
         reg-x-val (machine-state/get-register machine-state reg-x-num)]
-    (log/info (format "0x%04x FX18 0x%04x sst V[%d](0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-x-num reg-x-val))
+    (trace machine-state opcode "FX18 sst V[%d](0x%02x)" reg-x-num reg-x-val)
     (state/set-sound-timer reg-x-val)
     (machine-state/increment-pc machine-state)))

@@ -417,8 +399,7 @@
   (let [reg-x-num (utils/get-nibble1 opcode)
         reg-x-val (machine-state/get-register machine-state reg-x-num)
         addr-reg (machine-state/get-addr-reg machine-state)]
-    (log/info (format "0x%04x FX1E 0x%04x adi V[%d](0x%02x) I(0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-x-num reg-x-val addr-reg))
+    (trace machine-state opcode "FX1E adi V[%d](0x%02x) I(0x%02x)" reg-x-num reg-x-val addr-reg)
     (-> machine-state
         (machine-state/set-addr-reg (+ addr-reg reg-x-val))
         (machine-state/increment-pc))))
@@ -429,8 +410,7 @@
   [machine-state opcode]
   (let [reg-x-num (utils/get-nibble1 opcode)
         reg-x-val (machine-state/get-register machine-state reg-x-num)]
-    (log/info (format "0x%04x FX29 0x%04x gfa V[%d](0x%02x)"
-                       (machine-state/get-pc machine-state) opcode reg-x-num reg-x-val))
+    (trace machine-state opcode "FX29 gfa V[%d](0x%02x)" reg-x-num reg-x-val)
     (-> machine-state
         (machine-state/set-addr-reg (* reg-x-val 5))
         (machine-state/increment-pc))))
@@ -449,8 +429,7 @@
         ones (mod reg-x-val 10)
         tens (quot (mod reg-x-val 100) 10)
         hundreds (quot (mod reg-x-val 1000) 100)]
-    (log/info (format "0x%04x FX33 0x%04x bcd V[%d](0x%02x), I(0x%04x), %d-%d-%d"
-                       (machine-state/get-pc machine-state) opcode reg-x-num reg-x-val addr-reg, hundreds, tens, ones))
+    (trace machine-state opcode "FX33 bcd V[%d](0x%02x), I(0x%04x), %d-%d-%d" reg-x-num reg-x-val addr-reg, hundreds, tens, ones)
     (-> machine-state
         (machine-state/set-memory addr-reg hundreds)
         (machine-state/set-memory (+ addr-reg 1) tens)
@@ -462,8 +441,7 @@
   [machine-state opcode]
   (let [reg-x (utils/get-nibble1 opcode)
         addr-reg (machine-state/get-addr-reg machine-state)]
-    (log/info (format "0x%04x FX55 0x%04x rtm V[%d], I(0x%04x)"
-                       (machine-state/get-pc machine-state) opcode reg-x addr-reg))
+    (trace machine-state opcode "FX55 rtm V[%d], I(0x%04x)" reg-x addr-reg)
     (-> (reduce (fn [machine-state index]
                   (let [reg-val (machine-state/get-register machine-state index)]
                     (machine-state/set-memory machine-state (+ addr-reg index) reg-val)))
@@ -475,8 +453,7 @@
   [machine-state opcode]
   (let [reg-x (utils/get-nibble1 opcode)
         addr-reg (machine-state/get-addr-reg machine-state)]
-    (log/info (format "0x%04x FX65 0x%04x mtr V[%d], I(0x%04x)"
-                       (machine-state/get-pc machine-state) opcode reg-x addr-reg))
+    (trace machine-state opcode "FX65 mtr V[%d], I(0x%04x)" reg-x addr-reg)
     (-> (reduce (fn [machine-state index]
                   (let [reg-val (machine-state/get-memory machine-state (+ addr-reg index))]
                     (machine-state/set-register machine-state index reg-val)))


Less shit in the state atom

Less shit in the state atom

--- src/cljs/dragonspawn/core.cljs
+++ src/cljs/dragonspawn/core.cljs
@@ -29,9 +29,22 @@
 (def game-x-cells (pixels->cell game-width))
 (def game-y-cells (pixels->cell game-height))

-(defn surface-element
+(def surface
+  (let [surface (dom/getElement "surface")]
+    (set! (.-width surface) game-width)
+    (set! (.-height surface) game-height)
+    surface))
+(def draw-context (.getContext surface "2d"))
+
+(def start-position
+  [(pixels->cell (/ game-width 2))
+   (- (pixels->cell game-height) 1)])
+
+(defn initial-state
   []
-  (dom/getElement "surface"))
+  {:start-time (js/Date.)
+   :state :playing
+   :player start-position} )

 (def keycode->key
   {kcs/SPACE :space
@@ -50,11 +63,8 @@
   {:blue "#127496"})

 (defn log-state
-  [{:keys [surface-width surface-height surface player]}]
+  [{:keys [player]}]
   (let [[player-x player-y] player]
-    (.log js/console "surface width:" surface-width
-          "surface height:" surface-height)
-    (.log js/console "surface:" surface)
     (.log js/console "player x" player-x "player y" player-y)))

 (defn draw-square
@@ -62,13 +72,13 @@
   )

 (defn draw-sprite
-  [{:keys [draw-context]} x y size sprite]
+  [state x y size sprite]
   (let [sprite (sprites sprite)
         [x y] (cell->coords x y)]
     (.drawImage draw-context sprite x y size size)))

 (defn draw-text
-  [{:keys [draw-context]} x y text]
+  [state x y text]
   (let [[x y] (cell->coords x y)]
     (set! (.-font draw-context) "bold 1.5em sans-serif")
     (set! (.-textBaseline draw-context) "top")
@@ -92,6 +102,9 @@
     (draw-sprite state 4 4 cell-size :flask)
     (draw-sprite state player-x player-y cell-size :player)
     (draw-text state game-x-cells 0 (str countdown " seconds"))))
+
+(defmethod render :finished
+  [state])

 (defn render-world
   [state]
@@ -157,9 +170,8 @@
   (str (int size) ".px"))

 (defn resize
-  [state e]
-  (let [{:keys [draw-context surface]} @state
-        winWidth (.-innerWidth js/window)
+  [& args]
+  (let [winWidth (.-innerWidth js/window)
         winHeight (.-innerHeight js/window)
         currentRatio (float (/ winWidth winHeight))
         [width height] (if (> currentRatio aspectRatio)
@@ -173,27 +185,19 @@
                   :marginTop (px top)
                   :marginLeft (px left)})))

-(defn ^:export main
+(defn setup-events
+  [state]
+  (let [timer (goog.Timer. 200)]
+    (events/listen timer goog.Timer/TICK (partial check-game state))
+    (events/listen js/window event-type/RESIZE resize)
+    (events/listen js/window event-type/KEYDOWN (partial keydown state))
+    (.start timer)))
+
+(defn main
   []
-  (let [surface (surface-element)
-        draw-context (.getContext surface "2d")
-        timer (goog.Timer. 200)
-        state (atom {:surface surface
-                     :draw-context draw-context
-                     :surface-width (.-width surface)
-                     :surface-height (.-height surface)
-                     :start-time (js/Date.)
-                     :state :playing
-                     :player [(pixels->cell (/ game-width 2))
-                              (- (pixels->cell game-height) 1)]})]
-    (set! (.-width surface) game-width)
-    (set! (.-height surface) game-height)
-    (events/listen timer goog.Timer/TICK (partial check-game state))
-    (events/listen js/window event-type/RESIZE (partial resize state))
-    (events/listen js/window event-type/KEYDOWN (partial keydown state))
-    (.start timer)
-    (resize state)
-    (log-state @state)
+  (let [state (atom (initial-state))]
+    (setup-events state)
+    (resize)
     (render-world state)))

 (main)


Don't disable split pane

Don't disable split pane

--- src/clojure/nightcode/core.clj
+++ src/clojure/nightcode/core.clj
@@ -105,8 +105,7 @@
       (s/top-bottom-split (get-editor-pane)
                           (get-builder-pane)
                           :divider-location 0.8
-                          :resize-weight 0.5)
-      :enabled? false)))
+                          :resize-weight 0.5))))

 (defn -main
   "Launches the main window."


add stop server function

add stop server function

--- src/clojure/staircase/main.clj
+++ src/clojure/staircase/main.clj
@@ -5,18 +5,24 @@
         [clojure.tools.logging :only (info)]
         [staircase.app :as app]))

-(defn- to-int [s] (Integer/parseInt s))
+(defn- to-int [s] (Integer/parseInt s 10))

-(defonce server (atom nil))
+(defonce server (atom {}))

 (defn stop-server
-  []
-  (when-not (nil? @server)
-    (@server :timeout 100)
-    (reset! server nil)))
+  [port]
+  (when-let [app (get @server port)]
+    (app :timeout 100) ;; Close port
+    (swap! server dissoc port))) ;; Delete ref.

-(defn -main [ & args ]
-  (let [port (to-int (get env :port "3000"))]
-    (reset! server (run-server app/handler {:port port}))
+(defn start-server
+  [port]
+  (let [port (or port 3000)]
+    (stop-server port)
+    (swap! server assoc port (run-server app/handler {:port port}))
     (info "Started staircase server on port" port)))

+(defn -main [ & [userport] ]
+  (let [port (to-int (or userport (get env :port "3000")))]
+    (start-server port)))
+


URL decode now sensitive to request character encoding

--- src/compojure/http/request.clj
+++ src/compojure/http/request.clj
@@ -28,6 +28,11 @@
         [cur val])
       val)))

+(defn urldecode
+  "Decode a urlencoded string using the default encoding."
+  [s]
+  (URLDecoder/decode s *default-encoding*))
+
 (defn parse-params
   "Parse parameters from a string into a map."
   [param-str]
@@ -37,8 +42,8 @@
         param-map
         (let [[key val] (re-split #"=" s)]
           (assoc-vec param-map
-            (keyword (URLDecoder/decode key))
-            (URLDecoder/decode val)))))
+            (keyword (urldecode key))
+            (urldecode val)))))
     {}
     (re-split #"&" param-str)))

@@ -49,6 +54,7 @@
     (parse-params query)))

 (defn get-character-encoding
+  "Get the character encoding, or use the default from duck-streams."
   [request]
   (or (request :character-encoding) *default-encoding*))