+(defn alzarsi)

+(defn alzarsi)

--- src/babel/italiano/writer.clj
+++ src/babel/italiano/writer.clj
@@ -7,6 +7,7 @@
 (require '[babel.writer :refer [delete-from-expressions process write-lexicon]])
 (require '[clojure.tools.logging :as log])
 (require '[dag-unify.core :refer (fail? get-in strip-refs unify)])
+(require '[clojure.string :refer [join]])

 (defn rewrite-lexicon []
   (write-lexicon "it" @lexicon))
@@ -56,6 +57,82 @@
                              (filter #(= % "camminare")
                                      (sort (keys root-verbs)))))))))

+
+(defn alzarsi [ & [count]]
+  (let [count (if count (Integer. count) 10)
+        ;; subset of the lexicon: only verbs which are infinitives and that can be roots:
+        ;; (i.e. those that have a specific (non- :top) value for [:synsem :sem :pred])
+        root-verbs
+        (zipmap
+         (keys @lexicon)
+         (map (fn [lexeme-set]
+                (filter (fn [lexeme]
+                          (and
+                           (= (get-in lexeme [:synsem :cat]) :verb)
+                           (= (get-in lexeme [:synsem :infl]) :top)
+                           (not (= :top (get-in lexeme [:synsem :sem :pred] :top)))))
+                        lexeme-set))
+              (vals @lexicon)))
+
+        alzarsi
+        (reduce concat
+                (map (fn [key]
+                       (get root-verbs key))
+                     (filter #(= % "alzarsi")
+                             (sort (keys root-verbs)))))]
+
+    (delete-from-expressions "it" {:root {:italiano {:italiano "alzarsi"}}})
+
+;    (write-lexicon "it" @lexicon)
+;    (log/info (str "done writing lexicon."))
+    (log/info (str "generating examples with this many verbs:"
+                   (.size alzarsi)))
+    (.size (map (fn [verb]
+                  (log/debug (str "HELLO: VERB: " verb))
+                  (let [root-form (get-in verb [:italiano :italiano])]
+                    (log/debug (str "generating from root-form:" root-form))
+                    (.size (map (fn [tense]
+                                  (let [spec (unify {:root {:italiano {:italiano root-form}}}
+                                                    tense)]
+                                    (.size
+                                     (map (fn [gender]
+                                            (let [spec (unify spec
+                                                              {:comp {:synsem {:agr gender}}})]
+                                              (log/trace (str "generating from gender: " gender))
+                                              (.size
+                                               (map (fn [person]
+                                                      (let [spec (unify spec
+                                                                        {:comp {:synsem {:agr {:person person}}}})]
+                                                        (log/trace (str "generating from person: " person))
+                                                        (.size
+                                                         (map (fn [number]
+                                                                (let [spec (unify spec
+                                                                                {:comp {:synsem {:agr {:number number}}}})]
+                                                                  (log/debug (str "generating from spec: " spec))
+                                                                  (process [{:fill
+                                                                             {:count 1
+                                                                              :spec spec
+                                                                              :target-model small
+                                                                              :source-model en/small-plus-vp-pronoun}}]
+                                                                "it")))
+                                                              [:sing :plur]))))
+                                                    [:1st :2nd :3rd]))))
+                                          (cond (= tense
+                                                   {:synsem {:sem {:aspect :perfect
+                                                                   :tense :past}}})
+                                                [{:gender :masc}
+                                                 {:gender :fem}]
+                                                true
+                                                [:top])))))
+                                (list {:synsem {:sem {:tense :conditional}}}
+                                      {:synsem {:sem {:tense :future}}}
+                                      {:synsem {:sem {:tense :present}}}
+                                      {:synsem {:sem {:aspect :progressive
+                                                      :tense :past}}}
+                                      {:synsem {:sem {:aspect :perfect
+                                                      :tense :past}}})))))
+                alzarsi))))
+
 (defn tutti [ & [count]]
   (let [count (if count (Integer. count) 10)
         ;; subset of the lexicon: only verbs which are infinitives and that can be roots:


Fix broken fleetdb.server.

Fix broken fleetdb.server.

--- src/clj/fleetdb/server.clj
+++ src/clj/fleetdb/server.clj
@@ -3,7 +3,6 @@
             (clojure.contrib [def :only (defvar-)]))
   (:require (fleetdb [file :as file] [thread-pool :as thread-pool]
                      [lint :as lint] [embedded :as embedded])
-            fleetdb
             (clj-stacktrace [repl :as stacktrace])
             (clojure.contrib [str-utils :as str-utils] [duck-streams :as du])
             (clj-json [core :as json]))
@@ -16,8 +15,12 @@
             (joptsimple OptionParser OptionSet OptionException))
   (:gen-class))

