Fix hard coded idle strategy

Fix hard coded idle strategy

--- src/onyx/messaging/aeron.clj
+++ src/onyx/messaging/aeron.clj
@@ -140,7 +140,7 @@
             (>!! (:retry-ch (get @virtual-peers (:peer-id message)))
                  retry-id)))))

-(defn start-subscriber! [bind-addr port virtual-peers decompress-f]
+(defn start-subscriber! [bind-addr port virtual-peers decompress-f idle-strategy]
   (let [ctx (.errorHandler (Aeron$Context.) no-op-error-handler)
         conn (Aeron/connect ctx)
         channel (aeron-channel bind-addr port)
@@ -150,8 +150,7 @@
                                     buffer offset length header)))

         subscription (.addSubscription conn channel send-stream-id)
-        receive-idle-strategy (backoff-strategy :high-restart-latency)
-        subscriber-fut (future (try (.accept ^Consumer (consumer handler receive-idle-strategy 10) subscription)
+        subscriber-fut (future (try (.accept ^Consumer (consumer handler idle-strategy 10) subscription)
                                     (catch Throwable e (fatal e))))]
     {:conn conn :subscription subscription :subscriber-fut subscriber-fut}))

@@ -197,7 +196,7 @@
           virtual-peers (atom {})
           publications (atom {})
           connections (atom {})
-          subscriber (start-subscriber! bind-addr port virtual-peers decompress-f)]
+          subscriber (start-subscriber! bind-addr port virtual-peers decompress-f receive-idle-strategy)]
       (assoc component
              :bind-addr bind-addr
              :external-addr external-addr


s/diotonic/diatonic/

s/diotonic/diatonic/

--- src/overtone/music/pitch.clj
+++ src/overtone/music/pitch.clj
@@ -106,7 +106,7 @@
               :major-pentatonic (only major [1 2 3 5 6])
               :minor-pentatonic (only minor [1 3 4 5 7])}))

-(def DIOTONIC-MODES
+(def DIATONIC-MODES
   (let [ionian-sequence [2 2 1 2 2 2 1]
         ionian-len (count ionian-sequence)
         rotate-ionian (fn [offset] (drop offset (take (+ ionian-len offset) (cycle ionian-sequence))))]
@@ -120,13 +120,13 @@
      :minor      (rotate-ionian 5)
      :lochrian   (rotate-ionian 6)}))

-(defn nth-diotonic
+(defn nth-diatonic
   "Return the count of semitones for the nth interval from the start of the diatonic scale in the specifiec mode (or ionian/major by default).
      i.e. the ionian/major scale has an interval sequence of 2 2 1 2 2 2 1
           therefore the 4th interval is (+ 2 2 1 2) semitones from the start of the scale."
-  ([n] (nth-diotonic n :ionian))
+  ([n] (nth-diatonic n :ionian))
   ([n mode]
-     (reduce + (take n (cycle (mode DIOTONIC-MODES))))))
+     (reduce + (take n (cycle (mode DIATONIC-MODES))))))

 ;; Various scale intervals in terms of steps on a piano, or midi note numbers
 ;; All sequences should add up to 12 - the number of semitones in an octave


Add type hint

Add type hint

