sanitize cb minor to b minor

sanitize cb minor to b minor

--- src/riffmuse/scales.clj
+++ src/riffmuse/scales.clj
@@ -3,31 +3,31 @@

 (defn sanitize [pitch scale]
   "For the sake of simplicity, Riffmuse does not support the use of more than
-   one accidental; e.g., double sharps and double flats. For this reason,
+   one accidental; e.g., double sharps and double flats. For this reason,
    scales like E# major (E# Fx Gx A# B# Cx Dx) are not supported. This function
    is used to ensure that such scales will be spelled enharmonically, e.g.
    E# major -> F major (F G A Bb C D E)."
   (get (condp contains? scale
-         #{:major :major-pentatonic}
-         {:d-sharp :e-flat, :e-sharp :f, :f-flat :e,
+         #{:major :major-pentatonic}
+         {:d-sharp :e-flat, :e-sharp :f, :f-flat :e,
           :g-sharp :a-flat, :a-sharp :b-flat, :b-sharp :c}
-
-         #{:minor :minor-pentatonic :blues}
-         {:d-flat :c-sharp, :e-sharp :f, :f-flat :e,
+
+         #{:minor :minor-pentatonic :blues}
+         {:c-flat :b, :d-flat :c-sharp, :e-sharp :f, :f-flat :e,
           :g-flat :f-sharp, :a-flat :g-sharp, :b-sharp :c})
        pitch
        pitch))

 (defn scale-name [{:keys [pitch scale]}]
   "Converts a scale (a map) to a human-readable string version of its name."
-  (let [pitch (when pitch
-                (str/replace (name (sanitize pitch scale)) #"-flat|-sharp"
+  (let [pitch (when pitch
+                (str/replace (name (sanitize pitch scale)) #"-flat|-sharp"
                              {"-flat" "b" "-sharp" "#"}))
         scale (str/replace (name scale) #"-" " ")]
     (-> (str pitch \space scale) str/trim str/capitalize)))

 (defmulti notes
-  "Takes the scale (a map) output by parse-cli-args and returns a set of
+  "Takes the scale (a map) output by parse-cli-args and returns a set of
    notes representing the appropriate scale."
    :scale)

@@ -43,10 +43,10 @@

 (defn- circle-of-fifths [major-or-minor]
   (zipmap (case major-or-minor
-            :major [:c-flat :g-flat :d-flat :a-flat :e-flat :b-flat :f
+            :major [:c-flat :g-flat :d-flat :a-flat :e-flat :b-flat :f
                     :c :g :d :a :e :b :f-sharp :c-sharp]
             :minor [:a-flat :e-flat :b-flat :f :c :g :d
-                    :a :e :b :f-sharp :c-sharp :g-sharp :d-sharp :a-sharp])
+                    :a :e :b :f-sharp :c-sharp :g-sharp :d-sharp :a-sharp])
           (range -7 8)))

 (defn key-signature [pitch major-or-minor]
@@ -60,11 +60,11 @@
         letter->number (zipmap "abcdefg" (range 8))
         number->letter (zipmap (range 8) "ABCDEFG")
         base-number    (->> pitch name first letter->number)
-        base-notes     (take 7 (map number->letter
+        base-notes     (take 7 (map number->letter
                                     (iterate #(rem (inc %) 7) base-number)))
         {:keys [sharps flats]} (key-signature pitch major-or-minor)]
-    (map (fn [letter]
-           (str letter (when (and sharps (sharps letter)) \#)
+    (map (fn [letter]
+           (str letter (when (and sharps (sharps letter)) \#)
                        (when (and flats (flats letter)) \b)))
          base-notes)))

@@ -103,6 +103,6 @@
 (defmethod notes :blues [{:keys [pitch]}]
   (let [minor-pentatonic (pentatonic-scale pitch :minor)
         extra-note       (augment (nth minor-pentatonic 2))]
-    (set (concat (take 3 minor-pentatonic)
+    (set (concat (take 3 minor-pentatonic)
                  [extra-note]
                  (drop 3 minor-pentatonic)))))


Make harvestables drop even more

Make harvestables drop even more

--- src/robinson/update.clj
+++ src/robinson/update.clj
@@ -1762,7 +1762,7 @@
       (fn [place]
         (update-matching-cells place
                                (fn [cell] (contains? #{:gravel :tree :palm-tree :tall-grass} (get cell :type)))
-                               (fn [cell] (if (= (uniform-int 0 2000) 0)
+                               (fn [cell] (if (= (uniform-int 0 1000) 0)
                                             (assoc cell :harvestable true)
                                             cell)))))))


Exit to main menu rather than stopping game

--- src/robinson/update.clj
+++ src/robinson/update.clj
@@ -3144,6 +3144,7 @@
   ;;         state         symbol      fn                     state            time?
   (let [table {:start     {:space      [identity               :enter-name      false]
                            \c          [identity               :configure       false]
+                           \q          [identity               :quit            false]
                            :else       [pass-state             rw/current-state false]}
                :configure
                           {\f          [identity               :configure-font  false]
@@ -3550,7 +3551,7 @@
                :share-score
                           {\y          [identity               :start-inventory false]
                            \n          [identity               :start           false]}
-               :quit?     {\y          [identity               :quit            false]
+               :quit?     {\y          [identity               :start           false]
                            :else       [pass-state             :normal          false]}}
         expander-fn (fn [table] table)]
     (expander-fn table)))


Use 'map' instead of 'for' in problem64.clj

--- euler_clojure/src/euler/problem64.clj
+++ euler_clojure/src/euler/problem64.clj
@@ -42,5 +42,5 @@
                    next-a)))))))

 (defn problem64 []
-  (let [cont-fracs (for [i (range 2 10001)] (continued-fraction-sqrt i))]
+  (let [cont-fracs (map continued-fraction-sqrt (range 2 10001))]
     (count (filter #(odd? (count (rest %))) cont-fracs))))


with-temp-files makes a single :command call for n temp files

--- plugins/matross/tasks/temp_file.clj
+++ plugins/matross/tasks/temp_file.clj
@@ -24,11 +24,9 @@
         temp-file (trim-newline (stream-to-string data :out))]
     (task-result succeeded? true (assoc data :path temp-file))))

-(defn n-temp-files-command [opts n]
-  (clojure.string/join "; " (repeatedly n #(temp-file-command opts))))
-
-(defn temp-file-list [conn command-str]
-  (let [{:keys [data succeeded?]} (run-task conn {:type :command :command command-str})
+(defn temp-file-list [conn opts n]
+  (let [command-str (clojure.string/join "; " (repeatedly n #(temp-file-command opts)))
+        {:keys [data succeeded?]} (run-task conn {:type :command :command command-str})
         out (stream-to-string data :out)]
     (clojure.string/split-lines out)))

@@ -36,21 +34,25 @@
 ;;        split on newline, and bind each line to a given binding
 (defmacro with-temp-files
   "Evaluate the body with the symbols in `bindings` bound to temp file paths on the target machine. Once the
-   body has been evaluated, the temp files are deleted from the target machine."
+  body has been evaluated, the temp files are deleted from the target machine."

   [conn & args]

   (let [[opts args] (if (map? (first args))
-                      [(first args) (rest args)]
-                      [nil args])
+                       [(first args) (rest args)]
+                       [nil args])
         opts (merge opts {:type :temp-file})
         [bindings body] [(first args) (rest args)]]
     (cond
       (some #(= conn %1) bindings)
       (throw (IllegalArgumentException. "Collission between conn and tempfile bindings."))
       :else
-      (let [get-tmpfile (fn [_] `(-> (run-task ~conn ~opts) (get-in [:data :path])))]
-        `(let [~@(interleave bindings (map get-tmpfile bindings))
+      (let [binding-count (count bindings)
+            temp-files (gensym "temp-files")]
+        `(let [~temp-files (temp-file-list ~conn ~opts ~binding-count)
+               ~@(apply concat
+                        (map-indexed (fn [i v] [v `(nth ~temp-files ~i)])
+                                     bindings))
                cleanup# (str "/bin/rm -f " (clojure.string/join " " ~bindings))]
            (try ~@body
                 (finally


Handle min-peers/max-peers/n-peers correctly #24

--- src/onyx/plugin/kafka.clj
+++ src/onyx/plugin/kafka.clj
@@ -169,13 +169,15 @@
       (throw e))))

 (defn check-num-peers-equals-partitions
-  [{:keys [onyx/min-peers onyx/max-peers kafka/partition] :as task-map} n-partitions]
+  [{:keys [onyx/min-peers onyx/max-peers onyx/n-peers kafka/partition] :as task-map} n-partitions]
   (let [fixed-partition? (and partition (= 1 max-peers))
-        all-partitions-covered? (= n-partitions min-peers max-peers)
-        one-partition? (= 1 n-partitions max-peers)]
-    (when-not (or fixed-partition? all-partitions-covered? one-partition?)
-      (let [e (ex-info ":onyx/min-peers must equal :onyx/max-peers and the number of kafka partitions"
+        all-partitions-covered? (or (= n-partitions min-peers max-peers)
+                                    (= 1 n-partitions max-peers)
+                                    (= n-partitions n-peers))]
+    (when-not (or fixed-partition? all-partitions-covered?)
+      (let [e (ex-info ":onyx/min-peers must equal :onyx/max-peers and the number of partitions, or :onyx/n-peers must equal number of kafka partitions"
                        {:n-partitions n-partitions
+                        :n-peers n-peers
                         :min-peers min-peers
                         :max-peers max-peers
                         :task-map task-map})]


Fix NPE when neither min-peers/max-peers are set.

--- src/onyx/plugin/kafka.clj
+++ src/onyx/plugin/kafka.clj
@@ -74,7 +74,8 @@
   [{:keys [onyx/min-peers onyx/max-peers onyx/n-peers kafka/partition] :as task-map} n-partitions]
   (let [fixed-partition? (and partition (or (= 1 n-peers)
                                             (= 1 max-peers)))
-        fixed-npeers? (or (= min-peers max-peers) (= 1 max-peers)
+        fixed-npeers? (or (and min-peers (= min-peers max-peers))
+                          (= 1 max-peers)
                           (and n-peers (and (not min-peers) (not max-peers))))
         n-peers (or max-peers n-peers)
         n-peers-less-eq-n-partitions (and n-peers (<= n-peers n-partitions))]


Attempt to make the mixer even safer - unfortunately the select ugen seems to behave strangely with massive inputs such that it lets the large signal through even when not wanted. Not sure if this is a bug in Overtone or SC.

Still - the mixer is a little safer now.

--- src/overtone/sc/mixer.clj
+++ src/overtone/sc/mixer.clj
@@ -15,14 +15,18 @@
   (do
     (defsynth out-bus-mixer [in-bus 20 out-bus 0
                              volume 0.5 master-volume 0.5]
-      (let [source  (internal:in in-bus)
-            source  (* volume master-volume source)
-            limited (compander source source 0.7
-                               1 0.1
-                               0.05 0.05)
-            clipped (clip2 limited 1.5)]
-        (send-reply (trig1 (> (a2k source) 1.5) 0.25) "/server-audio-clipping" out-bus)
-        (internal:out out-bus clipped)))
+      (let [source       (internal:in in-bus)
+            source       (clip2 source 2)
+            not-safe?    (> (a2k source) 1)
+            limited      (compander source source 0.7
+                                    1 0.1
+                                    0.05 0.05)
+            std-clipped  (clip2 limited 1)
+            safe-clipped (clip2 limited 0.1)
+            safe-snd     (select not-safe? [std-clipped safe-clipped])
+            safe-snd     (* volume master-volume safe-snd)]
+        (send-reply (trig1 not-safe? 0.25) "/server-audio-clipping" out-bus)
+        (internal:out out-bus safe-snd)))

     (defsynth in-bus-mixer [in-bus 10 out-bus 0
                             gain 1 master-gain 1]


list-tags-all is bound to user

list-tags-all is bound to user

--- src/ontrail/core.clj
+++ src/ontrail/core.clj
@@ -126,7 +126,7 @@
        (json-response (get-latest-ex-list (user-from-cookie cookies) {:tags (:tag params)} (get-page params) {:creationDate -1})))

   (GET "/rest/v1/list-tags/:user" [user] (json-response (get-distinct-tags {:user user})))
-  (GET "/rest/v1/list-tags-all" [] (json-response (get-distinct-tags {})))
+  (GET "/rest/v1/list-tags-all" {params :params cookies :cookies} (json-response (get-distinct-tags {:user (user-from-cookie cookies)})))

   (GET "/rest/v1/list-users/:page" [page] (json-response (user/get-user-list {} page)))


Improve Window schema

Improve Window schema

--- src/onyx/schema.cljc
+++ src/onyx/schema.cljc
@@ -259,19 +259,23 @@
           'unsupported-window-key))

 (def Window
-  {:window/id s/Keyword
-   :window/task TaskName
-   :window/type WindowType
-   :window/aggregation (s/either s/Keyword [s/Keyword])
-   (s/optional-key :window/init) s/Any
-   (s/optional-key :window/window-key) s/Any
-   (s/optional-key :window/min-value) s/Int
-   (s/optional-key :window/range) Unit
-   (s/optional-key :window/slide) Unit
-   (s/optional-key :window/timeout-gap) Unit
-   (s/optional-key :window/session-key) s/Any
-   (s/optional-key :window/doc) s/Str
-   UnsupportedWindowKey s/Any})
+  (s/constrained
+    {:window/id s/Keyword
+     :window/task TaskName
+     :window/type WindowType
+     :window/aggregation (s/either s/Keyword [s/Keyword])
+     (s/optional-key :window/init) s/Any
+     (s/optional-key :window/window-key) s/Any
+     (s/optional-key :window/min-value) s/Int
+     (s/optional-key :window/range) Unit
+     (s/optional-key :window/slide) Unit
+     (s/optional-key :window/timeout-gap) Unit
+     (s/optional-key :window/session-key) s/Any
+     (s/optional-key :window/doc) s/Str
+     UnsupportedWindowKey s/Any})
+  (fn [v] (and (#{:fixed :sliding} (:window/type v))
+	       (:window/range v)))
+  ":window/range must be defined for :fixed or :sliding window")

 (def StateAggregationCall
   {(s/optional-key :aggregation/init) Function


decrs file-request:id on bad get

decrs file-request:id on bad get

--- src/server/core.cljs
+++ src/server/core.cljs
@@ -94,7 +94,8 @@
                           absolute-file-path (.toString reply)
                           read-stream (.createReadStream fs absolute-file-path)]
                       (.emit (socketio-stream client-socket) "file-to-client" stream)
-                      (.pipe read-stream stream))))))))))))
+                      (.pipe read-stream stream))
+                    (.decr rooms/redis-client (str "file-request:" message))))))))))))

 ; TODO: probably dont even need this subscription anymore...
 (.subscribe redis-subscribe-client "file-upload")


add language to HTML page

add language to HTML page

--- src/server/html.cljs
+++ src/server/html.cljs
@@ -5,7 +5,7 @@

 (hiccups/defhtml head [page-title]
   "<!doctype html>"
-  "<html>"
+  "<html lang='en-us'>"
   [:head
     [:meta {:charset "utf-8"}]
     [:meta {:http-equiv "X-UA-Compatible" :content "IE=edge"}]


require

require

--- src/splash/core.cljs
+++ src/splash/core.cljs
@@ -1,5 +1,14 @@
 (ns ^:figwheel-always splash.core
-    (:require [infinitelives.pixi.canvas :as canv]))
+    (:require [infinitelives.pixi.canvas :as canv]
+              [infinitelives.pixi.resources :as resources]
+              [infinitelives.pixi.sprite :as sprite]
+              [infinitelives.utils.events :as events]
+              [infinitelives.utils.console :refer [log]]
+              ;[splash.macros :refer-macros [ignore]]
+              [cljs.core.async :refer [<!]])
+    (:require-macros [cljs.core.async.macros :refer [go]]
+                     [splash.macros :as macros]
+                     ))

 (enable-console-print!)


Exercise 3.6

Exercise 3.6

--- src/sicp/chapter3_1.clj
+++ src/sicp/chapter3_1.clj
@@ -152,6 +152,17 @@
          double)))

 ;; Exercise 3.6
-;; TODO
+(def random-init (atom 0))
+(defn rand-update [n]
+  (inc n))
+
+(defn rand' [m]
+  (let [r random-init]
+    (case m
+      :generate (swap! r rand-update)
+      :reset #(reset! r %)
+      (throw (IllegalArgumentException.
+              (str "Unknown request -- rand' "
+                   m))))))

 ;;; 3.1.3  The Costs of Introducing Assignment


Added integer casting.

Added integer casting.

--- src/simulacrum/util.clj
+++ src/simulacrum/util.clj
@@ -32,7 +32,8 @@
         sequence))))

 (defn check-input [input]
-  (let [valid-range (range 1 6)]
+  (let [valid-range (range 1 6)
+        input (Integer. input)]
     (cond
       (in? valid-range input)
         input


Google site verification

Google site verification

--- src/sinon_docs/page.clj
+++ src/sinon_docs/page.clj
@@ -12,6 +12,7 @@
      (-> (html5
           [:head
            [:meta {:charset "utf-8"}]
+           [:meta {:name "google-site-verification" :content "mkRakJ_AGQ2BuUur1LqqqHh-x3wFVnE_UmPxLFxGHro"}]
            [:title (str "Sinon.JS - " title)]
            [:link {:rel "stylesheet" :type "text/css" :href (link/file-path request "/styles/sinon.css")}]]
           [:body {:class (:body-class options)}


CMR-192: Fixed typos.

CMR-192: Fixed typos.

--- test/cmr/system_int_test/search/collection_search_test.clj
+++ test/cmr/system_int_test/search/collection_search_test.clj
@@ -52,8 +52,8 @@

 (use-fixtures :once wrap-setup)

-(deftest search-by-concpet-id
-  (testing "Search by existing concpet-id."
+(deftest search-by-concept-id
+  (testing "Search by existing concept-id."
     (let [references (search/find-collection-refs {:concept-id "C1000000000-CMR_PROV1"})]
       (is (= 1 (count references)))))
   (testing "Search by multiple concept-ids."


Add introductory notes on state in Clojure.

--- test/com/nomistech/clojure_the_language/intro_to_state.clj
+++ test/com/nomistech/clojure_the_language/intro_to_state.clj
@@ -1,5 +1,22 @@
 (ns com.nomistech.clojure-the-language.intro-to-state
   (:require [midje.sweet :refer :all]))
+
+;;;; ___________________________________________________________________________
+
+;;;; Concurrency and state management without locks.
+;;;; Focus on sane management of state.
+;;;; Sane concurrency follows.
+
+;;;; References
+;;;; - There are a fair few types of reference
+;;;;   - atoms, refs, vars, agents, promises, futures...
+;;;; - Some are for managing state
+;;;; - Some are for managing concurrency
+;;;; - Some combine the two
+
+;;;; Here we will look at two reference types, both for managing state
+;;;; - Atoms
+;;;; - Refs (confusing names! A ref is one kind of reference.)

 ;;;; ___________________________________________________________________________
 ;;;; Atoms: `atom`, `reset!` and `swap!`


CMR-1885 Refactor platform and instrument parsing code to be more DRY

--- umm-spec-lib/src/cmr/umm_spec/xml_to_umm_mappings/serf.clj
+++ umm-spec-lib/src/cmr/umm_spec/xml_to_umm_mappings/serf.clj
@@ -5,20 +5,35 @@
             [camel-snake-kebab.core :as csk]
             [clojure.string :as string]
             [cmr.umm-spec.xml.parse :refer :all]
-            [cmr.umm-spec.util :as u :refer [without-default-value-of]]
+            [cmr.umm-spec.util :refer [without-default-value-of not-provided]]
             [cmr.umm-spec.date-util :as date]))

-(defn- parse-characteristics
-  [el]
-  (for [characteristic (select el "Characteristics")]
-    (fields-from characteristic :Name :Description :DataType :Unit :Value)))
+(defn- parse-short-name-long-name
+  [doc path]
+  (seq (for [elem (select doc path)]
+      {:ShortName (value-of elem "Short_Name")
+       :LongName (value-of elem "Long_Name")})))

 (defn- parse-instruments
   [doc]
-    (for [inst (select doc "/SERF/Sensor_Name")]
-      {:ShortName (value-of inst "Short_Name")
-       :LongName (value-of inst "Long_Name")
-       }))
+    (parse-short-name-long-name doc "/SERF/Sensor_Name"))
+
+(defn- parse-just-platforms
+  "Parses a doc for a SERF representation of platforms only."
+  [doc]
+  (parse-short-name-long-name doc "/SERF/Source_Name"))
+
+(defn- parse-platforms
+  [doc]
+  (let [platforms (parse-just-platforms doc)
+        instruments (parse-instruments doc)]
+    (if (= 1 (count platforms))
+      (map #(assoc % :Instruments instruments) platforms)
+      (if instruments
+        (conj platforms {:ShortName not-provided
+                         :LongName not-provided
+                         :Instruments instruments})
+        platforms))))

 (defn- parse-projects
   [doc]
@@ -41,28 +56,7 @@
               {:Type date-type
                :Date (date/not-default (value-of md-dates-el tag))}))))

-(defn- parse-platform
-  "Returns a platform parsed from a SERF Source_Name element"
-  [platform]
-  {:ShortName (value-of platform "Short_Name")
-   :LongName (value-of platform "Long_Name")})
-
-(defn- parse-platforms
-  [doc]
-  (let [platforms (select doc "/SERF/Source_Name")
-                    not-provided "Not provided"
-                    instruments (parse-instruments doc)]
-       (if (= 1 (count platforms))
-         [(assoc (parse-platform (first platforms)) :Instruments instruments)]
-         (concat (map parse-platform platforms)
-                 (when (seq instruments)
-                   [{:ShortName not-provided
-                   :LongName not-provided
-                   :Type not-provided
-                   :Characteristics not-provided
-                   :Instruments instruments }])))))
-
-(defn- parse_responsibilities
+(defn- parse-responsibilities
   [doc]
   (let [personnel (select doc "/SERF/Personnel")]))


CMR-2318: Added docstring

CMR-2318: Added docstring

--- umm-spec-lib/test/cmr/umm_spec/test/generate_and_parse.clj
+++ umm-spec-lib/test/cmr/umm_spec/test/generate_and_parse.clj
@@ -17,7 +17,8 @@
             [cmr.umm-spec.iso19115-2-util :as iu]
             [cmr.umm-spec.umm-to-xml-mappings.echo10 :as echo10]
             [cmr.common.util :refer [are2]]
-            [cmr.umm-spec.test.umm-generators :as umm-gen]))
+            [cmr.umm-spec.test.umm-generators :as umm-gen]
+            [cmr.umm-spec.json-schema :as js]))

 (def tested-formats
   "Seq of formats to use in round-trip conversion and XML validation tests."
@@ -66,8 +67,12 @@
   (core/validate-xml :collection format
                      (core/generate-metadata :collection format record)))

-(def minimal-umm-c (cmr.umm-spec.json-schema/parse-umm-c {:ShortName "foo"
-                                                          :Version "bar"}))
+(def minimal-umm-c
+  "UMM-C with the bare minimum number of fields. It does not include all required fields because
+  there is existing data in the system which does not contain all of the required UMM-C fields. We
+  are testing that even without all the required UMM-C fields, we still produce valid XML in each
+  of the formats."
+  (js/parse-umm-c {:ShortName "foo" :Version "bar"}))

 (deftest minimal-dif10
   (is (empty? (generate-and-validate-xml :dif10 minimal-umm-c))))


Writes can block the thread from coming down, too.

--- src/onyx/log/zookeeper.clj
+++ src/onyx/log/zookeeper.clj
@@ -1,5 +1,5 @@
 (ns onyx.log.zookeeper
-  (:require [clojure.core.async :refer [chan >!! <!! close! thread alts!!]]
+  (:require [clojure.core.async :refer [chan >!! <!! close! thread alts!! offer!]]
             [com.stuartsierra.component :as component]
             [taoensso.timbre :refer [fatal warn info trace]]
             [onyx.log.curator :as zk]
@@ -265,11 +265,11 @@
                (seek-and-put-entry! log position ch)
                (loop []
                  (let [read-ch (chan 2)]
-                   (zk/children conn (log-path prefix) :watcher (fn [_] (>!! read-ch true)))
+                   (zk/children conn (log-path prefix) :watcher (fn [_] (offer! read-ch true)))
                    ;; Log entry may have been added in between initial check and when we
                    ;; added the watch.
                    (when (zk/exists conn path)
-                     (>!! read-ch true))
+                     (offer! read-ch true))
                    (let [[_ active-ch] (alts!! [read-ch kill-ch])]
                      (when (= active-ch read-ch)
                        (close! read-ch)


Use assert rather than rolling own exception throwing

--- src/overtone/sc/buffer.clj
+++ src/overtone/sc/buffer.clj
@@ -5,7 +5,7 @@
         [overtone.sc.machinery allocator]
         [overtone.sc.machinery.server connection comms native]
         [overtone.sc server info]
-        [overtone.helpers audio-file lib file]
+        [overtone.helpers audio-file lib file doc]
         [overtone.sc.util :only [id-mapper]]))

 (defn- emit-inactive-buffer-modification-error
@@ -242,10 +242,11 @@
   ([buf start-idx data]
      (ensure-buffer-active! buf)
      (assert (buffer? buf))
-     (when (> (count data) MAX-OSC-SAMPLES)
-       (throw (Exception. (str "Error - the data you attempted to write to the buffer was too large to be sent via UDP."))))
-     (let [data (if (number? data) [data] data)
-           size (count data)
+     (assert (<= (count data) MAX-OSC-SAMPLES)
+             (fs "Error - the data you attempted to write to the buffer was
+                  too large to be sent via UDP."))
+     (let [data    (if (number? data) [data] data)
+           size    (count data)
            doubles (map double data)]
        (if (> (+ start-idx size) (:size buf))
          (throw (Exception. (str "the data you attempted to write to buffer " (:id buf) "was too large for its capacity. Use a smaller data list and/or a lower start index.")))


Log pod identifiers with pod state updates (#692)

--- waiter/src/waiter/scheduler/kubernetes.clj
+++ waiter/src/waiter/scheduler/kubernetes.clj
@@ -122,6 +122,11 @@
   [k8s-obj]
   (get-in k8s-obj [:metadata :name]))

+(defn k8s-object->namespace
+  "Get the namespace from a ReplicaSet or Pod's metadata"
+  [k8s-obj]
+  (get-in k8s-obj [:metadata :namespace]))
+
 (defn k8s-object->resource-version
   "Get the resource version from a Kubernetes API response object.
    Valid on ReplicaSets, Pods, and watch-update objects."
@@ -200,7 +205,7 @@
   (try
     (let [port0 (get-in pod [:spec :containers 0 :ports 0 :containerPort])
           restart-count (get-in pod [:status :containerStatuses 0 :restartCount])
-          namespace (get-in pod [:metadata :namespace])]
+          namespace (k8s-object->namespace pod)]
       (scheduler/make-ServiceInstance
         {:extra-ports (->> (get-in pod [:metadata :annotations :waiter/port-count])
                            Integer/parseInt range next (mapv #(+ port0 %)))
@@ -908,8 +913,10 @@
                                   (assoc-in state [:pods-metadata :timestamp :watch] now)
                                   (assoc-in state [:pods-metadata :version :watch] version)))
                         (let [old-pod (get-in old-state [:service-id->pod-id->pod service-id pod-id])
-                              [pod-fields pod-fields'] (data/diff old-pod pod)]
-                          (scheduler/log "pod state update:" update-type version pod-fields "->" pod-fields')))))}
+                              [pod-fields pod-fields'] (data/diff old-pod pod)
+                              pod-ns (k8s-object->namespace pod)
+                              pod-handle (str pod-ns "/" pod-id)]
+                          (scheduler/log "pod state update:" update-type pod-handle version pod-fields "->" pod-fields')))))}
       (merge options))))

 (defn global-rs-state-query


Added mod-out to select-consensus-comments

--- src/polismath/clusters.clj
+++ src/polismath/clusters.clj
@@ -574,13 +574,14 @@

 (defn select-consensus-comments
-  [cons-stats]
-  (let [stats (map
-                (fn [stat]
-                  (assoc stat
-                         :dm (* (:pd stat) (:pdt stat))
-                         :am (* (:pa stat) (:pat stat))))
-                cons-stats)
+  [cons-stats & [mod-out]]
+  (let [stats (->> cons-stats
+                   (remove (comp (set mod-out) :tid))
+                   (map
+                     (fn [stat]
+                       (assoc stat
+                              :dm (* (:pd stat) (:pdt stat))
+                              :am (* (:pa stat) (:pat stat))))))
         format-stat
               (fn [cons-for stat]
                 (let [[n-success p-success p-test] (if (= cons-for :agree)


Fix database environment name

Fix database environment name

--- src/storemi/models/db.clj
+++ src/storemi/models/db.clj
@@ -13,7 +13,7 @@
     (catch java.io.FileNotFoundException e )))

 (def db
-  (or (System/getenv "PORT")
+  (or (System/getenv "DATABASE_URL")
       (merge
         {:subprotocol "postgresql"
          :subname "//127.0.0.1:5432/demitalesdb"}


Fix bootnodes toggle

Fix bootnodes toggle

Signed-off-by: yenda <96f164ad4d9b2b0dacf8ebee2bb1eeb3aa69adf1@status.im>

--- src/status_im/subs.cljs
+++ src/status_im/subs.cljs
@@ -800,14 +800,14 @@
  :settings/bootnodes-enabled
  :<- [:multiaccount]
  :<- [:networks/current-network]
- (fn [{:keys [settings]} current-network]
+ (fn [[{:keys [settings]} current-network]]
    (get-in settings [:bootnodes current-network])))

 (re-frame/reg-sub
  :settings/network-bootnodes
  :<- [:multiaccount]
  :<- [:networks/current-network]
- (fn [multiaccount current-network]
+ (fn [[multiaccount current-network]]
    (get-in multiaccount [:bootnodes current-network])))

 (re-frame/reg-sub


Add 404 helper

Add 404 helper

--- src/time_tracker/util.clj
+++ src/time_tracker/util.clj
@@ -14,6 +14,9 @@

 (def disallowed-method-response
   (error-response 405 "Method not allowed"))
+
+(def not-found-response
+  (error-response 404 "Not found"))

 (defn snake-case->hyphenated-kw
   "In: \"key_string\"


Fix #42

Fix #42

--- src/re_frame/handlers.cljs
+++ src/re_frame/handlers.cljs
@@ -52,6 +52,9 @@

 ;; -- lookup and call -----------------------------------------------------------------------------

+(def ^:dynamic *handling* nil)    ;; remember what event we are currently handling
+
+
 (defn handle
   "Given an event vector, look up the handler, then call it.
   By default, handlers are not assumed to be pure. They are called with
@@ -65,5 +68,8 @@
         handler-fn  (lookup-handler event-id)]
     (if (nil? handler-fn)
       (warn "re-frame: no event handler registered for: \"" event-id "\". Ignoring.")   ;; TODO: make exception
-      (handler-fn app-db event-v))))
+      (if  *handling*
+        (warn "re-frame: in the middle of handling \""  *handling*  "\"  tried to handle \"" event-v "\"")
+        (binding [*handling*  event-v]
+          (handler-fn app-db event-v))))))


CMR-3050: Remove commented out code.

CMR-3050: Remove commented out code.

--- metadata-db-app/src/migrations/046_add_primary_key_to_providers.clj
+++ metadata-db-app/src/migrations/046_add_primary_key_to_providers.clj
@@ -8,10 +8,6 @@
   (println "migrations.046-add-primary-key-to-providers up...")
   (h/sql "alter table providers drop constraint unique_provider_id")
   (h/sql "alter table providers add constraint providers_pk primary key (provider_id)"))
-  ; (h/sql (str "alter table sync_delete_work add constraint sync_delete_work_pk "
-  ;             "primary key (concept_id, revision_id)")))
-  ; (h/sql (str "alter table get_concepts_work_area add constraint get_concepts_work_area_pk "
-              ; "primary key (concept_id, revision_id)")))

 (defn down
   "Migrates the database down from version 46."
@@ -20,5 +16,3 @@
   (h/sql "alter table providers drop constraint providers_pk")
   (h/sql (str "alter table providers add constraint unique_provider_id unique(provider_id) "
               "using index (create unique index provider_id_index on providers(provider_id))")))
-  ; (h/sql "alter table sync_delete_work drop constraint sync_delete_work_pk")
-  ; (h/sql "alter table get_concepts_work_area drop constraint get_concepts_work_area_pk"))


Update to Clojure 1.7.0-beta3

Update to Clojure 1.7.0-beta3

--- ClojureScript/project.clj
+++ ClojureScript/project.clj
@@ -1,6 +1,6 @@
 (defproject bocko-ios "0.2.0"
   :description "Use Bocko on iOS"
-  :dependencies [[org.clojure/clojure "1.7.0-beta2"]
+  :dependencies [[org.clojure/clojure "1.7.0-beta3"]
                  [org.clojure/clojurescript "0.0-3269"]
                  [org.clojure/core.async "0.1.346.0-17112a-alpha"]
                  [bocko "0.3.0"]


Fixed issue #56

Fixed issue #56

--- src/clojure/alfresco_technical_validation/impl/validations/stb.clj
+++ src/clojure/alfresco_technical_validation/impl/validations/stb.clj
@@ -298,7 +298,7 @@
                         RETURN n.name AS ClassName, COLLECT(DISTINCT m.name) AS APIs
                          ORDER BY n.name
                        ")]
-    (standard-binary-validation "STB13" res true "The technology does not use common HTTP RPC client libraries." #(when (empty? %) true))))
+    (standard-binary-validation "STB13" res true "The technology does not use common HTTP RPC client libraries." (constantly nil))))

 (defn- stb14
   [indexes]


updated parser to handle multiple closing tags

--- src/selmer/test_parser.clj
+++ src/selmer/test_parser.clj
@@ -31,12 +31,12 @@
     (if-not (== -1 ch) (char ch))))

 (defn for-handler [[id _ items] rdr]
-  (let [content (tag-content :endfor rdr)
+  (let [content (:endfor (tag-content rdr :endfor))
         id (map keyword (.split id "\\."))
         items (keyword items)]
     (fn [args]
       (let [buf (StringBuilder.)]
-        (doseq [value (get args items)]
+        (doseq [value (get args items)]
           (.append buf (render content (assoc-in args id value))))
         (.toString buf)))))

@@ -44,7 +44,7 @@
   {:for {:handler for-handler}
    :block {:handler
            (fn [args rdr]
-             (let [content (tag-content :endblock rdr)]
+             (let [content (tag-content rdr :endblock)]
                (fn [args] (render content args))))}})

 (defn expr-tag [{:keys [tag-name args] :as tag} rdr]
@@ -52,7 +52,7 @@
     (handler args rdr)
     (throw (Exception. (str "unrecognized tag: " tag-name)))))

-(defn filter-tag [{:keys [tag-value]}]
+(defn filter-tag [{:keys [tag-value]}]
   (let [value (map keyword (.split tag-value "\\."))]
     (fn [args] (get-in args value))))

@@ -68,8 +68,8 @@
            ch2 (read-char rdr)]
       (when-not (and (or (= filter-close ch1) (= tag-second ch1))
                      (= tag-close ch2))
-        (.append buf ch1)
-        (recur ch2 (read-char rdr))))
+        (.append buf ch1)
+        (recur ch2 (read-char rdr))))
     (let [content (->>  (.split (.toString buf ) " ") (remove empty?) (map (memfn trim)))]
       (merge {:tag-type tag-type}
              (if (= :filter tag-type)
@@ -81,37 +81,48 @@
 ;{:args ("i" "in" "nums"), :tag-name "for", :tag-type :expr}

 #_(read-tag-info (java.io.StringReader. "{ nums }}"))
-;{:tag-value "nums", :tag-type :value}

-(defn tag-content [end-tag rdr]
-  (let [content (transient [])
-        buf (StringBuilder.)]
-    (loop [ch (read-char rdr)]
-      (if (= tag-open ch)
-        (let [{:keys [tag-name tag-type] :as tag} (read-tag-info rdr)]
-          (when (not= end-tag tag-name)
-            (conj! content (.toString buf))
-            (.setLength buf 0)
-            (conj! content (if (= :filter tag-type)
-                             (filter-tag tag)
-                             (expr-tag tag rdr)))
-            (recur (read-char rdr))))
+(defn parse-tag [{:keys [tag-type] :as tag} rdr]
+  (if (= :filter tag-type)
+    (filter-tag tag)
+    (expr-tag tag rdr)))
+
+(defn tag-content [rdr & end-tags]
+  (let [buf (StringBuilder.)]
+    (loop [ch       (read-char rdr)
+           tags     {}
+           content  []
+           end-tags end-tags]
+      (cond
+        (empty? end-tags)
+        tags
+
+        (= tag-open ch)
+        (let [{:keys [tag-name tag-type] :as tag} (read-tag-info rdr)]
+          (if (some #{tag-name} end-tags)
+            (let [tags     (assoc tags tag-name (conj content (.toString buf)))
+                  end-tags (rest (drop-while #(not= tag-name %) end-tags))]
+              (.setLength buf 0)
+              (recur (read-char rdr) tags [] end-tags))
+            (let [content (-> content
+                                  (conj (.toString buf))
+                                  (conj (parse-tag tag rdr)))]
+              (.setLength buf 0)
+              (recur (read-char rdr) tags content end-tags))))
+        :else
         (do
           (.append buf ch)
-          (recur (read-char rdr)))))
-    (conj! content (.toString buf))
-    (persistent! content)))
+          (recur (read-char rdr) tags content end-tags))))))

-#_(tag-content "endfor" (java.io.StringReader. "foo {{name}} bar {% endfor %}"))
+#_(tag-content (java.io.StringReader. "foo bar {%else%} baz{% endif %}") :else :endif)
+#_(tag-content (java.io.StringReader. "foo {{name}} bar  baz {{test}} bat{% endfor %}") :endfor)

-#_(render (tag-content "endfor" (java.io.StringReader. "foo {{name.first}} bar {% endfor %}")) {:name {:first "Bob"}})
+#_(render (tag-content (java.io.StringReader. "foo {{name.first}} bar {% endfor %}") :endfor) {:name {:first "Bob"}})
 ;"foo Bob bar "

 (defn handle-tag [rdr]
   (let [tag (read-tag-info rdr)]
-    (if (= :filter (:tag-type tag))
-      (filter-tag tag)
-      (expr-tag tag rdr))))
+    (parse-tag tag rdr)))

 (defn parse [file]
   (with-open [rdr (clojure.java.io/reader file)]
@@ -122,7 +133,7 @@
             (if (= tag-open ch)
               (do
                 ;we hit a tag so we append the buffer content to the template
-                ; and empty the buffer, then we proceed to parse the tag
+                ; and empty the buffer, then we proceed to parse the tag
                 (conj! template (.toString buf))
                 (.setLength buf 0)
                 (conj! template (handle-tag rdr))


allow action type to be customized when creating batches

--- src/wb_es/bulk/core.clj
+++ src/wb_es/bulk/core.clj
@@ -53,7 +53,7 @@
   (let [url-prefix (if index
                      (format "%s/%s" es-base-url index)
                      es-base-url)]
-    (http/post (format "%s/_bulk?refresh=%s" url-prefix (or refresh "true"))
+    (http/post (format "%s/_bulk?refresh=%s" url-prefix (or refresh "false"))
                {:headers {:content-type "application/x-ndjson"}
                 :body formatted-docs})))

@@ -71,7 +71,8 @@
   "turn a list datomic entity ids to batches of the given size.
   attach some metadata for debugging"
   ([eids] (make-batches 500 nil eids))
-  ([batch-size order-info eids]
+  ([batch-size order-info eids] (make-batches batch-size order-info "index" eids))
+  ([batch-size order-info action eids]
    (->> eids
         (sort-by (fn [param]
                    (if (sequential? param)
@@ -80,6 +81,7 @@
         (partition batch-size batch-size [])
         (map (fn [batch]
                (with-meta batch {:order order-info
+                                 :action action
                                  :size (count batch)
                                  :start (first batch)
                                  :end (last batch)}))))))
@@ -93,7 +95,7 @@
                 (let [[eid & other-params] param]
                   (apply create-document (d/entity db eid) other-params))
                 (create-document (d/entity db param)))))
-       (format-bulk "update")
+       (format-bulk (:action (meta batch)))
        ((fn [formatted-bulk]
           (submit formatted-bulk :index index)))
        )
@@ -316,16 +318,16 @@
                          db)]
             (let [jobs (->> (map (fn [[v g]]
                                    [v gene/->Variation g]) v-g)
-                            (make-batches 1000 :gene->variation))]
+                            (make-batches 1000 :gene->variation "update"))]
               (doseq [job jobs]
                 (>!! scheduler job)))
             (let [jobs (->> (map (fn [[v g]]
                                    [g variation/->Gene v]) v-g)
-                            (make-batches 1000 :variation->gene))]
+                            (make-batches 1000 :variation->gene "update"))]
               (doseq [job jobs]
                 (>!! scheduler job)))
-
             )
+

           ;; close the channel to indicate no more input
           ;; existing jobs on the channel will remain available for consumers


Fix infinite spinner when an org has no repos

Distinguish between no repos and the API call not having returned yet.

This cropped up twice in support today.

--- frontend/components/add_projects.cljs
+++ frontend/components/add_projects.cljs
@@ -182,19 +182,24 @@
          [:div.proj-wrapper
           (if-not (get-in settings [:add-projects :selected-org :login])
             repos-explanation
-            (if-not (seq repos)
-              [:div.loading-spinner common/spinner]
-              [:ul.proj-list
-               (let [filtered-repos (filter (fn [repo]
-                                              (-> repo
-                                                  :name
-                                                  (.toLowerCase)
-                                                  (.indexOf repo-filter-string)
-                                                  (not= -1)))
-                                            repos)]
-                 (map (fn [repo] (om/build repo-item {:repo repo
-                                                      :settings settings}))
-                      filtered-repos))]))
+            (cond
+              (nil? repos)
+                [:div.loading-spinner common/spinner]
+              (not (seq repos))
+                [:ul.proj-list
+                  [:li (str "No repos found for organization " (:selected-org data))]]
+              :else
+                [:ul.proj-list
+                 (let [filtered-repos (filter (fn [repo]
+                                                (-> repo
+                                                    :name
+                                                    (.toLowerCase)
+                                                    (.indexOf repo-filter-string)
+                                                    (not= -1)))
+                                              repos)]
+                   (map (fn [repo] (om/build repo-item {:repo repo
+                                                        :settings settings}))
+                        filtered-repos))]))
           invite-modal])))))

 (defn add-projects [data owner]
@@ -203,8 +208,9 @@
     (render [_]
       (let [user (:current-user data)
             settings (:settings data)
+            selected-org (get-in settings [:add-projects :selected-org :login])
             repo-key (gstring/format "%s.%s"
-                                     (get-in settings [:add-projects :selected-org :login])
+                                     selected-org
                                      (get-in settings [:add-projects :selected-org :type]))
             repos (get-in user [:repos repo-key])]
         (html
@@ -225,5 +231,6 @@

            (om/build main {:user user
                            :repos repos
+                           :selected-org selected-org
                            :settings settings})]
           [:div.sidebar]])))))


Add selected shapes state lense.

Add selected shapes state lense.

--- frontend/uxbox/ui/workspace/base.cljs
+++ frontend/uxbox/ui/workspace/base.cljs
@@ -29,6 +29,10 @@

 (def ^:static workspace-state
   (as-> (l/in [:workspace]) $
+    (l/focus-atom $ s/state)))
+
+(def ^:static selected-state
+  (as-> (l/in [:workspace :selected]) $
     (l/focus-atom $ s/state)))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Dispach db-handling to separate pool & small tuning (#4734)

--- frameworks/Clojure/reitit/src/hello/handler.clj
+++ frameworks/Clojure/reitit/src/hello/handler.clj
@@ -2,6 +2,7 @@
   (:require [immutant.web :as web]
             [hikari-cp.core :as hikari]
             [reitit.ring :as ring]
+            [immutant.web.internal.ring :as immutant]
             [porsas.core :as p]
             [jsonista.core :as j])
   (:gen-class)
@@ -10,8 +11,13 @@

 (defn blocking [handler]
   (fn [req]
-    (.startBlocking ^HttpServerExchange (:server-exchange req))
-    (handler req)))
+    (let [exchange ^HttpServerExchange (:server-exchange req)]
+      (if (.isInIoThread exchange)
+        (.dispatch exchange ^Runnable ^:once (fn []
+                                               (.startBlocking exchange)
+                                               (immutant/write-response exchange (handler req))
+                                               (.endExchange exchange)))
+        (handler req)))))

 (defn random []
   (unchecked-inc (.nextInt (ThreadLocalRandom/current) 10000)))
@@ -41,7 +47,7 @@
 (defn -main [& _]
   (let [ds (hikari/make-datasource
              {:read-only true
-              :maximum-pool-size 64
+              :maximum-pool-size 48
               :pool-name "db-pool"
               :adapter "postgresql"
               :username "benchmarkdbuser"
@@ -57,11 +63,13 @@
            ["/json" json-handler]
            ["/db" (blocking (db-handler ds))]])
         (ring/create-default-handler)
-        {:inject-match? false, :inject-router? false})
+        {:inject-match? false
+         :inject-router? false})
       {:port 8080
        :host "0.0.0.0"
+       :io-threads (* 2 (.availableProcessors (Runtime/getRuntime)))
        :dispatch? false
-       :worker-threads 64
+       :worker-threads 48
        :server {:always-set-keep-alive false}})))

 (comment


Update and use some cool leiningen plugins

--- clojure/profiles.clj
+++ clojure/profiles.clj
@@ -3,4 +3,10 @@
                   [lein-try "0.4.3"]
                   ;; Convert pom.xml to project.clj
                   ;; Note: from https://github.com/thickey/lein-nevam
-                  [lein-nevam "0.1.2"]]}}
+                  [lein-nevam "0.1.2"]
+                  ;; https://github.com/venantius/ultra
+                  [venantius/ultra "0.5.2"]]
+        ;; Experimental
+        :dependencies [[pjstadig/humane-test-output "0.8.3"]]
+        :injections [(require 'pjstadig.humane-test-output)
+                     (pjstadig.humane-test-output/activate!)]}}


mprint working

mprint working

--- src/tenbytenbot/matrix.clj
+++ src/tenbytenbot/matrix.clj
@@ -33,8 +33,11 @@

 (defn mprint [matrix]
   (let [values (get matrix :values) dims (get matrix :dims)]
-    (doseq [x (range (get dims 0)) y (range (get dims 1))]
-      (print (str x "," y "\n")))))
+    (doseq [y (range (get dims 1)) x (range (get dims 0))]
+      (let [v (mget matrix [x y])]
+        (print (if v "1" "0"))
+        (when (= x (- (get dims 0) 1))
+          (print "\n"))))))

-(mprint (mcreate [2 3] []))
+(mprint (mcreate [3 2] (list [0 0] [2 1])))


Version 2.0.0-beta2-SNAPSHOT

Version 2.0.0-beta2-SNAPSHOT

--- template/project.clj
+++ template/project.clj
@@ -1,4 +1,4 @@
-(defproject friboo/lein-template "2.0.0-beta1"
+(defproject friboo/lein-template "2.0.0-beta2-SNAPSHOT"
   :description "Leiningen template for Friboo library"
   :url "https://github.com/zalando/friboo/template"
   :license {:name "Apache License"


add audio tag when there's an audio file

--- iwaswhere-web/src/clj/iwaswhere_web/imports.clj
+++ iwaswhere-web/src/clj/iwaswhere_web/imports.clj
@@ -172,6 +172,14 @@
         (log/info "Trying to import " filename)
         (import-visits-fn (io/reader file) put-fn msg-meta filename)))))

+(defn update-audio-tag
+  [entry]
+  (if (:audio-file entry)
+    (-> entry
+        (update-in [:tags] conj "#audio")
+        (update-in [:md] str " #audio"))
+    entry))
+
 (defn import-text-entries-fn
   [rdr put-fn msg-meta filename]
   (try (let [lines (line-seq rdr)]
@@ -180,6 +188,7 @@
              (let [entry (-> (cc/parse-string line #(keyword (s/replace % "_" "-")))
                              (m/add-tags-mentions)
                              (update-in [:tags] conj "#import")
+                             (update-audio-tag)
                              (update-in [:timestamp] double-ts-to-long))]
                (put-fn (with-meta [:entry/import entry] msg-meta))))))
        (catch Exception ex (log/error (str "Error while importing " filename) ex))))


latest code

latest code

--- throwaway/unity-test-01/Assets/Arcadia/Scripts/hello/hellounity.clj
+++ throwaway/unity-test-01/Assets/Arcadia/Scripts/hello/hellounity.clj
@@ -30,7 +30,7 @@
 (defn reset-world []
 	(Application/LoadLevel Application/loadedLevel))

-(defn do-stuff []
+(comment
 	(reset-world)
 	(set! (.. (object-named "Cube")
 		  (GetComponent hello.hellounity.MoveSomething)


Let server write acks

Let server write acks

--- server/src/inlein/server/server.clj
+++ server/src/inlein/server/server.clj
@@ -33,10 +33,21 @@
 (defn- bencode-write [^BencodeWriter out val]
   (.write out (transform val)))

+(defn- write-ack [^BencodeWriter out msg]
+  (bencode-write out {:type "ack" :op (:op msg)}))
+
+(defn- warn [^BencodeWriter out ^String msg]
+  (bencode-write out {:type "log"
+                      :level "warn"
+                      :timestamp "zero"
+                      :msg msg}))
+
 (defmulti handle-request (fn [operation in out] (:op operation)))

 (defmethod handle-request "ping" [op in out]
-  (bencode-write out {:ret "PONG"}))
+  (bencode-write out {:type "response"
+                      :returns "ping"
+                      :msg "PONG"}))

 (defmethod handle-request :default [operation in out]
   (println "unknown op!")
@@ -51,6 +62,7 @@
     (when-not (.. client-sock getInetAddress isSiteLocalAddress)
       (let [first-op (bencode-read in)]
         (println "first op:" first-op)
+        (write-ack out first-op)
         (handle-request first-op in out)))))

 (defn run-server [server-socket]


Config: add index function.

Config: add index function.

--- reimann/src/reimann/config.clj
+++ reimann/src/reimann/config.clj
@@ -1,6 +1,7 @@
 (ns reimann.config
   (:require [reimann.core])
   (:require [reimann.server])
+  (:require reimann.index)
   (:use reimann.client)
   (:use reimann.streams)
   (:use reimann.email)
@@ -21,6 +22,11 @@
   (dosync
     (alter (core :streams) concat things)))

+; Create an index
+(defn index [& opts]
+  (dosync
+    (ref-set (core :index) (apply reimann.index/index opts))))
+
 ; Start the core
 (defn start []
   (reimann.core/start core))


Made tag cloud item sorting case insensitive.

--- lambda-blog/src/lambda_blog/templates/tags.clj
+++ lambda-blog/src/lambda_blog/templates/tags.clj
@@ -1,5 +1,6 @@
 (ns lambda-blog.templates.tags
-  (:require [lambda-blog.templates.bits :refer [panel text-centered]]
+  (:require [clojure.string :refer [lower-case]]
+            [lambda-blog.templates.bits :refer [panel text-centered]]
             [lambda-blog.templates.page :refer [page]]
             [lambda-blog.utils :refer [pathcat]]
             [s-html.tags.html :refer [a h1 li span ul]]))
@@ -33,7 +34,7 @@
                                                         (/ c total)))))}
                              (:id t))
                        " ")))
-              (sort-by (comp :id first)
+              (sort-by (comp lower-case str :id first)
                        counts))))))

 (defn tags-index


Fix the tag-modification test.

Fix the tag-modification test.

--- test/shale/test/client.clj
+++ test/shale/test/client.clj
@@ -92,11 +92,14 @@

 (deftest ^:integration test-tag-modification
   (testing "setting tags"
-    (let [session (first (shale.client/sessions))
-          id (:id session)]
-      (shale.client/modify-session! id {:tags ["test-tag"]})
-      (is (= "test-tag" (-> (shale.client/session id)
-                            :tags
+    (let [test-fn (fn []
+                    (let [session (first (shale.client/sessions))
+                          id (get session "id")]
+                      (shale.client/modify-session! id {:tags ["test-tag"]})
+                      id))]
+      (is (= "test-tag" (-> (logged-in-sessions-fixture test-fn)
+                            shale.client/session
+                            (get "tags")
                             first))))))

 (deftest ^:integration test-reservations


(maint) realign comment in java service example

--- examples/java_service/src/clj/java_service_example/java_service.clj
+++ examples/java_service/src/clj/java_service_example/java_service.clj
@@ -10,7 +10,7 @@
 (defservice java-service
   JavaService
   []
-            ;; Service functions are implemented in a java `ServiceImpl` class
+  ;; Service functions are implemented in a java `ServiceImpl` class
   (msg-fn [this] (ServiceImpl/getMessage))
   (meaning-of-life-fn [this] (ServiceImpl/getMeaningOfLife)))


Delete core_test.clj

Delete core_test.clj

--- test/mailer/core_test.clj
+++ test/mailer/core_test.clj
@@ -1,7 +0,0 @@
-(ns mailer.core-test
-  (:require [clojure.test :refer :all]
-            [mailer.core :refer :all]))
-
-(deftest a-test
-  (testing "FIXME, I fail."
-    (is (= 0 1))))


fix db option.

fix db option.

--- test/metabase/test_db.clj
+++ test/metabase/test_db.clj
@@ -6,7 +6,7 @@

 (def testdb-jdbc {:subprotocol "h2"
-                  :subname (str db-file ";DATABASE_TO_UPPER=FALSE")})
+                  :subname (str db-file)})

 ; create a simple sample table


Pass env through to config-map inside main

--- resources/leiningen/new/jcf/src/jcf/main.clj
+++ resources/leiningen/new/jcf/src/jcf/main.clj
@@ -1,12 +1,14 @@
 (ns {{ns}}.main
   (:gen-class)
   (:require [com.stuartsierra.component :as component]
+            [environ.core :refer [env]]
             [{{ns}}.config :as config]))

 (defn new-system [config]
   (component/system-map :config-options config))

 (defn -main []
-  (-> config/config-map
+  (-> env
+      config/config-map
       new-system
       component/start-system))


Upgrade some dependencies.

Upgrade some dependencies.

--- project.clj
+++ project.clj
@@ -12,9 +12,9 @@
   :pedantic? :abort

   :dependencies
-  [[org.clojure/clojure "1.10.0"]
+  [[org.clojure/clojure "1.10.1"]
    [org.clojure/data.priority-map "0.0.10"]
-   [org.clojure/tools.logging "0.4.1"]
+   [org.clojure/tools.logging "0.5.0"]
    [byte-streams "0.2.4"]
    [com.stuartsierra/component "0.4.0"]
    [commons-io "2.6"]
@@ -52,7 +52,7 @@
     :dependencies
     [[org.clojure/test.check "0.9.0"]
      [commons-logging "1.2"]
-     [mvxcvi/puget "1.1.0"]
+     [mvxcvi/puget "1.1.2"]
      [mvxcvi/test.carly "0.4.1"]]}

    :repl
@@ -62,7 +62,8 @@
    {:jvm-opts ["-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog"]}

    :coverage
-   {:plugins [[org.clojure/clojure "1.10.0"]
-              [lein-cloverage "1.0.13"]]
+   {:plugins
+    [[org.clojure/clojure "1.10.1"]
+     [lein-cloverage "1.0.13"]]
     :jvm-opts ["-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog"
                "-Dorg.apache.commons.logging.simplelog.defaultlog=trace"]}})


figwheel 0.5.13

figwheel 0.5.13


Back to dev version

Back to dev version

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject clojurewerkz/cassaforte "1.2.1-SNAPSHOT"
+(defproject clojurewerkz/cassaforte "1.3.0-SNAPSHOT"
   :min-lein-version "2.0.0"
   :description "A Clojure client for Apache Cassandra"
   :url "http://clojurecassandra.info"


Prepare for next release cycle.

Prepare for next release cycle.

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject onyx-cheat-sheet "0.12.2.0"
+(defproject onyx-cheat-sheet "0.12.2.1-SNAPSHOT"
   :description "Cheat sheet for Onyx"
   :url "https://github.com/onyx-platform/onyx-cheat-sheet"
   :license {:name "Eclipse Public License"


(maint) Update version to 6.22.1-SNAPSHOT

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(def pdb-version "6.22.0")
+(def pdb-version "6.22.1-SNAPSHOT")

 (def clj-parent-version "4.11.1")


Version 0.1.6

Version 0.1.6

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject corpus-enormous "0.1.6-SNAPSHOT"
+(defproject corpus-enormous "0.1.6"
   :description "Randomized Data Set Generator"
   :url "https://github.com/kyleburton/corpus-enormous"
   :license {:name "Eclipse Public License"


Version 1.3.5-SNAPSHOT

Version 1.3.5-SNAPSHOT


Upgrade deps.

Upgrade deps.


Update lib-noir 0.7.9 -> 0.9.4

Update lib-noir 0.7.9 -> 0.9.4


Use timbre instead of println in scheduler

--- src/braid/base/server/scheduler.clj
+++ src/braid/base/server/scheduler.clj
@@ -1,7 +1,8 @@
 (ns braid.base.server.scheduler
   (:require
    [clojurewerkz.quartzite.scheduler :as qs]
-   [mount.core :as mount :refer [defstate]]))
+   [mount.core :as mount :refer [defstate]]
+   [taoensso.timbre :as timbre]))

 (defn stop-scheduler!
   [s]
@@ -9,7 +10,7 @@

 (defn start-scheduler!
   []
-  (println "starting quartz scheduler")
+  (timbre/infof "starting quartz scheduler")
   (doto (qs/initialize)
     (qs/start)))


supporting running specific classes

supporting running specific classes

--- src/celestial/puppet_standalone.clj
+++ src/celestial/puppet_standalone.clj
@@ -82,8 +82,12 @@
       )))

-(defmethod pconstruct :puppet-std [{:keys [run-opts] :as type} {:keys [machine env] :as spec}]
-  (let [remote {:host (machine :ip) :user (or (machine :user) "root")}
-        by-env (get-in type [:puppet-std env])
-        with-opts (update-in by-env [:args] (fn [a] (concat a ((or run-opts {}) :args))))]
-    (Standalone. remote (assoc with-opts :hostname (machine :hostname)))))
+(defmethod pconstruct :puppet-std
+  [{:keys [run-opts] :as type :or {run-opts {}}} {:keys [machine env] :as spec}]
+  (let [remote {:host (machine :ip) :user (or (machine :user) "root")}]
+    (Standalone. remote
+      (-> (get-in type [:puppet-std env])
+        (update-in [:args] (fn [a] (concat a (run-opts :args))))
+        (merge (select-keys run-opts [:classes]))
+        (assoc :hostname (machine :hostname))
+        ))))


Forgot what

Forgot what

--- src/clj/forma/hadoop/jobs/forma.clj
+++ src/clj/forma/hadoop/jobs/forma.clj
@@ -154,16 +154,17 @@
 (defn forma-estimate
   "query to end all queries: estimate the probabilities for each
   period after the training period."
-  [beta-src dynamic-src static-src trap-tap]
+  [beta-src dynamic-src static-src trap-tap period]
   (let [betas (log/beta-dict beta-src)]
-      (<- [?s-res ?mod-h ?mod-v ?s ?l ?prob-series]
-          (dynamic-src ?s-res ?pd ?mod-h ?mod-v ?s ?l ?val ?neighbor-val)
-          (static-src ?s-res ?mod-h ?mod-v ?s ?l _ _ ?eco _)
-          (apply-betas [betas] ?eco ?val ?neighbor-val :> ?prob)
-          (log/mk-timeseries ?pd ?prob :> ?prob-series)
-          (= ?pd 827)
-          (:distinct false)
-          (:trap (hfs-seqfile trap-tap)))))
+    (<- [?s-res ?mod-h ?mod-v ?s ?l ?prob-series]
+        (dynamic-src ?s-res ?pd ?mod-h ?mod-v ?s ?l ?val ?neighbor-val)
+        (static-src ?s-res ?mod-h ?mod-v ?s ?l _ _ ?eco _)
+        (apply-betas [betas] ?eco ?val ?neighbor-val :> ?prob)
+        (log/mk-timeseries ?pd ?prob :> ?prob-series)
+        (= ?pd 827)
+        (:distinct false)
+        ;;(:trap (hfs-seqfile trap-tap))
+        )))

 (comment
   (let [m {:est-start "2005-12-31"


fixed issue with card sorting

fixed issue with card sorting

--- src/cljs/netrunner/cardbrowser.cljs
+++ src/cljs/netrunner/cardbrowser.cljs
@@ -143,8 +143,8 @@
                             (filter-cards (:faction-filter state) :faction)
                             (filter-cards (:type-filter state) :type)
                             (match (.toLowerCase (:search-query state)))
-                            (take (* (:page state) 41))
-                            (sort-by (sort-field (:sort-field state))))
+                            (sort-by (sort-field (:sort-field state)))
+                            (take (* (:page state) 41)))
                        {:key :code})]]))))

 (om/root card-browser app-state {:target (. js/document (getElementById "cardbrowser"))})


Replace genome_close_eq with genome_gene_close, and genome_silent_eq with genome_gene_silent

--- src/clojush/instructions/genome.clj
+++ src/clojush/instructions/genome.clj
@@ -618,38 +618,32 @@
       state)))

 (define-registered
-  genome_close_eq
-  ^{:stack-types [:genome :integer :exec :boolean]}
-  (fn [state]
-    (if (and (not (empty? (:integer state)))
-             (not (empty? (:exec state)))
-             (not (empty? (:genome state)))
-             (not (empty? (stack-ref :genome 0 state))))
-      (let [genome (stack-ref :genome 0 state)
-            index (mod (stack-ref :integer 0 state) (count genome))]
-        (->> (pop-item :integer state)
-             (pop-item :exec)
-             (pop-item :genome)
-             (push-item (= (top-item :exec state)
-                           (:close (nth genome index)))
-                        :boolean)))
-      state)))
-
-(define-registered
-  genome_silent_eq
-  ^{:stack-types [:genome :integer :exec :boolean]}
-  (fn [state]
-    (if (and (not (empty? (:integer state)))
-             (not (empty? (:exec state)))
-             (not (empty? (:genome state)))
-             (not (empty? (stack-ref :genome 0 state))))
-      (let [genome (stack-ref :genome 0 state)
-            index (mod (stack-ref :integer 0 state) (count genome))]
-        (->> (pop-item :integer state)
-             (pop-item :exec)
-             (pop-item :genome)
-             (push-item (= (top-item :exec state)
-                           (:silent (nth genome index)))
+  genome_gene_close
+  ^{:stack-types [:genome :integer :boolean]}
+  (fn [state]
+    (if (and (not (empty? (:integer state)))
+             (not (empty? (:genome state)))
+             (not (empty? (stack-ref :genome 0 state))))
+      (let [genome (stack-ref :genome 0 state)
+            index (mod (stack-ref :integer 0 state) (count genome))]
+        (->> (pop-item :integer state)
+             (pop-item :genome)
+             (push-item (:close (nth genome index))
+                        :integer)))
+      state)))
+
+(define-registered
+  genome_gene_silent
+  ^{:stack-types [:genome :integer:boolean]}
+  (fn [state]
+    (if (and (not (empty? (:integer state)))
+             (not (empty? (:genome state)))
+             (not (empty? (stack-ref :genome 0 state))))
+      (let [genome (stack-ref :genome 0 state)
+            index (mod (stack-ref :integer 0 state) (count genome))]
+        (->> (pop-item :integer state)
+             (pop-item :genome)
+             (push-item (:silent (nth genome index))
                         :boolean)))
       state)))


host header was not removed from proxy

host header was not removed from proxy

--- src/com/ig/swagger/search/proxy.clj
+++ src/com/ig/swagger/search/proxy.clj
@@ -8,7 +8,7 @@
 (defn- build-request [{:keys [request-method headers body]} endpoint]
   (let [proxy-request {:url     endpoint
                        :method  request-method
-                       :headers (dissoc headers ["host" "connection"])}]
+                       :headers (dissoc headers "host" "connection")}]
     (if (#{:get :head} request-method)
       proxy-request
       (assoc proxy-request


Started creating association functions for context widget and variable association.

--- src/conexp/gui/editors/contexts.clj
+++ src/conexp/gui/editors/contexts.clj
@@ -19,7 +19,38 @@
     clojure.contrib.swing-utils
     conexp.gui.editors.util
     conexp.fca
-    ))
+    [clojure.contrib.string :only (join split-lines split)]))
+
+;; (ns conexp.gui.editors.contexts)
+
+;;
+;;
+;; Helper functions
+;;
+;;
+;;
+;;
+
+(defn map-to-unique-strings
+  "Takes a sequence of (unique) keys and returns a map
+   that maps each unique key to a unique string
+
+  Parameters:
+   keys    _sequence of (unique) keys"
+  [keys]
+  (loop [ k (set keys)
+          m {}
+          taken #{}
+          nbr 0]
+    (if (empty? k) m
+      (let [ k1 (first k)
+             k1-as-str (if (< 0 nbr)
+                         (join "-" [(str k1) (str nbr)])
+                         (str k1))]
+        (if (contains? taken k1-as-str)
+          (recur k m taken (+ 1 nbr))
+          (recur (disj k k1) (conj m {k1 k1-as-str})
+            (conj taken k1-as-str) 0))))))

 ;;
 ;;
@@ -57,6 +88,25 @@
          :widget root
          :table table
          :control (get-control table)
+         :context (ref nil)
+
+         :associate-context
+         (fn-doc "Associates a context with the widget object and implicitly
+  updates the control
+
+  Parameters:
+    ectx      _editable context"
+           [ectx]
+           (let [ ctx (if (editable-context? ectx) ectx
+                       (make-editable-context ectx))
+                  ctx-ref (@self :context)
+                  old-ctx @ctx-ref]
+             (do
+               (dosync-wait (ref-set ctx-ref nil))
+               (if (not (nil? old-ctx)) (!! old-ctx :remove-widget- @self))
+               (!! ctx :add-widget- @self))
+               (dosync-wait (ref-set ctx-ref ctx))))
+

          }

@@ -98,22 +148,71 @@
    editable context structure.

   Parameters:
-    ctx     _context or editable context"
-  ([ctx]
-    (let [editable-ctx
+    context-in     _context or editable context"
+  ([context-in]
+    (let [ ctx (get-context context-in)
+           obj (objects ctx)
+           attr (attributes ctx)
+           inc (incidence ctx)
+           obj-map (map-to-unique-strings obj)
+           attr-map (map-to-unique-strings attr)
+           compatible-obj (map obj-map obj)
+           compatible-attr (map attr-map attr)
+           compatible-inc  (map (fn [x] [(obj-map (first x))
+                                          (attr-map (second x))]) inc)
+           compatible-ctx (make-context compatible-obj
+                            compatible-attr compatible-inc)
+           attr-range (range 1 (+ 1 (count compatible-attr)))
+           assoc-widgets (ref #{})
+           context (ref compatible-ctx)
+           editable-ctx
            {:editable-context 1
-           :context (ref (get-context ctx))
-           :associated-widgets (ref [])}]
-      editable-ctx))
-  ([]
-    (make-editable-context (make-context [] [] []))))
+           :context context
+           :associated-widgets assoc-widgets
+           :attribute-columns (ref (conj
+                                     (zipmap compatible-attr attr-range)
+                                     (zipmap attr-range compatible-attr)))
+
+           :remove-widget-
+           (fn-doc "Removes a widget from associated widgets.
+  Parameters:
+    widget     _widget to be removed"
+             [widget]
+             (dosync-wait (commute assoc-widgets disj widget)))
+
+           :add-widget-
+           (fn-doc "Adds a widget to associated widgets and updates the control
+  accordingly.
+
+  Parameters:
+    widget    _context-widget to be added"
+             [widget]
+             (do
+               (dosync-wait (commute assoc-widgets conj widget))
+               (let [ table (widget :table)
+                      ctx @context
+                      fca-ctx (get-context ctx)]
+                 (do
+                   (!! table :set-column-count
+                     (+ 1 (count (attributes fca-ctx))))
+                   (!! table :set-row-count
+                     (+ 1 (count (objects fca-ctx))))
+                   ))))
+          }]
+        editable-ctx))
+ ([]
+   (make-editable-context (make-context [] [] []))))

 (def ctx (conexp.fca/make-context ["a" "b" "c"] [1 2 3] [["a" 1] ["c" 3]]))
+(def ectx (make-editable-context ctx))
+(def gui conexp/gui)

 (def context-pane (ref nil))
 (def context-workspace (ref nil))
 (def context-workspace-tree (ref nil))
 (def +debug+ (ref nil))
+(defn +debug-hook+ []
+  (!! @+debug+ :associate-context ectx))

 (defn update-workspace-tree
   "Updates the data displayed in the current workspace tree
@@ -178,10 +277,11 @@
         (do
           (add-tab-with-name-icon-tooltip frame (get-widget pane)
             "Contexts" nil "View and edit contexts")
-          (dosync
+          (dosync-wait
             (ref-set context-workspace-tree workspace-tree)
             (ref-set context-pane pane)
-            (ref-set +debug+ right)) ))) ) )
+            (ref-set +debug+ right))
+          (+debug-hook+)))) ) )

 (defn plug-unload-hook
   "Unloads the context-editor plugin.


Indentation, Nth time is the charm.

Indentation, Nth time is the charm.

--- satellite-slave/src/satellite_slave/core.clj
+++ satellite-slave/src/satellite_slave/core.clj
@@ -178,10 +178,10 @@
                 (fn [_]
                   (try
                     (let [riemann (assoc riemann
-                                     :time (.toSeconds TimeUnit/MILLISECONDS
-                                                       (System/currentTimeMillis))
-                                     :service (str (:service settings)
-                                                   (:service riemann)))
+                                    :time (.toSeconds TimeUnit/MILLISECONDS
+                                                      (System/currentTimeMillis))
+                                    :service (str (:service settings)
+                                                  (:service riemann)))
                           test-output (run-test (dissoc test :schedule))
                           final-event (eventify riemann test-output)]
                       (doseq [client clients]


Finished chapter 02

Finished chapter 02

--- clojure-programming/src/clojure_programming/chp02.clj
+++ clojure-programming/src/clojure_programming/chp02.clj
@@ -141,7 +141,7 @@
   => 10)

 (fact "using a collection a seed alows us to reduce to that type of collection"
-  (reduce
+  (reduce
    (fn [m v]
      (assoc m v (* v v)))
    {}
@@ -157,7 +157,7 @@

 "
 No one would define 'maxOf' of 'toLowercase' type functions that operate over
-entire collections in Clojure. It makes more sense core functions like 'max' or
+entire collections in Clojure. It makes more sense core functions like 'max' or
 'lower-case' and use higher-order functions to apply them to collections.
 "

@@ -216,8 +216,6 @@
     => '(28 80 162)))

-(comp-negated-sum-str 10 12 3.4)
-(comp-negated-sum-str 10 12 3.4)
 [[:section {:title "Composition of Functionality --  page: 68"}]]

 "
@@ -237,17 +235,218 @@
   (comp-negated-sum-str 10 12 3.4)
   => "-25.4")

-" (comp f g h) acts like a pipeline passing arguments from h to g to f
-"
-
+" (comp f g h) acts like a pipeline passing arguments from h to g to f
+
+"
+
+(fact "the resulting type of each function must be compatible with the next function"
+  ((comp + - str) 5 10)
+  => (throws java.lang.ClassCastException))
+
+"Another example:"
+
+(require '[clojure.string :as str])
+
+(def camel->keyword (comp keyword
+                          str/join
+                          (partial interpose \-)
+                          (partial map str/lower-case)
+                          #(str/split % #"(?<=[a-z])(?=[A-Z])")))
+
+(fact (camel->keyword "CamelCase")
+  => :camel-case)
+
+(fact (camel->keyword "lowerCamelCase")
+  => :lower-camel-case)
+
+(def camel-pairs->map (comp (partial apply hash-map)
+                            (partial map-indexed (fn [i x]
+                                                   (if (odd? i)
+                                                     x
+                                                     (camel->keyword x))))))
+
+(fact (camel-pairs->map ["CamelCase" 5 "lowerCamelcase" 3])
+  => {:camel-case 5, :lower-camelcase 3})

 [[:subsection {:title "Writing Higher-Order Functions -- page: 71"}]]
+"
+Functional composition is one way to build abstractions, a more genral way
+is higher-order functions
+"
+(defn adder
+  "produce a function that add a given number to it's result"
+  [n]
+  (fn [x] (+ n x)))
+
+(fact ((adder 5) 18)
+  => 23)
+
+(def add5 (adder 5))
+
+(fact (add5 18)
+  => 23)
+
+(defn doubler
+  "doubles the result of the given function"
+  [f]
+  (fn [& args]
+    (* 2 (apply f args))))
+
+(def double-+ (doubler +))
+
+(fact (double-+ 1 2 3)
+  => 12)

 [[:subsection {:title "Primative Logging System Example -- page: 72"}]]

+"Use something more useful than System.out.println for error logging "
+
+(defn print-logger
+  [writer]
+  #(binding [*out* writer]
+     (println %)))
+
+(def *out*-logger
+  "a logger that prints to standard output"
+  (print-logger *out*))
+
+(fact (*out*-logger "hello")
+  ; hello
+  => nil)
+
+"
+Logging to a memory buffer:"
+
+(def writer
+  "a memory buffer"
+  (java.io.StringWriter. ))
+
+(def retained-logger
+  "a logger that logs to a defined memory buffer"
+  (print-logger writer))
+
+(facts
+  (fact (retained-logger "hello") => nil)
+  (fact (str writer)
+    => #"hello\n"))   ;test for only one "hello\n"
+
+"
+logging to a file:"
+
+(require 'clojure.java.io)
+
+(defn file-logger
+  "a logger that logs to a given file"
+  [file]
+  #(with-open [f (clojure.java.io/writer file :append true)]
+     ((print-logger f) %)))
+
+"
+Let's see how we are doing:"
+
+(def log->file
+  "a file to log to"
+  (file-logger "messages.log"))
+
+(log->file "hello")
+
+"
+Logging to multiple paths:"
+
+(defn multi-logger
+  "chain a series of given loggers"
+  [& logger-fns]
+  #(doseq [f logger-fns]
+     (f %)))
+
+(def log
+  "log to a given log file and standard output"
+  (multi-logger
+   (print-logger *out*)
+   (file-logger "messages.log")))
+
+(log "hello again")
+
+
+"
+Timestamped logger:"
+
+(defn timestamped-logger
+  "creates logger that prepends a timestamp to a log message"
+  [logger]
+  #(logger (format "[%1$tY-%1$tm-%1$te %1$tH:%1$tM:%1$tS] %2$s" (java.util.Date.) %)))
+
+(def log-timestamped (timestamped-logger
+                      (multi-logger
+                       (print-logger *out*)
+                       (file-logger "messages.log"))))
+
+(log-timestamped "goodbye, now")
+
+
 [[:section {:title "Pure Functions --  page: 78"}]]
+"
+Other side of the coin of immutable data. Many errors in programs can be attributed
+to function side effects.
+"
+"
+(defn perform-bank-transfer!
+  [from-account to-account amount]
+  ..fun...)
+"
+"a twitter function"
+
+(require 'clojure.xml)
+
+(defn twitter-followers
+[username]
+(->> (str "https://api.twitter.com/1/users/show.xml?screen_name=" username)
+clojure.xml/parse
+:content
+(filter (comp #{:followers_count} :tag))
+first
+:content
+first
+Integer/parseInt))
+
+;; (twitter-followers "ClojureBook") ;;outdated.
+

 [[:subsection {:title "Why are pure functions Interesting -- page: 78"}]]

-[[:section {:title "Real World --  page: 81"}]]
+"
+Some advantages:
+Pure functions are easier to reason about (same input - same output).
+Pure functions are easier to test (no side effects).
+Pure functions are easier to cache and parallelize (referntially transparent).
+"
+"cache -  memoize:"
+
+(defn prime?
+  [n]
+  (cond
+   (== 1 n) false
+   (== 2 n) true
+   (even? n) false
+   :else (->> (range 3 (inc (Math/sqrt n)) 2)
+              (filter #(zero? (rem n %)))
+              empty?)))
+(comment
+  (time (prime? 1125899906842679))
+  ;; Elapsed time: 13701.7049 msecs
+  ;; => true
+
+  (time (prime? 1125899906842679))
+  ;;"Elapsed time: 14383.205084 msecs"
+  ;; => true
+
+  (let [m-prime? (memoize prime?)]
+    (time (m-prime? 1125899906842679))
+    (time (m-prime? 1125899906842679)))
+  )
+
+(repeatedly 10 (partial rand-int 10))
+"=> (7 2 2 1 6 5 4 0 8 4)"
+(repeatedly 10 (partial (memoize rand-int) 10))
+"=> (7 7 7 7 7 7 7 7 7 7)  ;; oops!"


adjust timeout for jepsen test

adjust timeout for jepsen test

--- jepsen/src/nsq/core.clj
+++ jepsen/src/nsq/core.clj
@@ -200,8 +200,8 @@
 (defn dequeue!
   "Given a channel and an operation, dequeues a value and returns the
   corresponding operation."
-  [rc op]
-  (let [timeout-ch (async/timeout 10000)]
+  [to_ms rc op]
+  (let [timeout-ch (async/timeout to_ms)]
     (alt!!
       timeout-ch (assoc op :type :fail :value :timeout)
       rc ([value] (assoc op :type :ok :value value)))))
@@ -234,14 +234,14 @@
                      (warn e "pub failed")
                      (assoc op :type :fail))))

-      :dequeue (dequeue! receive-ch op)
+      :dequeue (dequeue! 5000 receive-ch op)

       :drain   (do
                  ; Note that this does more dequeues than strictly necessary
                  ; owing to lazy sequence chunking.
                  (->> (repeat op)                  ; Explode drain into
                    (map #(assoc % :f :dequeue)) ; infinite dequeues, then
-                   (map (partial dequeue! receive-ch))  ; dequeue something
+                   (map (partial dequeue! 40000 receive-ch))  ; dequeue something
                    (take-while op/ok?)  ; as long as stuff arrives,
                    (interleave (repeat op))     ; interleave with invokes
                    (drop 1)                     ; except the initial one


simplify assertions

simplify assertions

--- src/hu/ssh/github_changelog/git.clj
+++ src/hu/ssh/github_changelog/git.clj
@@ -3,9 +3,11 @@
     [clj-jgit.porcelain :as git]
     [clj-jgit.util :as util])
   (:import (java.io FileNotFoundException)
-           (org.eclipse.jgit.lib Ref)))
+           (org.eclipse.jgit.lib Ref)
+           (org.eclipse.jgit.api Git)))

-(defn- repo? [x] (instance? org.eclipse.jgit.api.Git x))
+(defn- repo? [x] (instance? Git x))
+(defn- ref? [x] (instance? Ref x))

 (defn- git-path [uri]
   {:pre [(string? uri)]}
@@ -28,12 +30,12 @@
     repo))

 (defn- get-merge-sha [tag]
-  {:pre  (instance? Ref repo)
+  {:pre  (ref? repo)
    :post [(string? %)]}
   (. (if-let [peeled-id (. tag getPeeledObjectId)] peeled-id (. tag getObjectId)) name))

 (defn- map-tag [repo tag]
-  {:pre  (instance? Ref repo)
+  {:pre  (ref? repo)
    :post [(map? %)]}
   (let [peeled (. repo peel tag)]
     {:name (. tag getName) :sha (get-merge-sha peeled)}))


Fix :gen-class directive.

Fix :gen-class directive.

- It seems it had accidentally been wrapped in parens at some point.

--- src/afterglow/core.clj
+++ src/afterglow/core.clj
@@ -3,7 +3,7 @@
             [afterglow.ola-messages :refer [DmxData]]
             [taoensso.timbre :as timbre :refer [info debug]])
   (:import [com.google.protobuf ByteString])
-  (:gen-class))
+  :gen-class)

 (defn -main
   "Test connectivity to the OLA server by sending a few messages and pretty-printing the responses.


Use CIDER nrepl.

Use CIDER nrepl.

--- src/afterglow/core.clj
+++ src/afterglow/core.clj
@@ -9,6 +9,7 @@
     [environ.core :refer [env]]
     [clojure.tools.cli :refer [parse-opts]]
     [clojure.tools.nrepl.server :as nrepl]
+    [cider.nrepl :refer [cider-nrepl-handler]]
     [clojure.java.browse :as browse]
     [selmer.parser :as parser]
     [taoensso.timbre :as timbre]
@@ -117,7 +118,7 @@
   [port]
   (try
     (swap! nrepl-server #(do (when % (nrepl/stop-server %))
-                             (nrepl/start-server :port port)))
+                             (nrepl/start-server :port port :handler cider-nrepl-handler)))
     (timbre/info "nREPL server started on port" port)
     (catch Throwable t
       (timbre/error "failed to start nREPL" t))))


Add auto-binding for generic MIDI devices.

--- src/afterglow/midi.clj
+++ src/afterglow/midi.clj
@@ -914,6 +914,62 @@
       (throw (IllegalArgumentException. (str "No MIDI sources " (describe-name-filter name-filter) "were found."))))
     (swap! aftertouch-mappings #(update-in % [(:device (first result)) (int channel) (int note)] disj f))))

+(defn watch-for
+  "Watches for a device whose name or description matches the string
+  or regex pattern supplied for `name-filter`. If it is present when
+  this function is called, or whenever a matching device is connected
+  in the future (as long as none alread was), `found-fn` will be
+  called, with no arguments. This is useful for setting up MIDI
+  mappings to the device whenever it is present. If the device is
+  disconnected and later reconnected, `found-fn` will be called again,
+  so those bindings can be counted on to be present whenver the device
+  is available.
+
+  If there is any cleanup that you need to perform when the device is
+  disconnected, you can pass the optional keyword argument `:lost-fn`
+  along with a function to be called (also with no arguments) whenever
+  a device reported by `found-fn` has disappeared. You do not need to
+  use `:lost-fn` to clean up MIDI bindings created by `found-fn`,
+  because Afterglow automatically cleans up any MIDI bindings for
+  devices which have been disconnected. But if you have your own data
+  structures or state that you want to update, you can use `:lost-fn`
+  to do that.
+
+  In order to give the newly-attached device time to stabilize before
+  trying to send messages to it, `watch-for` waits for a second after
+  it is seen before calling `found-fn`. If your device needs more (or
+  less) time to stabilize, you can pass a number of milliseconds after
+  the optional keyword argument `:sleep-time` to configure this delay.
+
+  The return value of `watch-for` is a function that you can call to
+  cancel the watcher if you no longer need it."
+  [name-filter found-fn & {:keys [lost-fn sleep-time] :or {sleep-time 1000}}]
+  {:pre [(fn? found-fn) (or (nil? lost-fn) (fn? lost-fn)) (number? sleep-time)]}
+  (let [found (atom false)]
+    (letfn [(disconnection-handler []
+              (when lost-fn (lost-fn))
+              (reset! found false))
+            (connection-handler [device]
+              (when (and (seq (filter-devices [device] name-filter)) (compare-and-set! found false true))
+                (timbre/info "watch-for found" (describe-name-filter name-filter))
+                (future
+                  (Thread/sleep sleep-time)
+                  (found-fn))
+                (add-disconnected-device-handler! device disconnection-handler)))
+            (cancel-handler []
+              (remove-new-device-handler! connection-handler))]
+
+      ;; See if the specified device seems to already be connected, and if so, bind to it right away.
+      (when-let [match (first (filter-devices (concat (open-inputs-if-needed!) (open-outputs-if-needed!))
+                                              name-filter))]
+        (connection-handler match))
+
+      ;; Set up to bind when connected in the future
+      (add-new-device-handler! connection-handler)
+
+      ;; Return the function that will cancel this watcher
+      cancel-handler)))
+
 (defn find-midi-out
   "Find a MIDI output whose name matches the specified string or regex
   pattern."


add support for Class-Path helper jars

add support for Class-Path helper jars

sometimes the classpath is too long on windows and tools use
helper jars with a classpath manifest instead.

--- src/main/shadow/build/classpath.clj
+++ src/main/shadow/build/classpath.clj
@@ -18,7 +18,7 @@
             [shadow.build.npm :as npm]
             [shadow.build.data :as data])
   (:import (java.io File)
-           (java.util.jar JarFile JarEntry)
+           (java.util.jar JarFile JarEntry Attributes$Name)
            (java.net URL)
            (java.util.zip ZipException)
            (shadow.build.closure JsInspector)
@@ -37,12 +37,38 @@
   ;; we can't use java.class.path so its used last
   ;; shadow-cljs-launcher sets shadow.class.path
   ;; boot-clj sets boot.class-path
-  (-> (or (System/getProperty "shadow.class.path")
-          (System/getProperty "boot.class.path")
-          (System/getProperty "java.class.path"))
-      (.split File/pathSeparator)
-      (->> (into [] (map io/file)))
-      ))
+  (let [classpath-entries
+        (-> (or (System/getProperty "shadow.class.path")
+                (System/getProperty "boot.class.path")
+                (System/getProperty "java.class.path"))
+            (.split File/pathSeparator)
+            (->> (into [] (map io/file))))]
+
+    ;; java -cp helper.jar foo.main
+    ;; java supports a single jar with a manifest Class-Path entry to further
+    ;; expand the classpath. sometimes used when the classpath is too long
+    ;; on Windows to be invoked as a command. the original jar will likely be empty
+    (if (not= 1 (count classpath-entries))
+      classpath-entries
+      (let [^File entry (nth classpath-entries 0)]
+        ;; don't think it is even possible to get here
+        ;; with one classpath entry that isn't a jar but who knows
+        (if-not (.endsWith (-> entry (.getName) (.toLowerCase)) ".jar")
+          classpath-entries
+          (let [jar-file (JarFile. entry)
+                manifest (.getManifest jar-file)
+                cp-from-jar
+                (-> (.getMainAttributes manifest)
+                    (.getValue Attributes$Name/CLASS_PATH))]
+            ;; no Class-Path:, might be uberjar?
+            (if-not cp-from-jar
+              classpath-entries
+              (->> (str/split cp-from-jar #"\s")
+                   ;; spec says they must he urls, so assuming file:/...
+                   ;; spec also allows remote urls but unlikely we have that?
+                   ;; FIXME: should likely check just in case
+                   (map (fn [s] (-> (URL. s) (.getPath) (io/file))))
+                   (vec)))))))))

 (defn service? [x]
   (and (map? x) (::service x)))


[#2296] Use integrant env and specs instead of check-env-vars

--- backend/src/akvo/lumen/admin/add_tenant.clj
+++ backend/src/akvo/lumen/admin/add_tenant.clj
@@ -130,22 +130,6 @@
      :auth-type (conform-auth-type auth-type)
      :url url}))

-(defn check-env-vars []
-;;  (assert (:lumen-encryption-key env) (error-msg "Specify LUMEN_ENCRYPTION_KEY env var"))
-;;  (assert (:lumen-keycloak-url env) (error-msg "Specify LUMEN_KEYCLOAK_URL env var"))
-;;  (assert (:lumen-email-user env) (error-msg "Specify LUMEN_EMAIL_USER env var"))
-;;  (assert (:lumen-email-password env) (error-msg "Specify LUMEN_EMAIL_PASSWORD env var"))
-  #_(assert (:lumen-keycloak-client-secret env)
-          (do
-            (browse/browse-url
-             (format "%s/auth/admin/master/console/#/realms/akvo/clients" (:kc-url env)))
-            (error-msg "Specify LUMEN_KEYCLOAK_CLIENT_SECRET env var from the Keycloak admin opened in the browser window at Client (akvo-lumen-confidential) -> Credentials -> Secret.")))
-;;  (assert (:pg-host env) (error-msg "Specify PG_HOST env var"))
-;;  (assert (:pg-database env) (error-msg "Specify PG_DATABASE env var"))
-;; (assert (:pg-user env) (error-msg "Specify PG_USER env var"))
-  #_(when (not (= (:pg-host env) "localhost"))
-    (assert (:pg-password env) (error-msg "Specify PG_PASSWORD env var"))))
-
 (defn exec-mail [{:keys [emailer user-creds tenant-db auth-type url]}]
   (let [{:keys [user-id email tmp-password]} user-creds
         text-part (if (some? tmp-password)
@@ -184,14 +168,12 @@

 (defn -main [url title email auth-type edn-file]
   (try
-    (check-env-vars)
     (admin.system/ig-derives)
-
     (binding [keycloak/http-client-req-defaults (http.client/req-opts 50000)]
       (let [admin-system (admin.system/new-system (admin.system/new-config (or edn-file "prod.edn"))
-                                                  (admin.system/ig-select-keys [:akvo.lumen.admin/add-tenant]))]
-        (exec (:akvo.lumen.admin/add-tenant admin-system)
-              {:url url :title title :email email :auth-type auth-type})))
+                                                  (admin.system/ig-select-keys [:akvo.lumen.admin/add-tenant]))
+            administer (:akvo.lumen.admin/add-tenant admin-system)]
+        (exec administer {:url url :title title :email email :auth-type auth-type})))
     (catch java.lang.AssertionError e
       (prn (.getMessage e)))
     (catch Exception e


Fix UIv2 build parameters tab link

Fix UIv2 build parameters tab link

--- src-cljs/frontend/components/build_head.cljs
+++ src-cljs/frontend/components/build_head.cljs
@@ -1013,7 +1013,7 @@

             (when (seq build-params)
               [tab-tag {:class (when (= :build-parameters selected-tab) "active")}
-               [tab-link-v2 {:href "build-parameters"} "Build Parameters"]])
+               [tab-link-v2 {:href "#build-parameters"} "Build Parameters"]])

             (when (has-scope :read-settings data)
               [tab-tag {:class (when (= :usage-queue selected-tab) "active")}


Add notification for commit details truncation

--- src-cljs/frontend/components/build_head.cljs
+++ src-cljs/frontend/components/build_head.cljs
@@ -960,7 +960,11 @@
               [:div.summary-item
                (build-canceler canceler github-endpoint)]]])
           [:div.card
-           [:div.small-emphasis "Commits (" (-> build :all_commit_details count) ")"]
+           [:div.small-emphasis
+            (let [n (-> build :all_commit_details count)]
+              (if (:all_commit_details_truncated build)
+                (gstring/format "Last %d Commits" n)
+                (gstring/format "Commits (%d)" n)))]
            (om/build build-commits build-data)]
           [:div.build-head-wrapper
            [:div.build-head


Show saved/cleared feedback.

Show saved/cleared feedback.

Was still trying to use old Push text display functions.

--- src/afterglow/controllers/ableton_push_2.clj
+++ src/afterglow/controllers/ableton_push_2.clj
@@ -1931,7 +1931,10 @@
             cur-vals    (cues/snapshot-cue-variables cue (:id info) :show (:show controller))
             saved-vals  (controllers/cue-vars-saved-at (:cue-grid (:show controller)) (:x info) (:y info))
             save-action (when (seq cur-vals)
-                          (if (= cur-vals saved-vals) :clear :save))]
+                          (if (= cur-vals saved-vals) :clear :save))
+            save-color (case save-action
+                         :save  green-color
+                         :clear amber-color)]
         (when save-action
           (case save-action
             :save  (controllers/save-cue-vars! (:cue-grid (:show controller)) (:x info) (:y info) cur-vals)
@@ -1939,13 +1942,11 @@
           (controllers/add-control-held-feedback-overlay (:overlays controller) note
                                                          (fn [_]
                                                            (swap! (:next-top-pads controller) assoc (* 2 x)
-                                                                  (case save-action
-                                                                    :save  green-color
-                                                                    :clear amber-color))
-                                                           (write-display-cell controller 3 x
-                                                                               (case save-action
-                                                                                :save  "  Saved  "
-                                                                                :clear "Cleared  "))
+                                                                  save-color)
+                                                           (draw-bottom-button-label controller (* 2 x)
+                                                                                (case save-action
+                                                                                :save "Saved"
+                                                                                :clear "Cleared") save-color)
                                                            true)))))))

 (defn- handle-end-effect


fix missing paren

fix missing paren

--- src/clj/collect_earth_online/db/projects.clj
+++ src/clj/collect_earth_online/db/projects.clj
@@ -178,7 +178,7 @@
     (p-insert-rows! "samples" samples)
     (if allow-drawn-samples?
       (when (#{"csv" "shp"} sample-distribution)
-        (p-insert-rows! "ext_samples" samples)
+        (p-insert-rows! "ext_samples" samples))
       (when-let [bad-plots (seq (map :visible_id (call-sql "plots_missing_samples" project-id)))]
         (pu/init-throw (str "The uploaded plot and sample files do not have correctly overlapping data. "
                             (count bad-plots)


Generate converted vectors with float values.

--- src/clj/popchange/lib/raster_calculation.clj
+++ src/clj/popchange/lib/raster_calculation.clj
@@ -35,6 +35,8 @@
 (def raster-to-png-script (str working-dir "/raster_to_png.py"))
 (def raster-median-script-src "scripts/raster_median.py")
 (def raster-median-script (str working-dir "/raster_median.py"))
+(def gdal-polygonize-script-src "scripts/gdal_polygonize.py")
+(def gdal-polygonize-script (str working-dir "/gdal_polygonize.py"))

 (def raster-style-template "scripts/raster_style_template.qml")

@@ -48,7 +50,9 @@
     (if-not (.exists (io/as-file raster-to-png-script))
       (spit raster-to-png-script (slurp (io/resource raster-to-png-script-src))))
     (if-not (.exists (io/as-file raster-median-script))
-      (spit raster-median-script (slurp (io/resource raster-median-script-src))))))
+      (spit raster-median-script (slurp (io/resource raster-median-script-src))))
+    (if-not (.exists (io/as-file gdal-polygonize-script))
+      (spit gdal-polygonize-script (slurp (io/resource gdal-polygonize-script-src))))))

 (defn sets
   "Data sets available for generating raster calculations"
@@ -308,6 +312,7 @@
         style-template (slurp (io/resource raster-style-template))
         stops (colour-map-stops tiff)]
     (do
+      (prep-scripts!)
       (spit
        style-filename
        (-> style-template
@@ -323,8 +328,9 @@
         tmpf (partial str wd "/")
         vector-file (str basename vector-file-ext)]
     (do
+      (prep-scripts!)
       @(exec/sh ["mkdir" wd])
-      @(exec/sh ["gdal_polygonize.py" tiff "-f" ogr-format (tmpf vector-file)])
+      (python gdal-polygonize-script tiff "-f" ogr-format "-p" (tmpf vector-file))
       @(exec/sh ["zip" "-r" dst "."] {:dir wd})
       @(exec/sh ["rm" "-Rf" wd]))))


No need to use vector for query-cursor

No need to use vector for query-cursor

--- src/cljs/cglossa/search_inputs/cwb/core.cljs
+++ src/cljs/cglossa/search_inputs/cwb/core.cljs
@@ -220,7 +220,7 @@
              multilingual? (> (count languages) 1)
              set-view      (fn [view e] (reset! search-view view) (.preventDefault e))
              query-get-set (fn
-                             ([k] (get-in @search-queries k))
+                             ([k] (get @search-queries k))
                              ([k v] (let [query (as-> (:query v) $
                                                       (if (get-in @search-queries
                                                                   [k :headword-search])
@@ -232,7 +232,7 @@
                                                                    #"\[\(?word=\"\.\*\"(?:\s+%c)?\)?\]"
                                                                    "[]")
                                                       (str/replace $ #"^\s*\[\]\s*$" ""))]
-                                      (swap! search-queries assoc-in [(first k) :query] query)
+                                      (swap! search-queries assoc-in [k :query] query)
                                       ;; TODO: Handle state.maxHits and state.lastSelectedMaxHits
                                       )))]
          [:span
@@ -270,7 +270,7 @@
                                                     #(vec (concat (subvec % 0 i)
                                                                   (subvec % (inc i))))))]
             (doall (for [index (range nqueries)]
-                     (let [query-cursor       (reagent/cursor query-get-set [index])
+                     (let [query-cursor       (reagent/cursor query-get-set index)
                            selected-language  (-> @query-cursor :query :lang)
                            remove-row-handler (partial remove-query index)]
                        ^{:key index}


Make input stack for penn problem a vector.

--- src/clojush/problems/classification/penn.clj
+++ src/clojush/problems/classification/penn.clj
@@ -67,14 +67,15 @@
       (let [inputs (:inputs fitness-case)
             target (:target fitness-case)
             state (run-push program
-                            (loop [to-push (reverse inputs)
+                            #_(loop [to-push (reverse inputs)
                                    with-inputs (make-push-state)]
                               (if (empty? to-push)
                                 with-inputs
                                 (recur (rest to-push)
                                        (push-item (first to-push)
                                                   :input
-                                                  with-inputs)))))
+                                                  with-inputs))))
+                            (assoc (make-push-state) :input inputs))
             top-string (top-item :string state)]
         (if (string? top-string)
           (if (= top-string target) 0 1)