+(let [stream  (.getResourceAsStream (RT/baseLoader) "project.clj")
+      version (nth (read-string (du/slurp* stream)) 2)]
+  (defvar- fleetdb-version version))
+
 (defn- info-map [dba]
-  (let [base {"fleetdb-version" fleetdb/version}
+  (let [base {"fleetdb-version" fleetdb-version}
         pers (embedded/persistent? dba)]
     (if pers
       (assoc base
@@ -123,10 +126,6 @@
 (defn- parse-int [s]
   (and s (Integer/decode s)))

-(let [stream  (.getResourceAsStream (RT/baseLoader) "project.clj")
-      version (nth (read-string (du/slurp* stream)) 2)]
-  (defvar- fleetdb-version version))
-
 (defn -main [& args]
   (let [args-array (into-array String args)
         opt-parser (OptionParser. "f:ep:a:t:x:vh")


issue #8 openid impl

issue #8 openid impl

--- src/clj/hit_wl/handler.clj
+++ src/clj/hit_wl/handler.clj
@@ -17,15 +17,36 @@
             [clojure.edn :as edn]
             [cemerick.friend :as friend]
             [clojure.java.io :as io]
+            [cemerick.friend.openid :as openid]
             (cemerick.friend [workflows :as workflows]
                              [credentials :as creds])
             [nomad :refer [defconfig]]
-            [frodo.web :refer [App]]))
+            [frodo.web :refer [App]])
+  (:import java.net.URI))

 (defconfig app-config (io/resource "config.edn"))
+
+(def providers [{:name "Google" :url "https://www.google.com/accounts/o8/id"}
+                {:name "Yahoo" :url "http://me.yahoo.com/"}
+                {:name "AOL" :url "http://openid.aol.com/"}
+                {:name "Wordpress.com" :url "http://username.wordpress.com"}
+                {:name "MyOpenID" :url "http://username.myopenid.com/"}])

 (defn is-dev? []
   (= :dev (:env app-config)))
+
+(defn resolve-uri
+  [context uri]
+  (let [context (if (instance? URI context) context (URI. context))]
+    (.resolve context uri)))
+
+(defn context-uri
+  "Resolves a [uri] against the :context URI (if found) in the provided
+   Ring request.  (Only useful in conjunction with compojure.core/context.)"
+  [{:keys [context]} uri]
+  (if-let [base (and context (str context "/"))]
+    (str (resolve-uri base uri))
+    uri))

 (def login-form
   [:div {:class "container"}
@@ -60,6 +81,34 @@
   (:db-config (app-config)))

+(defn open-id-login-form [req]
+  [:div {:class "container"}
+   [:h2 "Authenticating with various services using OpenID"]
+   [:h3 "Current Status " [:small "(this will change when you log in/out)"]]
+   (if-let [auth (friend/current-authentication req)]
+     [:p "Some information delivered by your OpenID provider:"
+      [:ul (for [[k v] auth
+                 :let [[k v] (if (= :identity k)
+                               ["Your OpenID identity" (str (subs v 0 (* (count v) 2/3)) "…")]
+                               [k v])]]
+             [:li [:strong (str (name k) ": ")] v])]]
+     [:div
+      [:h3 "Login with…"]
+      (for [{:keys [name url]} providers
+            :let [base-login-url (context-uri req (str "/login?identifier=" url))
+                  dom-id (str (gensym))]]
+        [:form {:method "POST" :action (context-uri req "login")
+                :onsubmit (when (.contains ^String url "username")
+                            (format "var input = document.getElementById(%s); input.value = input.value.replace('username', prompt('What is your %s username?')); return true;"
+                                    (str \' dom-id \') name))}
+         [:input {:type "hidden" :name "identifier" :value url :id dom-id}]
+         [:input {:type "submit" :class "button" :value name}]])
+      [:p "…or, with a user-provided OpenID URL:"]
+      [:form {:method "POST" :action (context-uri req "login")}
+       [:input {:type "text" :name "identifier" :style "width:250px;"}]
+       [:input {:type "submit" :class "button" :value "Login"}]]])
+   [:h3 "Logging out"]
+   [:p [:a {:href (context-uri req "logout")} "Click here to log out"] "."]])

 (defn get-userdata [username]
   {:username username
@@ -83,22 +132,26 @@

 (defroutes app-routes
   (GET "/" [] (h/html5 pretty-head (pretty-body
-                                   [:a {:href "/login"} "Login"])))
+                                   [:a {:href "/signin"} "Login"])))
   (GET "/user/profile" []
-       (friend/authorize #{::user}
+       (friend/authenticated
                          (slurp "resources/public/html/index.html")))
   (GET "/user/data" request
-       (friend/authorize #{::user}
+       (friend/authenticated
                          (->
-                          (:username (friend/current-authentication))
+                          (:email (friend/current-authentication))
                           (get-userdata)
                           response)))
   (POST "/user/save" {body :body}
-        (friend/authorize #{::user}
+        (friend/authenticated
                           (do (save-document body)
                               (response
                                {:status  "OK"}))))
-  (GET "/login" request
+  (GET "/signin" request
+       (h/html5
+        pretty-head
+        (pretty-body (open-id-login-form request))))
+  (GET "/login2" request
        (h/html5 pretty-head (pretty-body login-form)))
   (GET "/logout" req
     (friend/logout* (redirect (str (:context req) "/"))))
@@ -153,16 +206,15 @@
   (-> (handler/site app-routes)
       (init-middleware)
       (friend/authenticate {:allow-anon? true
-                            :login-uri "/login"
                             :default-landing-uri "/user/profile"
                             :unauthorized-handler #(do
                                                      ( println (friend/current-authentication))
                                                      ( -> (h/html5 [:h2 "You do not have sufficient privileges to access " (:uri %)])
                                                           response
                                                           (status 401)))
-                            :credential-fn
-                            (partial creds/bcrypt-credential-fn users)
-                            :workflows [(workflows/interactive-form)]})
+                            :workflows [(openid/workflow
+                                         :openid-uri "/login"
+                                         :credential-fn identity)]})
       (ring-json/wrap-json-body {:keywords? true})
       (ring-json/wrap-json-response)
       (keyword-params/wrap-keyword-params)


diff fix failing on val :sentinel

diff fix failing on val :sentinel

--- src/cljc/commos/delta.cljc
+++ src/cljc/commos/delta.cljc
@@ -73,14 +73,14 @@
     (cond (and (map? a)
                (map? b))
           (reduce
-           (fn [acc k]
-             (let [in-a (get a k :sentinel)
-                   in-b (get b k :sentinel)]
+           (fn this-fn [acc k]
+             (let [in-a (get a k this-fn)
+                   in-b (get b k this-fn)]
                (cond
-                 (kw-identical? in-a :sentinel)
+                 (identical? in-a this-fn)
                  (assoc-in acc [1 k] in-b)

-                 (kw-identical? in-b :sentinel)
+                 (identical? in-b this-fn)
                  (assoc-in acc [0 k] in-a)

                  (not= in-a in-b)


Make creatuures spawn slightly less frequently

--- src/cljc/robinson/npc.cljc
+++ src/cljc/robinson/npc.cljc
@@ -254,7 +254,8 @@
   "Randomly add monsters inside the viewport."
   [state]
   (let [num-npcs (reduce + (vals (npc-freqs-in-player-place state)))]
-    (if (and (< (rr/uniform-int 100)
+    ;; higher random number = less npcs
+    (if (and (< (rr/uniform-int 110)
                 (if (rw/is-night? state)
                    (/ 180 (inc num-npcs))
                    (/ 80 (inc num-npcs))))


Use native long operations in clojure

Use native long operations in clojure

--- src/cljc/seria/buffer.cljc
+++ src/cljc/seria/buffer.cljc
@@ -56,7 +56,7 @@
                (read-ushort!  [this] (int (bit-and (.getShort this) 0xFFFF)))
                (read-int!     [this] (.getInt this))
                (read-uint!    [this] (long (bit-and (.getInt this) 0xFFFFFFFF)))
-               (read-long!    [this] (ints->long (.getInt this) (.getInt this)))
+               (read-long!    [this] (.getLong this))
                (read-float!   [this] (.getFloat this))
                (read-double!  [this] (.getDouble this))
                (read-char!    [this] (.getChar this))
@@ -68,9 +68,7 @@
                (write-ushort!  [this value] (.putShort this (unchecked-short (bit-and value 0xFFFF))))
                (write-int!     [this value] (.putInt this (int value)))
                (write-uint!    [this value] (.putInt this (unchecked-int (bit-and value 0xFFFFFFFF))))
-               (write-long!    [this value] (let [[int-1 int-2] (long->ints value)]
-                                              (.putInt this int-1)
-                                              (.putInt this int-2)))
+               (write-long!    [this value] (.putLong this (long value)))
                (write-float!   [this value] (.putFloat this (float value)))
                (write-double!  [this value] (.putDouble this (double value)))
                (write-char!    [this value] (.putChar this (char value)))


Fix toggle visibility of vectors

Fix toggle visibility of vectors

--- src/cljs/praline/core.cljs
+++ src/cljs/praline/core.cljs
@@ -62,7 +62,10 @@
       [:div.row.gutter
        [:div.grid.twelve
         [:div.parent
-         {:on-click (handle-show-path (range (count this)) app-state)} label]
+         {:on-click (handle-show-path
+                     (map #(conj key-path %) (range (count this)))
+                     app-state)}
+         label]
         (for [[indx i] (map-indexed vector this)
               :let [next-key-path (conj key-path indx)]
               :when (some #{next-key-path} visible)]


A way around out-of-flow scenario: https://www.figma.com/file/OgVe3FWrbzUaeYzjusVCK3/Google-Material-Design Adds props to re-form.core/field: - :key, so they don't get messed up - :soft-key, supplying different :soft-key will trigger re-bind of field

--- src/cljs/re_form/core.cljs
+++ src/cljs/re_form/core.cljs
@@ -210,9 +210,9 @@
           (rf/dispatch [:re-form/input-removed form-name path]))

         update-binding
-        (fn [{new-form :form-name new-path :path validators :validators}]
-          (swap! state (fn [{val :value err :errors path :path form :form-name :as curr-state}]
-                         (if (not (and (= new-path path) (= new-form form)))
+        (fn [{new-soft-key :soft-key new-form :form-name new-path :path validators :validators :as new-state}]
+          (swap! state (fn [{soft-key :soft-key val :value err :errors path :path form :form-name :as curr-state}]
+                         (if (or (not= soft-key new-soft-key) (not= path new-path) (not= form new-form))
                            (do
                              (when (and form path)
                                (unbind-input form path))
@@ -223,7 +223,8 @@
                                ;; future validations
                                (add-watch new-val-subscr :binded-field run-validators)

-                               {:form-name new-form
+                               {:soft-key new-soft-key
+                                :form-name new-form
                                 :path new-path
                                 :value new-val-subscr
                                 :validators validators}))
@@ -245,14 +246,15 @@
         (update-binding (second new-props)))

       :reagent-render
-      (fn [{:keys [on-change form-name path on-blur error-paths] :as props}]
+      (fn [{:keys [key on-change form-name path on-blur error-paths] :as props}]
         (let [flags @(rf/subscribe [:re-form/input-flags form-name path])
               is-form-submitting @(rf/subscribe [:re-form/is-form-submitting form-name])
               errors @(rf/subscribe [:re-form/input-errors form-name (into [path] error-paths)])]
           [:div.re-form-field {:class (->> flags
                                            (filter second)
                                            (map #(name (first %)))
-                                           (str/join " "))}
+                                           (str/join " "))
+                               :key key}
            [(:input props)
             (merge (dissoc props :form-name :path :input :validators)
                    {:value @(:value @state)


Moving from index to repository view works

--- src/cljs/repodoc/core.cljs
+++ src/cljs/repodoc/core.cljs
@@ -242,8 +242,12 @@
                                ])])
                (if repositories
                  (nm "div" [(nm "h2" "Repositories")
-                            (nm "ul" [(map #(nm "li" (get % "name"))
-                                           repositories)])]))])))
+                            (nm "ul"
+                                [(map #(nm "li"
+                                           [(nm "a"
+                                                {:href (str "#/repo/" (get % "full_name"))}
+                                                (get % "name"))])
+                                      repositories)])]))])))

 ;; Setup


cleaning

cleaning

--- src/clojure/nossal/app.clj
+++ src/clojure/nossal/app.clj
@@ -14,7 +14,7 @@

             [sitemap.core :refer [generate-sitemap]]

-            [nossal.web :refer [index dot log breakout iframe-demo]]
+            [nossal.web :refer [index dot log iframe-demo]]
             [nossal.util.web :refer [resize-image pwa-manifest]]
             [nossal.api.core :refer [debug]]
             [nossal.api.shortner :refer [create-database new-url redirect]]
@@ -88,9 +88,6 @@
   (GET "/log" request
     (log request))

-  (GET "/breakout" request
-    (breakout request))
-
   ; (GET "/miner" request
   ;   (miner request))


Fixed simulation; action choosing was broken.

--- src/clojure_robby/core.clj
+++ src/clojure_robby/core.clj
@@ -62,25 +62,34 @@

 (defn get-tile-index [t]
   "Returns the numeric index of a tile."
-  (+ 1 (.indexOf tiles t)))
+  (.indexOf tiles t))
+
+(defn get-action-index [a]
+  "Returns the numeric index of a tile."
+  (.indexOf actions a))

 (defn add-vec [v1 v2]
   "Adds 2 vectors"
   (map + v1 v2))

+
 (defn simulate [dna the-map]
   "Simulates the DNA on a map. Evaluates to the score the robot achieved in simul-steps."
   (defn make-step [[current-map pos score]]
     "Makes a single step on the map, according to the DNA sequence."
-    (defn nearby-tiles-idx []
-      "Returns the tile indices of nearby tiles in a vector."
+    (defn get-situation []
+      "Returns the tile situation at the current pos."
       (def nearby-tiles (map (fn[v] (get-tile the-map (add-vec pos v))) dir-vects))
       (map get-tile-index nearby-tiles))
-    (def action (nth dna (- (reduce * (nearby-tiles-idx)) 1)))
+    (defn get-action [tile-situation]
+      "Returns the index of action to take when faced with a given tile situation."
+      (def multipliers (map (fn [n] (** (count tiles) n)) (range (count actions))))
+      (reduce + (map * tile-situation multipliers)))
+    (def action (nth dna (get-action (get-situation))))
     (case action
       (\l \r \u \d)
       (do
-        (def new-pos (add-vec pos (nth dir-vects (get-tile-index action))))
+        (def new-pos (add-vec pos (nth dir-vects (get-action-index action))))
         (if (not= \w (get-tile current-map new-pos))
           [current-map new-pos score]
           [current-map pos (- score action-penalty)]))
@@ -98,6 +107,7 @@
   "Takes a bunch of individuals (DNAs) and cross-breeds by fitness."
   (def the-map (rand-map))
   (def ordered (reverse (sort-by (fn[dna] (simulate dna the-map)) individuals)))
+  (println (simulate (first ordered) the-map))
   (def crossed (map (fn [pair]
          (let [[a b] (vec pair)] (cross a b)))
        (partition 2 ordered)))


first cut at remote file invocation

first cut at remote file invocation

--- src/co/nclk/linen/node.clj
+++ src/co/nclk/linen/node.clj
@@ -62,13 +62,27 @@
     (log :debug
       (node-log-str node-name ip runid "stderr: " (clojure.string/trim err)))))

+(defn tempfile-name
+  []
+  (str ;;(System/getProperty "user.dir")
+       ".linen-temp-script-"
+       (java.util.UUID/randomUUID)))
+
+(defn invocation-string
+  [invocation tmpfile-name]
+  (if-let [t (:template invocation)]
+    (if-not (clojure.string/blank? (:match invocation))
+      (clojure.string/replace
+        t
+        (re-pattern (str (:match invocation)))
+        tmpfile-name)
+      (str t " " tmpfile-name))
+    (str invocation " " tmpfile-name)))

 (defn- invoke-local
   [checkpoint & [argv]]
   (binding [*log* (not (false? (:log checkpoint)))]
-    (let [tmpfile-name (str (System/getProperty "user.dir")
-                            "/.linen-temp-script-"
-                            (java.util.UUID/randomUUID))
+    (let [tmpfile-name (tempfile-name)
           proxy? (not (nil? argv))
           argv (or argv
                    (remove clojure.string/blank?
@@ -76,14 +90,7 @@
                        [(if-let [u (:user checkpoint)] ["sudo" "-u" u])
                         (if-let [d (:invocation checkpoint)]
                           (clojure.string/split
-                            (if-let [t (:template d)]
-                              (if-not (clojure.string/blank? (:match d))
-                                (clojure.string/replace
-                                  t
-                                  (re-pattern (str (:match d)))
-                                  tmpfile-name)
-                                (str t " " tmpfile-name))
-                              (str d " " tmpfile-name))
+                            (invocation-string d tmpfile-name)
                             #" ")
                           tmpfile-name
                           )])))]
@@ -214,12 +221,37 @@
                                                          (clojure.string/trim
                                                            (:source checkpoint)))))

-                             (let [result (ssh/ssh session {:cmd
+;;                             (let [result (ssh/ssh session {:cmd
+;;                                                            (str "sudo su "
+;;                                                                 (or (:user checkpoint)
+;;                                                                     "root")
+;;                                                                 " - ")
+;;                                                            :in (:source checkpoint)})]
+                             (let [tmpfile-name (str "./" (tempfile-name))
+                                   instr (str "echo " (-> (clojure.string/trim
+                                                            (with-out-str
+                                                              (clojure.pprint/pprint
+                                                                (:source checkpoint))))
+                                                          (clojure.string/replace "$" "\\$")
+                                                          (clojure.string/replace #"\\n" "\n")
+                                                          (clojure.string/replace #"\\\n" "\n")
+                                                          )
+                                              " > " tmpfile-name
+                                              ";\nchmod a+x " tmpfile-name
+                                              ";\n"
+                                              (invocation-string
+                                                (:invocation checkpoint)
+                                                tmpfile-name)
+                                              ";\nrc=$?"
+                                              ";\nrm " tmpfile-name
+                                              ";\nexit $rc")
+                                   ;;_ (do (println instr)) ;; (System/exit 0))
+                                   result (ssh/ssh session {:cmd
                                                             (str "sudo su "
                                                                  (or (:user checkpoint)
                                                                      "root")
                                                                  " - ")
-                                                            :in (:source checkpoint)})]
+                                                            :in instr})]
                                (when *log*
                                  (log-result (:out result)
                                              (:err result)


Add some logging to startup.

Add some logging to startup.

--- src/kixi/event/producer.clj
+++ src/kixi/event/producer.clj
@@ -9,13 +9,15 @@

 (defrecord EventProducer []
   component/Lifecycle
-  (start [this]
+  (start [{:keys [zookeeper max-message-size]}]
     (log/info "Starting EventProducer")
+    (log/info "  Zookeeper is: " zookeeper)
+    (log/info "  Max message size is: " max-message-size)
     (assoc this :instance
-           (p/producer {"metadata.broker.list" (zk/broker-list (:zookeeper this))
+           (p/producer {"metadata.broker.list" (zk/broker-list zookeeper)
                         "serializer.class" "kafka.serializer.DefaultEncoder"
                         "partitioner.class" "kafka.producer.DefaultPartitioner"
-                        "max.message.size" (:max-message-size this)
+                        "max.message.size" (str max-message-size)
                         "compression.codec" "1"})))
   (stop [this]
     (log/info "Stopping EventProducer")


Added thrift/status-loading? function.

Added thrift/status-loading? function.

--- src/clj/elephantdb/thrift.clj
+++ src/clj/elephantdb/thrift.clj
@@ -25,6 +25,9 @@

 (defn status-failed? [#^DomainStatus domain-status]
   (= (.getSetField domain-status) DomainStatus$_Fields/FAILED))
+
+(defn status-loading? [#^DomainStatus domain-status]
+  (= (.getSetField domain-status) DomainStatus$_Fields/LOADING))

 (defn domain-not-found-ex [domain]
   (DomainNotFoundException. domain))


Added docstring comment for ssl-context in create-client

--- src/clj/http/async/client.clj
+++ src/clj/http/async/client.clj
@@ -55,7 +55,8 @@
   - :request-timeout :: request timeout in ms
   - :user-agent :: User-Agent branding string
   - :async-connect :: Execute connect asynchronously
-  - :executor-service :: provide your own executor service for callbacks to be executed on"
+  - :executor-service :: provide your own executor service for callbacks to be executed on
+  - :ssl-context :: provide your own SSL Context"
   {:tag AsyncHttpClient}
   [& {:keys [compression-enabled
              connection-timeout


change messages to be a single thread/stream consumer only

--- src/clj_kafka/consumer/zk.clj
+++ src/clj_kafka/consumer/zk.clj
@@ -35,19 +35,18 @@
      (cons (.next it) (lazy-iterate it)))))

 (defn create-message-streams
+  "Creates message streams for consuming topics. "
   ([^ConsumerConnector consumer topic-count-map]
    (.createMessageStreams consumer topic-count-map))
   ([^ConsumerConnector consumer topic-count-map key-decoder value-decoder]
    (.createMessageStreams consumer topic-count-map key-decoder value-decoder)))

 (defn messages
-  "Creates a sequence of KafkaMessage messages from the given topic. Consumes
-   messages from a single stream."
-  [^ConsumerConnector consumer topic & {:keys [threads
-                                               key-decoder
-                                               value-decoder]
-                                        :or   {threads 1}}]
-  (let [topic-count-map {topic (int threads)}
+  "Provides a simple way to consume a sequence of KafkaMessage messages from the
+  named topic. Consumes on a single thread and returns a lazy sequence."
+  [^ConsumerConnector consumer topic & {:keys [key-decoder
+                                               value-decoder]}]
+  (let [topic-count-map {topic (int 1)}
         streams (if (or key-decoder value-decoder)
                   (create-message-streams consumer topic-count-map key-decoder value-decoder)
                   (create-message-streams consumer topic-count-map))


Update death reason text

Update death reason text

--- src/cljc/robinson/combat.cljc
+++ src/cljc/robinson/combat.cljc
@@ -379,7 +379,7 @@
                                               :dead)
                           :white))
             ;; defender is player
-            (let [cause-of-death (format "%s %s %s" (rc/noun->indefinite-article (get attacker :name))
+            (let [cause-of-death (format "%s %s's %s." (rc/noun->indefinite-article (get attacker :name))
                                                                                (get attacker :name)
                                                                                (name attack))]
               (-> state


Fixing the regular expression for matching concept type with extensions.

--- src/cmr/search/api/routes.clj
+++ src/cmr/search/api/routes.clj
@@ -88,7 +88,7 @@
 (def concept-type-w-extension-regex
   "A regular expression that matches URLs including the concept type (pluralized) along with a file
   extension."
-  #"(?:granules)|(?:collections)(?:\..+)?")
+  #"(?:(?:granules)|(?:collections))(?:\..+)?")

 (defn- build-routes [system]
   (routes


Fixing bug 001

Fixing bug 001

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/io/contexts.clj
+++ src/conexp/io/contexts.clj
@@ -175,14 +175,16 @@

             obj-idxs-map (hash-from-pairs
                           (for [obj-map (:content objs-map)]
-                            [(-> obj-map :content (find-tag :Name) :content first trim)
+                            [(apply str (-> obj-map :content (find-tag :Name) :content))
                              (set-of (get-in att [:attrs :AttributeIdentifier])
                                      [att (-> obj-map :content (find-tag :Intent) :content)])]))

             idx-atts-map (hash-from-pairs
                           (for [att-map (:content atts-map)]
                             [(get-in att-map [:attrs :Identifier])
-                             (-> att-map :content (find-tag :Name) :content first trim)]))]
+                             (apply str (-> att-map :content (find-tag :Name) :content))]))]
+        (assert (distinct? (vals idx-atts-map))
+                "Names of attributes must be different.")
         (make-context-nc (set (keys obj-idxs-map))
                          (set (vals idx-atts-map))
                          (set-of [g (idx-atts-map idx) ]


Fix message key so that message status updates work

--- src/status_im/ui/screens/desktop/main/chat/views.cljs
+++ src/status_im/ui/screens/desktop/main/chat/views.cljs
@@ -27,31 +27,32 @@
                                    :as current-chat}]
   (views/letsubs [chat-name         [:get-current-chat-name]
                   {:keys [pending? whisper-identity photo-path]} [:get-current-chat-contact]]
-    [react/view {:style styles/toolbar-chat-view}
-     [react/view {:style {:flex-direction :row
-                          :flex 1}}
-      (if public?
-        [react/view {:style (styles/topic-image color)}
-         [react/text {:style styles/topic-text}
-          (string/capitalize (second chat-name))]]
-        [react/image {:style styles/chat-icon
-                      :source {:uri photo-path}}])
-      [react/view {:style (styles/chat-title-and-type pending?)}
-       [react/text {:style styles/chat-title
-                    :font  :medium}
-        chat-name]
-       (cond pending?
-             [react/text {:style styles/add-contact-text
-                          :on-press #(re-frame/dispatch [:add-contact whisper-identity])}
-              (i18n/label :t/add-to-contacts)]
-             public?
-             [react/text {:style styles/public-chat-text}
-              (i18n/label :t/public-chat)])]]
-     [react/view
-      (when (and (not group-chat) (not public?))
-        [react/text {:style (styles/profile-actions-text colors/black)
-                     :on-press #(re-frame/dispatch [:show-profile-desktop whisper-identity])}
-         (i18n/label :t/view-profile)])
+    [react/view
+     [react/view {:style styles/toolbar-chat-view}
+      [react/view {:style {:flex-direction :row
+                           :flex 1}}
+       (if public?
+         [react/view {:style (styles/topic-image color)}
+          [react/text {:style styles/topic-text}
+           (string/capitalize (second chat-name))]]
+         [react/image {:style styles/chat-icon
+                       :source {:uri photo-path}}])
+       [react/view {:style (styles/chat-title-and-type pending?)}
+        [react/text {:style styles/chat-title
+                     :font  :medium}
+         chat-name]
+        (cond pending?
+              [react/text {:style styles/add-contact-text
+                           :on-press #(re-frame/dispatch [:add-contact whisper-identity])}
+               (i18n/label :t/add-to-contacts)]
+              public?
+              [react/text {:style styles/public-chat-text}
+               (i18n/label :t/public-chat)])]]
+      [react/view
+       (when (and (not group-chat) (not public?))
+         [react/text {:style (styles/profile-actions-text colors/black)
+                      :on-press #(re-frame/dispatch [:show-profile-desktop whisper-identity])}
+          (i18n/label :t/view-profile)])

       [react/text {:style (styles/profile-actions-text colors/black)
                    :on-press #(re-frame/dispatch [:chat.ui/clear-history-pressed])}
@@ -59,7 +60,7 @@
       [react/text {:style (styles/profile-actions-text colors/black)
                    :on-press #(re-frame/dispatch [:chat.ui/delete-chat-pressed chat-id])}
        (i18n/label :t/delete-chat)]]]
-    [connectivity/error-view {:top 2}]))
+    [connectivity/error-view {:top 2}]]))

 (views/defview message-author-name [{:keys [outgoing from] :as message}]
   (views/letsubs [current-account [:get-current-account]
@@ -170,7 +171,7 @@
         [react/view
          (doall
           (for [[index {:keys [from content message-id type value] :as message-obj}] (map-indexed vector (reverse messages))]
-            ^{:key (or message-id (str type value))}
+            ^{:key message-obj}
             [message content (= from current-public-key)
              (assoc message-obj :group-chat group-chat
                     :current-public-key current-public-key)]))]]])))


Update system.cljs

Update system.cljs

--- src/divergence/system.cljs
+++ src/divergence/system.cljs
@@ -248,9 +248,19 @@
 (defn use-item [entities]
   ())

-;;GAME CAMERA---------------------------------------------
+;;GAME CAMERA============================================
+(def screenWidth 800) ;not needed
+(def screenHeight 600) ;not needed
+
+(defn cameraXCheck [x]
+  (if (< x screenWidth) true false)) ;replace screenWidth with a levelWidth once it exists
+
 (defn update-camera-coords [camera x y]
-  (set! (.-x (.-position @camera)) x);;adjust the math here
+  (set! (.-x (.-position @camera)) (if (= (cameraXCheck x) true) (* -1 (- x 375)) (* x 0)))
+  ;;when the camera hits the end of the screen (screenWidth), it should stop scrolling
+  ;;right now when player hits edge of the screen he vanishes. (This is okay, final
+  ;;product will have object boundaries to prevent this)
+
   ;(set! (.-y (.-position @camera)) (- (@camera-coords :y) 50))
 )


implementing list products by category and list categories

--- src/eatme/item_library.clj
+++ src/eatme/item_library.clj
@@ -36,10 +36,12 @@
   ([q] (search q 1))
   ([q p] (call-api :productsearch {:searchtext q :page p})))

+(defn categories []
+  (call-api :listproductcategories))
+
+(defn products [category-id]
+  (call-api :listproductsbycategory {:category category-id}))
+
 ;; login and get a session id
 (defn init []
   (login))
-
-;; useful commands
-;; LISTPRODUCTCATEGORIES - Lists the departments, aisles and shelves in a nested format
-;; LISTPRODUCTSBYCATEGORY - Lists the products for a given shelf (provided by ListProductCategories. Now with new parameter EXTENDEDINFO=Y


Fix bug.

Fix bug.

--- src/forces_assemble/db.clj
+++ src/forces_assemble/db.clj
@@ -98,7 +98,7 @@

 (defn get-user-notification-tokens-on-channel
   [channel-id]
-  (filter cstr/blank? (distinct (map get-user-notification-token (get-channel-subscribers channel-id)))))
+  (remove cstr/blank? (distinct (map get-user-notification-token (get-channel-subscribers channel-id)))))

 (defn add-event-to-channel
   [channel-id event]


"anonymous solution", not "anonymous's solution"

--- src/foreclojure/social.clj
+++ src/foreclojure/social.clj
@@ -40,11 +40,14 @@
   "Create a new gist containing a user's solution to a problem and
   return its url."
   [user-name problem-num solution]
-  (let [user-name (or user-name "anonymous")
+  (let [[user-name possessive] (if user-name
+                                 [user-name "'s"]
+                                 ["anonymous" nil])
+
         {name :title} (fetch-one :problems
                                  :where {:_id problem-num})
         filename (str user-name "-4clojure-solution" problem-num ".clj")
-        text (str ";; " user-name "'s solution to " name "\n"
+        text (str ";; " user-name possessive " solution to " name "\n"
                   ";; https://4clojure.com/problem/" problem-num
                   "\n\n"
                   solution)]


disable printing compiled code

disable printing compiled code

--- src/kondolisp/compiler.clj
+++ src/kondolisp/compiler.clj
@@ -382,10 +382,9 @@
         (compile-resolve-labels
          (compile-compact
           (compile-pass1 exp)))]
-  (assemble
-   (pp-program
-    `(~@vm-inst-program
-      (:VM_EXIT))))))
+    (assemble
+     `(~@vm-inst-program
+       (:VM_EXIT)))))

 (defn compile-pass1 [exp]
   (cond


also store the source map in compiler state

--- src/main/cljs/cljs/js.cljs
+++ src/main/cljs/cljs/js.cljs
@@ -392,13 +392,18 @@
              (do
                (when (:source-map opts)
                  (let [t    (.valueOf (js/Date.))
-                       src  (str "cljs-" t ".cljs")
-                       file (str "cljs-" t ".js")
+                       smn  (if name
+                              (munge name)
+                              (str "cljs-" t))
                        smd  @comp/*source-map-data*
+                       src  (str smn ".cljs")
+                       file (str smn ".js")
                        json (sm/encode {src (:source-map smd)}
                               {:lines (+ (:gen-line smd) 3)
                                :file file :sources-content [source]})]
                    (when (:verbose opts) (debug-prn json))
+                   (swap! env/*compiler* assoc-in
+                     [:source-maps name] (:source-map smd))
                    (.append sb
                      (str "\n//# sourceURL=" file
                           "\n//# sourceMappingURL=data:application/json;base64,"


CMR-586: Added test for getting metadata with pure granule id search.

--- test/cmr/system_int_test/search/granule_search_test.clj
+++ test/cmr/system_int_test/search/granule_search_test.clj
@@ -381,6 +381,19 @@
            ;; Multiple values
            [gran1 gran2 gran3 gran4 gran5] [gran1-cid gran2-cid gran3-cid gran4-cid gran5-cid] {}
            [] [gran1-cid gran5-cid] {:and true}))
+    (testing "search granules by concept id retrieve metadata"
+      (are [items cid options]
+           (let [params (merge {:concept_id cid}
+                               (when options
+                                 {"options[concept_id]" options}))]
+             (d/assert-metadata-results-match :echo10
+                                              items
+                                              (search/find-metadata :granule :echo10 params)))
+           [gran1] gran1-cid {}
+           [gran5] gran5-cid {}
+           ;; Multiple values
+           [gran1 gran2 gran3 gran4 gran5] [gran1-cid gran2-cid gran3-cid gran4-cid gran5-cid] {}
+           [] [gran1-cid gran5-cid] {:and true}))
     (testing "Search with wildcards in concept_id param not supported."
       (is (= {:status 422
               :errors [(msg/invalid-pattern-opt-setting-msg #{:concept-id :echo-collection-id :echo-granule-id})]}


shrinked dot paint size

shrinked dot paint size

--- src/mastersign/drawing.clj
+++ src/mastersign/drawing.clj
@@ -12,7 +12,7 @@
            :or {color Color/RED}}]
   (doto g
     (.setColor color)
-    (.fill (ellipse (- (.x p) 2) (- (.y p) 2) 4 4)))))
+    (.fill (ellipse (- (.x p) 1) (- (.y p) 1) 2 2)))))

 (defn draw-dots
   [g ps o & {color :color


versino 1.8.0 of clojure and 0.2.395 of core.async

--- async-tea-party/project.clj
+++ async-tea-party/project.clj
@@ -1,8 +1,8 @@
-(defproject async-tea-party "0.1.0-SNAPSHOT"
+(defproject async-tea-party "1.0.0"
   :description "FIXME: write description"
   :url "http://example.com/FIXME"
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
-  :dependencies [[org.clojure/clojure "1.7.0"]
-                 [org.clojure/core.async "0.1.346.0-17112a-alpha"]]
+  :dependencies [[org.clojure/clojure "1.8.0"]
+                 [org.clojure/core.async "0.2.395"]]
   :main async-tea-party.core)


Add generator for :workflo.macros.view/view-name spec

--- src/main/workflo/macros/view.clj
+++ src/main/workflo/macros/view.clj
@@ -8,7 +8,9 @@
 ;;;; Specs

 (s/def ::view-name
-  capitalized-symbol?)
+  (s/with-gen
+    capitalized-symbol?
+    #(s/gen '#{Foo Bar FooBar})))

 (s/def ::view-form
   seq?)


remove bad reference to self

remove bad reference to self

--- src/metabase/models/database.clj
+++ src/metabase/models/database.clj
@@ -5,7 +5,6 @@
             [swiss.arrows :refer :all]
             [metabase.db :refer :all]
             (metabase.models [hydrate :refer [realize-json]]
-                             [database :refer [Database]]
                              [org :refer [Org]])
             [metabase.util :refer :all]))


Quick and dirty patch inspector

Quick and dirty patch inspector

--- src/mininova_web_ui/ui.cljs
+++ src/mininova_web_ui/ui.cljs
@@ -1,16 +1,18 @@
 (ns mininova-web-ui.ui
-  (:require [reagent.core :as reagent]
+  (:require [reagent.core :as r]
             [re-frame.core :as rf]
             [mininova-web-ui.midi :as midi]
             [mininova-web-ui.params :as params]))

+(def patch-inspector-enabled? true)
+
 (def patch-request-message
   [0xF0 0x00 0x20 0x29 0x03 0x01 0x7F 0x40 0x00 0x00 0x00 0x00 0x00 0xF7])

 (def patch-response-sentinel
   [0xF0 0x00 0x20 0x29 0x03 0x01 0x7F 0x00 0x00 0x09 0x04])

-(def default-panel :osc)
+(def default-panel (keyword (subs js/location.hash 1)))

 ;; FIXME: Get ridi of `re-frame: no :fx handler registered for :event` error
 (rf/reg-fx :event (fn [_ _]))
@@ -91,34 +93,40 @@

 (defn make-set-patch-value [data]
   (fn [db [id param]]
-    (if (contains? param :offset)
+    (if (and (contains? param :offset) (not= 0 (:offset param)))
       (assoc-in db [::control id] (nth data (:offset param)))
       db)))

+(defn apply-patch [db data]
+  (reduce (make-set-patch-value data) db params/params))
+
 (rf/reg-event-db ::midi/sysex
   [rf/debug]
   (fn [db [_ data]]
     (if (patch-dump? data)
-      (reduce (make-set-patch-value data) db params/params))))
+      (-> db
+          (apply-patch data)
+          (assoc ::patch data)))))
+
+(rf/reg-sub ::patch
+  (fn [db]
+    (::patch db)))
+
+(defn tab [{:keys [id]}]
+  (let [current-tab @(rf/subscribe [::panel])]
+    [:a {:class (if (or (= current-tab id)) (nil? current-tab) "is-active")
+         :href (str "#" (name id))
+         :on-click #(rf/dispatch [::panel id])}
+      (first (r/children (r/current-component)))]))

 (defn tabs []
-  (let [tab @(rf/subscribe [::panel])]
-    [:ul.tabs
-      [:li {:class (if (or (= tab :osc)) (nil? tab) "is-active")
-            :on-click #(rf/dispatch [::panel :osc])}
-        "Osc"]
-      [:li {:class (if (= tab :filter) "is-active")
-            :on-click #(rf/dispatch [::panel :filter])}
-        "Filter"]
-      [:li {:class (if (= tab :env) "is-active")
-            :on-click #(rf/dispatch [::panel :env])}
-        "Env"]
-      [:li {:class (if (= tab :lfo) "is-active")
-            :on-click #(rf/dispatch [::panel :lfo])}
-        "LFO"]
-      [:li {:class (if (= tab :arp) "is-active")
-            :on-click #(rf/dispatch [::panel :arp])}
-        "ARP"]]))
+  [:ul.tabs
+    [:li [tab {:id :filter} "Filter"]]
+    [:li [tab {:id :env} "Env"]]
+    [:li [tab {:id :lfo} "LFO"]]
+    [:li [tab {:id :arp} "ARP"]]
+    (if patch-inspector-enabled?
+      [:li [tab {:id :patch-inspector} "Patch inspector"]])])

 (defn map-in-out [in out value]
   (+ (- value (first in)) (first out)))
@@ -279,6 +287,20 @@
       [:li [toggle {:id :arp-7/step :label "Step 7"}]]
       [:li [toggle {:id :arp-8/step :label "Step 8"}]]]])

+(defn patch-inspector-panel []
+  (let [patch @(rf/subscribe [::patch])]
+    [:div.patch-inspector-panel
+      [:h2 "Patch inspector"]
+      [:button {:on-click #(rf/dispatch [::midi/patch])} "Fetch patch"]
+      [:div {:style {:height "400px" :overflow-y "scroll"}}
+        [:table
+          [:thead
+            [:tr [:th "Offset"] [:th "Value"]]]
+          [:tbody
+            (for [[offset value] (map vector (range (count patch)) patch)]
+              ^{:key offset}
+              [:tr [:td offset] [:td (str "0b" (.toString value 2))]])]]]]))
+
 (defn main-panel []
   (let [tab @(rf/subscribe [::panel])]
     [:main.main-panel
@@ -289,4 +311,5 @@
         :env [env-panel]
         :lfo [lfo-panel]
         :arp [arp-panel]
+        :patch-inspector [patch-inspector-panel]
         [:h2 "Select a panel"])]))


Addressing review comments.

Addressing review comments.

--- metadata-db-app/src/cmr/metadata_db/api/routes.clj
+++ metadata-db-app/src/cmr/metadata_db/api/routes.clj
@@ -30,6 +30,22 @@
         (concept-service/reset context)
         {:status 204}))))

+(def job-api-routes
+  (common-routes/job-api-routes
+    (routes
+      ;; Trigger the old revision concept cleanup
+      (POST "/old-revision-concept-cleanup" {:keys [request-context params headers]}
+        (let [context (acl/add-authentication-to-context request-context params headers)]
+          (acl/verify-ingest-management-permission context :update)
+          (mdb-jobs/old-revision-concept-cleanup context)
+          {:status 204}))
+
+      (POST "/expired-concept-cleanup" {:keys [request-context params headers]}
+        (let [context (acl/add-authentication-to-context request-context params headers)]
+          (acl/verify-ingest-management-permission context :update)
+          (mdb-jobs/expired-concept-cleanup context)
+          {:status 204})))))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (defn- build-routes [system]
@@ -38,23 +54,7 @@
       concepts-api/concepts-api-routes
       provider-api/provider-api-routes
       common-routes/cache-api-routes
-
-      (common-routes/job-api-routes
-        (routes
-          ;; Trigger the old revision concept cleanup
-          (POST "/old-revision-concept-cleanup" {:keys [request-context params headers]}
-            (let [context (acl/add-authentication-to-context request-context params headers)]
-              (acl/verify-ingest-management-permission context :update)
-              (mdb-jobs/old-revision-concept-cleanup context)
-              {:status 204}))
-
-          (POST "/expired-concept-cleanup" {:keys [request-context params headers]}
-            (let [context (acl/add-authentication-to-context request-context params headers)]
-              (acl/verify-ingest-management-permission context :update)
-              (mdb-jobs/expired-concept-cleanup context)
-              {:status 204}))))
-
-
+      job-api-routes
       (common-routes/health-api-routes hs/health)
       admin-api-routes)


edit return now have both save and cancel button, but they don't do anything

--- src/noteServer/handler.clj
+++ src/noteServer/handler.clj
@@ -56,7 +56,8 @@
                      [:button.remove-cancel-btn  {:name "cancel"} "Cancel"]]]
                     [:div.meta-module.edit-control-module {:role "module"}
                      [:div.button-spacer
-                      [:button {:name "end-edit"} "End Edit"]]]
+                      [:button {:name "save-edit"} "Save"]
+                      [:button {:name "cancel-edit"} "Cancel"]]]
                    ;[:template#meta-control-template
                     ;; TODO call this module something better
                     [:div.meta-module.meta-control-module {:role "module"}


convert from reference cursors to command channel

--- cljs/sledge/core.cljs
+++ cljs/sledge/core.cljs
@@ -38,15 +38,13 @@
               :term #{}
               :results []
               }
-     :queue {
-             :tracks []
-             :next-track 0 ; now-playing (dec next-track)
-             }
-     :player-queue []  ; do not use
-     :viewing-queue? false
-     :player {:track-number 0
-              :playing true
-              :track-offset 0
+     :player {
+              :queue {
+                      :tracks []
+                      :next-track 0 ; now-playing (dec next-track)
+                      }
+              :want-play true
+              :audio-el {:track-offset 0 :playing false}
               }
      }))

@@ -120,53 +118,10 @@
 (defn enqueue-track [queue track]
   (update-in queue [:tracks] conj track))

-(defn search-results []
-  (om/ref-cursor (:results (:search (om/root-cursor app-state)))))
-
-(defn player-queue []
-  (om/ref-cursor (:player-queue (om/root-cursor app-state))))
-
-(defn player-state []
-  (om/ref-cursor (:player (om/root-cursor app-state))))
-
-(defn player-pause []
-  (om/transact! (player-state) #(update-in % [:playing] not)))
-
-(defn current-track []
-  (nth (player-queue) (:track-number (player-state)) nil))
-
-(defn player-next []
-  ;; how do we make this fail if there are no more tracks?
-  (om/transact! (player-state) #(update-in % [:track-number] inc)))
-
-(defn player-playing [e]
-  (let [player (.-target e)
-        offset (.-currentTime player)]
-    (om/transact! (player-state)
-                  #(update-in % [:track-offset]
-                              (fn [time] offset)))))
-
-(defn player-prev []
-  (let [dec0 #(max (dec %) 0)]
-    (om/transact! (player-state) #(update-in % [:track-number] dec0))))
-
-
-(defn player-el []
-  (aget (.getElementsByTagName js/document "audio") 0))
-
-(defn enqueue-track [track]
-  (om/transact! (player-queue) #(conj % track)))
-
-(defn dequeue-track [index]
-  (om/transact! (player-queue)
-                (fn [v] (vec (concat (subvec v 0 index)
-                                     (subvec v (inc index)))))))
 (deftest enqueue-test
   (let [q {:tracks [:a :b :c :d] :next-track 2}]
     (is (= (:tracks (enqueue-track q :z)) [:a :b :c :d :z]))))

-(defn dequeue-all []
-  (om/transact! (player-queue) (fn [v] [])))

 (defn mmss [seconds]
   (let [m (quot seconds 60)
@@ -189,6 +144,7 @@
     om/IRender
     (render [this]
       (let [search-chan (om/get-shared owner :search-channel)
+            command-chan (om/get-shared owner :command-channel)
             artist (dom/span
                     #js {:className "artist"
                          :onClick #(put! search-chan
@@ -205,7 +161,10 @@
             title (dom/span #js {:className "title"}
                             (str (get track "track") " - " (get track "title")))
             duration (dom/span #js {:className "duration"} (mmss (get track "length")))
-            button (dom/button #js {:onClick #(enqueue-track @track)} "+")]
+            button (dom/button #js
+                               {:onClick #(put! command-chan
+                                                [:enqueue @track])}
+                               "+")]
         (apply dom/div #js {:className "track"}
                [title artist album duration button]
                )))))
@@ -240,10 +199,12 @@
   (reify
     om/IRender
     (render [this]
-      (let [button (dom/button
+      (let [command-chan (om/get-shared owner :command-channel)
+            button (dom/button
                     #js {:onClick
-                         (fn [e] (doall (map #(enqueue-track %)
-                                             tracks)))}
+                         (fn [e] (doall
+                                  (map #(put! command-chan [:enqueue %])
+                                       tracks)))}
                     "+")
             track-components
             (om/build-all results-track-view tracks)]
@@ -261,23 +222,29 @@
   (reify
     om/IRenderState
     (render-state [this {:keys [index current?]}]
-      (dom/div #js {:className (if current? "current-track track" "track")}
-               (dom/span #js {:className "artist"} (get track "artist"))
-               (dom/span #js {:className "album"} (get track "album" ))
-               (dom/span #js {:className "title"} (get track "title"))
-               (dom/span #js {:className "duration"} (mmss (get track "length")))
-               (dom/button #js {:onClick #(dequeue-track index)}
-                           "-")))))
+      (let [command-chan (om/get-shared owner :command-channel)]
+        (html
+         [:div {:className (if current? "current-track track" "track")}
+          [:span {:className "artist"} (get track "artist")]
+          [:span {:className "album"} (get track "album" )]
+          [:span {:className "title"} (get track "title")]
+          [:span {:className "duration"} (mmss (get track "length"))]
+          [:button {:onClick #(put! command-chan [:dequeue index])}
+           "-"]])))))

 (defn audio-el [state owner]
   (reify
     om/IDidMount
     (did-mount [_]
       (let [el (om/get-node owner)]
-        ;; last arg "true" is cos audio events don't bubble
-        ;; http://stackoverflow.com/questions/11291651/why-dont-audio-and-video-events-bubble
-        (.addEventListener el "ended" player-next true)
-        (.addEventListener el "timeupdate" player-playing true)))
+        ;; add capturing handler (last arg "true")
+        ;; cos audio events don't bubble
+        (.addEventListener el "ended"
+                           #(om/update! state [:ended] true)
+                           true)
+        (.addEventListener el "timeupdate"
+                           #(om/update! state [:time-offset]
+                                        (.-currentTime (.-target %))))))
     om/IRender
     (render [_]
       (html [:audio {:ref "player"}]))))
@@ -327,23 +294,36 @@
         (polygon 40,0 80,50 40,100 40,0)
         (polygon 85,0 95,0 95,100 85,100 85,0)]))

+(defn player-el []
+  (aget (.getElementsByTagName js/document "audio") 0))
+
 (defn transport-buttons-view [app owner]
   (reify
     om/IRender
     (render [this]
-      (let [queue (om/observe owner (player-queue))
-            playing? (:playing (player-state))
-            track (current-track)]
+      (let [wanted (:player app)
+            queue (:queue wanted)
+            actual (player-el)
+            want-play (:playing (:audio-el wanted))
+            actually-playing (and actual (not (.-paused actual)))
+            command-chan (om/get-shared owner :command-channel)
+            playing (cond
+                      (and actually-playing (not want-play))
+                      :pending
+                      (and (not actually-playing) want-play)
+                      :pending
+                      (:playing wanted)
+                      true
+                      :else false)
+            track (queue-current-entry queue)]
         (html
          [:div {:id "transport"
                 :onClick #(om/transact! app [:viewing-queue?] not)
                 }
           [:span {:className "index"}
-           [:span {:className "current"}
-            (inc (:track-number (player-state)))]
+           [:span {:className "current"} (:next-track queue)]
            "/"
-           [:span {:className "total"}
-            (count (player-queue))]]
+           [:span {:className "total"} (count (:tracks queue))]]
           [:div {:className "title-artist"}
            [:span {:className "title"}
             (get track "title")]
@@ -352,15 +332,21 @@
            [:span {:className "album"}
             (get track "album")]]
           [:span {:className "buttons"}
-           [:button {:onClick (swallowing player-prev) }
+           [:button {:onClick
+                     (swallowing #(put! command-chan [:previous-track]))}
             (svg-skip-track :backwards)]
-           [:button {:onClick (swallowing player-pause) }
-            (if playing? (svg-pause) (svg-play))]
-           [:button {:onClick (swallowing player-next) }
+           [:button {:onClick
+                     (swallowing #(put! command-chan [:toggle-pause]))}
+            (case playing
+              true (svg-pause)
+              :pending (svg-spinner)
+              false (svg-play))]
+           [:button {:onClick
+                     (swallowing #(put! command-chan [:next-track]))}
             (svg-skip-track)]]
           [:span {:className "offset"}
            [:span {:className "elapsed-time time"}
-            (mmss (:track-offset (player-state)))]
+            (mmss (-> wanted :audio-el :time-offset))]
            " / "
            [:span {:className "track-time"}
             (mmss (get track "length" 0))]]
@@ -370,18 +356,19 @@
   (reify
     om/IRender
     (render [this]
-      (let [queue (om/observe owner (player-queue))]
+      (let [queue (-> app :player :queue)
+            command-chan (om/get-shared owner :command-channel)]
         (html
          [:div {}
           [:div {:className "track header"}
            [:span {:className "artist"} "Delete queue"]
-           [:button {:onClick #(dequeue-all)} "-"]]
+           [:button {:onClick #(put! command-chan [:delete-queue])}
+            "-"]]
           (map #(om/build queue-track-view
                           %1
                           {:state
                            {:index %2
-                            :current? (= (-> app :player :track-number)
-                                         %2)
+                            :current? (= (dec (:next-track queue)) %2)
                             }})
                queue (range 0 999))
           ])))))
@@ -483,15 +470,10 @@
       (when (and bits (not (= actual-path bits)))
         (set! (.-src actual) bits)))

-    (when (and (.-paused actual) (:playing desired) urls)
-      ;; it might have paused because it reached the end of track, or
-      ;; because the user previously paused it.  If we have music available,
-      ;; now, resume.
-      ;; On Android, this appears to trigger the generation of an ended event
-      ;; that might not otherwise get sent, which is nice.  However,
+    (when (and (.-paused actual) (:want-play desired) urls)
       (.play actual))

-    (if-not (:playing desired)
+    (if-not (:want-play desired)
       (.pause actual))))

@@ -508,19 +490,40 @@
            (om/build queue-view state)]
           [:div {:className "queue tracks" } " "])
         (om/build transport-buttons-view state)
-        (om/build audio-el state)
+        (om/build audio-el (:audio-el (:player state)))
         ]))))
+
+(defmulti dispatch-command (fn  [command & args] command))
+
+(defmethod dispatch-command :enqueue [_ track]
+  (swap! app-state #(update-in % [:player :queue] enqueue-track track)))
+
+(defmethod dispatch-command :toggle-pause [_]
+  (swap! app-state #(update-in % [:player :want-play] not)))
+
+(defmethod dispatch-command :next-track [_]
+  (swap! app-state #(update-in % [:player :queue] advance-queue)))
+
+;; still to add: [dequeue previous-track delete-queue]
+
+(defn command-loop []
+  (let [ch (chan)]
+    (go
+      (loop []
+        (let [command (<! ch)]
+          (apply dispatch-command command)
+          (recur))))
+    ch))

 (defn init []
   (add-watch app-state :transport sync-transport)
   (let [el (. js/document (getElementById "om-app"))
+        command-chan (command-loop)
         search (chan)]
     (om/root app-view app-state
              {:target el
-              :shared {:search-channel search}})))
+              :shared {:command-channel command-chan
+                       :search-channel search}})))

 (.addEventListener js/window "load" init)
-
-
-
 (cljs.test/run-tests)


Riemann batch size 1 test

Riemann batch size 1 test

--- src/onyx_benchmark/peer.clj
+++ src/onyx_benchmark/peer.clj
@@ -65,7 +65,7 @@
         host-id (str (java.util.UUID/randomUUID))
         m-cfg (monitoring/monitoring-config 10000)
         riemann-config {:riemann/address riemann-addr
-                        :riemann/batch-size 5
+                        :riemann/batch-size 1
                         :riemann/port (Integer/parseInt riemann-port)}
         monitoring-thread (riemann/riemann-sender riemann-config (:monitoring/ch m-cfg))
         peers (onyx.api/start-peers n-peers-parsed peer-group m-cfg)]


Fix bad merge that messed up COUNT aggregations

--- src/cfpb/qu/data/aggregation.clj
+++ src/cfpb/qu/data/aggregation.clj
@@ -34,7 +34,8 @@
                (var vals (.map ary (fn [obj] (return (aget obj field)))))
                (return (.sum Array vals))))
    :count (js* (fn [ary field]
-                 (return (aget ary "length"))))})
+                 (var vals (.map ary (fn [obj] (return (aget obj field)))))
+                 (return (.sum Array vals))))})

 (defn- generate-map-fn
   ([group-fields agg-fields]


Call finished even if the build fails. Fixes a bug with masters not gracefully shutting down.

--- src/circle/backend/build/run.clj
+++ src/circle/backend/build/run.clj
@@ -58,6 +58,7 @@
       (email/send-build-error-email b e)
       (throw e))
     (finally
+     (finished b)
      (log-result b)

      (when (and (-> @b :failed) cleanup-on-failure)


add restriction to have events on Heap when playing SOT, fixes #1054

--- src/clj/game/cards-resources.clj
+++ src/clj/game/cards-resources.clj
@@ -656,7 +656,9 @@

    "Same Old Thing"
    {:abilities [{:cost [:click 2]
-                 :req (req (not (seq (get-in @state [:runner :locked :discard]))))
+                 :req (req (and (not (seq (get-in @state [:runner :locked :discard])))
+                                (< 0 (count (filter #(is-type? % "Event")
+                                                    (get-in @state [:runner :discard]))))))
                  :prompt "Choose an event to play"
                  :msg (msg "play " (:title target))
                  :show-discard true


Change label to "Lobby"

Change label to "Lobby"

--- src/clj/ji/service/templates.clj
+++ src/clj/ji/service/templates.clj
@@ -46,7 +46,7 @@
            [:section.top-bar-section
             [:ul.left
              [:li.divider]
-             [:li [:a {:href "/games"} "All Games"]]]]]
+             [:li [:a {:href "/games"} "Lobby"]]]]]
           [:div#messages.large-12.columns]
           [:div#content.large-12.columns
            ~@(:content blocks)]


ENH: chapter 6, part 2: working with immutable data structures

--- src/clj_prj03/ch6_functional.clj
+++ src/clj_prj03/ch6_functional.clj
@@ -39,3 +39,52 @@

 ;; Section 1.2: Side Effects
 ; Clojure core data structures are all immutable!
+
+;;; Part 2: Immutable Data structures
+
+;; 2.1 Recursion instead of for/while
+; The functional alternative to mutation is recursion
+
+(defn no-mutation
+  [x]
+  (println x) ; --> original x
+
+  ;; let creates a new scope
+  (let [x "Kafka Human"]
+    (println x)) ; --> Kafka Human
+
+  ;; Exiting the let scope, x is the same
+  (println x)) ; --> original x
+(no-mutation "Existential Angst Person")
+
+(defn sum
+  ([vals] (sum vals 0))
+  ([vals accum]
+    (if (empty? vals)
+      accum
+      (sum (rest vals) (+ (first vals) accum)))))
+
+; evaluation is as follows:
+(sum [39 5 1])
+(sum [39 5 1] 0)
+(sum [5 1] 39)
+(sum [1] 44)
+(sum [] 45)
+
+; Use recur!
+; wait?!?!?! no tail-call optimization????
+
+(defn sum
+  ([vals] (sum vals 0))
+  ([vals accum]
+    (if (empty? vals)
+      accum
+      (recur (rest vals) (+ (first vals) accum)))))
+
+;; 2.2 Functional Composition instead of Attribute mutation
+
+(require '[clojure.string :as s])
+(defn clean
+  [text]
+  (s/replace (s/trim text) #"lol" "LOL"))
+(clean "My boa constrictor is so sassy lol!")


make adding and remoting tags functional

--- src/cljs/salava/core/ui/tag.cljs
+++ src/cljs/salava/core/ui/tag.cljs
@@ -1,28 +1,48 @@
 (ns salava.core.ui.tag
   (:require [clojure.string :refer [trim lower-case]]
-            [salava.core.i18n :refer [t]]))
+            [salava.core.i18n :refer [t]]
+            [salava.core.ui.helper :refer [plugin-fun]]
+            [reagent.session :as session]))

-(defn add-tag [tags-atom new-tag-atom]
-  (let [new-tag (trim @new-tag-atom)
-        tag-exists? (some #(= (lower-case new-tag)
-                              (lower-case %)) @tags-atom)]
-    (when (and (not (empty? new-tag))
-               (not tag-exists?))
-      (reset! tags-atom (conj (vec @tags-atom) new-tag))
-      (reset! new-tag-atom ""))))
+(defn add-tag
+  ([tags-atom new-tag-atom]
+   (let [new-tag (trim @new-tag-atom)
+         tag-exists? (some #(= (lower-case new-tag)
+                               (lower-case %)) @tags-atom)]
+     (when (and (not (empty? new-tag))
+                (not tag-exists?))
+       (reset! tags-atom (conj (vec @tags-atom) new-tag))
+       (reset! new-tag-atom ""))))
+  ([tags-atom new-tag-atom state reload-fn]
+   (let [save-settings (first (plugin-fun (session/get :plugins) "settings" "save_settings"))]
+     (do
+       (add-tag tags-atom new-tag-atom)
+       (save-settings state reload-fn "share")
+       ))))

 (defn remove-tag [tags-atom tag-value]
   (reset! tags-atom (remove #(= % tag-value) @tags-atom)))

-(defn new-tag-input [tags-atom new-tag-atom]
-  [:input {:type        "text"
-           :class       "form-control"
-           :placeholder (t :badge/Typetag)
-           :id          "newtags"
-           :value       @new-tag-atom
-           :on-change   #(reset! new-tag-atom (-> % .-target .-value))
-           :on-key-down #(if (= (.-which %) 13)
-                          (add-tag tags-atom new-tag-atom))}])
+(defn new-tag-input
+  ([tags-atom new-tag-atom]
+   [:input {:type        "text"
+            :class       "form-control"
+            :placeholder (t :badge/Typetag)
+            :id          "newtags"
+            :value       @new-tag-atom
+            :on-change   #(reset! new-tag-atom (-> % .-target .-value))
+            :on-key-down #(if (= (.-which %) 13)
+                            (add-tag tags-atom new-tag-atom))}])
+
+  ([tags-atom new-tag-atom state reload-fn]
+   [:input {:type        "text"
+            :class       "form-control"
+            :placeholder (t :badge/Typetag)
+            :id          "newtags"
+            :value       @new-tag-atom
+            :on-change   #(reset! new-tag-atom (-> % .-target .-value))
+            :on-key-down #(if (= (.-which %) 13)
+                            (add-tag tags-atom new-tag-atom state reload-fn))}]))

 (defn tags
   ([tags-atom] (tags tags-atom true))
@@ -34,5 +54,16 @@
             (if show-remove-link?
               [:a {:class "remove-tag"
                    :dangerouslySetInnerHTML {:__html "×"}
-                   :on-click #(remove-tag tags-atom tag)}])]))))
-
+                   :on-click #(remove-tag tags-atom tag)}])])))
+  ([tags-atom state reload-fn]
+   (let [save-settings (first (plugin-fun (session/get :plugins) "settings" "save_settings"))]
+     (into [:div.tag-labels]
+           (for [tag @tags-atom]
+             [:span {:class "label label-default"}
+              tag
+              [:a {:class "remove-tag"
+                   :dangerouslySetInnerHTML {:__html "×"}
+                   :on-click #(do
+                                (.preventDefault %)
+                                (remove-tag tags-atom tag)
+                                (save-settings state reload-fn "share"))}]])))))


Don't print db config when migrating

Don't print db config when migrating

This prints the db password.

--- src/clojars/tools/migrate_db.clj
+++ src/clojars/tools/migrate_db.clj
@@ -5,5 +5,5 @@

 (defn -main [& _]
   (let [db (:db (config))]
-    (println "=> Migrating" db)
+    (println "=> Migrating db")
     (migrate db)))


Memoize create-sandbox

Memoize create-sandbox

--- src/clojure/nightmod/sandbox.clj
+++ src/clojure/nightmod/sandbox.clj
@@ -62,34 +62,36 @@
                                play-clj.utils])
    (jail-test/blanket "clojail" "nightcode")])

-(def context
-  (memoize (fn [path]
-             (-> (doto (jvm/permissions)
-                   (.add (FilePermission. "<<ALL FILES>>" "read"))
-                   (.add (-> (io/file path)
-                             .getCanonicalPath
-                             (str File/separatorChar "*")
-                             (FilePermission. "write")))
-                   (.add (ReflectPermission. "suppressAccessChecks"))
-                   (.add (SocketPermission. "play-clj.net" "connect")))
-                 jvm/domain
-                 jvm/context))))
+(def create-context
+  (memoize
+    (fn [path]
+      (-> (doto (jvm/permissions)
+            (.add (FilePermission. "<<ALL FILES>>" "read"))
+            (.add (-> (io/file path)
+                      .getCanonicalPath
+                      (str File/separatorChar "*")
+                      (FilePermission. "write")))
+            (.add (ReflectPermission. "suppressAccessChecks"))
+            (.add (SocketPermission. "play-clj.net" "connect")))
+          jvm/domain
+          jvm/context))))

-(defn create-sandbox
-  []
-  (jail/sandbox tester
-                :context (context @u/project-dir)
-                :timeout u/timeout
-                :namespace u/game-ns
-                :max-defs Integer/MAX_VALUE
-                :init '(require '[nightmod.game :refer :all]
-                                '[play-clj.core :refer :all]
-                                '[play-clj.g2d :refer :all]
-                                '[play-clj.g3d :refer :all]
-                                '[play-clj.math :refer :all]
-                                '[play-clj.net :refer :all]
-                                '[play-clj.physics :refer :all]
-                                '[play-clj.ui :refer :all])))
+(def create-sandbox
+  (memoize
+    (fn [path]
+      (jail/sandbox tester
+                    :context (create-context path)
+                    :timeout u/timeout
+                    :namespace u/game-ns
+                    :max-defs Integer/MAX_VALUE
+                    :init '(require '[nightmod.game :refer :all]
+                                    '[play-clj.core :refer :all]
+                                    '[play-clj.g2d :refer :all]
+                                    '[play-clj.g3d :refer :all]
+                                    '[play-clj.math :refer :all]
+                                    '[play-clj.net :refer :all]
+                                    '[play-clj.physics :refer :all]
+                                    '[play-clj.ui :refer :all])))))

 (defn safe-read
   [f]
@@ -103,7 +105,7 @@
   (reset! u/error nil)
   (reset! u/out nil)
   (let [writer (StringWriter.)
-        sb (create-sandbox)]
+        sb (create-sandbox @u/project-dir)]
     (-> (io/file path)
         safe-read
         (sb {#'*out* writer})
@@ -120,7 +122,7 @@
   [func]
   (binding [*out* (StringWriter.)]
     (try
-      (jvm/jvm-sandbox func (context @u/project-dir))
+      (jvm/jvm-sandbox func (create-context @u/project-dir))
       (catch Throwable e
         (when-not @u/error
           (reset! u/error


Auto-advance GTM head to right after reading too

--- src/clojush/instructions/gtm.clj
+++ src/clojush/instructions/gtm.clj
@@ -141,7 +141,8 @@
                  (-> state
                      (assoc-in [:gtm :tapes 0 :contents destination-position]
                                source-instr-map)
-                     (update-in [:gtm :tapes 0 :position] inc)))
+                     (update-in [:gtm :tapes 0 :position] inc)
+                     (update-in [:gtm :tapes source :position] inc)))
           state))
       state)))

@@ -153,11 +154,14 @@
       (let [active (:active (:gtm state))
             active-tape (get (:tapes (:gtm state)) active)]
         (trace 'gtm_blank
-               (push-item (if (get (:contents active-tape) (:position active-tape))
-                            false
-                            true)
-                          :boolean
-                          state)))
+               (update-in
+                 (push-item (if (get (:contents active-tape) (:position active-tape))
+                              false
+                              true)
+                            :boolean
+                            state)
+                 [:gtm :tapes active :position]
+                 inc)))
       state)))

 (define-registered ;; make tape 0 blank at current position
@@ -180,11 +184,15 @@
   ^{:stack-types [:gtm :code]}
   (fn [state]
     (if (:gtm state)
-      (let [active-tape (get (:tapes (:gtm state)) (:active (:gtm state)))
+      (let [active (:active (:gtm state))
+            active-tape (get (:tapes (:gtm state)) active)
             instr-map (get (:contents active-tape) (:position active-tape))]
         (if instr-map
           (trace 'gtm_instruction
-                 (push-item (:instruction instr-map) :code state))
+                 (update-in
+                   (push-item (:instruction instr-map) :code state)
+                   [:gtm :tapes active :position]
+                   inc))
           state))
       state)))

@@ -218,7 +226,10 @@
             instr-map (get (:contents active-tape) (:position active-tape))]
         (if instr-map
           (trace 'gtm_silent
-                 (push-item (:silent instr-map) :boolean state))
+                 (update-in
+                   (push-item (:silent instr-map) :boolean state)
+                   [:gtm :tapes active :position]
+                   inc))
           state))
       state)))

@@ -251,7 +262,10 @@
             instr-map (get (:contents active-tape) (:position active-tape))]
         (if instr-map
           (trace 'gtm_close
-                 (push-item (:close instr-map) :integer state))
+                 (update-in
+                   (push-item (:close instr-map) :integer state)
+                   [:gtm :tapes active :position]
+                   inc))
           state))
       state)))

@@ -299,8 +313,6 @@
         pgm '(gtm_tape1              ;; initial source is tape1
                exec_y                ;; repeatedly
                (gtm_copy            ;;   copy a gene
-                 gtm_tape1 gtm_right ;;   move all heads to right
-                 gtm_tape2 gtm_right ;;
                  boolean_rand        ;;   make next source randomly tape1 or tape2
                  exec_if gtm_tape1 gtm_tape2))
         run-pgm #(run-push pgm %)]
@@ -318,19 +330,19 @@
 ;; back and forth on one parent
 #_(let [g [{:instruction 1}{:instruction 2}{:instruction 3}]
         pgm '(true                  ;; top boolean indicates if moving right
-               gtm_tape1           ;;   source is tape1
+               gtm_tape1            ;;   source is tape1
                exec_y               ;; repeatedly
                ( gtm_copy           ;;   copy a gene
                  exec_if
-                 (true gtm_right)
-                 (false gtm_left)
+                 true
+                 (false gtm_left gtm_left)
                  gtm_blank          ;;   if blank, reverse and move twice
                  exec_if
                  (exec_if false true
                           exec_if
-                          (true gtm_right gtm_right)
-                          (false gtm_left gtm_left))
-                 ()))
+                          (true gtm_right)
+                          (false gtm_left gtm_left gtm_left))
+                 gtm_left))
         run-pgm #(run-push pgm %)]
     (println "g:" g)(newline)
     (println "result:"
@@ -352,7 +364,7 @@
                  (100 code_rand                   ;;     set instruction randomly
                       gtm_set_instruction)
                  gtm_copy                         ;;     or copy it
-                 gtm_tape1 gtm_right))
+                 ))
         run-pgm #(run-push pgm %)]
     (println "g:" g)(newline)
     (println "result:"
@@ -362,3 +374,4 @@
                  (run-pgm)
                  (dump-tape 0))))

+


Fix namespace-aliases barfs on hidden files

--- src/refactor_nrepl/core.clj
+++ src/refactor_nrepl/core.clj
@@ -20,10 +20,15 @@
        (filter fs/directory?)
        (remove #(-> % str normalize-to-unix-path (.endsWith "target/srcdeps")))))

+(defn- hidden? [path-or-file]
+  (.isHidden (io/file path-or-file)))
+
 (defn find-in-dir
   "Searches recursively under dir for files matching (pred ^File file). "
   [pred ^File dir]
-  (filter pred (file-seq dir)))
+  (->> (file-seq dir)
+       (remove hidden?)
+       (filter pred)))

 (defn cljc-file?
   [path-or-file]


more heiaheia mappings

more heiaheia mappings

--- src/ontrail/heiaimport.clj
+++ src/ontrail/heiaimport.clj
@@ -30,7 +30,16 @@
                     "Etunojapunnerrus" {:sport "Kuntopiiri" :tags "punnerrus"}
                     "Terapeuttinen harjoittelu" {:sport "Jumppa"
                                                  :tags "kuntoutus"}
-                    "Avantouinti" {:sport "Muu merkintä" :tags "avantouinti"}
+                    "Avantouinti" {:sport "Uinti" :tags "avantouinti"}
+                    "Lumikenkäkävely" {:sport "Lumikenkäily"}
+                    "Vuorikiipeily" {:sport "Kiipeily" :tags "vuorikiipeily"}
+                    "Moottoripyöräily" {:sport "Muu merkintä" :tags "moottoripyöräily"}
+                    "Potkypyöräily" {:sport "Kickbike"}
+                    "Rakennustyöt" {:sport "Muu merkintä" :tags "rakentaminen"}
+                    "Remontointi" {:sport "Muu merkintä" :tags "remontointi"}
+                    "Rogaining" {:sport "Suunnistus" :tags "rogaining"}
+                    "Suoritin" {:sport "Muu merkintä"}
+                    "Avovestiuinti" {:sport "Uiniti" :tags "avovesi"}
                     "Jalkakyykky" {:sport "Kuntosali" :tags "jalkakyykky"}
                     "Leijahiihto" {:sport "Muu laji" :tags "kite"}
                     "Lenkkeily" {:sport "Juoksu"}


No longer check if log is on a compatible version for subscribe-to-log. We may wish to playback an old log with a new version of onyx. We should not apply any log entries however.

--- src/onyx/log/zookeeper.clj
+++ src/onyx/log/zookeeper.clj
@@ -280,7 +280,6 @@
        (let [log-parameters (find-log-parameters log)
              origin (extensions/read-chunk log :origin nil)
              starting-position (inc (:message-id origin))]
-         (onyx.peer.log-version/check-compatible-log-versions! (:log-version log-parameters))
          (>!! rets (merge (:replica origin) log-parameters))
          (close! rets)
          (loop [position starting-position]


www/render.clj: made template-group a memoized function

So that it doesn't try to read context until called.

--- src/org/altlaw/www/render.clj
+++ src/org/altlaw/www/render.clj
@@ -11,14 +11,6 @@
   (if (keyword? x)
     (name x)
     (str x)))
-
-(def *template-group*
-     (let [page-templates (StringTemplateGroup. "org.altlaw.www.templates")]
-       (when (= (context/altlaw-env) "development")
-         ;; By default, templates are never refreshed.
-         ;; In development mode, always refresh.
-         (.setRefreshInterval page-templates 0))
-       page-templates))

 (with-test
  (defn- render-template
@@ -61,13 +53,22 @@
                                    "Foo: $user:{f$it.foo$}$")
                                   {:user [{:foo 1} {:foo 2} {:foo 3}]})))))

+(def #^{:private true} template-group
+     (memoize (fn []
+                (let [page-templates (StringTemplateGroup. "org.altlaw.www.templates")]
+                  ;; By default, templates are never refreshed.
+                  ;; In development mode, always refresh.
+                  (when (= (context/altlaw-env) "development")
+                    (.setRefreshInterval page-templates 0))
+                  page-templates))))
+
 (with-test
  (defn render
    "Renders a template from a file.  name does not include the '.st'
    extension.  attrs is a :keyword=>value map as with
    render-template."
    [name & attrs]
-   (-> *template-group*
+   (-> (template-group)
        (.getInstanceOf (str "org/altlaw/www/templates/" (string name)))
        (render-template (if (map? (first attrs))
                           (if (next attrs)


defect

defect

--- src/fat_jar/core.clj
+++ src/fat_jar/core.clj
@@ -21,16 +21,13 @@
   (let [selector (:map data-mapping)
          output (:to data-mapping)]
     {:output output
-      :v(reduce #(% %2) coll selector)}))
+      :v (reduce #(% %2) coll selector)}))

 (defn write-file [filename payload]
    (with-open [w (clojure.java.io/writer filename)]
   (doseq [line payload]
     (.write w line)
     (.newLine w))))
-
-(let [pl (p/load-from {"key" "value"})]
-  (p/properties->map pl true))

 (def config
   (p/properties->map


refactor: extract main to an explanatory variable

--- src/fat_jar/core.clj
+++ src/fat_jar/core.clj
@@ -29,20 +29,16 @@
     (.write w line)
     (.newLine w))))

+(let [pl (p/load-from {"key" "value"})]
+  (p/properties->map pl true))
+
 (def config
   (p/properties->map
     (->> "./mapper.properties" io/file p/load-from)
     true))

-(defn -main [& args]
-  (let [options (parse-opts args cli-options :strict true :missing true)
-         errors? #(not (empty? (:errors %)))
-         help? #(:help %)
-         print-help #(do (println "usage:") (println (:summary %)))]
-    (cond
-      (errors? options) (do (print-help options) (println (:errors options)))
-      (help? options) (print-help options)
-      :else (do
+(defn process []
+  (do
         (let [mappings (->> (config :input.mappings)
                      slurp
                      edn/read-string)
@@ -62,4 +58,14 @@
        (->>  mappings
           (map #(select-values user-data %))
           (map format-value)
-          (write-file (config :output.filename)))))))))+          (write-file (config :output.filename)))))))
+
+(defn -main [& args]
+  (let [options (parse-opts args cli-options :strict true :missing true)
+         errors? #(not (empty? (:errors %)))
+         help? #(:help %)
+         print-help #(do (println "usage:") (println (:summary %)))]
+    (cond
+      (errors? options) (do (print-help options) (println (:errors options)))
+      (help? options) (print-help options)
+      :else (process))))


Add block methods for left-most or right-most nodes

--- src/fatlip/plot.cljs
+++ src/fatlip/plot.cljs
@@ -23,6 +23,17 @@
            :src dest
            :dest src)))

+(defn left
+  [block]
+  (if (:reversed (meta block))
+    (peek block)
+    (first block)))
+
+(defn right
+  [block]
+  (if (:reversed (meta block))
+    (first block)
+    (peek block)))

 (defn get-block-rel-ys
   "Calculates the relative y-positions of blocks within a class. If the class


Setup network to RPC call the background

--- src/popup/ygq/popup/core.cljs
+++ src/popup/ygq/popup/core.cljs
@@ -6,7 +6,23 @@
             [cljs.core.async :as async]
             [om.next :as om]
             [chrome.rpc :as rpc]
-            [google.api :refer [get-auth-token]]))
+            [google.api :refer [get-auth-token]]
+            [untangled.client.impl.network :as un]
+            [untangled.client.data-fetch :as df]))
+
+(defrecord Network [complete-app]
+  un/NetworkBehavior
+  (serialize-requests? [this] true)
+
+  un/UntangledNetwork
+  (send [this edn ok error]
+    (let [res (<! (rpc/send [:app/graph edn]))]
+      (ok res)))
+
+  (start [this app]
+    (assoc this :complete-app app)))
+
+(defn make-network [] (map->Network {}))

 (defn request-token [reconciler]
   (go
@@ -15,8 +31,11 @@

 (defonce app
   (atom (uc/new-untangled-client
+          :network (make-network)
           :started-callback (fn [app]
-                              (request-token (:reconciler app))))))
+                              (go
+                                (<! (request-token (:reconciler app)))
+                                (df/load app :video/queue ui/QueuedVideo))))))

 (defn setup-comm []
   (go


Not showing previous build when there isn't one.

--- src-cljs/frontend/components/build_head.cljs
+++ src-cljs/frontend/components/build_head.cljs
@@ -1171,10 +1171,11 @@
              (when (:stop_time build)
                (build-finished-status build))]
             [:div.summary-items
-             [:div.summary-item
-              [:span.summary-label "Previous: "]
-              [:a {:href (routes/v1-build-path (vcs-url/org-name vcs-url) (vcs-url/repo-name vcs-url) (:build_num (:previous build)))}
-               (:build_num (:previous build))]]
+             (when (not-empty (:previous build))
+               [:div.summary-item
+                [:span.summary-label "Previous: "]
+                [:a {:href (routes/v1-build-path (vcs-url/org-name vcs-url) (vcs-url/repo-name vcs-url) (:build_num (:previous build)))}
+                 (:build_num (:previous build))]])
              [:div.summary-item
               [:span.summary-label "Parallelism: "]
               (if (has-scope :write-settings data)


Fix re-uploads of same wdl file: GAWB-2547 (#958)

* fix re-uploads of same wdl file

--- src/cljs/main/broadfcui/page/method_repo/create_method.cljs
+++ src/cljs/main/broadfcui/page/method_repo/create_method.cljs
@@ -79,15 +79,23 @@
                                     :defaultValue (:documentation info)
                                     :style {:width "100%"}
                                     :rows 5})
-
-           [:input {:type "file" :ref "wdl-uploader" :style {:display "none"}
+           ;; This key is changed every time a file is selected causing React to completely replace the
+           ;; element. Otherwise, if a user selects the same file (even after having modified it), the
+           ;; browser will not fire the onChange event.
+           [:input {:key (:file-input-key @state)
+                    :type "file"
+                    :ref "wdl-uploader"
+                    :style {:display "none"}
                     :onChange (fn [e]
                                 (let [file (-> e .-target .-files (aget 0))
                                       reader (js/FileReader.)]
                                   (when file
                                     (set! (.-onload reader)
                                           #(let [text (.-result reader)]
-                                             (swap! state assoc :file-name (.-name file) :file-contents text)
+                                             (swap! state assoc
+                                                    :file-name (.-name file)
+                                                    :file-contents text
+                                                    :file-input-key (gensym "wdl-uploader-"))
                                              (this :-set-wdl-text text)))
                                     (.readAsText reader file))))}]
            (style/create-form-label


Clean up Channel fn signature docstrings

--- src/org/httpkit/server.clj
+++ src/org/httpkit/server.clj
@@ -26,49 +26,49 @@
 ;;;; Asynchronous extension

 (defprotocol Channel
-  "Asynchronous channel for HTTP streaming/long polling & websocekt"
-  (open? [ch] "Tells whether or not this channel is still open")
-  (websocket? [ch] "Tells whether or not this channel is websocket")
+  "Unified asynchronous channel interface for HTTP (streaming or long-polling)
+  and WebSockets."
+
+  (open? [ch] "Returns true iff channel is open.")
   (close [ch]
-    "Closes this channel.
-    If this channel is already closed then invoking this method has no effect.
-    For websocket a CloseFrame is sent to client, for streaming, last-chunk is sent.")
+    "Closes the channel. Idempotent: returns true if the channel was actually
+    closed, or false if it was already closed.")
+  (websocket? [ch] "Returns true iff channel is a WebSocket.")
   (send! [ch data] [ch data close-after-send?]
-    "Send data to client.
-     If channel is closed, invoking this method has no effect, false is returned.
-     For Webocket, a text frame is sent to client.
-     For streaming:
-     1. First call of send!, data expect to be {:headers _ :status _ :body _} or just body.
-     2. Any further call, body(String, File, InputStream, ISeq) or {:body body} are expected.
-        The data is encoded as chunk, sent to client")
-  (alter-send-hook [ch f] ; just experiment, will be removed if not needed
+    "Sends data to client and returns true if the data was successfully sent,
+    or false if the channel is closed.
+
+    When unspecified, `close-after-send?` defaults to true for HTTP channels and
+    false for WebSockets.
+
+    Data form: {:headers _ :status _ :body _} or just body. Note that :headers
+    and :status will be stripped for WebSockets and for HTTP streaming responses
+    after the first.")
+  (on-receive [ch callback]
+    "Sets handler (fn [message-string]) for notification of client WebSocket
+    messages. Message ordering is guaranteed by server.")
+  (on-close [ch callback]
+    "Sets handler (fn [status]) for notification of channel being closed by the
+    server or client. Handler will be invoked at most once. Useful for clean-up.
+
+    Callback status argument:
+      :server-close   : Channel closed by sever
+      :client-close   : HTTP channel closed by client
+      :normal         : WebSocket closed by client (CLOSE_NORMAL)
+      :going-away     : WebSocket closed by client (CLOSE_GOING_AWAY)
+      :protocol-error : WebSocket closed by client (CLOSE_PROTOCOL_ERROR)
+      :unsupported    : WebSocket closed by client (CLOSE_UNSUPPORTED)
+      :unknown        : WebSocket closed by client (unknown reason)")
+
+  ;;; just experiment, will be removed if not needed
+  (alter-send-hook [ch f]
     "Callback: (fn [old-hook] new-hook)
      hook : (fn [data websocket? first-send?] data-write-to-client)
      Do something with the sending data (like JSON encoding), the return value is sending off")
-  (alter-receive-hook [ch f] ; just experiment, will be removed if not needed
+  (alter-receive-hook [ch f]
     "Callback: (fn [old-hook] new-hook)
      hook: (fn [string] ret), ret is pass to on-receive handler
-     Do something with the receiving data (like JSON decoding), the return value is pass to receive handler")
-  (on-receive [ch callback]
-    "Only valid for websocket.
-     Callback: (fn [message-string])
-     Set the handler to get notified when there is message from client.
-     Messages receided from a client are handled orderly by server.
-     For streaming, another HTTP connection can be used to emulate the behaviour")
-  (on-close [ch callback]
-    "Callback: (fn [close-keyword])
-     Set the handler to get notified when channel closed, by client, or server call `close`.
-     If the channel is ready closed, the callback is invoked immediately.
-     Callback is only invoked once if server and client both close the channel.
-     Useful for doing clean up.
-     argument:
-       :server-close   : closed by sever;
-       :client-close   : closed by streaming client client
-       :normal         : websocket, a normal closure by client
-       :away           : websocket, client close, \"going away\"
-       :protocol-error : websocket, client close, due to a protocol error
-       :not-acceptable : websocket, client close, type of data cannot accept
-       :unknow         : websocket, client close"))
+     Do something with the receiving data (like JSON decoding), the return value is pass to receive handler"))

 (extend-type AsyncChannel
   Channel


full /login api-method defined

full /login api-method defined

--- src/otaservice/handler.clj
+++ src/otaservice/handler.clj
@@ -21,14 +21,13 @@
 (defn find-user [id pass]
   (if (and (= id "yolo") (= pass "swag"))
     {:id "yolo"}
-    {}))
+    nil))

 (defn login-handler [request]
-  (let [user (find-user (:username request)
-                        (:password request))
-        token (jwt/sign {:user (:id user)} secret)]
-    (rh/ok {:token token
-            :user (:id user)})))
+  (if-let [user (find-user (:username request)
+                        (:password request))]
+    (rh/ok {:token (jwt/sign {:user (:id user)} secret)})
+    (rh/forbidden {:reason "Wrong credentials"})))

 (defn ota-update
   "Performs OTA update for ESP8266"
@@ -51,8 +50,11 @@
             :tags ["api1"]

             (sw/POST "/login" []
+                     :body [creds Credentials]
+                     :responses {403 {:schema {:reason s/Str}
+                                      :description "No user with this login & pass found."}}
+                     :return {:token s/Str}
                      :summary "authorize and receive jwt token"
-                     :body [creds Credentials]
                      (login-handler creds))

             (sw/GET "/plus" []


load each sample once only for each unique [path args]

--- src/overtone/sc/sample.clj
+++ src/overtone/sc/sample.clj
@@ -8,7 +8,7 @@
         [overtone.sc.machinery allocator]
         [overtone.sc.machinery.server comms]
         [overtone.sc server synth gens buffer]
-        [overtone.helpers.file :only [glob resolve-tilde-path mk-path]]))
+        [overtone.helpers.file :only [glob canonical-path resolve-tilde-path mk-path]]))

 ; Define a default wav player synth
 (defonce __DEFINE-PLAYERS__
@@ -76,10 +76,13 @@
   in the file (:start). If the number of frames argument is less than or equal
   to zero, the entire file is read."
   [path & args]
-  (let [path (resolve-tilde-path path)]
-    (dosync (alter loaded-samples* assoc [path args] nil))
-    (if (server-connected?)
-      (apply load-sample* path args))))
+  (let [path (canonical-path path)]
+    (if-let [sample (get @loaded-samples* [path args])]
+      sample
+      (do
+        (dosync (alter loaded-samples* assoc [path args] nil))
+        (if (server-connected?)
+          (apply load-sample* path args))))))

 (defn load-samples
   "Takes a directoy path or glob path (see #'overtone.helpers.file/glob) and


osc-clj no longer requires a peer for the without-osc-bundle macro

--- src/overtone/sc/server.clj
+++ src/overtone/sc/server.clj
@@ -58,7 +58,7 @@

 (defmacro snd-immediately
   [& body]
-  `(without-osc-bundle @server-osc-peer* ~@body))
+  `(without-osc-bundle ~@body))

 (defn snd
   "Sends an OSC message to the server. If the message path is a known