--- src/play_clj/core_render.clj
+++ src/play_clj/core_render.clj
@@ -28,7 +28,7 @@
   (assert renderer)
   (if (isa? (type layer) MapLayer)
     layer
-    (-> renderer .getMap .getLayers (.get layer))))
+    (-> renderer .getMap .getLayers (.get ^String layer))))

 (defn tiled-map-layers
   [{:keys [^BatchTiledMapRenderer renderer]}]


Add tests for :strip and :both

Add tests for :strip and :both

--- test/cljc/reitit/ring_test.cljc
+++ test/cljc/reitit/ring_test.cljc
@@ -240,29 +240,67 @@
           (is (= response (app {:request-method :options, :uri "/any"}))))))))

 (deftest trailing-slash-handler-test
-  (testing "using :method :add"
-    (let [ok {:status 200 :body "ok"}
-          app (ring/ring-handler
-                (ring/router
-                  [["/slash-less" {:get (constantly ok),
-                                   :post (constantly ok)}]
-                   ["/with-slash/" {:get (constantly ok),
-                                    :post (constantly ok)}]])
-                (ring/redirect-trailing-slash-handler {:method :add}))]
-
-      (testing "exact matches work"
-        (is (= ok (app {:request-method :get, :uri "/slash-less"})))
-        (is (= ok (app {:request-method :post, :uri "/slash-less"})))
-        (is (= ok (app {:request-method :get, :uri "/with-slash/"})))
-        (is (= ok (app {:request-method :post, :uri "/with-slash/"}))))
-
-      (testing "adds slashes"
-        (is (= 301 (:status (app {:request-method :get, :uri "/with-slash"}))))
-        (is (= 308 (:status (app {:request-method :post, :uri "/with-slash"})))))
-
-      (testing "does not strip slashes"
-        (is (= nil (app {:request-method :get, :uri "/slash-less/"})))
-        (is (= nil (app {:request-method :post, :uri "/slash-less/"})))))))
+  (let [ok {:status 200, :body "ok"}
+        routes [["/slash-less" {:get (constantly ok),
+                                :post (constantly ok)}]
+                ["/with-slash/" {:get (constantly ok),
+                                 :post (constantly ok)}]]]
+    (testing "using :method :add"
+      (let [app (ring/ring-handler
+                 (ring/router routes)
+                 (ring/redirect-trailing-slash-handler {:method :add}))]
+
+        (testing "exact matches work"
+          (is (= ok (app {:request-method :get, :uri "/slash-less"})))
+          (is (= ok (app {:request-method :post, :uri "/slash-less"})))
+          (is (= ok (app {:request-method :get, :uri "/with-slash/"})))
+          (is (= ok (app {:request-method :post, :uri "/with-slash/"}))))
+
+        (testing "adds slashes"
+          (is (= 301 (:status (app {:request-method :get, :uri "/with-slash"}))))
+          (is (= 308 (:status (app {:request-method :post, :uri "/with-slash"})))))
+
+        (testing "does not strip slashes"
+          (is (= nil (app {:request-method :get, :uri "/slash-less/"})))
+          (is (= nil (app {:request-method :post, :uri "/slash-less/"}))))))
+
+    (testing "using :method :strip"
+      (let [app (ring/ring-handler
+                  (ring/router routes)
+                  (ring/redirect-trailing-slash-handler {:method :strip}))]
+
+        (testing "exact matches work"
+          (is (= ok (app {:request-method :get, :uri "/slash-less"})))
+          (is (= ok (app {:request-method :post, :uri "/slash-less"})))
+          (is (= ok (app {:request-method :get, :uri "/with-slash/"})))
+          (is (= ok (app {:request-method :post, :uri "/with-slash/"}))))
+
+        (testing "does not add slashes"
+          (is (= nil (app {:request-method :get, :uri "/with-slash"})))
+          (is (= nil (app {:request-method :post, :uri "/with-slash"}))))
+
+        (testing "strips slashes"
+          (is (= 301 (:status (app {:request-method :get, :uri "/slash-less/"}))))
+          (is (= 308 (:status (app {:request-method :post, :uri "/slash-less/"})))))))
+
+    (testing "without option (equivalent to using :method :both)"
+      (let [app (ring/ring-handler
+                  (ring/router routes)
+                  (ring/redirect-trailing-slash-handler))]
+
+        (testing "exact matches work"
+          (is (= ok (app {:request-method :get, :uri "/slash-less"})))
+          (is (= ok (app {:request-method :post, :uri "/slash-less"})))
+          (is (= ok (app {:request-method :get, :uri "/with-slash/"})))
+          (is (= ok (app {:request-method :post, :uri "/with-slash/"}))))
+
+        (testing "adds slashes"
+          (is (= 301 (:status (app {:request-method :get, :uri "/with-slash"}))))
+          (is (= 308 (:status (app {:request-method :post, :uri "/with-slash"})))))
+
+        (testing "strips slashes"
+          (is (= 301 (:status (app {:request-method :get, :uri "/slash-less/"}))))
+          (is (= 308 (:status (app {:request-method :post, :uri "/slash-less/"})))))))))

 (deftest async-ring-test
   (let [promise #(let [value (atom ::nil)]


[boot] comment-out everything

[boot] comment-out everything

--- .boot/profile.boot
+++ .boot/profile.boot
@@ -1,8 +1,10 @@
 ;; https://github.com/clojure-vim/vim-cider#using
+#_
 (swap! boot.repl/*default-dependencies*
        concat '[[cider/cider-nrepl "0.20.0"]
                 [refactor-nrepl "2.4.0"]])

+#_
 (swap! boot.repl/*default-middleware* conj
        'cider.nrepl/cider-middleware
        'refactor-nrepl.middleware/wrap-refactor)


Update various leiningen plugins.

Update various leiningen plugins.

--- .lein/profiles.clj
+++ .lein/profiles.clj
@@ -3,23 +3,23 @@
                        [alembic "0.3.2"]
                        [debugger "0.1.7"]
                        [bolth "0.1.0"]
-                       [com.aphyr/prism "0.1.2"]
+                       [com.aphyr/prism "0.1.3"]
                        [slamhound "1.5.5"]]
         :plugins [[lein-difftest "2.0.0"]
-                  [lein-exec "0.3.4"]
+                  [lein-exec "0.3.5"]
                   [com.palletops/lein-shorthand "0.4.0"]
-                  [lein-instant-cheatsheet "2.1.3"]
-                  [lein-ancient "0.5.5"]
-                  [com.aphyr/prism "0.1.2"]
+                  [lein-instant-cheatsheet "2.1.4"]
+                  [lein-ancient "0.6.7"]
+                  [com.aphyr/prism "0.1.3"]
                   [org.bodil/lein-noderepl "0.1.11"]
-                  [quickie "0.3.6"]
-                  [lein-kibit "0.0.8"]
-                  [jonase/eastwood "0.2.0"]
+                  [quickie "0.4.0"]
+                  [lein-kibit "0.1.2"]
+                  [jonase/eastwood "0.2.1"]
                   [lein-clojars "0.9.1"]
                   [lein-pprint "1.1.2"]
-                  [lein-ring "0.8.13"]
-                  [lein-cljsbuild "1.0.6"]
-                  [mvxcvi/whidbey "0.4.1"]
+                  [lein-ring "0.9.7"]
+                  [lein-cljsbuild "1.1.0"]
+                  [mvxcvi/whidbey "1.0.0"]
                   [lein-typed "0.3.5"]
                   [lein-marginalia "0.8.0"]]
         ; printing options are customizable:


Remove large-cookie

Remove large-cookie

Remove large-cookie from common.clj, as it was no longer
being used.

--- test/clj/puppetlabs/trapperkeeper/testutils/webserver/common.clj
+++ test/clj/puppetlabs/trapperkeeper/testutils/webserver/common.clj
@@ -50,58 +50,5 @@
    :ssl-ca-cert "./dev-resources/config/jetty/ssl/certs/ca.pem"
    :as :text})

-(def large-cookie
-  (str
-    "puppet_enterprise_console=BAh7DEkiD3Nlc3Npb25faWQGOgZFRiJFMWZjMjVjMzk2NzM5MW"
-    "ZmZDQ3NDEx%0AYzE2ZDNjNWQ5OTlmNWExYTVjOGU5NzA2OGQ0OWZhMDdjZWMwYzY3NzI5NUki%0AH"
-    "kNPTlNPTEVfQVVUSF9BQ0NPVU5UX05BTUUGOwBGSSIbbGluZHNleUBwdXBw%0AZXRsYWJzLmNvbQY"
-    "7AFRJIh5DT05TT0xFX0FVVEhfQUNDT1VOVF9ST0xFBjsA%0ARkkiD3JlYWQtd3JpdGUGOwBUSSIfQ"
-    "09OU09MRV9BVVRIX0FVVEhFTlRJQ0FU%0AT1IGOwBGSSILZ29vZ2xlBjsAVEkiGEFDQ0VTU19DT05"
-    "UUk9MX1JPTEUGOwBG%0ASSIOUkVBRF9PTkxZBjsARkkiD2NzcmYudG9rZW4GOwBGSSIxaDBMSkUwM"
-    "S9r%0AZXFUWThjVXVzSXRNTzFPUDNKell3bmRCZ2pjUXVZQWJxVT0GOwBGSSIQX2Nz%0AcmZfdG9r"
-    "ZW4GOwBGSSIxZnl2Sm5scUxEQkhKVDlWelR2NnlMTmkyM3JtWWpj%0AdjdNYm9YR2dsdW9mTT0GOw"
-    "BG%0A--15b097175979539c53f06ca7caf018cfabecaef9; rack.session=BAh7B0kiD3Nlc3N"
-    "pb25faWQGOgZFRiJFMDk2ZTJiZmY1MzllYzI4MDM4ZjYw%0AOTFlNTAzYmViYjE4ODk1ZTUzNjFmM"
-    "2U5ZWNjZGNjNGFhM2JiYTI0NWI3N0ki%0AD2NzcmYudG9rZW4GOwBGSSIxVXFxMk0zVE1EYXBJMHY"
-    "5eWhpOHJ4TVdVYjM5%0AeWxWVVVvbEhZelk5cHdIND0GOwBG%0A; _session_id=BAh7DEkiD3Nl"
-    "c3Npb25faWQGOgZFRkkiJTk1NmUxYzdjNGZhMjJhZGY0N2ZkMDBhYjYxYjBkYzRkBjsAVEkiD2Nzc"
-    "mYudG9rZW4GOwBGSSIxRFlYdktwVjdDSVBXclZWbW1ja2toVnpYT1ZEeU1Ic0UrNFo5SCtHM0V3az"
-    "0GOwBGSSIQX2NzcmZfdG9rZW4GOwBGSSIxZUY4bWdzcmtyeTlRekViK2kvOTdxVkNOdjdTK3UwZlh"
-    "JMjhxRGZYdXJyST0GOwBGSSIeQ09OU09MRV9BVVRIX0FDQ09VTlRfTkFNRQY7AEZJIhh0ZXN0QHB1"
-    "cHBldGxhYnMuY29tBjsAVEkiHkNPTlNPTEVfQVVUSF9BQ0NPVU5UX1JPTEUGOwBGSSIKYWRtaW4GO"
-    "wBUSSIYQUNDRVNTX0NPTlRST0xfUk9MRQY7AEZJIg9SRUFEX1dSSVRFBjsARkkiCGNhcwY7AEZ7CE"
-    "kiFmxhc3RfdmFsaWRfdGlja2V0BjsARm86HUNBU0NsaWVudDo6U2VydmljZVRpY2tldAk6DEB0aWN"
-    "rZXRJIiVTVC0xMzk4MTIyOTIwcnpGRzdqQllYWkVZUHZ2Tlc4NwY7AFQ6DUBzZXJ2aWNlSSIjaHR0"
-    "cDovL2xvY2FsaG9zdDozMDAwL2V2ZW50cy8%2FBjsARjoLQHJlbmV3MDoOQHJlc3BvbnNlbzoiQ0F"
-    "TQ2xpZW50OjpWYWxpZGF0aW9uUmVzcG9uc2UKOhRAcGFyc2VfZGF0ZXRpbWVJdToJVGltZQ23jhyA"
-    "%2BlGNcgc6C0Bfem9uZUkiCFBEVAY7AFQ6C29mZnNldGn%2BkJ06CUB4bWxvOhNSRVhNTDo6RWxlbW"
-    "VudA86DEBwYXJlbnRvOxEPOxJvOhRSRVhNTDo6RG9jdW1lbnQROhxAZW50aXR5X2V4cGFuc2lvbl9j"
-    "b3VudGkAOxIwOg5AY2hpbGRyZW5bCW86E1JFWE1MOjpYTUxEZWNsCzoPQHdyaXRldGhpc1Q6E0B3cm"
-    "l0ZWVuY29kaW5nVDsSQB06DUB2ZXJzaW9uSSIIMS4wBjsAVDoOQGVuY29kaW5nSSIKVVRGLTgGOwBU"
-    "OhBAc3RhbmRhbG9uZTBvOhBSRVhNTDo6VGV4dAs6CUByYXdUOxJAHToTQGVudGl0eV9maWx0ZXIwOh"
-    "JAdW5ub3JtYWxpemVkMDoQQG5vcm1hbGl6ZWQwOgxAc3RyaW5nSSIGCgY7AFRAHG87HAs7HVQ7EkAd"
-    "Ox4wOx8wOyAwOyFJIgYKBjsAVDoOQGVsZW1lbnRzbzoUUkVYTUw6OkVsZW1lbnRzBjoNQGVsZW1lbn"
-    "RAHToQQGF0dHJpYnV0ZXNJQzoWUkVYTUw6OkF0dHJpYnV0ZXN7AAY7JEAdOg1AY29udGV4dHsAOhNA"
-    "ZXhwYW5kZWRfbmFtZUkiDlVOREVGSU5FRAY7AEY6DEBwcmVmaXhJIgAGOwBGOg9AbmFtZXNwYWNlSS"
-    "IABjsARjoKQG5hbWVJIg5VTkRFRklORUQGOwBGOh1AaWdub3JlX3doaXRlc3BhY2Vfbm9kZXNGOhBA"
-    "d2hpdGVzcGFjZVQ7J0AoOxVbCG87HAs7HVQ7EkAcOx4wOx8wOyAwOyFJIggKICAGOwBUQBtvOxwLOx"
-    "1UOxJAHDseMDsfMDsgMDshSSIGCgY7AFQ7Im87IwY7JEAcOyVJQzsmewZJIghjYXMGOwBUbzoVUkVY"
-    "TUw6OkF0dHJpYnV0ZQs7JEAcOx9JIh9odHRwOi8vd3d3LnlhbGUuZWR1L3RwL2NhcwY7AFQ7IDA7KE"
-    "kiDnhtbG5zOmNhcwY7AFQ7KUkiCnhtbG5zBjsAVDsrSSIIY2FzBjsAVAY7JEAcOyhJIhhjYXM6c2Vy"
-    "dmljZVJlc3BvbnNlBjsAVDspSSIIY2FzBjsAVDsrSSIUc2VydmljZVJlc3BvbnNlBjsAVDssRjstVD"
-    "snQCg7FVsKbzscCzsdVDsSQBs7HjA7HzA7IDA7IUkiCgogICAgBjsAVG87EQ87EkAbOydAKDsVWwZv"
-    "OxwLOx1UOxJAQDseMDsfSSIYdGVzdEBwdXBwZXRsYWJzLmNvbQY7AFQ7IDA7IUkiGHRlc3RAcHVwcG"
-    "V0bGFicy5jb20GOwBUOyJvOyMGOyRAQDslSUM7JnsABjskQEA7KEkiDWNhczp1c2VyBjsAVDspSSII"
-    "Y2FzBjsAVDsrSSIJdXNlcgY7AFQ7LEY7LVRvOxwLOx1UOxJAGzseMDsfMDsgMDshSSIKCiAgICAGOw"
-    "BUbzsRDzsSQBs7J0AoOxVbBm87HAs7HVQ7EkBMOx4wOx9JIixDQVNTZXJ2ZXI6OkF1dGhlbnRpY2F0"
-    "b3JzOjpTUUxFbmNyeXB0ZWQGOwBUOyAwOyFJIixDQVNTZXJ2ZXI6OkF1dGhlbnRpY2F0b3JzOjpTUU"
-    "xFbmNyeXB0ZWQGOwBUOyJvOyMGOyRATDslSUM7JnsABjskQEw7KEkiFmNhczphdXRoZW50aWNhdG9y"
-    "BjsAVDspSSIIY2FzBjsAVDsrSSISYXV0aGVudGljYXRvcgY7AFQ7LEY7LVRvOxwLOx1UOxJAGzseMD"
-    "sfMDsgMDshSSIICiAgBjsAVDsibzsjBjskQBs7JUlDOyZ7AAY7JEAbOyhJIh5jYXM6YXV0aGVudGlj"
-    "YXRpb25TdWNjZXNzBjsAVDspSSIIY2FzBjsAVDsrSSIaYXV0aGVudGljYXRpb25TdWNjZXNzBjsAVD"
-    "ssRjstVDoOQHByb3RvY29sZgYyOgpAdXNlckkiGHRlc3RAcHVwcGV0bGFicy5jb20GOwBUOhZAZXh0"
-    "cmFfYXR0cmlidXRlc3sASSIPZmlsdGVydXNlcgY7AEZAXkkiGXVzZXJuYW1lX3Nlc3Npb25fa2V5Bj"
-    "sARkBe--4aaa7f88f10137c85d99a851bc08490934a2da80"))
-
 (def absurdly-large-cookie
   (apply str (repeat 8192 "a")))


Clean up code I commented out for previous commit

--- test/frereth_cp/server_test.clj
+++ test/frereth_cp/server_test.clj
@@ -4,31 +4,8 @@
             [frereth-cp.server.state :as state]
             [frereth-cp.shared :as shared]
             [frereth-cp.shared.constants :as K]
-            ;; TODO: This also needs to go away
-            #_[com.stuartsierra.component :as cpt]
-            #_[component-dsl.system :as cpt-dsl]
             [manifold.stream :as strm])
   (:import io.netty.buffer.Unpooled))
-
-(comment
-  (defrecord StreamOwner [chan]
-    ;; TODO: Make this just totally go away
-    cpt/Lifecycle
-    (start
-      [this]
-      (assoc this :chan (or chan (strm/stream))))
-    (stop
-      [this]
-      (println "Stopping StreamOwner")
-      (when chan
-        (strm/close! chan))
-      (assoc this :chan nil)))
-  (defn chan-ctor
-    [_]
-    (->StreamOwner (strm/stream)))
-
-  (def sys-struct {:cp-server 'com.frereth.common.curve.server/ctor
-                   :client-chan 'com.frereth.common.curve.server-test/chan-ctor}))

 (defn system-options
   []


re-implemented tests with midje

re-implemented tests with midje

--- test/ruuvi_server/test/core.clj
+++ test/ruuvi_server/test/core.clj
@@ -1,41 +1,31 @@
 (ns ruuvi-server.test.core
-  (:use [ruuvi-server.core])
-  (:use clojure.test))
+  (:use ruuvi-server.core)
+  (:use clojure.test)
+  (:use midje.sweet))

-(deftest wrap-dir-index-test
-  (defn f [param] ((wrap-dir-index identity) param))
-  (testing "wrap-dir-index"
-
-    (testing "converts URI / to /index.html"
-      (is (= (f {:uri "/"})
-             {:uri "/index.html"})))
+;; wrap-dir-index
+(fact "wrap-dir-index appends index.html to end of :uri that ends with /"
+      ((wrap-dir-index identity) {:uri "/"} ) => {:uri "/index.html"}
+      ((wrap-dir-index identity) {:uri "/some/path/"} ) => {:uri "/some/path/index.html"}
+      )

-    (testing "converts URI /some/path to /some/path"
-      (is (= (f {:uri "/some/path"})
-             {:uri "/some/path"})))
-
-    (testing "converts URI /some/path/ to /some/path/index.html"
-      (is (= (f {:uri "/some/path/"})
-             {:uri "/some/path/index.html"})))
-    ))
+(fact "wrap-dir-index leaves untouched :uri's that do not end with /"
+      ((wrap-dir-index identity) {:uri "/path."} ) => {:uri "/path."}
+      ((wrap-dir-index identity) {:uri "/some/path"} ) => {:uri "/some/path"}
+      ((wrap-dir-index identity) {:uri "/some/path/index.html"} ) => {:uri "/some/path/index.html"})

-(deftest wrap-add-html-suffix-test
-  (defn f [param] ((wrap-add-html-suffix identity) param))
-  (testing "wrap-add-html-suffix"
-
-    (testing "leaves URI / unconverted"
-      (is (= (f {:uri "/"})
-             {:uri "/"})))
-
-    (testing "converts URI /foo to /foo.html"
-      (is (= (f {:uri "/foo"})
-             {:uri "/foo.html"})))
-
-    (testing "leaves URI /foo. unconverted"
-      (is (= (f {:uri "/foo."})
-             {:uri "/foo."})))
-
-    (testing "leaves URI /foo.html unconverted"
-      (is (= (f {:uri "/foo.html"})
-             {:uri "/foo.html"})))
-    ))+;; wrap-add-html-suffix
+(fact "wrap-add-html-suffix leaves untouched :uri's ending with /"
+      ((wrap-add-html-suffix identity) {:uri "/"} ) => {:uri "/" }
+      ((wrap-add-html-suffix identity) {:uri "/foo/"} ) => {:uri "/foo/" }
+      )
+
+(fact "wrap-add-html-suffix leaves untouched :uri's containing a dot"
+      ((wrap-add-html-suffix identity) {:uri "/foo.html"} ) => {:uri "/foo.html" }
+      ((wrap-add-html-suffix identity) {:uri "/foo/foo.jpg"} ) => {:uri "/foo/foo.jpg" }
+      )
+
+(fact "wrap-add-html-suffix adds '.html' suffix to :uri's that do not have a suffix"
+      ((wrap-add-html-suffix identity) {:uri "/foo"} ) => {:uri "/foo.html" }
+      ((wrap-add-html-suffix identity) {:uri "/path/foo.html"} ) => {:uri "/path/foo.html" }
+      )


Support for handler in constructor

Support for handler in constructor

--- modules/aleph/src/modular/aleph.clj
+++ modules/aleph/src/modular/aleph.clj
@@ -5,27 +5,36 @@
    [com.stuartsierra.component :refer (Lifecycle)]
    [schema.core :as s]
    [modular.ring :refer (request-handler WebRequestHandler)]
-   [aleph.http :as http]))
+   [aleph.http :as http]
+   ))

-(defrecord Webserver []
+(defn get-handler
+  "Extract the Ring handler from the component"
+  [component]
+  (or
+   ;; Handlers can be specified as a constructor arg
+   (:handler component)
+
+   ;; Or as a dependency (which satisfies WebRequestHandler)
+   (when-let [provider (first (filter #(satisfies? WebRequestHandler %) (vals component)))]
+     (request-handler provider))
+
+   ;; Or an exception is thrown
+   (throw (ex-info (format "aleph http server requires a handler, or a dependency that satisfies %s" WebRequestHandler)))))
+
+(defrecord Webserver [handler]
   Lifecycle
   (start [component]
-    (if-let [provider (first (filter #(satisfies? WebRequestHandler %) (vals component)))]
-      (let [h (request-handler provider)]
-        (assert h)
-        (let [server (http/start-server h component)]
-          (assoc component :server server)))
-      (throw (ex-info (format "aleph http server requires the existence of a component that satisfies %s" WebRequestHandler)
-                      {:component component})))
-
-    )
+    (let [server (http/start-server (get-handler component) component)]
+      (assoc component :server server)))
   (stop [component]
     (when-let [server (:server component)]
       (.close server)
       (dissoc component :server))))

-(def new-webserver-schema {:port s/Int
-                           s/Keyword s/Any})
+(def new-webserver-schema
+  {:port s/Int
+   s/Keyword s/Any})

 (defn new-webserver [& {:as opts}]
   (->> opts


Updating http-kit-events to latest bidi

Updating http-kit-events to latest bidi

--- modules/http-kit-events/project.clj
+++ modules/http-kit-events/project.clj
@@ -1,11 +1,11 @@
 ;; Copyright © 2014 JUXT LTD.

-(defproject juxt.modular/http-kit-events "0.5.3"
+(defproject juxt.modular/http-kit-events "0.5.4"
   :description "A modular extension that provides support for events over http-kit channels"
   :url "https://github.com/juxt/modular/tree/master/modules/http-kit-events"
   :license {:name "The MIT License"
             :url "http://opensource.org/licenses/MIT"}
   :dependencies [[juxt.modular/http-kit "0.5.3"]
-                 [juxt.modular/bidi "0.5.4"]
-                 [juxt.modular/async "0.5.2"]
+                 [juxt.modular/bidi "0.7.1"]
+                 [juxt.modular/async "0.5.3"]
                  ])


Adjusted logging

Adjusted logging

--- src/video_server/watcher.clj
+++ src/video_server/watcher.clj
@@ -81,7 +81,7 @@
   "Checks the pending files and adds the stable ones to the library."
   [folder]
   (when (seq @pending-files)
-    (log/trace "checking pending files")
+    #_(log/trace "checking pending files")
     (doseq [file @pending-files]
       (try (when (stable? file)
              (dosync (alter pending-files disj file))
@@ -93,8 +93,9 @@
 (defn add-pending-file
   "Adds a new or changing file to the list of pending files."
   [file]
-  (log/trace "adding pending file" (str file))
-  (dosync (alter pending-files conj file)))
+  (when-not (contains? @pending-files file)
+    (log/trace "adding pending file" (str file))
+    (dosync (alter pending-files conj file))))

 (defn remove-file
   "Removes the file from the video library."
@@ -105,11 +106,12 @@
 (defn file-event-callback
   "Processes the file system events."
   [folder event filename]
-  (log/trace "file event:" event filename)
   (when (or (file/video? filename) (file/subtitles? filename))
     (let [file (io/file filename)]
       (try (case event
-             :create (add-pending-file file)
+             :create (do
+                       (log/info "watching file" filename)
+                       (add-pending-file file))
              :modify (add-pending-file file)
              :delete (remove-file folder file)
              nil)


wish-li-last cljs

wish-li-last cljs

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -12,3 +12,10 @@
    [:div.delete]
    [:input {:type "text" :class "description" :value desc}]
    [:input {:type "text" :class "url" :value url}]])
+
+(defpartial wish-li-last []
+  [:li.wish.last
+   [:div.delete]
+   [:input {:type "text" :class "description" :value desc}]
+   [:input {:type "text" :class "url" :value url}]])
+


Введен компонент для полноэкранного отображения картинок

--- radiolamp-6P3S/src/ixinfestor/omut.cljs
+++ radiolamp-6P3S/src/ixinfestor/omut.cljs
@@ -2357,7 +2357,7 @@

                (dom/div
                 #js {:className "well well-sm"
-                     :style #js {:marginTop 4
+                     :style #js {:marginTop 4
                                  :display "inline-block"}}
                 (let [image (@app :image)]
                   (if (empty? image)
@@ -2388,6 +2388,82 @@

 ;; END Upload one image
+;;..................................................................................................
+
+;;**************************************************************************************************
+;;* BEGIN Full screen image viewer
+;;* tag: <full screen image viewer>
+;;*
+;;* description: Просмоторщик картинок в полный экран
+;;*
+;;**************************************************************************************************
+
+(defonce chan-thumb-show-in-full-screen-app-init (chan))
+
+                                        ;TODO: Вынести данную констату в общий файл cljc
+(def thumb-show-in-full-screen-id "thumb-show-in-full-screen")
+
+
+
+(defonce thumb-show-in-full-screen-app-state
+  (atom {:src nil
+         :description nil :top_description nil
+         :zoom? false}))
+
+(defn- thumb-show-in-full-screen [app]
+  (reify
+    om/IWillMount
+    (will-mount [this]
+      (go
+        (while true
+          (let [{:keys [path src title top_description description]}
+                (<! chan-thumb-show-in-full-screen-app-init)]
+            (om/transact!
+             app #(assoc % :src (or path src)
+                         :descrioption description
+                         :top_description (or top_description title)))))))
+    om/IRender
+    (render [_]
+      (when-let [src (@app :src)]
+        (let [zoom? (:zoom? @app)]
+          (dom/div
+           #js {:style #js {:position "fixed" :zIndex 3000
+                            :top 0 :bottom 0 :left 0 :right 0
+                            :overflow "auto"}}
+           (dom/button #js {:class "close"
+                            :style #js {:position "fixed" :left 0 :top 0}
+                            :onClick #(om/transact! app :zoom? not)}
+                       (ui-glyphicon (if zoom? "zoom-out" "zoom-in")
+                                     "" "3em"))
+           (dom/button #js {:class "close"
+                            :style #js {:position "fixed" :right 20 :top 0}
+                            :onClick (fn []
+                                       (om/transact!
+                                        app #(assoc % :src nil :descrioption nil
+                                                    :top_description nil))
+                                       1)}
+                       (ui-glyphicon "remove" "" "3em"))
+           (dom/img #js {:src src
+                         :style #js {:width (if zoom? "" "100%")}})))))))
+
+
+;; Инициализация
+(def thumb-show-in-full-screen--tag (by-id thumb-show-in-full-screen-id))
+
+(if thumb-show-in-full-screen--tag
+  (do
+    (om/root
+     thumb-show-in-full-screen
+     thumb-show-in-full-screen-app-state
+     {:target thumb-show-in-full-screen--tag :opts {}})
+    (println "Компонент FULL SCREEN найден и проинициализирован."))
+  (println "Компонент FULL SCREEN НЕ найден по id ="
+           thumb-show-in-full-screen-id " и не проинициализирован."))
+
+
+
+
+;; END Full screen image viewer
 ;;..................................................................................................

@@ -2449,7 +2525,6 @@
                                             :onMouseDown (fn [e] (.select (.-target e)))
                                             }))
                    )))))))
-

 (def thumbnails-edit-form-app-init
   (merge edit-form-for-id-app-init
@@ -2567,14 +2642,21 @@
                                        (put! chan-modal-act
                                              {:label (str "Выбор действий над записью №" id)
                                               :acts
-                                              [{:text "Редактировать" :btn-type :primary
-                                                :act-fn (fn []
-                                                          (put! chan-thumbnails-modal-edit-form-open-for-id id)
-                                                          (modal-show (:modal app)))}
+                                              [{:text "Просмотр" :btn-type :primary
+                                                :act-fn
+                                                (fn []
+                                                  (put! chan-thumb-show-in-full-screen-app-init r))
+                                                }
+                                               {:text "Редактировать" :btn-type :primary
+                                                :act-fn
+                                                (fn []
+                                                  (put! chan-thumbnails-modal-edit-form-open-for-id id)
+                                                  (modal-show (:modal app)))}
                                                {:text "Удалить" :btn-type :danger
-                                                :act-fn #(do
-                                                           (om/update! app [:modal-yes-no :row] r)
-                                                           (modal-show (:modal-yes-no app)))}]
+                                                :act-fn
+                                                #(do
+                                                   (om/update! app [:modal-yes-no :row] r)
+                                                   (modal-show (:modal-yes-no app)))}]
                                               }))}}))
                  (:list app)))


tests fixed

tests fixed

--- test/celestial/test/jobs.clj
+++ test/celestial/test/jobs.clj
@@ -1,5 +1,6 @@
 (ns celestial.test.jobs
   (:require
+    [celestial.persistency.systems :as s]
     [taoensso.carmine :as car]
     [celestial.redis :refer (server-conn)]
     [taoensso.carmine.locks :refer (with-lock acquire-lock)]
@@ -14,9 +15,10 @@
 (fact "with-lock used if :identity key was provided"
    (job-exec identity {:message {:identity "red1" :args {:machine {:hostname "red1"}}} :attempt 1 :user "ronen"}) => {:status :success}
    (provided
+     (s/get-system "red1") => {:machine {:hostname "red1"}}
      (server-conn) => {}
      (acquire-lock {} "red1" 1800000 300000) => nil :times 1
-     (jobs/save-status "red1" anything :success)  => {:status :success}  :times 1
+     (jobs/save-status anything :success)  => {:status :success}  :times 1
      ))


Don't throw if tables to clear don't exist

The tables won't exist in a fresh postgres.

--- test/clojars/test_helper.clj
+++ test/clojars/test_helper.clj
@@ -25,7 +25,7 @@
                   :db {:dbtype "postgresql"
                        :dbname "clojars"
                        :host "localhost"
-                       :port 55432
+                       :port 55433
                        :user "clojars"
                        :password "clojars"}
                   :repo "data/test/repo"
@@ -64,11 +64,13 @@
 (declare ^:dynamic *db*)

 (defn clear-database [db]
-  (jdbc/db-do-commands db
-                       "delete from deps"
-                       "delete from groups"
-                       "delete from jars"
-                       "delete from users"))
+  (try
+    (jdbc/db-do-commands db
+                         "delete from deps"
+                         "delete from groups"
+                         "delete from jars"
+                         "delete from users")
+    (catch Exception _)))

 (defn with-clean-database [f]
   (binding [*db* {:connection (jdbc/get-connection (:db test-config))}]


removed trailing whitespace

removed trailing whitespace

--- test/compojure/test/core.clj
+++ test/compojure/test/core.clj
@@ -31,7 +31,7 @@
        nil)
      (-> (request :get "/foo")
          (assoc :params {"y" "bar", "z" "baz"}))))
-
+
   (testing "vector ':as request' arguments"
     (let [req (-> (request :get "/foo")
                   (assoc :params {:y "bar"}))]
@@ -41,7 +41,7 @@
                    (dissoc req :params)))
             nil)
        req)))
-
+
   (testing "map arguments"
     ((GET "/foo" {params :params}
        (is (= (params {:x "a", :y "b"})))
@@ -62,7 +62,7 @@
           route (GET "/foo" []  resp)]
       (is (= (route (request :head "/foo"))
              (assoc resp :body nil)))))
-
+
   (testing "custom regular expressions"
     (let [route (GET ["/foo/:id" :id #"\d+"] [id] id)]
       (is (nil? (route (request :get "/foo/bar"))))
@@ -118,7 +118,7 @@
       (are [url body] (= (:body (handler (request :get url)))
                          body)
         "/foo/10"    "root"
-        "/foo/10/"   "root"
+        "/foo/10/"   "root"
         "/foo/10/id" "10"
         "/foo/1/x/2" "2"))))


Exclude keys.

Exclude keys.

--- test/onyx/peer/flow_test.clj
+++ test/onyx/peer/flow_test.clj
@@ -273,38 +273,46 @@
    {:flow/from :colors-in
     :flow/to :all
     :flow/short-circuit? true
+    :flow/exclude-keys [:extra-key]
     :flow/predicate :onyx.peer.flow-test/white?}

    {:flow/from :colors-in
     :flow/to :none
     :flow/short-circuit? true
+    :flow/exclude-keys [:extra-key]
     :flow/predicate :onyx.peer.flow-test/black?}

    {:flow/from :colors-in
     :flow/to [:process-red]
     :flow/short-circuit? true
+    :flow/exclude-keys [:extra-key]
     :flow/predicate :onyx.peer.flow-test/red?}

    {:flow/from :colors-in
     :flow/to [:process-blue]
     :flow/short-circuit? true
+    :flow/exclude-keys [:extra-key]
     :flow/predicate :onyx.peer.flow-test/blue?}

    {:flow/from :colors-in
     :flow/to [:process-green]
     :flow/short-circuit? true
+    :flow/exclude-keys [:extra-key]
     :flow/predicate :onyx.peer.flow-test/green?}

    {:flow/from :colors-in
     :flow/to [:process-red]
+    :flow/exclude-keys [:extra-key]
     :flow/predicate :onyx.peer.flow-test/orange?}

    {:flow/from :colors-in
     :flow/to [:process-blue]
+    :flow/exclude-keys [:extra-key]
     :flow/predicate :onyx.peer.flow-test/orange?}

    {:flow/from :colors-in
     :flow/to [:process-green]
+    :flow/exclude-keys [:extra-key]
     :flow/predicate :onyx.peer.flow-test/orange?}])

 (defn child? [event {:keys [age]} max-child-age]
@@ -332,6 +340,23 @@
   (= color "orange"))

 (def constantly-true (constantly true))
+
+(def process-children identity)
+
+(def process-adults identity)
+
+(def process-athletes-in-washington identity)
+
+(def process-everyone identity)
+
+(defn process-red [segment]
+  (assoc segment :extra-key "Some extra context for the predicates"))
+
+(defn process-blue [segment]
+  (assoc segment :extra-key "Some extra context for the predicates"))
+
+(def process-green [segment]
+  (assoc segment :extra-key "Some extra context for the predicates"))

 (def v-peers (onyx.api/start-peers! 1 peer-config))


scheduler: Don't double count offer sizes in histogram on error.

--- scheduler/src/cook/mesos/scheduler.clj
+++ scheduler/src/cook/mesos/scheduler.clj
@@ -498,13 +498,6 @@
   "Gets a list of offers from mesos. Decides what to do with them all--they should all
    be accepted or rejected at the end of the function."
   [conn driver ^TaskScheduler fenzo fid pending-jobs num-considerable offers-chan offers]
-  (doseq [offer offers]
-    (histograms/update!
-      offer-size-cpus
-      (get-in offer [:resources :cpus] 0))
-    (histograms/update!
-      offer-size-mem
-      (get-in offer [:resources :mem] 0)))
   (log/debug "invoked handle-resource-offers!")
   (let [offer-stash (atom nil)] ;; This is a way to ensure we never lose offers fenzo assigned if an errors occures in the middle of processing
     (timers/time!
@@ -1019,6 +1012,14 @@
              (log/error "Got a mesos error!!!!" message))
       (resourceOffers [driver offers]
                       (log/debug "Got an offer, putting it into the offer channel:" offers)
+                      (doseq [offer offers]
+                        (histograms/update!
+                         offer-size-cpus
+                         (get-in offer [:resources :cpus] 0))
+                        (histograms/update!
+                         offer-size-mem
+                         (get-in offer [:resources :mem] 0)))
+
                       (when-not (async/offer! offers-chan offers)
                         (decline-offers driver offers)))
       (statusUpdate [driver status]


added Chris's bio

added Chris's bio

--- src-cljs/frontend/components/about.cljs
+++ src-cljs/frontend/components/about.cljs
@@ -199,7 +199,7 @@
     :role "DevOps"
     :github ""
     :email ""
-    :bio "Bio coming soon!"}
+    :bio "One of the few surviving San Francisco natives, Chris recently graduated from the University of California, Irvine with a degree in Classical Civilization. Quickly realizing that Latin was a dead language and having a passion for computers and technology, he began working at CircleCI, where he is excited to develop and expand his DevOps knowledge."}
    {:name "Jia Le"
     :img-path (scaled-image-path "jia")
     :role "Account Manager"


autoscroll chat

autoscroll chat

--- src-cljs/frontend/components/aside.cljs
+++ src-cljs/frontend/components/aside.cljs
@@ -28,10 +28,17 @@
     om/IWillUnmount
     (will-unmount [_]
       (d/unlisten! (om/get-shared (om/get-shared owner :db)) (om/get-state owner :listener-key)))
+    om/IWillUpdate
+    (will-update [_ _ _]
+      ;; check for scrolled all of the way down
+      (let [node (om/get-node owner "chat-messages")]
+        (om/set-state! owner :auto-scroll (= (- (.-scrollHeight node) (.-scrollTop node))
+                                             (.-clientHeight node)))))
     om/IDidUpdate
     (did-update [_ _ _]
-      ;; maybe scroll chat
-      )
+      (when (om/get-state owner :auto-scroll)
+        (set! (.-scrollTop (om/get-node owner "chat-messages"))
+              10000000)))
     om/IRender
     (render [_]
       (let [{:keys [cast!]} (om/get-shared owner)
@@ -42,7 +49,7 @@
                         :server/timestamp (om/get-state owner :mount-time)}]
         (html
          [:section.aside-chat
-          [:div.chat-messages
+          [:div.chat-messages {:ref "chat-messages"}
            (for [chat (sort-by :server/timestamp (concat chats [dummy-chat]))
                  :let [id (apply str (take 6 (str (:session/uuid chat))))]]
              (html [:div.message


fix the blog link from the form

fix the blog link from the form

--- src-cljs/frontend/components/outer.cljs
+++ src-cljs/frontend/components/outer.cljs
@@ -173,7 +173,8 @@
               [:p
                "Next, "
                [:a.feature-link {:title "Private docs early access"
-                                 :href "/blog/private-docs-early-access"}
+                                 :href "/blog/private-docs-early-access"
+                                 :target "_self"}
                 "learn to use private docs"]
                " or "
                [:a.feature-link {:title "Launch Precursor"


Removed enable-console-print so we don't break IE8.

--- src-cljs/kixi/hecuba/tabs/profiles.cljs
+++ src-cljs/kixi/hecuba/tabs/profiles.cljs
@@ -1,8 +1,6 @@
 (ns kixi.hecuba.tabs.profiles
   (:require [om.core :as om :include-macros true]
             [sablono.core :as html :refer-macros [html]]))
-
-(enable-console-print!)

 (defn get-profiles [selected-property-id data]
   (->>  data


txd-gen: Fix processing of URI strings

txd-gen: Fix processing of URI strings

Datomic wants a URI object, but of course we don't get URI objects over
the wire. Add the missing conversion from string to URI object.

--- src/clj/theatralia/database/txd_gen.clj
+++ src/clj/theatralia/database/txd_gen.clj
@@ -1,7 +1,8 @@
 (ns theatralia.database.txd-gen
   "Functions for generating Datomic transaction data structures."
   (:require [datomic.api :as d]
-            [medley.core :refer [remove-vals]]))
+            [medley.core :refer [remove-vals]])
+  (:import java.net.URI))

 ;;;; Utilities for adding materials

@@ -72,7 +73,8 @@
   database or being added during the same transaction."
   (remove-vals nil? {:db/id #db/id[:part/bibliography]
                      :material/title    (m :title)
-                     :material/uri      (m :uri)
+                     :material/uri      (if (contains? m :uri)
+                                          (URI. (m :uri)))
                      :material/comments (m :comments)
                      :material/tags     tag-eids
                      :material/owner    user-eid}))


make declob public

make declob public

--- src/clj_oracle_namedparameters/core.clj
+++ src/clj_oracle_namedparameters/core.clj
@@ -24,7 +24,7 @@
   (with-open [rdr (java.io.BufferedReader. (.getCharacterStream clob))]
     (apply str (line-seq rdr))))

-(defn- declob
+(defn declob
   "If parameter is an Oracle Clob, converts it to a string."
   [s]
   (if (instance? oracle.sql.CLOB s) (clob-to-string s) s))


Rename link

Rename link

--- src/cljs/cglossa/search_inputs/cwb.cljs
+++ src/cljs/cglossa/search_inputs/cwb.cljs
@@ -101,8 +101,8 @@
         [:a {:href "" :title "Search for grammatical categories etc." :on-click #()} "Extended"])
       " | "
       (if (= view cqp)
-        [:b "CQP"]
-        [:a {:href "" :title "CQP expressions" :on-click #()} "CQP"])
+        [:b "CQP query"]
+        [:a {:href "" :title "CQP expressions" :on-click #()} "CQP query"])
       [search-button multilingual?]
       (when multilingual? [add-language-button])]


Better reporting style (warning, danger) for projects with low code coverage

--- src/cloverage_jenkins_reporter/core.clj
+++ src/cloverage_jenkins_reporter/core.clj
@@ -101,6 +101,13 @@
     (for [job jobs]
         (get-coverage-for-job job)))

+(defn get-progress-bar-style
+    [coverage]
+    (cond
+        (< coverage 25) "progress-bar-danger"
+        (< coverage 75) "progress-bar-warning"
+        :else           "progress-bar-success"))
+
 (defn make-report
     [jobs jenkins-url]
     (doseq [job jobs]
@@ -111,7 +118,10 @@
                               "" (:instrumented job) "	"
                               "" (:covered job) "	"
                               ;"" (:lines-coverage job) "%	"
-                              "
" (:lines-coverage job) "
"
+                              "
"
+                                  (:lines-coverage job) "
"
                               "
")))))

 (defn -main


Bootstrap styling of the tag filter

Bootstrap styling of the tag filter

--- src/freecoin/views/transaction_list.clj
+++ src/freecoin/views/transaction_list.clj
@@ -44,11 +44,12 @@
      [:div
       [:p "Filter by tags:"
        [:form {:method "get"}
-        [:select {:multiple true
-                  :name "tags"
-                  :size (min (count all-tags) 5)}
+        [:select.form-control
+         {:multiple true
+          :name "tags"
+          :size (min (count all-tags) 5)}
          (map tag-filter all-tags)]
-        [:p [:button {:type "submit"} "Filter"]]]]
+        [:p [:button.form-control {:type "submit"} "Filter"]]]]
       [:table.func--transactions-page--table.table.table-striped
        [:thead
         [:tr


Shorten line length a bit for integrations section

--- src-cljs/frontend/components/enterprise.cljs
+++ src-cljs/frontend/components/enterprise.cljs
@@ -84,8 +84,9 @@
              {:on-click #(raise! owner [:enterprise-learn-more-clicked {:source "integration"}])}
              "Learn More"]]]]
          [:section.row
-          [:h2.text-center "Integrations"]
-          [:p "CircleCI is built for unlimited flexibility. From hosting options to test frameworks or programming frameworks, we let you use the technology you need. GitHub Enterprise, Docker, SauceLabs, and many more."]]
+          [:div.col-xs-8.col-xs-offset-2
+           [:h2.text-center "Integrations"]
+           [:p "CircleCI is built for unlimited flexibility. From hosting options to test frameworks or programming frameworks, we let you use the technology you need. GitHub Enterprise, Docker, SauceLabs, and many more."]]]
          [:section.row
           [:div.col-xs-4
            [:div.integration-logo.github


Remove unused destructuring

Remove unused destructuring

--- src/cljs/cglossa/search_inputs/cwb/core.cljs
+++ src/cljs/cglossa/search_inputs/cwb/core.cljs
@@ -185,7 +185,7 @@
 (defn search-inputs
   "Component that lets the user select a search view (simple, extended
   or CQP query view) and displays it."
-  [{:keys [search-view search-queries] :as a} {:keys [corpus search-results] :as m}]
+  [{:keys [search-view search-queries] :as a} {:keys [corpus] :as m}]
   (let [query-ids (atom nil)]
     (reagent/create-class
       {:display-name
@@ -195,7 +195,7 @@
        focus-text-input

        :reagent-render
-       (fn [{:keys [search-view search-queries] :as a} {:keys [corpus search-results] :as m}]
+       (fn [{:keys [search-view search-queries] :as a} {:keys [corpus] :as m}]
          (let [view          (case @search-view
                                :extended extended
                                :cqp cqp


Name jobs better via deployment pulse info

--- src/cljs/onyx_dashboard/components/jobs.cljs
+++ src/cljs/onyx_dashboard/components/jobs.cljs
@@ -79,8 +79,8 @@

 (defn displayed-job-status [{:keys [status tasks] :as job}]
   (case status
-    :incomplete (if (empty? tasks) :incomplete :running)
-    status))
+    :incomplete (if (empty? tasks) "pending" "running")
+    (name status)))

 (defcomponent job-overview-panel [job owner]
   (render [_]


cleanup

cleanup

--- src/cljs/swarmpit/component/config/info.cljs
+++ src/cljs/swarmpit/component/config/info.cljs
@@ -106,7 +106,6 @@

 (rum/defc form-config < rum/static
                         mixin-init-editor [config]
-  (print config)
   (comp/card
     {:className "Swarmpit-form-card"
      :key       "cdc"}


Implement showing/hiding solved solutions

--- src/clojure/org/bytopia/foreclojure/main.clj
+++ src/clojure/org/bytopia/foreclojure/main.clj
@@ -26,10 +26,16 @@
   :classname GridView
   :traits [:on-item-click])

+(defn hide-solved-problem? [a]
+  (-> (neko.data/get-shared-preferences a "4clojure" :private)
+      like-map
+      :hide-solved?))
+
 (defn refresh-ui [a]
   (let [user (:user (like-map (.getIntent a)))]
     (doto (.getAdapter (find-view a ::problems-gv))
-      (.changeCursor (db/get-problems-cursor a user true))
+      (.changeCursor (db/get-problems-cursor
+                      a user (not (hide-solved-problem? a))))
       (.notifyDataSetChanged))
     (.invalidateOptionsMenu a)))

@@ -43,13 +49,15 @@
          (user/login-via-saved a user true))
        (let [last-id (db/initialize a)
              {:keys [solved-ids new-ids]} (api/fetch-solved-problem-ids last-id)
-             locally-solved (db/get-solved-ids-for-user a user)]
+             locally-solved (db/get-solved-ids-for-user a user)
+             to-download (clojure.set/difference solved-ids locally-solved)
+             to-upload (clojure.set/difference locally-solved solved-ids)]
          ;; Mark new problems as solved although we don't have the code yet.
-         (doseq [problem-id (clojure.set/difference solved-ids locally-solved)]
+         (doseq [problem-id to-download]
            (neko.log/d "Marking problem " problem-id " as solved.")
            (db/update-solution a user problem-id {:is_solved true, :code nil}))
          ;; Upload solutions to locally solved problems which aren't synced.
-         (doseq [problem-id (clojure.set/difference locally-solved solved-ids)
+         (doseq [problem-id to-upload
                  :let [solution (db/get-solution a user problem-id)]]
            (neko.log/d "Sumbitting solution " problem-id solution)
            (if (api/submit-solution problem-id (:solutions/code solution))
@@ -61,9 +69,9 @@
            (when-let [json (assoc (api/fetch-problem problem-id)
                              "id" problem-id)]
              (db/insert-problem a json)))
-         (when (pos? (count new-ids))
-           (on-ui (toast (format "Downloaded %d new problems."
-                                 (count new-ids)))))))
+         (when (pos? (+ (count new-ids) (count to-download) (count to-upload)))
+           (on-ui (toast a (format "Downloaded %d new problem(s).\nDiscovered %d server solution(s).\nUploaded %d local solution(s)."
+                                   (count new-ids) (count to-download) (count to-upload)))))))
      (on-ui (refresh-ui a)))))

 ;; (reload-from-server (*a))
@@ -79,6 +87,13 @@
   (.startActivity
    a (Intent. a (resolve 'org.bytopia.foreclojure.LoginActivity)))
   (.finish a))
+
+(defn toggle-hide-solved [a]
+  (let [sp (neko.data/get-shared-preferences a "4clojure" :private)
+        previous (-> sp like-map :hide-solved?)]
+    (neko.log/d "Toggled" previous)
+    (-> sp .edit (neko.data/assoc! :hide-solved? (not previous)) .commit)
+    (refresh-ui a)))

 (defn make-problem-adapter [a]
   (proxy [CursorAdapter] [a nil]
@@ -136,6 +151,7 @@
   :key :main
   :on-create
   (fn [this bundle]
+    (neko.log/d "onCreate()" this)
     (neko.activity/request-window-features! this :indeterminate-progress)
     (.addFlags (.getWindow this) android.view.WindowManager$LayoutParams/FLAG_KEEP_SCREEN_ON)
     (safe-for-ui
@@ -145,9 +161,9 @@
                       neko.data/like-map
                       :last-user)]
          (.putExtra (.getIntent this) "user" user)
-         (set-content-view! (*a)
+         (set-content-view! this
            [:grid-view {:id ::problems-gv
-                        :column-width (traits/to-dimension (*a) [160 :dp])
+                        :column-width (traits/to-dimension this [160 :dp])
                         :num-columns :auto-fit
                         :stretch-mode :stretch-spacing-uniform
                         :adapter (make-problem-adapter this)
@@ -168,15 +184,18 @@
      (let [user (:user (like-map (.getIntent this)))
            online? (api/logged-in?)]
        (menu/make-menu
-        menu [[:item {:title "Reload"
+        menu [[:item {:title "Show solved"
+                      :show-as-action :never
+                      :checkable true
+                      :checked (not (hide-solved-problem? this))
+                      :on-click (fn [_] (safe-for-ui (toggle-hide-solved this)))}]
+              [:item {:title "Reload"
                       :icon #res/drawable :org.bytopia.foreclojure/ic-menu-refresh
                       :show-as-action :always
                       :on-click (fn [_] (safe-for-ui (reload-from-server this)))}]
               [:item {:title (format "%s (%s)" user
                                      (if online? "online" "offline"))
-                      :icon (if online?
-                              #res/drawable :org.bytopia.foreclojure/ic-menu-friendslist
-                              #res/drawable :org.bytopia.foreclojure/ic-menu-login)
+                      :icon #res/drawable :org.bytopia.foreclojure/ic-menu-friendslist
                       :show-as-action [:always :with-text]
                       :on-click (fn [_] (safe-for-ui (switch-user this)))}]])))))


DBZ bug

DBZ bug

--- src/clojure/zensols/nlparse/feature/lang.clj
+++ src/clojure/zensols/nlparse/feature/lang.clj
@@ -104,7 +104,7 @@
                  {})
          (merge (zipmap pos-tag-types (repeat (count pos-tag-types) 0)))
          (map (fn [[k v]]
-                {(pos-tag-ratio-keyword k) (/ v tc)
+                {(pos-tag-ratio-keyword k) (if (= 0 tc) 0 (/ v tc))
                  (pos-tag-count-keyword k) v}))
          (apply merge)
          (merge {:pos-last-tag (->> tokens last :pos-tag pos-tag-or-none)


add some parsing tests

add some parsing tests

--- test/babel/test/fr.cljc
+++ test/babel/test/fr.cljc
@@ -5,6 +5,7 @@
             [babel.forest :as forest]
             [babel.francais.grammar :refer [small medium]]
             [babel.francais.morphology :refer [fo]]
+            [babel.francais.workbook :refer [generate parse]]
             [babel.over :as over]
             [clojure.string :as string]
             #?(:clj [clojure.test :refer [deftest is]])
@@ -223,3 +224,19 @@
                                                   :subj {:pred :lui}
                                                   :obj {:pred :Jean}}}})]
     (is (= (fo result) "il l'appele Jean"))))
+
+(deftest parse-reflexive
+  (let [result (first (parse "il l'amuse"))]
+    (not (nil? result))
+    (is (= (get-in result [:synsem :sem :pred])
+           :have-fun))
+    (is (= (get-in result [:synsem :sem :subj :pred])
+           :lui))))
+
+(deftest parse-reflexive
+  (let [result (first (parse "tu t'amuses"))]
+    (not (nil? result))
+    (is (= (get-in result [:synsem :sem :pred])
+           :have-fun))
+    (is (= (get-in result [:synsem :sem :subj :pred])
+           :tu))))


Added show-table

Added show-table

--- profiles.clj
+++ profiles.clj
@@ -14,7 +14,8 @@
                         :upload-list
                         :histories
                         :hello-world
-                        :show-table
+                        :show-table ;; TODO: make these autoconfigure...
+                        :show-list
                         ]
             :web-audience "http://localhost:3000"
             :verifier "https://verifier.login.persona.org/verify"


Fixed scaling by complex number

Fixed scaling by complex number

--- src/main/clj/clojure/core/matrix/complex.clj
+++ src/main/clj/clojure/core/matrix/complex.clj
@@ -110,10 +110,17 @@
     (cond
       (number? a) (ComplexArray. (mp/scale (clojure.core.matrix.complex/real m) a)
                                  (mp/scale (clojure.core.matrix.complex/imag m) a))
-      (instance? Complex a) (ComplexArray. (mp/scale (clojure.core.matrix.complex/real m)
-                                                     (c/real-part a))
-                                           (mp/scale (clojure.core.matrix.complex/imag m)
-                                                     (c/imaginary-part a)))
+      (instance? Complex a) (ComplexArray.
+                              (mp/matrix-sub
+                                (mp/scale (clojure.core.matrix.complex/real m)
+                                          (c/real-part a))
+                                (mp/scale (clojure.core.matrix.complex/imag m)
+                                          (c/imaginary-part a)))
+                              (mp/matrix-add
+                                (mp/scale (clojure.core.matrix.complex/imag m)
+                                          (c/real-part a))
+                                (mp/scale (clojure.core.matrix.complex/real m)
+                                          (c/imaginary-part a))))
       :else (error "Unable to multiply " (class a) " with a Complex value")))
   (pre-scale [m a]
     (cond
@@ -192,7 +199,7 @@
      :else (error "Unable to coerce to complex value: " r)))
   ([r i]
    (cond
-     (and  (number? r) (number? i)) (c/complex-number r i)
+     (and (number? r) (number? i)) (c/complex-number r i)
      :else (error "Unable to coerce to complex value: " r i))))

 (defn complex?


Fix arity.

Fix arity.

--- src/onyx/log/commands/exhaust_input.clj
+++ src/onyx/log/commands/exhaust_input.clj
@@ -20,7 +20,7 @@
   [{:keys [args message-id]} old new diff state]
   (when (and (common/all-inputs-exhausted? new (:job args))
              (common/executing-output-task? new (:job args) (:task args))
-             (common/elected-sealer? new message-id) (:job args) (:task args) (:id state))
+             (common/elected-sealer? new message-id (:job args) (:task args) (:id state)))
     (>!! (:seal-response-ch state) true))
   state)


[ONYX-462] Live peer that sees its own leave-cluster should restart

--- src/onyx/log/commands/leave_cluster.clj
+++ src/onyx/log/commands/leave_cluster.clj
@@ -48,34 +48,41 @@
      :updated-watch {:observer observer
                      :subject subject}}))

+(defn abort? [replica state {:keys [args]}]
+  (or (= (:id state) (get (:prepared replica) (:id args)))
+      (= (:id state) (get (:accepted replica) (:id args)))))
+
 (s/defmethod extensions/reactions :leave-cluster :- Reactions
-  [{:keys [args]} old new diff state]
-  (when (or (= (:id state) (get (:prepared old) (:id args)))
-            (= (:id state) (get (:accepted old) (:id args))))
+  [entry old new diff state]
+  (when (abort? old state entry)
     [{:fn :abort-join-cluster
       :args {:id (:id state)}}]))

 (s/defmethod extensions/fire-side-effects! :leave-cluster :- State
-  [{:keys [message-id args]} old new {:keys [updated-watch] :as diff} state]
-  (let [job (:job (common/peer->allocated-job (:allocations new) (:id state)))]
-    (common/start-new-lifecycle
-     old new diff
-     (cond (common/should-seal? new job state message-id)
-           (>!! (:seal-ch (:task-state state)) true)
+  [{:keys [args message-id] :as entry} old new {:keys [updated-watch] :as diff} state]
+  (if (and (= (:id state) (:id args))
+           (not (abort? old state entry)))
+    (do (close! (:restart-ch state))
+        state)
+    (let [job (:job (common/peer->allocated-job (:allocations new) (:id state)))]
+      (common/start-new-lifecycle
+        old new diff
+        (cond (common/should-seal? new job state message-id)
+              (>!! (:seal-ch (:task-state state)) true)

-           (and (= (:id state) (:observer updated-watch))
-                (not= (:observer updated-watch) (:subject updated-watch)))
+              (and (= (:id state) (:observer updated-watch))
+                   (not= (:observer updated-watch) (:subject updated-watch)))

-           (let [ch (chan 1)]
-             (extensions/on-delete (:log state) (:subject updated-watch) ch)
-             (go (when (<! ch)
-                   (extensions/write-log-entry
-                    (:log state)
-                    {:fn :leave-cluster :args {:id (:subject updated-watch)}
-                     :entry-parent message-id
-                     :peer-parent (:id state)}))
-                 (close! ch))
-             (close! (or (:watch-ch state) (chan)))
-             (assoc state :watch-ch ch))
+              (let [ch (chan 1)]
+                (extensions/on-delete (:log state) (:subject updated-watch) ch)
+                (go (when (<! ch)
+                      (extensions/write-log-entry
+                        (:log state)
+                        {:fn :leave-cluster :args {:id (:subject updated-watch)}
+                         :entry-parent message-id
+                         :peer-parent (:id state)}))
+                    (close! ch))
+                (close! (or (:watch-ch state) (chan)))
+                (assoc state :watch-ch ch))

-           :else state))))
+              :else state)))))


copy refinement

copy refinement

--- src/pc/views/blog/blue_ocean_made_of_ink.clj
+++ src/pc/views/blog/blue_ocean_made_of_ink.clj
@@ -35,8 +35,8 @@
      [:h3 "Simplicity—a good start."]
      [:p "Pen and paper demands no conscious effort.
          So competing here requires a minimum level of cognitive load.
-         This is why we only interface sparingly and omit common customization options.
-         Our constraints focus effort on productive behaviors.
+         This should explain our lean interface and modest amount of customization options.
+         Our constraints help us design productive behaviors.
          E.g., monotone shapes make emphasizing collaborator activity simple with color."]]

     [:article
@@ -50,13 +50,13 @@
      [:h3 "Accessibility—done."]
      [:p "Collaboration is the Precursor flagship.
          Handing someone a notebook is easy, but no easier than handing them a phone or a tablet.
-         Precursor takes it even further by connecting collaborators around the world.
+         Precursor takes the advantage by connecting collaborators around the world.
          Entire product teams can be communicating and designing concepts together in real time, within seconds."]]

     [:article
      [:h3 "We're more productive without pen and paper."]
      [:p "Paper inevitably gets damaged or forgotten.
-         I justified that to myself by looking at my sketches disposable, but I haven't actually found this to be true.
+         I tried justifying that to myself by looking at my sketches disposable, but I'm starting to realize this isn't true.
          Whenever I scroll through past prototypes on Precursor, I learn something new about my process.
          Consider the implications of a system like that for a moment.
          Imagine recalling every drawing or doodle you ever scratched on a piece of paper.


Simplify pepa.resources/image-resources.

--- src-cljs/pepa/resources.clj
+++ src-cljs/pepa/resources.clj
@@ -10,9 +10,7 @@
 (def +image-path+ (str +public-path+ "img/"))

 (defmacro image-resources []
-  (let [files# (->> (io/file +image-path+)
-                   (file-seq)
-                   (remove #(.isDirectory %))
-                   (map str)
-                   (map #(s/replace-first % +public-path+ "")))]
-    (vec files#)))
+  (into [] (comp (remove #(.isDirectory %))
+                 (map str)
+                 (map #(s/replace-first % +public-path+ "")))
+        (file-seq (io/file +image-path+))))


Jobs page edits

Jobs page edits

Adds actively hiring sections for support engineer, designer, and product manager.

Will likely need tweaking with the code, since I was copy/pasting for format and likely mangled it. :/

--- src-cljs/frontend/components/jobs.cljs
+++ src-cljs/frontend/components/jobs.cljs
@@ -32,7 +32,7 @@
           [:h2 "Why you'll love working at CircleCI"]
           [:p
            [:strong "Our culture is customer-driven."]
-           " Our customers and our founders are engineers, and most of our employees are too. We are inspired by companies like "
+           " Our customers and our founders are developers, and most of our employees are too. We are inspired by companies like "
            [:a {:href "http://blog.alexmaccaw.com/stripes-culture"} "Stripe,"]
            " "
            [:a {:href "http://gigaom.com/2012/03/26/tales-from-the-trenches-github/"} "GitHub,"]
@@ -41,18 +41,18 @@
            " and "
            [:a {:href "http://www.valvesoftware.com/company/Valve_Handbook_LowRes.pdf"} "Valve."]]
           [:p
-           [:strong "We have a flat organization."]
-           " There are no managers, no org-chart and no hierarchy, and we plan to keep it that way for as long as possible. Everyone gets access to all company information and can be involved in decision-making. By keeping communication open and transparent, we believe everybody is able to make good decisions about the best thing to work on."]
+           [:strong "We have an empowering organization."]
+           "Everyone gets access to all company information and can be involved in decision-making. By keeping communication open and transparent, we believe everybody is able to make good decisions about the best thing to work on."]
           [:p
            [:strong
             "We have a very strong focus on productivity, and on shipping product."]
            " This means you'll have a lot of days where you finish the day with the happy glow of having achieved something. We ship often, and shape our work lives around enabling that."]
           [:p
            [:strong "We spend a lot of time talking to customers."]
-           " We make it really easy for customers to reach out to us, and we reach out to them to ask for their feedback too. This means you'll probably spend significant time listening to and fixing their problems. We refer to that as \"support\", but really think of it as \"customer development\"."]
+           " We make it really easy for customers to reach out to us, and we reach out to them to ask for their feedback too. We pride ourselves in being customer-driven."]
           [:p
            [:strong "We use cool technology."]
-           " Our backend is written in Clojure. Everything from managing LXC containers to package management to serving our REST API is all done in Clojure. This allows us to be really productive, handle concurrency with ease, and leads to beautiful manageable code. Clojure isn't just a fancy new language, it's the most productive, powerful and elegant language we've ever used. So much so, that we're in the process of switching our frontend over to ClojureScript."]
+           " Our backend is written in Clojure. Everything from managing LXC containers to package management to serving our REST API is all done in Clojure. This allows us to be really productive, handle concurrency with ease, and leads to beautiful manageable code. Clojure isn't just a fancy new language, it's the most productive, powerful and elegant language we've ever used. So much so, that we've open sourced our front-end, and switched it over to ClojureScript."]
           [:p
            [:strong
             "At a small growing company, your work has a disproportionate effect."]
@@ -98,7 +98,7 @@
              "Folks with an interest in the whole company, not just their job. Our transparent culture allows everyone to take a holistic view of the company. As a result, we really like people who enjoy getting familiar with the whole business, customers, product, culture, selling, etc."]]]

           [:div#engineer
-           [:h3 [:span "Engineering roles"]]
+           [:h3 [:span "Developer roles"]]
            [:p
             "We're looking for great engineers: whether you've 10 years of experience shipping products, or are new to the industry with talent to burn and a fire in your belly, we need you to have amazing coding chops."]
            [:h5 "We'd love to see"]
@@ -125,9 +125,25 @@
             [:li
              "Experience building fat JS apps, stateful HTML5 apps, and data visualizations."]
             [:li "Good product and user experience sensibilities."]]
-           [:a
-            {:role "button", :href "/jobs#apply"}
-            [:span "Apply for Engineering roles"]]]
+           [:h5 "Actively Hiring"]
+           [:h5
+            [:strong "Support Engineer"]
+            " — are you empathetic to developers and love to problem-solve? We’d love to talk to you if you:"]
+           [:ul
+            [:li
+             "Have a strong familiarity with a broad spectrum of technology stacks, including Rails, Python, PHP, Node, Java, and others."]
+            [:li "Have the ability to dive into a codebase easily to discover issues."]
+            [:li "Have a customer-centric and diplomatic writing style: you'll be helping customers from a wide range of backgrounds, languages, and experience levels."]
+            [:li
+             "Love talking to people and helping them solve problems."]
+            [:li "Really want to assist developers in being happy and successful."]
+            [:li
+             "Have significant technical ability, with an understanding of the developer mindset, tools and culture."]
+            [:li
+             "Have the ability to fix problems that come up often so that they never happen to any customer again."]]
+           [:a
+            {:role "button", :href "/jobs#apply"}
+            [:span "Apply for Developer roles"]]]

           [:div#designer
            [:h3 [:span "Design roles"]]
@@ -146,15 +162,66 @@
            [:h5 "We would love to see"]
            [:ul
              [:li "An aptitude in many skill sets and a hunger for learning."]
-             [:li "The ability to communicate effeciently in a developer-centric environment."]
+             [:li "The ability to communicate efficiently in a developer-centric environment."]
              [:li "A keen eye and a very strong sense of taste."]
              [:li "A deep understanding of web design and development best practices."]
              [:li "Work you've done for other web-based developer tools."]
              [:li "Any other interesting work you wish to share, finished or not."]
              [:li "A willingness to approach sophisticated problems."]]
+           [:h5 "Actively Hiring"]
+           [:h5
+            [:strong "Designer"]
+            " — do you thrive on creating a customer experience that’s visually delightful? If so, you’ll fit in if you have:"]
+           [:ul
+            [:li
+             "An aptitude in many skill sets and a hunger for learning."]
+            [:li "The ability to communicate efficiently in a developer-centric environment."]
+            [:li "A keen eye and a very strong sense of taste."]
+            [:li
+             "A deep understanding of web design and development best practices."]
+            [:li "Work you've done for other web-based developer tools."]
+            [:li
+             "Any other interesting work you wish to share, finished or not."]
+            [:li
+             "A willingness to approach sophisticated problems."]]
            [:a
             {:role "button", :href "/jobs#apply"}
             [:span "Apply for Design roles"]]]
+
+          [:div#product
+           [:h3 [:span "Product Roles"]]
+           [:p
+            "We’re building tools for the next generation of application developers."]
+           [:h5 "You should be interested in:"]
+           [:ul
+            [:li "Helping create product roadmaps that maximize business opportunities while delighting customers."]
+            [:li
+             "Skillfully articulating your decision-making processes."]
+            [:li
+             "The convergence of marketing, engineering, and design."]
+            [:li
+             "Innovations in developer and SaaS tools."]]
+                     [:h5 "Actively Hiring"]
+           [:h5
+            [:strong "Product Manager"]
+            " — Do you love working with a variety of teams to create the best customer experience you can? We’d love to talk to you if you:"]
+           [:ul
+            [:li
+             "Have deep understanding of the developer community and the supporting ecosystem."]
+            [:li "Have launched developer or SaaS products or features."]
+            [:li "Like the challenge of prioritizing between customer needs and business priorities."]
+            [:li
+             "Can easily communicate with developers and designers to be the voice of your customer."]
+            [:li "Have an affinity for tracking metrics and utilizing them to build a better product."]
+            [:li
+             "Are passionate about open-source technologies."]
+            [:li
+             "Possess more than a passing interest in agile development methodologies."]
+           [:li
+             "Love working with customers to solve their problems."]]
+           [:a
+            {:role "button", :href "/jobs#apply"}
+            [:span "Apply for Product roles"]]]

           [:div#business
            [:h3 [:span "Business roles"]]


Morphs come with stable (arbitrary) sort order

--- src-cljs/frontend/devcards/morphs.cljs
+++ src-cljs/frontend/devcards/morphs.cljs
@@ -136,7 +136,10 @@
   (render [this]
     (let [{:keys [render-morphs]} (om-next/props this)
           {:keys [previous-morphs current-morphs]} (om-next/get-state this)]
-      (render-morphs (vals (merge previous-morphs current-morphs))))))
+      (->> (merge previous-morphs current-morphs)
+           (sort-by (comp hash key))
+           vals
+           render-morphs))))

 (def ^:private morph-display (om-next/factory MorphDisplay))


Pretty print the smoke-test output, add doc string

--- src/afterglow/core.clj
+++ src/afterglow/core.clj
@@ -13,10 +13,9 @@
 (def UniverseInfoReply (protodef Ola$UniverseInfoReply))

 (defn -main
-  "I don't do a whole lot ... yet."
+  "Test connectivity to the OLA server by sending a few messages and pretty-printing the responses."
   [& args]
-  (println "Hello, World!")
   (let [p (protobuf PluginListRequest)]
-    (ola/send-request "GetPlugins" p PluginListReply #(info "handling" %)))
+    (ola/send-request "GetPlugins" p PluginListReply #(info "Plugins" (with-out-str (clojure.pprint/pprint %)))))
   (let [p (protobuf OptionalUniverseRequest)]
-    (ola/send-request "GetUniverseInfo" p UniverseInfoReply #(info "universes" %))))
+    (ola/send-request "GetUniverseInfo" p UniverseInfoReply #(info "Universes" (with-out-str (clojure.pprint/pprint %))))))


Remove unused import on jws ns.

Remove unused import on jws ns.

--- src/buddy/sign/jws.clj
+++ src/buddy/sign/jws.clj
@@ -24,7 +24,6 @@
             [buddy.core.sign.rsapss :as rsapss]
             [buddy.core.sign.rsapkcs15 :as rsapkcs]
             [buddy.core.sign.ecdsa :as ecdsa]
-            [buddy.core.util :refer [maybe-let]]
             [clj-time.coerce :as jodac]
             [clj-time.core :as jodat]
             [clojure.string :as str]


Changes read-config to be more concise.

Changes read-config to be more concise.

The change made to read-config results in configuration from the file
taking precedence over environment variables. The resulting code is
more concise and the change in precedence is irrelevant anyways

--- src/cadence/config.clj
+++ src/cadence/config.clj
@@ -8,11 +8,10 @@
     (-> cres (.getPath) (load-file)) {}))

 (defn read-config [config-var]
-  (or (System/getenv config-var)
-      (get config-from-file
-            (keyword (string/replace
-                       (string/lower-case config-var)
-                       "_" "-")))))
+  (get config-from-file
+       (keyword (string/replace
+                  (string/lower-case config-var)
+                  "_" "-")) (System/getenv config-var)))

 (def storage {:uri (read-config "MONGOHQ_URL")
               :db-name (read-config "MONGO_DB_NAME")


Renable wrap-refresh on dev.

Renable wrap-refresh on dev.

--- src/cadence/server.clj
+++ src/cadence/server.clj
@@ -65,7 +65,7 @@
                              (-> app
                                (wrap-force-ssl))
                              (-> app
-                               ;(wrap-refresh)
+                               (wrap-refresh)
                                (wrap-stacktrace)))
                            {:port port})))
   ([] (-main {})))


Allow unknown-fn callback for state-loop.

--- src/cbfg/world/t2.cljs
+++ src/cbfg/world/t2.cljs
@@ -60,10 +60,10 @@

 ; --------------------------------------------

-(defn state-loop [actx name initial-state]
+(defn state-loop [actx name initial-state & {:keys [unknown-fn]}]
   (let [req-ch (achan actx)]
     (act-loop state-loop actx [name name state initial-state]
-              (let [m (atake state-loop req-ch)]
+              (when-let [m (atake state-loop req-ch)]
                 (case (:op m)
                   :get (do (aput state-loop (:res-ch m)
                                  (assoc m :status :ok :value state))
@@ -72,7 +72,11 @@
                                 (aput state-loop (:res-ch m)
                                       (assoc m :status :ok)))
                               (recur name ((:update-fn m) state)))
-                  :unknown-op)))
+                  (when unknown-fn
+                    (when-let [[state2 res] (unknown-fn state m)]
+                      (when res
+                        (aput state-loop (:res-ch m) res))
+                      (recur name state2))))))
     req-ch))

 ; --------------------------------------------


Rename to handle-lane.

Rename to handle-lane.

--- src/cbfg/world/t2.cljs
+++ src/cbfg/world/t2.cljs
@@ -34,13 +34,13 @@
            (assoc (dissoc m :pswd)
              :status :failed :status-info [:authenticate :closed])))))

-(defn rq-dispatch-lane [actx m]
-  (act rq-dispatch-lane actx
+(defn rq-handle-lane [actx m] ; Forward to lane-state-ch to handle the request.
+  (act rq-handle-lane actx
        (let [lane-state-ch (:lane-state-ch m)
-             res-ch (achan rq-dispatch-lane)]
-         (if (aput rq-dispatch-lane lane-state-ch
+             res-ch (achan rq-handle-lane)]
+         (if (aput rq-handle-lane lane-state-ch
                    (assoc m :res-ch res-ch))
-           (atake rq-dispatch-lane res-ch)
+           (atake rq-handle-lane res-ch)
            (assoc m :status :failed
                   :status-info [(:op m) :closed :dispatch-lane])))))

@@ -48,17 +48,17 @@

 (def rq-handlers
   {"authenticate" rq-authenticate
-   "realms-list" rq-dispatch-lane
+   "realms-list" rq-handle-lane
    "add" cbfg.world.base/example-add
    "sub" cbfg.world.base/example-add
    "count" cbfg.world.base/example-count
    "close-lane" cbfg.world.base/close-lane})

-(defn rq-dispatch [actx m] ((get rq-handlers (:op m)) actx m))
+(defn rq-handle [actx m] ((get rq-handlers (:op m)) actx m))

 ; --------------------------------------------

-(defn cmd-handler [c] (assoc c :rq rq-dispatch))
+(defn cmd-handler [c] (assoc c :rq rq-handle))

 (def cmd-handlers (into {} (map (fn [k] [k cmd-handler]) (keys rq-handlers))))


Implement update op in lane-handler.

Implement update op in lane-handler.

--- src/cbfg/world/t2.cljs
+++ src/cbfg/world/t2.cljs
@@ -55,9 +55,9 @@
            (let [res (atake rq-authenticate res-ch)]
              (when (= (:status res) :ok)
                (aput rq-authenticate lane-state-ch
-                     {:op :update
-                      :update-fn #(assoc % :cred {:realm realm
-                                                  :user user})}))
+                     (assoc m :op :update
+                            :update-fn #(assoc % :cred
+                                               {:realm realm :user user}))))
              res)
            (assoc (dissoc m :pswd)
              :status :failed :status-info [:authenticate :closed])))))
@@ -66,6 +66,8 @@

 (defn lane-handler [actx lane-state m]
   (case (:op m)
+    :update
+    [((:update-fn m) lane-state) (assoc m :status :ok)]
     "realms-list"
     (let [server-state-ch (:server-state-ch m)]
       (act fwd-realms-list actx


make create-entity! take conn arg

make create-entity! take conn arg

--- src/chat/server/db.clj
+++ src/chat/server/db.clj
@@ -136,15 +136,9 @@
                                :type (:extension/type x)})
                       (:extension/_group e))}))

-(defmacro with-conn
-  "Execute the body with *conn* dynamically bound to a new connection."
-  [& body]
-  `(binding [*conn* (d/connect *uri*)]
-     ~@body))
-
 (defn- create-entity!
   "create entity with attrs, return entity"
-  [attrs]
+  [conn attrs]
   (let [new-id (d/tempid :entities)
         {:keys [db-after tempids]} @(d/transact conn
                                                 [(assoc attrs :db/id new-id)])]
@@ -298,10 +292,10 @@
   (some? (d/pull (d/db conn) '[:group/id] [:group/name group-name])))

 (defn create-group!
-  [{:keys [name id]}]
-  (-> {:group/id id
+  [conn {:keys [name id]}]
+  (->> {:group/id id
        :group/name name}
-      create-entity!
+      (create-entity! conn)
       db->group))

 (defn email-taken?
@@ -310,13 +304,13 @@

 (defn create-user!
   "creates a user, returns id"
-  [{:keys [id email avatar nickname password]}]
-  (-> {:user/id id
+  [conn {:keys [id email avatar nickname password]}]
+  (->> {:user/id id
        :user/email email
        :user/avatar avatar
        :user/nickname (or nickname (-> email (string/split #"@") first))
        :user/password-token (password/encrypt password)}
-      create-entity!
+      (create-entity! conn)
       db->user))

 (defn nickname-taken?
@@ -373,13 +367,13 @@
   (:user/email (d/pull (d/db conn) [:user/email] [:user/id user-id])))

 (defn create-invitation!
-  [{:keys [id inviter-id invitee-email group-id]}]
-  (-> {:invite/id id
+  [conn {:keys [id inviter-id invitee-email group-id]}]
+  (->> {:invite/id id
        :invite/group [:group/id group-id]
        :invite/from [:user/id inviter-id]
        :invite/to invitee-email
        :invite/created-at (java.util.Date.)}
-      create-entity!
+      (create-entity! conn)
       db->invitation))

 (defn get-invite
@@ -579,11 +573,12 @@
     conn
     [[:db/retract [:user/id user-id] :user/open-thread [:thread/id thread-id]]]))

-(defn create-tag! [attrs]
-  (-> {:tag/id (attrs :id)
+(defn create-tag!
+  [conn attrs]
+  (->> {:tag/id (attrs :id)
        :tag/name (attrs :name)
        :tag/group [:group/id (attrs :group-id)]}
-      create-entity!
+      (create-entity! conn)
       db->tag))

 (defn tag-group-id [conn tag-id]
@@ -774,13 +769,13 @@
                        :tag/description description]]))

 (defn create-extension!
-  [{:keys [id type group-id user-id config]}]
-  (-> {:extension/group [:group/id group-id]
+  [conn {:keys [id type group-id user-id config]}]
+  (->> {:extension/group [:group/id group-id]
        :extension/user [:user/id user-id]
        :extension/type type
        :extension/id id
        :extension/config (pr-str config)}
-      create-entity!
+      (create-entity! conn)
       db->extension))

 (defn retract-extension!