don't show payment plans in Enterprise

don't show payment plans in Enterprise

--- src-cljs/frontend/components/add_projects.cljs
+++ src-cljs/frontend/components/add_projects.cljs
@@ -5,6 +5,7 @@
             [frontend.analytics :as analytics]
             [frontend.components.common :as common]
             [frontend.components.forms :refer [managed-button]]
+            [frontend.config :as config]
             [frontend.datetime :as datetime]
             [frontend.models.organization :as organization]
             [frontend.models.repo :as repo-model]
@@ -413,6 +414,7 @@
                          :organizations
                          (filter some?)
                          (first))]
-            (if (or (= selected-org (:login user)) (organization/show-upsell? org))
+            (when (and (not (config/enterprise?))
+                       (or (= selected-org (:login user)) (organization/show-upsell? org)))
               (om/build payment-plan {:selected-org selected-org
                                       :view view})))]]]])))


Another update

Another update

--- src-cljs/frontend/components/project_settings.cljs
+++ src-cljs/frontend/components/project_settings.cljs
@@ -495,7 +495,7 @@
             (describe-flag {:flag :oss
                             :title "Free and Open Source"
                             :blurb [:p
-                                   "Be part of our F/OSS! Organizations now have three free containers "
+                                   "Organizations have three free containers "
                                     "reserved for F/OSS projects; enabling this will allow this project's "
                                     "builds to use them and let others see your builds, both through the "
                                     "web UI and the API."]})


CMR-1723: Temporal opendata mapping needs to include end date even for ongoing collections.

--- search-app/src/cmr/search/results_handlers/opendata_results_handler.clj
+++ search-app/src/cmr/search/results_handlers/opendata_results_handler.clj
@@ -9,6 +9,7 @@
             [clojure.string :as str]
             [clojure.set :as set]
             [clj-time.core :as time]
+            [clj-time.format :as f]
             [cheshire.core :as json]
             [cmr.common.util :as util]
             [cmr.search.models.results :as r]
@@ -145,9 +146,11 @@
   ;; entry whereas UMM-C allows multiple periodic-date-time entries. This will have to wait until
   ;; a decision is made about how to resolve multiple periodic-date-time entries.
   [start-date end-date]
-  (not-empty (if (and start-date end-date)
-               (str start-date "/" end-date)
-               start-date)))
+  (when start-date
+    (let [end-date (if end-date
+                     end-date
+                     (f/unparse (f/formatters :date-time-no-ms) (clj-time.core/today-at 0 0)))]
+      (str start-date "/" end-date))))

 (defn spatial
   "Get the spatial field from the spatial elements of the collection."


use a table instead

use a table instead


Minor naming fix on sitemap namespace.

Minor naming fix on sitemap namespace.

--- src/uxbox/main/ui/workspace/sidebar/sitemap.cljs
+++ src/uxbox/main/ui/workspace/sidebar/sitemap.cljs
@@ -29,7 +29,7 @@

 ;; --- Lenses

-(defn- resolve-page
+(defn- resolve-pages
   [state]
   (let [project (get-in state [:workspace :project])]
     (->> (vals (:pages-by-id state))
@@ -37,7 +37,7 @@
          (sort-by :created-at))))

 (def pages-ref
-  (-> (l/lens resolve-page)
+  (-> (l/lens resolve-pages)
       (l/derive st/state)))

 ;; --- Component


Add par-fetch-chan

Add par-fetch-chan

--- src/cyanite_fetcher/core.clj
+++ src/cyanite_fetcher/core.clj
@@ -3,6 +3,7 @@
             [clojure.tools.cli :as cli]
             [clj-time.local :as tl]
             [clojure.core.reducers :as r]
+            [clojure.core.async :as async]
             [clojurewerkz.elastisch.rest :as esr]
             [clojurewerkz.elastisch.rest.document :as esrd]
             [qbits.alia :as alia])
@@ -153,14 +154,35 @@
     (map my-deref channels)
     @data))

+(defn par-fetch-chan
+  "Fetch data in parallel fashion using execute-chan."
+  [session fetch! paths tenant rollup period from to]
+  (async/<!!
+   (async/go
+     (loop [queries
+            (map #(alia/execute-chan session fetch!
+                                     {:values [% tenant (int rollup)
+                                               (int period)
+                                               from to]
+                                      :fetch-size Integer/MAX_VALUE})
+                 paths)
+            query-results []]
+       (if (empty? queries)
+         query-results
+         (let [[result channel] (async/alts! queries)]
+           ;;(println (count queries))
+           (recur
+            (rest queries)
+            (into query-results result))))))))
+
 (defn c-get-data
   "Get data from C*."
-  [f-par-fetch host paths tenant rollup period from to]
+  [f-par-fetch n-par-fetch host paths tenant rollup period from to]
   (println "Connecting to Cassandra...")
   (let [cluster (alia/cluster {:contact-points [host]})
         session (alia/connect cluster keyspace)
         fetch! (fetchq session)]
-    (println "Getting data form Cassandra...")
+    (println (format "Getting data form Cassandra using %s..." n-par-fetch))
     (try
       (let [data (time (doall (f-par-fetch session fetch! paths tenant
                                            rollup period from to)))]
@@ -387,9 +409,10 @@
     (println "Period:" period)
     (newline)
     (let [paths (es-get-paths eshost path tenant)
-          data (c-get-data par-fetch chost paths tenant rollup period from to)
+          data (c-get-data par-fetch "par-fetch" chost paths tenant rollup period from to)
           ;;fdata (flatter data (fn [data] (r/reduce into [] data)) "r/reduce")
           ]
+      (c-get-data par-fetch-async "par-fetch-async" chost paths tenant rollup period from to)
       ;;(flatter data (fn [data] (reduce into data)) "reduce")
       ;;(cleaner fdata (fn [data] (into [] (r/remove nil? data))) "r/remove")
       ;;(cleaner fdata (fn [data] (remove nil? data))  "remove")


Unify the 'process-paths' function

Unify the 'process-paths' function

--- src/cyanite_remover/core.clj
+++ src/cyanite_remover/core.clj
@@ -191,7 +191,10 @@
   (clog/info (str title ":"))
   (let [start-time (time/now)
         pstore (pstore/elasticsearch-path-store es-url options)]
-    (process-fn pstore options tenant paths)
+    (dorun (map #(do
+                   (swap! stats-processed inc)
+                   (process-fn pstore options tenant %))
+                paths))
     (when show-stats?
       (let [pstore-stats (pstore/get-stats pstore)]
         (show-stats (:processed pstore-stats) (:errors pstore-stats)
@@ -205,10 +208,8 @@
     (log/info starting-str)
     (dry-mode-warn options)
     (process-paths tenant paths es-url options
-                   (fn [pstore options tenant paths]
-                     (dorun (map #(do (swap! stats-processed inc)
-                                      (pstore/delete pstore tenant false false %))
-                                 paths)))
+                   (fn [pstore options tenant path]
+                     (pstore/delete pstore tenant false false path))
                    "Removing paths" true)
     (catch Exception e
       (clog/unhandled-error e))))
@@ -219,9 +220,9 @@
   (try
     (clog/disable-logging!)
     (process-paths tenant paths es-url options
-                   (fn [pstore options tenant paths]
+                   (fn [pstore options tenant path]
                      (dorun (map println (lookup-paths pstore tenant false
-                                                       false paths))))
+                                                       false [path]))))
                    "Paths" false)
     (catch Exception e
       (clog/unhandled-error e))))


Add the value of the contact to the view state.

Write code to add the contact (text) to the view state. This particular
implementation adds the value of the contact field to the state (with
the key `:text`). In addition, it renders the component by extracting
the `:text` component from the state and setting the `:value` component
of the (contact) input field to that extracted value.

A problem results. Whenever I type a character, the component detects
that new character and adds it to the input field. The component that
detects that change and re-renders itself resulting in setting the value
of the input field to an empty string. As a result, one appears not to
be able to enter any characters.

To be fixed with the next change.

--- basic/om-tut/src/om_tut/core.cljs
+++ basic/om-tut/src/om_tut/core.cljs
@@ -57,7 +57,9 @@
 (defn contacts-view [data owner]
   (reify
     om/IInitState
-    (init-state [_] {:delete (chan)})
+    (init-state [_] {:delete (chan)
+                     :text ""} ;; Put the contact text into the view state
+                )
     om/IWillMount
     (will-mount [_]
       (let [delete (om/get-state owner :delete)]
@@ -75,7 +77,7 @@
                       (om/build-all contact-view (:contacts data)
                                     {:init-state state}))
                (dom/div nil
-                        (dom/input #js {:type "text" :ref "new-contact"})
+                        (dom/input #js {:type "text" :ref "new-contact" :value (:text state)})
                         (dom/button #js {:onClick #(add-contact data owner)} "Add contact"))))))

 (om/root contacts-view app-state


Indentation

Indentation

--- src/ansel/db.clj
+++ src/ansel/db.clj
@@ -8,14 +8,14 @@
             [ansel.util :refer [exists? minutes pretty-json cwd in?]])
   (:import org.mindrot.jbcrypt.BCrypt))

-(def users (ref nil))
-(def images (atom nil))
-(def albums (atom nil))
-(def likes (atom nil))
-(def config (atom nil))
+(def users    (ref nil))
+(def images   (atom nil))
+(def albums   (atom nil))
+(def likes    (atom nil))
+(def config   (atom nil))
 (def comments (atom nil))
-
-(def running (atom true))
+(def running  (atom true))
+
 (def save-interval (minutes 3))
 (def formatter (formatters :mysql))


t->tx

t->tx


Don't clojureify measurements in spike check.

--- src/kixi/hecuba/data/batch_checks.clj
+++ src/kixi/hecuba/data/batch_checks.clj
@@ -62,7 +62,7 @@
   (let [end-date     (m/add-hour start-date)
         month        (m/get-month-partition-key start-date)
         where        [:device-id device-id :type type :month month :timestamp [>= start-date] :timestamp [< end-date]]
-        measurements (filter #(number? (:value %)) (m/decassandraify-measurements (items querier :measurement where)))]
+        measurements (filter #(number? (:value %)) (items querier :measurement where))]
     (doseq [m measurements]
       (let [spike    (str (v/larger-than-median (read-string median) m))
             metadata (-> m :metadata)]


Ensure working animation in statusbar is stopped upon successful project connection

--- src/lt/plugins/elm_light/clients.cljs
+++ src/lt/plugins/elm_light/clients.cljs
@@ -47,6 +47,7 @@

       (= (second msg) "elm.client.connected")
       (do
+        (notifos/done-working (str "Project connected: " (:dir @client)))
         (object/raise client :connect)
         (object/raise cs/clients :connect client)
         (doseq [ed (pool/containing-path (:dir @client))]


fix panc script with string values of default parameters (fix #31)

--- panc/src/main/clojure/org/quattor/pan/pan_compiler.clj
+++ panc/src/main/clojure/org/quattor/pan/pan_compiler.clj
@@ -78,8 +78,8 @@
          ["--output-dir" "output directory" ]
          ["--formats" "generated output formats" :default "pan,dep"]
          ["--java-opts" "options for JVM"]
-         ["--max-iteration" "set max. no. of iterations" :default 10000]
-         ["--max-recursion" "set max. depth of recursion" :default 50]
+         ["--max-iteration" "set max. no. of iterations" :default "10000"]
+         ["--max-recursion" "set max. depth of recursion" :default "50"]
          ["--logging" "set logging types"]
          ["--log-file" "specify log file"]
          ["--warnings" "off, on, fatal" :default "on" ]


Improve RingBuffer visualization descriptions and add another test

--- src/devcards/audio_utils/devcards/ring_buffer.cljs
+++ src/devcards/audio_utils/devcards/ring_buffer.cljs
@@ -51,20 +51,21 @@
          [:div {:style {:text-align "center"}} "Actual"]]]]])))

 (defcard
-  "100 zeroes in a ring buffer of size 100.
-   100 values taken out of it."
+  "100 zeroes in a ring buffer of size 100. Taking 100 values
+   out of it results in 100 values of 0.0."
   (let [data (repeat 100 0.0)]
     (plot-buffer 100 data (into (ring-buffer 100) data))))

 (defcard
-  "100 zeroes in a ring buffer of size 100.
-   200 values taken out of it."
+  "100 zeroes in a ring buffer of size 100. Taking 200 values
+   out of it results in 100 values of 0.0, followed by 100
+   nils."
   (let [data (repeat 100 0.0)]
     (plot-buffer 200 data (into (ring-buffer 100) data))))

 (defcard
   "100 zeroes and 100 ones in a ring buffer of size 100.
-   100 values taken out of it."
+   Taking 100 values out of results in 100 values of 1.0."
   (let [data (concat (repeat 100 0.0) (repeat 100 1.0))]
     (plot-buffer 100
                  (drop 100 data)
@@ -72,7 +73,8 @@

 (defcard
   "100 values linearly distributed between -1.0 and 1.0
-   in ring buffer of size 100. 10 values taken out of it."
+   in ring buffer of size 100. Taking 10 values out of
+   it results in 10 values starting at -1.0."
   (let [data (linear-distribution [-1.0 1.0] 100)]
     (plot-buffer 10
                  (take 10 data)
@@ -80,15 +82,8 @@

 (defcard
   "100 values linearly distributed between -1.0 and 1.0
-   in ring buffer of size 100. 20 values taken out of it."
-  (let [data (linear-distribution [-1.0 1.0] 100)]
-    (plot-buffer 20
-                 (take 20 data)
-                 (into (ring-buffer 100) data))))
-
-(defcard
-  "100 values linearly distributed between -1.0 and 1.0
-   in ring buffer of size 100. 100 values taken out of it."
+   in ring buffer of size 100. Taking 100 values out of
+   it results in 100 values from -1.0 to 1.0."
   (let [data (linear-distribution [-1.0 1.0] 100)]
     (plot-buffer 100
                  (take 100 data)
@@ -96,7 +91,9 @@

 (defcard
   "100 values linearly distributed between -1.0 and 1.0
-   in ring buffer of size 100. 200 values taken out of it."
+   in ring buffer of size 100. Taking 200 values out of
+   it results in 100 values from -1.0 and 1.0, followed
+   by 100 nils."
   (let [data (linear-distribution [-1.0 1.0] 100)]
     (plot-buffer 200
                  (take 100 data)
@@ -104,8 +101,25 @@

 (defcard
   "200 values linearly distributed between -1.0 and 1.0
-   in ring buffer of size 100. 200 values taken out of it."
+   in ring buffer of size 100. Adding the 200 values into
+   the smaller buffer means that the first 100 values from
+   -1.0 to 0.0 are replaced with the second 100 values from
+   0.0 to 1.0. Taking 200 values out results in 100 values
+   from 0.0 to 1.0, followed by 100 nils."
   (let [data (linear-distribution [-1.0 1.0] 200)]
     (plot-buffer 200
                  (drop 100 data)
                  (into (ring-buffer 100) data))))
+
+(defcard
+  "300 values linearly distributed between -1.0 and 1.0
+   in ring buffer of size 100. Adding the 300 values into
+   the smaller buffer means that the first 100 values from
+   -1.0 to -0.33 are replaced with the second 100 values from
+   -0.33 to 0.33 and then replaced with the third 100 values
+   from 0.33 to 1.0. Taking 200 values out results in 100
+   values from -0.33 to 1.0, followed by 100 nils."
+  (let [data (linear-distribution [-1.0 1.0] 300)]
+    (plot-buffer 200
+                 (drop 200 data)
+                 (into (ring-buffer 100) data))))


Fix unseen filter check.

Fix unseen filter check.

--- src/oc/storage/db/common.clj
+++ src/oc/storage/db/common.clj
@@ -16,7 +16,7 @@
     (r/le start row-field)))

 (defn- unseen-filter [container-last-seen-at row-field]
-  (r/gt container-last-seen-at row-field))
+  (r/gt row-field container-last-seen-at))

 (defn- user-visibility-filter [user-id entry-row]
   (r/or ;; has :follow true


scheduler: If handling offers throws, don't penalize Fenzo.

--- scheduler/src/cook/mesos/scheduler.clj
+++ scheduler/src/cook/mesos/scheduler.clj
@@ -614,7 +614,9 @@
         (meters/mark! handle-resource-offer!-errors)
         (log/error t "Error in match:" (ex-data t))
         (async/go
-          (async/>! offers-chan @offer-stash)))))))
+          (async/>! offers-chan @offer-stash))
+        true
+        )))))

 (defn view-incubating-offers
   [^TaskScheduler fenzo]


Filter orgs by the selected vcs-type

Filter orgs by the selected vcs-type

--- src-cljs/frontend/components/add_projects.cljs
+++ src-cljs/frontend/components/add_projects.cljs
@@ -78,7 +78,7 @@
     (init-state [_]
       {:vcs-type "github"})
     om/IRenderState
-    (render-state [_ state]
+    (render-state [_ {:keys [vcs-type] :as state}]
       (let [{:keys [user settings repos]} data
             github-active? (= "github" (:vcs-type state))
             bitbucket-active? (= "bitbucket" (:vcs-type state))]
@@ -108,17 +108,17 @@
                  ;; organizations route is much faster than the repos route. We show them
                  ;; in this order (rather than e.g. putting the whole thing into a set)
                  ;; so that new ones don't jump up in the middle as they're loaded.
-                 (concat [user]
-                         (:organizations user)
-                         (let [org-names (->> user
-                                              :organizations
-                                              (cons user)
-                                              (map :login)
-                                              set)
-                               in-orgs? (comp org-names :login)]
-                           (->> repos (map :owner)
-                                (remove in-orgs?)
-                                (set)))))]
+                 (filter #(= (:vcs_type %) vcs-type) (concat [user]
+                                     (:organizations user)
+                                     (let [org-names (->> user
+                                                          :organizations
+                                                          (cons user)
+                                                          (map :login)
+                                                          set)
+                                           in-orgs? (comp org-names :login)]
+                                       (->> repos (map :owner)
+                                            (remove in-orgs?)
+                                            (set))))))]
            (when (:repos-loading user)
              [:div.orgs-loading
               [:div.loading-spinner common/spinner]])]])))))


open slack integrations page in new tab

open slack integrations page in new tab

--- src-cljs/frontend/components/integrations.cljs
+++ src-cljs/frontend/components/integrations.cljs
@@ -44,6 +44,7 @@
           [:p "Add a new Slack channel."]
           [:p "Go to the "
            [:a {:href "https://slack.com/services/new"
+                :target "_blank"
                 :role "button"}
             "Slack integrations page"]
            ", scroll to the bottom and add a new Incoming WebHook. Choose a channel, then copy the Webhook URL and fill out the form."]


:tada: Add node repl to tools.clj script.

--- frontend/tools.clj
+++ frontend/tools.clj
@@ -1,8 +1,16 @@
 (require '[clojure.pprint :refer [pprint]])
 (require '[clojure.java.shell :as shell])
 (require '[figwheel.main.api :as figwheel])
-(require '[cljs.build.api :as api])
 (require '[environ.core :refer [env]])
+(require '[cljs.build.api :as api]
+         '[cljs.repl :as repl]
+         '[cljs.repl.node :as node])
+(require '[rebel-readline.core]
+         '[rebel-readline.clojure.main]
+         '[rebel-readline.clojure.line-reader]
+         '[rebel-readline.clojure.service.local]
+         '[rebel-readline.cljs.service.local]
+         '[rebel-readline.cljs.repl])

 (defmulti task first)

@@ -125,6 +133,18 @@
   [args]
   (task ["dbg-dist:main"])
   (task ["dbg-dist:worker"]))
+
+(defmethod task "repl:node"
+  [args]
+  (rebel-readline.core/with-line-reader
+    (rebel-readline.clojure.line-reader/create
+     (rebel-readline.cljs.service.local/create))
+    (cljs.repl/repl
+     (node/repl-env)
+     :prompt (fn []) ;; prompt is handled by line-reader
+     :read (rebel-readline.cljs.repl/create-repl-read)
+     :output-dir "out"
+     :cache-analysis false)))

 ;; --- Tests Tasks


Fix redo shortcut

Fix redo shortcut

--- src/net/sekao/nightcode/shortcuts.clj
+++ src/net/sekao/nightcode/shortcuts.clj
@@ -22,7 +22,7 @@
                :up "u"
                :save "s"
                :undo "z"
-               :redo "y"
+               :redo "Z"
                :find "f"
                :replace "R"
                :close "w"


Removing irrelevant comment and require.

--- test/cmr/indexer/test/services/index_versions.clj
+++ test/cmr/indexer/test/services/index_versions.clj
@@ -10,7 +10,6 @@
             [cmr.indexer.data.elasticsearch :as es]
             [cmr.indexer.data.index-set :as idx-set]
             [cmr.indexer.data.cache :as cache]
-            [cheshire.core :as cheshire]
             [clojure.data.codec.base64 :as b64]
             [cmr.common.lifecycle :as lifecycle]))

@@ -48,11 +47,7 @@
   "Fixture that starts an instance of elastic in the JVM runs the tests and then shuts it down."
   [f]

-  ;; When this test runs as part of dev-systems all tests it changes the global endpoint and breaks
-  ;; other tests that run after it. We keep track of the internal endpoint of the elastisch endpoint
-  ;; and set it back after the tests have completed.
-  (let [current-endpoint esr/*endpoint*
-        http-port (:port test-config)
+  (let [http-port (:port test-config)
         server (lifecycle/start (elastic-server/create-server http-port 9215 "es_data/indexer_test") nil)]
     (reset! context {:system {:db {:conn (esr/connect (str "http://localhost:" http-port))}}})


Makefile.boot: more robust .depend generation

--- src/Makefile.boot
+++ src/Makefile.boot
@@ -74,13 +74,17 @@
 # file as the roots, mentioning the the modules that are to be
 # extracted. This emits dependences for each of the ML files we want
 # to produce.
+#
+# We do an indirection via ._depend so we don't write an empty file if
+# the dependency analysis failed.

 .depend:
 	$(FSTAR_C) --dep full                 \
 		   fstar/FStar.Main.fs	      \
 		   boot/FStar.Tests.Test.fst  \
 		   $(EXTRACT)		      \
-		   --codegen OCaml > .depend
+		   --codegen OCaml > ._depend
+	mv ._depend .depend

 depend: .depend


Better argument naming for add-slash

Better argument naming for add-slash

--- server/src/clinicico/server/domain.clj
+++ server/src/clinicico/server/domain.clj
@@ -12,8 +12,8 @@
             [clinicico.server.tasks :only [publish-task status task-available?] :as tasks]))

 (defn add-slash
-  [url]
-  (str url (when-not (.endsWith url "/") "/")))
+  [string]
+  (str string (when-not (.endsWith string "/") "/")))

 (defn represent-task
   [task url]
@@ -109,7 +109,6 @@
     (assoc
       (dissoc result :files) :_links [self] :_embedded {:_files embedded})))

-
 (defresource result-resource
   :available-media-types ["application/json"]
   :allowed-methods [:options :get]


[fix #6087] error on empty messages

[fix #6087] error on empty messages

add a guard so that `right-to-left-text?` function doesn't throw
an error on empty content

future empty messages aren't going to pass validation

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

--- src/status_im/ui/screens/chat/message/message.cljs
+++ src/status_im/ui/screens/chat/message/message.cljs
@@ -52,8 +52,9 @@
 (def rtl-characters-regex #"[^\u0591-\u06EF\u06FA-\u07FF\u200F\u202B\u202E\uFB1D-\uFDFD\uFE70-\uFEFC]*?[\u0591-\u06EF\u06FA-\u07FF\u200F\u202B\u202E\uFB1D-\uFDFD\uFE70-\uFEFC]")

 (defn right-to-left-text? [content]
-  (let [char (first content)]
-    (re-matches rtl-characters-regex char)))
+  (when-not (empty? content)
+    (let [char (first content)]
+      (re-matches rtl-characters-regex char))))

 (defview message-timestamp [t justify-timestamp? outgoing command? content]
   (when-not command?


make handler resolving more robust

make handler resolving more robust

--- sidecar/src/figwheel_sidecar/utils.clj
+++ sidecar/src/figwheel_sidecar/utils.clj
@@ -22,8 +22,12 @@
     (if (fn? handler)
       handler
       (let [h (symbol handler)]
-        (when (require? (symbol (namespace h)))
-          (resolve h))))))
+        (when-let [ns (namespace h)]
+          (when (require? (symbol ns))
+            (when-let [handler-var (resolve h)]
+              @handler-var)))))))
+
+#_(require-resolve-handler figwheel-sidecar.components.cljs-autobuild/figwheel-build)

 ;; TODO should use tools.analyzer
 (defn get-ns-from-source-file-path


Remove job check

Remove job check

--- slackbot/src/org/teamweek/slackbot.clj
+++ slackbot/src/org/teamweek/slackbot.clj
@@ -187,8 +187,6 @@
 (defjob QuestionnaireJob [job-data]
   (try
     (let [{:strs [domain db-conn scheduler]} (conversion/from-job-data job-data)
-          _ (when (scheduler/currently-executing-job? scheduler (str "jobs." domain))
-              (throw (ex-info "Job is still running" {:domain domain})))
           _ (log/info "Scheduled job started for" domain)
           db (d/db db-conn)
           token (:team/token (d/entity db [:team/domain domain]))


Avoid null pointer exceptions if possible

--- src/gpx/core.clj
+++ src/gpx/core.clj
@@ -84,4 +84,6 @@

 (defn -main
   [& args]
-  (pprint (parse/parse-gpx (first args))))
+  (if (empty? args)
+    (println "No input file given.")
+    (pprint (parse/parse-gpx (first args))) ))


(PDB-5114) query-eng/query->sql: avoid unnecessary trs

The unconditional trs call appeared in performance profiles because
the underlying i18n call is very expensive.  We'll fix that there
next, but for now, just avoid calling trs until we need to.

--- src/puppetlabs/puppetdb/query_eng.clj
+++ src/puppetlabs/puppetdb/query_eng.clj
@@ -148,8 +148,7 @@

                           :else
                           (get-in @entity-fn-idx [entity :rec]))
-              columns (orderable-columns query-rec)
-              unknown-err-msg (trs "Unknown exception when processing ast to add report type filter(s).")]
+              columns (orderable-columns query-rec)]
           (paging/validate-order-by! columns options)
           (if (:add-agent-report-filter options)
             (let [ast (try
@@ -158,12 +157,12 @@
                           (let [data (ex-data e)
                                 msg (.getMessage e)]
                             (when (not= ::dr/unrecognized-ast-syntax (:kind data))
-                              (log/error e unknown-err-msg)
+                              (log/error e (trs "Unknown exception when processing ast to add report type filter(s)."))
                               (throw e))
                             (log/error e msg)
                             ::failed))
                         (catch Exception e
-                          (log/error e unknown-err-msg)
+                          (log/error e (trs "Unknown exception when processing ast to add report type filter(s)."))
                           (throw e)))]
               (if (= ast ::failed)
                 (throw (ex-info "AST validation failed, but was successfully converted to SQL. Please file a PuppetDB ticket at https://tickets.puppetlabs.com"


Fixed the parameter 1 processing

Fixed the parameter 1 processing

--- src/research_clojure/eChild/Child.clj
+++ src/research_clojure/eChild/Child.clj
@@ -4,8 +4,10 @@

 (defn in?
   "Returns true if e is an element of sentence"
-  [sentence e]
-  (some #(= e %) sentence))
+  [sentence e]
+  (println "sentence: " sentence)
+  (println "e: " e)
+  (> (.indexOf sentence e) -1))

 (defn isDeclarative
@@ -92,16 +94,6 @@
     (do (def i (.indexOf sen "Aux"))
         (and (> i 0) (= (+ i 1) (.indexOf sen "S")))))
   false)
-
-
-;First parameter
-(defn setSubjPos
-  [sen grammar infoList]
-  (if (and (in? (get infoList 2) "01") (in? (get infoList 2) "S"))
-    ;;Check if 01 and S are in the sentence
-    (do (def first (.indexOf sen "01"))
-        (if (and (> first 0) (< first (.indexOf sen "S")))
-          (assoc grammar 0 "1")))))

 ;2nd parameter
@@ -232,10 +224,17 @@
     (assoc grammar 12 "0")))

-(defn parameter1
+(defn setSubjPos
+  "Parameter 1"
   [grammar infoList]
   (if (= (get grammar 0) "0")
-    (setSubjPos infoList grammar)))
+    (do (def sen (get infoList 2))
+        (if (and (in? sen "01") (in? sen "S"))
+          ;;Check if 01 and S are in the sentence
+          (do (def first (.indexOf sen "01"))
+              (if (and (> first 0) (< first (.indexOf sen "S")))
+                (assoc grammar 0 "1")))))
+    grammar))

 (defn parameter2
@@ -314,13 +313,11 @@

 (defn setParameters
   "Uses grammar, infolist"
-  [infoList grammar]
+  [infoList initGrammar]

   (def currentGrammar (atom []))

-  (swap! currentGrammar (parameter1 grammar infoList))
-  (println "currG 1: " currentGrammar)
-
+  (reset! currentGrammar (setSubjPos initGrammar infoList))
   (swap! currentGrammar (parameter2 currentGrammar infoList))
   (swap! currentGrammar (parameter3 currentGrammar infoList))
   (swap! currentGrammar (parameter4 currentGrammar infoList))


Bump deps versions (except for asciidoctorj and flexmark)

--- src/io/perun.clj
+++ src/io/perun.clj
@@ -58,7 +58,7 @@
   (filter filterer (meta-by-ext fileset extensions)))

 (def ^:private ^:deps print-meta-deps
-  '[[mvxcvi/puget "1.1.2"]])
+  '[[mvxcvi/puget "1.2.0"]])

 (def print-meta-pod (delay (create-pod' print-meta-deps)))

@@ -202,7 +202,7 @@
               copy-meta))))

 (def ^:private ^:deps content-deps
-  '[[org.clojure/tools.namespace "0.3.0"]])
+  '[[org.clojure/tools.namespace "0.3.1"]])

 (defn content-task
   "Wrapper for input parsing tasks. Calls the return from `render-form-fn` on
@@ -338,7 +338,7 @@
      (filter-meta-by-ext fileset options))))

 (def ^:private ^:deps images-resize-deps
-  '[[org.clojure/tools.namespace "0.3.0"]
+  '[[org.clojure/tools.namespace "0.3.1"]
     [image-resizer "0.1.10"]])

 (def ^:private +images-resize-defaults+
@@ -371,7 +371,7 @@
       :tmp tmp})))

 (def ^:private ^:deps yaml-metadata-deps
-  '[[org.clojure/tools.namespace "0.3.0"]
+  '[[org.clojure/tools.namespace "0.3.1"]
     [circleci/clj-yaml "0.6.0"]])

 (def ^:private +yaml-metadata-defaults+
@@ -399,7 +399,7 @@
       :pod pod})))

 (def ^:private ^:deps markdown-deps
-  '[[org.clojure/tools.namespace "0.3.0"]
+  '[[org.clojure/tools.namespace "0.3.1"]
     [com.vladsch.flexmark/flexmark "0.40.16"]
     [com.vladsch.flexmark/flexmark-profile-pegdown "0.40.16"]])

@@ -505,7 +505,7 @@
                    :cmd-opts cmd-opts))))

 (def ^:private ^:deps asciidoctor-deps
-  '[[org.clojure/tools.namespace "0.3.0"]
+  '[[org.clojure/tools.namespace "0.3.1"]
     [org.asciidoctor/asciidoctorj "2.0.0"]])

 (def ^:private +asciidoctor-defaults+
@@ -554,7 +554,7 @@
                         :meta       meta))))

 (def ^:private ^:deps highlight-deps
-  '[[org.clojure/tools.namespace "0.3.0"]
+  '[[org.clojure/tools.namespace "0.3.1"]
     [enlive "1.1.6"]
     [clygments "1.0.0"]])

@@ -624,8 +624,8 @@
         (pm/set-meta fileset updated-metas)))))

 (def ^:private ^:deps word-count-deps
-  '[[org.clojure/tools.namespace "0.3.0"]
-    [org.apache.lucene/lucene-analyzers-common "8.1.0"]])
+  '[[org.clojure/tools.namespace "0.3.1"]
+    [org.apache.lucene/lucene-analyzers-common "8.4.1"]])

 (def ^:private +word-count-defaults+
   {:filterer identity
@@ -779,7 +779,7 @@

 (def ^:private ^:deps sitemap-deps
   '[[sitemap "0.4.0"]
-    [clj-time "0.15.1"]])
+    [clj-time "0.15.2"]])

 (def ^:private +sitemap-defaults+
   {:filename "sitemap.xml"
@@ -804,7 +804,7 @@
         (commit fileset tmp)))))

 (def ^:private ^:deps render-deps
-  '[[org.clojure/tools.namespace "0.3.0"]])
+  '[[org.clojure/tools.namespace "0.3.1"]])

 (def render-pod (delay (create-pod' render-deps)))

@@ -1177,9 +1177,9 @@
       paths)))

 (def ^:private ^:deps atom-deps
-  '[[org.clojure/tools.namespace "0.3.0"]
+  '[[org.clojure/tools.namespace "0.3.1"]
     [org.clojure/data.xml "0.2.0-alpha6"]
-    [clj-time "0.15.1"]])
+    [clj-time "0.15.2"]])

 (def ^:private +atom-defaults+
   {:filename "atom.xml"
@@ -1225,7 +1225,7 @@

 (def ^:private ^:deps rss-deps
   '[[clj-rss "0.2.5"]
-    [clj-time "0.15.1"]])
+    [clj-time "0.15.2"]])

 (def ^:private +rss-defaults+
   {:filename "feed.rss"


Increase timeout

Increase timeout

--- src/cider_ci/builder/project_configuration.clj
+++ src/cider_ci/builder/project_configuration.clj
@@ -32,8 +32,8 @@
               (str "/project-configuration/" tree-id))]
     (catcher/snatch
       {:return-fn convert-http-exception}
-      (-> url (http/get {:socket-timeout 3000
-                         :conn-timeout 3000
+      (-> url (http/get {:socket-timeout 10000
+                         :conn-timeout 10000
                          :as :json})
           :body))))


Update text on Raster Calculator page.

Update text on Raster Calculator page.

--- src/clj/popchange/views/raster_calculation.clj
+++ src/clj/popchange/views/raster_calculation.clj
@@ -158,7 +158,7 @@
   [:div.container
    [:div.page-header
     [:h1 "Raster Calculation Visualisation"]]
-   [:p.lead "Generate a visualisation based on the calculation between two data sets (" [:code "[set 1] - [set 2]"] "). The visualisation can be used to identity areas of positive or negative growth by looking for \"hot spots\" and vice-versa."]
+   [:p.lead "Generate a visualisation based on the calculation between two data sets (" [:code "[set 1] - [set 2]"] "). The visualisation can be used to identity areas of positive or negative growth by looking for \"hot spots\" and vice-versa. Set 1 should be the most recent date (e.g. 2011) and set 2 should be the older date (e.g. 1991). Then positive values are increases and negative values are decreases."]

    [:div.col-md-4
     [:div.non-js


it seems I don't understand clojure nses

--- src/cu/web.clj
+++ src/cu/web.clj
@@ -6,6 +6,7 @@
     [compojure.core :refer :all]
     [compojure.handler :as handler]
     [compojure.route :refer [not-found]]
+    [cu.config :as global-config]
     [ring.adapter.jetty :refer [run-jetty]]
     [ring.middleware.basic-authentication :refer :all]
     ))
@@ -56,5 +57,5 @@

 (defn -main []
   (let [port (Integer/parseInt (System/getenv "PORT"))]
-    (run-jetty (app cu.config/config) {:port port})))
+    (run-jetty (app global-config/config) {:port port})))


Remove forgotten debug output

Remove forgotten debug output

--- frontend/src/warehouse/component_import/events.cljs
+++ frontend/src/warehouse/component_import/events.cljs
@@ -35,7 +35,6 @@
 (reg-event-db
  :import-providers
  (fn [db [_ providers]]
-   (println providers)
    (assoc db :component-providers providers)))

 (reg-event-db


Use test.check test for gen test for query generators

--- test/com/wsscode/pathom/gen_test.cljc
+++ test/com/wsscode/pathom/gen_test.cljc
@@ -4,6 +4,7 @@
             [clojure.test :refer :all]
             [clojure.test.check :as tc]
             [clojure.test.check.properties :as props]
+            [clojure.test.check.clojure-test :as test]
             [clojure.spec.alpha :as s]
             [fulcro.client.primitives :as fp]
             [clojure.test.check.generators :as gen]))
@@ -47,25 +48,24 @@
          {::fixed-number 43}))

   (is (= (sgen/query->props [[::fixed-number '_]])
-         {::fixed-number 42}))
+         {::fixed-number 42})))

-  (is (true? (-> (tc/quick-check 20
-                   (props/for-all [query (spec.query/make-gen
-                                           {::spec.query/gen-property
-                                            (fn [_] (gen/elements (keys (::sgen/settings gen-env))))
+(test/defspec parser-integrity {:max-size 18 :num-tests 100}
+  (props/for-all [query (spec.query/make-gen
+                          {::spec.query/gen-property
+                           (fn [_] (gen/elements (keys (::sgen/settings gen-env))))

-                                            ::spec.query/gen-ident-key
-                                            (fn [_] (gen/elements (keys (::sgen/settings gen-env))))
+                           ::spec.query/gen-ident-key
+                           (fn [_] (gen/elements (keys (::sgen/settings gen-env))))

-                                            ::spec.query/gen-union-key
-                                            (fn [_] (gen/elements (keys (::sgen/settings gen-env))))
+                           ::spec.query/gen-union-key
+                           (fn [_] (gen/elements (keys (::sgen/settings gen-env))))

-                                            ::spec.query/gen-params
-                                            (fn [_] (gen/return {}))}
+                           ::spec.query/gen-params
+                           (fn [_] (gen/return {}))}

-                                           ::spec.query/gen-query)]
-                     (sgen/query->props gen-env query)))
-                 :result))))
+                          ::spec.query/gen-query)]
+    (sgen/query->props gen-env query)))

 (deftest test-comp->props
   (is (= (sgen/comp->props Component)


Modernaize code-age code

Modernaize code-age code

--- src/atom_finder/questions/code_age.clj
+++ src/atom_finder/questions/code_age.clj
@@ -6,6 +6,8 @@
    [clj-jgit.internal  :as giti]
    [clj-jgit.porcelain :as gitp]
    [clj-jgit.querying  :as gitq]
+   [clj-cdt.clj-cdt :refer :all]
+   [clj-cdt.writer-util :refer :all]
    [atom-finder.patch :refer :all]
    [atom-finder.atom-patch :refer :all]
    [atom-finder.atoms-in-dir :refer :all]
@@ -140,36 +142,38 @@
 '((def code-age-repo (->> "~/opt/src/atom-finder/gcc" expand-home gitp/load-repo)))
 ;(def code-age-repo linux-historical-repo)

-(->> "~/opt/src/atom-finder-histories"
-     expand-home
-     list-dirs
-     (map #(juxt->> % .getName gitp/load-repo))
-     (into {})
-     (def history-repos))
-
-'((print (now)))
-'((-<>>
+(def history-repos
+  (->> "~/opt/src/atom-finder-histories"
+       expand-home
+       list-dirs
+       (map #(juxt->> % .getName gitp/load-repo))
+       (into {})))
+
+(defn atoms-on-the-first-of-every-month
+  [edn-file]
+  (-<>>
    "first-commits-per-month.txt"
    read-data
    (partition-by (fn [line] (-> line :date year-month first)))
    (map first)
-   (drop-while #(not= "ba68e9715ac5e695f105cbb6a3a1cf4e9b5422d1" (:rev-str %))) rest
-   ;(map pap)
-   ;(take 2) (map prn))
+   ;(drop-while #(not= "ba68e9715ac5e695f105cbb6a3a1cf4e9b5422d1" (:rev-str %))) rest
+   ;(map pap) (take 2) (map prn))
    (map (fn [h]
           (let [repo (-> h :project history-repos)]
                 {:project (:project h) :repo repo :rev-commit (find-rev-commit repo (-> h :rev-str))})))
+   ;(map #(vector (:project %1) (-> %1 :rev-commit year-month))) (map prn))
    (mapcat (fn [h] (map (partial-right assoc :project (:project h)) (repo-files (:repo h) (:rev-commit h)))))
  (filter (comp c-file? :path))
+ ;;(take 10) (map (juxt :project :date :path)) (map prn))
  (pmap (fn [rev-file]
     (log-err (str "parsing/finding atoms in " (juxt->> rev-file :path :rev-str)) nil
              (with-timeout 120
-        (if-let [ast (mem-tu (:path rev-file) (:content rev-file))]
+        (when-let [ast (parse-source (:content rev-file) {:filename (:path rev-file)})]
           (assoc (dissoc rev-file :content)
                  :atoms (->> ast find-all-atoms-non-atoms (map-values count))))))))
  (map prn)
  dorun
- (log-to "tmp/code-age_all_2018-01-16_03_per-year_skipped-clang-emacs_continued.edn")
+ (log-to edn-file)
  time-mins
  ))

@@ -185,9 +189,11 @@
      (log-to "tmp/code-age_all_2018-01-16_00_clang-emacs.edn")
      ))

-'((->>
-   "tmp/code-age_all_2018-01-16_all_per-year_combined.edn"
+(defn summarize-code-age [edn-file csv-file]
+  (->>
+   edn-file
    read-lines
+   (take 20)
    (filter :path)
    ;(remove #(->> % :path (re-find #"test\/|\/test")))
    (group-by (juxt :date :project :rev-str))
@@ -197,7 +203,7 @@
    (filter :date)
    (sort-by (juxt :project :date))
    reverse
-   (maps-to-csv "tmp/code-age_all_2018-01-16_all_per-year_combined.csv")
+   (maps-to-csv csv-file)
    time-mins
    ))

@@ -224,11 +230,11 @@
    )
   )

-'((def emacs-repo (->> "~/opt/src/emacs" expand-home gitp/load-repo)))
-'((->> "src/atimer.c"
+;; try parsing emacs with C instead of C++
+'((def emacs-repo (->> "~/opt/src/atom-finder/emacs" expand-home gitp/load-repo)))
+'((-<>> "src/atimer.c"
        (rev-filestr emacs-repo "1c027a2427524def8a03ee4ad3e48fefa352a9b0")
-       ;parse-source
-       c-tu
+       (parse-source <> {:language :c})
        flatten-tree
        (map type)
        (pap count)
@@ -237,3 +243,12 @@
        (map prn)
        )
   )
+
+  (defn main-code-age
+    []
+    (let [edn-file "tmp/code-age_all_2018-08-30_parse-source-args.edn"
+          csv-file "tmp/code-age_all_2018-08-30_parse-source-args.csv"]
+      (println (str (now)))
+      (atoms-on-the-first-of-every-month edn-file)
+      (summarize-code-age edn-file csv-file)
+      ))


Add a test to ensure that it is possible to return a status in any function.

--- test/plugboard/core/test_decision.clj
+++ test/plugboard/core/test_decision.clj
@@ -81,5 +81,12 @@
       (fn [state dlg] (dlg  (dissoc state :zip)))
       ]
      {:foo "foo"}
+
+     ;; It must be possible to return a pair which returns a status
+     ;; code and altered state.
+     {:foo "foo"}
+     [100 (fn [state dlg] [200 (assoc state :bar "bar")])]
+     {:foo "foo" :bar "bar"}
      )
-  ))
+    )
+  )


Support selectors as parameters

Support selectors as parameters

CSS selector strings or vectors of hiccup style keywords work as
selectors. A selector can be given in place of a node reference for convenience.

--- src/clj_chrome_devtools/automation.clj
+++ src/clj_chrome_devtools/automation.clj
@@ -10,7 +10,43 @@
             [clj-chrome-devtools.impl.connection :as connection]
             [clojure.core.async :as async :refer [go-loop go <!! <!]]
             [clojure.java.io :as io]
-            [clojure.string :as str]))
+            [clojure.string :as str]
+            [clojure.spec.alpha :as s]))
+
+;; Define what a node reference is
+
+(s/def ::node-id integer?)
+(s/def ::node-ref (s/keys :req-un [::node-id]))
+
+;; A hiccup selector is a vector of hiccup-like elements
+;; [:div.some-class :a]
+(s/def ::hiccup-selector (s/coll-of keyword?))
+
+(s/def ::selector (s/or :css-selector string?
+                        :hiccup-selector ::hiccup-selector))
+
+(s/def ::node-like (s/or :node-ref ::node-ref
+                         :selector ::selector))
+
+(defn- selector->string [selector]
+  (let [conformed-selector (s/conform ::selector selector)]
+    (assert (not= conformed-selector ::s/invalid)
+            (s/explain-str ::selector selector))
+    (let [[selector-type selector-value] conformed-selector]
+      (if (= selector-type :css-selector)
+        selector-value
+        (str/join " " (map name selector-value))))))
+
+(declare sel1)
+
+(defn- to-node-ref [ctx node-like]
+  (let [conformed-node-like (s/conform ::node-like node-like)]
+    (assert (not= conformed-node-like :s/invalid)
+            (s/explain-str ::node-like node-like))
+    (let [[ref-or-selector _] conformed-node-like]
+      (if (= :node-ref ref-or-selector)
+        node-like
+        (sel1 ctx (selector->string node-like))))))

 ;; Automation context wraps a low-level CDP connection with state handling
 (defrecord Automation [connection root])
@@ -91,14 +127,14 @@
    (:node-id @(:root ctx))))

 (defn sel
-  "Select elements by path. Path is a string."
-  ([path] (sel @current-automation path))
-  ([{c :connection :as ctx} path]
+  "Select elements by selector."
+  ([selector] (sel @current-automation selector))
+  ([{c :connection :as ctx} selector]
    (wait :element '()
          (map (fn [id]
                 {:node-id id})
               (:node-ids (dom/query-selector-all c {:node-id (root-node-id ctx)
-                                                    :selector path}))))))
+                                                    :selector selector}))))))

 (defn sel1
   "Select a single element by path."
@@ -111,7 +147,8 @@
 (defn bounding-box
   ([node] (bounding-box @current-automation node))
   ([{c :connection :as ctx} node]
-   (let [{:keys [width height content]} (:model (dom/get-box-model c node))
+   (let [node (to-node-ref ctx node)
+         {:keys [width height content]} (:model (dom/get-box-model c node))
          [x y] content]
      {:x x :y y
       :width width :height height
@@ -126,31 +163,7 @@
         ;; :value only works for simple values
         :result :value)))

-(comment
-  (defn scroll-visible
-    "Make the given node visible by scrolling to it. Returns the bounding box in
-  screen coordinates (NOT page).
-  Tries to center the viewport around the element."
-    ([node] (scroll-visible @current-automation node))
-    ([{c :connection :as ctx} node]
-     (println "SCROLL-VISIBLE: " node ", resolved: " (dom/resolve-node c node))
-     (let [[ww wh] (evaluate ctx "[window.innerHeight, window.innerWidth]")
-           [center-x center-y] (:center (bounding-box ctx node))
-           scroll-x (int (- center-x (/ ww 2)))
-           scroll-y (int (- center-y (/ wh 2)))]
-       (println "SCROLL TO " scroll-x ", " scroll-y)
-       (evaluate ctx (format "window.scrollTo(%d,%d)" scroll-x scroll-y))
-       (let [{:keys [x y width height]} (bounding-box ctx node)
-             [sx sy] (evaluate ctx "[window.scrollX, window.scrollY]")
-             screen-x (- x sx)
-             screen-y (- y sy)]
-         (println "scroll at: " sx "," sy)
-         {:x screen-x
-          :y screen-y
-          :center [(Math/round (double (+ screen-x (/ width 2))))
-                   (Math/round (double (+ screen-y (/ height 2))))]})))))
-
-(defn- node-object-id [{c :connection} node]
+(defn- node-object-id [{c :connection :as ctx} node]
   (->> node (dom/resolve-node c) :object :object-id))

 (defn- eval-node [{c :connection :as ctx} node-or-object-id & fn-def-strings]
@@ -167,7 +180,8 @@
   Returns the center X/Y of the element."
   ([node] (scroll-into-view @current-automation node))
   ([{c :connection :as ctx} node]
-   (let [node-object-id (node-object-id ctx node)
+   (let [node (to-node-ref ctx node)
+         node-object-id (node-object-id ctx node)
          {:keys [x y] :as ret} (eval-node
                                 ctx node
                                 "function() { this.scrollIntoViewIfNeeded(); "
@@ -181,7 +195,8 @@
   "Wait for element to become visible, return true if element is visible, false otherwise."
   ([node] (visible @current-automation node))
   ([{c :connection :as ctx} node]
-   (let [object-id (node-object-id ctx node)]
+   (let [node (to-node-ref ctx node)
+         object-id (node-object-id ctx node)]
      (wait :render false
            (eval-node ctx object-id
                       "function() {"
@@ -191,17 +206,18 @@
 (defn click
   ([node] (click @current-automation node))
   ([{c :connection :as ctx} node]
-   (visible ctx node)
-   (let [{:keys [x y]} (scroll-into-view ctx node)
-         event {:x x :y y :button "left" :click-count 1}]
-     (input/dispatch-mouse-event c (assoc event :type "mousePressed"))
-     (input/dispatch-mouse-event c (assoc event :type "mouseReleased"))
-
-     ;; FIXME: Artificial slowdown, nodes that appear after clicking may be found
-     ;; by a selector, but cannot be resolved (aren't sent to us by chrome yet?).
-     ;; Implement a "dom" model that has all the nodes and keep resolved nodes
-     ;; in the implementation. Always resolve a node from the "dom"
-     (Thread/sleep 100))))
+   (let [node (to-node-ref ctx node)]
+     (visible ctx node)
+     (let [{:keys [x y]} (scroll-into-view ctx node)
+           event {:x x :y y :button "left" :click-count 1}]
+       (input/dispatch-mouse-event c (assoc event :type "mousePressed"))
+       (input/dispatch-mouse-event c (assoc event :type "mouseReleased"))
+
+       ;; FIXME: Artificial slowdown, nodes that appear after clicking may be found
+       ;; by a selector, but cannot be resolved (aren't sent to us by chrome yet?).
+       ;; Implement a "dom" model that has all the nodes and keep resolved nodes
+       ;; in the implementation. Always resolve a node from the "dom"
+       (Thread/sleep 100)))))

 (defn click-navigate
   "Click element and wait for navigation to be done."
@@ -213,12 +229,14 @@
 (defn html-of
   ([node] (html-of @current-automation node))
   ([{c :connection :as ctx} node]
-   (:outer-html (dom/get-outer-html c node))))
+   (let [node (to-node-ref ctx node)]
+     (:outer-html (dom/get-outer-html c node)))))

 (defn text-of
   ([node] (text-of @current-automation node))
   ([{c :connection :as ctx} node]
-   (eval-node ctx node "function() { return this.innerText; }")))
+   (let [node (to-node-ref ctx node)]
+     (eval-node ctx node "function() { return this.innerText; }"))))

@@ -264,5 +282,6 @@
   ([node attribute-name attribute-value]
    (set-attribute @current-automation node attribute-name attribute-value))
   ([{c :connection :as ctx} node attribute-name attribute-value]
-   (dom/set-attribute-value c (merge node {:name attribute-name
-                                           :value attribute-value}))))
+   (let [node (to-node-ref ctx node)]
+     (dom/set-attribute-value c (merge node {:name attribute-name
+                                             :value attribute-value})))))


prevent non draggable morphs from blocking dragging of parent

--- src/cljs/cljs_workspace/draggable.cljs
+++ src/cljs/cljs_workspace/draggable.cljs
@@ -6,7 +6,6 @@
             [om.core :as om :include-macros true]
             [om.dom :as dom :include-macros true]
             [goog.style :as gstyle]
-
             ; [clojure.browser.repl :as repl]
             )
   (:import [goog.events EventType]))
@@ -34,27 +33,41 @@
 (defn location [e]
   [(.-clientX e) (.-clientY e)])

-(defn drag [e app offset]
-  (let [old-pos (get-in @app [:morph :Position])
+(defn is-draggable [self]
+  (and (get-in self [:morph :isDraggable])))
+
+(defn is-clicked [self]
+  (= (self :id) @clicked-morph))
+
+(defn drag [e ->self offset]
+  (let [self @->self
+        old-pos (get-in self [:morph :Position])
         [prev-cursor-x, prev-cursor-y] @prev-cursor-pos
         [delta-x, delta-y] [(- (.-clientX e) prev-cursor-x) (- (.-clientY e) prev-cursor-y)]
         [new-pos-x, new-pos-y] [(+ (old-pos :x) delta-x) (+ (old-pos :y) delta-y)]]
-    (when (and (= (@app :id) @clicked-morph) (get-in @app [:morph :isDraggable]))
+    (when (and (is-clicked self) (is-draggable self))
       (swap! prev-cursor-pos #(identity [(.-clientX e) (.-clientY e)]))
-      (om/update! app [:morph :Position] {:x new-pos-x :y new-pos-y} :update))))
+      (if-not
+        (if-let [callback (get-in self [:morph :onDrag])]
+            ; custom behavior
+            (callback ->self {:x new-pos-x :y new-pos-y})
+            false)
+        ; default behavior
+        (om/update! ->self [:morph :Position] {:x new-pos-x :y new-pos-y})))))

-(defn stop-dragging [e app]
+(defn stop-dragging [e ->self owner]
   (swap! clicked-morph #(identity nil))
-  (doto js/window
+    (doto js/window
       (events/unlisten EventType.MOUSEUP stop-dragging)
-      (events/unlisten EventType.MOUSEMOVE #(drag % app nil)))) ;; let the event propagate further down ??
+      (events/unlisten EventType.MOUSEMOVE #(drag % ->self nil)))) ;; let the event propagate further down ??

-(defn start-dragging [e app owner]
+(defn start-dragging [e ->self owner]
   (swap! prev-cursor-pos #(identity [(.-clientX e) (.-clientY e)]))
-  (when (not @clicked-morph) (swap! clicked-morph #(@app :id)))
+  (when (and (is-draggable @->self) (not @clicked-morph))
+    (swap! clicked-morph #(@->self :id)))
     ;; start listening for mouse movements in the window in case the mouse cursor
     ;; escapes temporarily from the dragged morph
-    (let [[offset-x, offset-y] (element-offset (om/get-node owner))]
-      (doto js/window
-        (events/listen EventType.MOUSEUP stop-dragging)
-        (events/listen EventType.MOUSEMOVE #(drag % app [offset-x offset-y]))))) ;; let the event propagate further down
+  (let [[offset-x, offset-y] (element-offset (om/get-node owner))]
+    (doto js/window
+      (events/listen EventType.MOUSEUP stop-dragging)
+      (events/listen EventType.MOUSEMOVE #(drag % ->self [offset-x offset-y]))))) ;; let the event propagate further down


modal navi tabs and funcs

modal navi tabs and funcs

--- src/cljs/salava/badge/ui/settings.cljs
+++ src/cljs/salava/badge/ui/settings.cljs
@@ -5,8 +5,13 @@
             [salava.core.time :refer [date-from-unix-time]]
             [salava.core.ui.tag :as tag]
             [salava.core.ui.rate-it :as r]
-            [salava.core.ui.helper :refer [private? navigate-to path-for]]
-            [salava.badge.ui.helper :as bh]))
+            [salava.core.ui.helper :refer [private? navigate-to path-for js-navigate-to]]
+            [salava.badge.ui.helper :as bh]
+            [salava.core.ui.share :as s]
+            [reagent.session :as session]
+            [clojure.string :refer [upper-case replace]]
+            [salava.core.ui.rate-it :as r]
+            [salava.badge.ui.my :as my]))

 (defn set-visibility [visibility state]
   (swap! state assoc-in [:badge-settings :visibility] visibility))
@@ -25,6 +30,13 @@
       (path-for (str "/obpv1/badge/export-to-pdf"))
       {:params {:badges (list (:id @state)) :lang-option lang-option }
        :handler (js-navigate-to badge-url)})))
+
+(defn save-raiting [id state init-data raiting]
+  (ajax/POST
+    (path-for (str "/obpv1/badge/save_raiting/" id))
+    {:params   {:rating  (if (pos? raiting) raiting nil)}
+     :handler (fn []
+                (init-data state id (:tab-no @state)))}))

 (defn save-settings [state init-data]
   (let [{:keys [id visibility tags rating evidence_url]} (:badge-settings @state)]
@@ -35,7 +47,7 @@
                  :rating       (if (pos? rating) rating nil)
                  :evidence-url evidence_url}
        :handler (fn []
-                  (init-data state id))})))
+                  (init-data state id (if (= 3 (:tab-no @state))(:tab-no @state) nil)))})))

 (defn toggle-recipient-name [id show-recipient-name-atom]
   (let [new-value (not @show-recipient-name-atom)]
@@ -55,136 +67,189 @@
                          (swap! state assoc-in [:badge-settings :show_evidence] new-value)
                          (swap! state assoc :show_evidence new-value)))})))

-(defn settings-modal [{:keys [id name image_file issued_on expires_on show_evidence revoked]} state init-data badgeinfo?]
+(defn toggle-receive-notifications [badge_id notifications-atom]
+  (let [req-path (if @notifications-atom
+                   (str "/obpv1/social/delete_connection_badge/" badge_id)
+                   (str "/obpv1/social/create_connection_badge/" badge_id))]
+    (ajax/POST (path-for req-path)
+               {:handler (fn [data]
+                           (reset! notifications-atom (:connected? data)))})))
+
+(defn visibility-form [state init-data]
+  [:form {:class "form-horizontal"}
+   [:div
+    [:fieldset {:class "form-group visibility"}
+     [:legend {:class "col-md-9 sub-heading"}
+      (t :badge/Badgevisibility)]
+     [:div {:class (str "col-md-12 " (get-in @state [:badge-settings :visibility]))}
+      (if-not (private?)
+        [:div [:input {:id              "visibility-public"
+                       :name            "visibility"
+                       :value           "public"
+                       :type            "radio"
+                       :on-change       #(do
+                                           (set-visibility "public" state)
+                                           (save-settings state init-data))
+                       :default-checked (= "public" (get-in @state [:badge-settings :visibility]))}]
+         [:i {:class "fa fa-globe" }]
+         [:label {:for "visibility-public"}
+          (t :badge/Public)]])
+      [:div [:input {:id              "visibility-internal"
+                     :name            "visibility"
+                     :value           "internal"
+                     :type            "radio"
+                     :on-change       #(do
+                                         (set-visibility "internal" state)
+                                         (save-settings state init-data))
+                     :default-checked (= "internal" (get-in @state [:badge-settings :visibility]))}]
+       [:i {:class "fa fa-group" }]
+       [:label {:for "visibility-internal"}
+        (t :badge/Shared)]]
+      [:div [:input {:id              "visibility-private"
+                     :name            "visibility"
+                     :value           "private"
+                     :type            "radio"
+                     :on-change       #(do
+                                         (set-visibility "private" state)
+                                         (save-settings state init-data))
+                     :default-checked (= "private" (get-in @state [:badge-settings :visibility]))}]
+       [:i {:class "fa fa-lock" }]
+       [:label {:for "visibility-private"}
+        (t :badge/Private)]]]]]])
+
+(defn delete-tab-content [{:keys [name image_file]} state]
+  [:div {:id "badge-settings" :class "row flip"}
+   [:div {:class "col-md-3 badge-image modal-left"}
+    [:img {:src (str "/" image_file) :alt name}]]
+   [:div {:class "col-md-9 delete-confirm delete-tab"}
+    [:div {:class "alert alert-warning"}
+     (t :badge/Confirmdelete)]
+    [:div
+     [:button {:type     "button"
+               :class    "btn btn-primary"
+               :data-dismiss "modal"
+               :on-click #(swap! state assoc-in [:badge-settings :confirm-delete?] false)}
+      (t :badge/Cancel)]
+     [:button {:type         "button"
+               :class        "btn btn-warning"
+               :data-dismiss "modal"
+               :on-click     #(delete-badge state)}
+      (t :badge/Delete)]]]])
+
+(defn share-tab-content [{:keys [id name image_file issued_on expires_on show_evidence revoked visibility issuer_content_name]} state init-data]
+  (let [expired? (bh/badge-expired? expires_on)
+        revoked (pos? revoked)]
+    [:div {:id "badge-settings" :class "row flip"}
+     [:div {:class "col-md-3 badge-image modal-left"}
+      [:img {:src (str "/" image_file) :alt name}]]
+     [:div {:class "col-md-9 settings-content"}
+      (if (and (not expired?) (not revoked))
+        [visibility-form state init-data])
+      (if (= "public" visibility)
+        [:div
+         [:hr]
+         [s/share-buttons-badge
+          (str (session/get :site-url) (path-for (str "/badge/info/" id)))
+          name
+          (= "public" visibility)
+          true
+          (cursor state [:show-link-or-embed])
+          image_file
+          {:name     name
+           :authory  issuer_content_name
+           :licence  (str (upper-case (replace (session/get :site-name) #"\s" "")) "-" id)
+           :url      (str (session/get :site-url) (path-for (str "/badge/info/" id)))
+           :datefrom issued_on
+           :dateto   expires_on}]])]]))
+
+(defn settings-tab-content [{:keys [id name image_file issued_on expires_on show_evidence revoked rating]} state init-data badgeinfo?]
   (let [expired? (bh/badge-expired? expires_on)
         show-recipient-name-atom (cursor state [:show_recipient_name])
-        revoked (pos? revoked)]
-    [:div {:id "badge-settings"}
-     [:div.modal-body
-      [:div.row.flip
-       [:div.col-md-12
-        [:button {:type         "button"
-                  :class        "close"
-                  :data-dismiss "modal"
-                  :aria-label   "OK"
-                  }
-         [:span {:aria-hidden             "true"
-                 :dangerouslySetInnerHTML {:__html "×"}}]]]]
-      [:div.row.flip
-       [:div {:class "col-md-3 badge-image modal-left"}
-
-        [:img {:src (str "/" image_file) :alt name}]
-        [:h1.uppercase-header name]]
-
-       [:div {:class "col-md-9 settings-content"}
-       (if revoked
-            [:div.revoked (t :badge/Revoked)])
-          (if expired?
-            [:div.expired (t :badge/Expiredon) ": " (date-from-unix-time (* 1000 expires_on))])
-
-        [:form {:class "form-horizontal"}
-         (if (and (not expired?) (not revoked))
-           [:div
-            [:fieldset {:class "form-group visibility"}
-            [:legend {:class "col-md-12 sub-heading"}
-              (t :badge/Badgevisibility)]
-             [:div {:class (str "col-md-12 " (get-in @state [:badge-settings :visibility]))}
-              (if-not (private?)
-                [:div [:input {:id              "visibility-public"
-                               :name            "visibility"
-                               :value           "public"
-                               :type            "radio"
-                               :on-change       #(set-visibility "public" state)
-                               :default-checked (= "public" (get-in @state [:badge-settings :visibility]))}]
-                 [:i {:class "fa fa-globe" }]
-                 [:label {:for "visibility-public"}
-                  (t :badge/Public)]])
-              [:div [:input {:id              "visibility-internal"
-                       :name            "visibility"
-                       :value           "internal"
-                       :type            "radio"
-                       :on-change       #(set-visibility "internal" state)
-                       :default-checked (= "internal" (get-in @state [:badge-settings :visibility]))}]
-              [:i {:class "fa fa-group" }]
-              [:label {:for "visibility-internal"}
-               (t :badge/Shared)]]
-              [:div [:input {:id              "visibility-private"
-                       :name            "visibility"
-                       :value           "private"
-                       :type            "radio"
-                       :on-change       #(set-visibility "private" state)
-                       :default-checked (= "private" (get-in @state [:badge-settings :visibility]))}]
-              [:i {:class "fa fa-lock" }]
-              [:label {:for "visibility-private"}
-               (t :badge/Private)]]]]])
-            (if (and (not revoked) (not expired?))
-               [:div.form-group
-             [:fieldset {:class "col-md-12 checkbox"}
-             [:legend {:class "col-md-12 sub-heading"}
-              (t :badge/Earnervisibility)]
-              [:div.col-md-12 [:label {:for "show-name"}
-               [:input {:type      "checkbox"
-                        :id        "show-name"
-                        :on-change #(toggle-recipient-name id show-recipient-name-atom)
-                        :checked   @show-recipient-name-atom}]
-               (t :badge/Showyourname)]]]])
-
-         (if (and (not revoked) (not expired?))
-           [:div
-            [:div {:class "row"}
-             [:label {:class "col-md-12 sub-heading" :for "newtags"}
-              (t :badge/Tags)]]
-            [:div {:class "row"}
-             [:div {:class "col-md-12"}
-              [tag/tags (cursor state [:badge-settings :tags])]]]
-            [:div {:class "form-group"}
-             [:div {:class "col-md-12"}
-              [tag/new-tag-input (cursor state [:badge-settings :tags]) (cursor state [:badge-settings :new-tag])]]]
-            [:div {:class "row"}
-             [:label {:class "col-md-12 sub-heading" :for "evidenceurl"}
-              (t :badge/Evidenceurl)]]
-            [:div {:class "form-group"}
-             [:div {:class "col-md-12"}
-              [:input {:class       "form-control"
-                       :type        "text"
-                       :id          "evidenceurl"
-                       :placeholder (t :badge/EnterevidenceURLstartingwith)
-                       :value       (get-in @state [:badge-settings :evidence_url])
-                       :on-change   #(swap! state assoc-in [:badge-settings :evidence_url] (-> % .-target .-value))}]]]
-            (if (not-empty (get-in @state [:badge-settings :evidence_url]))
-               [:fieldset {:class "checkbox"}
-               [:legend {:class "sub-heading"}
-              (t :badge/Evidencevisibility)]
-                [:div [:label {:class (str show_evidence)}
-                 [:input {:type      "checkbox"
-                          :on-change #(toggle-evidence state)
-                          :checked    (get-in @state [:badge-settings :show_evidence])}]
-                 (t :badge/Showevidence)]]])
-
-              ])]
-     [:div.modal-footer
-      (if (and (not expired?) (not revoked ))
-        [:button {:type         "button"
-                  :class        "btn btn-primary"
-                  :data-dismiss "modal"
-                  :on-click     #(save-settings state init-data)}
-         (t :badge/Save)])
-         (if (get-in @state [:badge-settings :confirm-delete?])
-           [:div {:class "delete-confirm"}
-            [:div {:class "alert alert-warning"}
-             (t :badge/Confirmdelete)]
-            [:button {:type     "button"
-                      :class    "btn btn-primary"
-                      :on-click #(swap! state assoc-in [:badge-settings :confirm-delete?] false)}
-             (t :badge/Cancel)]
-            [:button {:type         "button"
-                      :class        "btn btn-warning"
-                      :data-dismiss "modal"
-                      :on-click     #(delete-badge id state init-data badgeinfo?)}
-             (t :badge/Delete)]]
-           [:a {:class    "delete-button"
-                :on-click #(swap! state assoc-in [:badge-settings :confirm-delete?] true)}
-                [:i {:class "fa fa-trash"}]
-            (t :badge/Deletebadge)])
-         ]]]]
-         ]))
+        notifications-atom (cursor state [:receive-notifications])
+        revoked (pos? revoked)
+        badge_id (:badge_id @state)]
+    [:div {:id "badge-settings" :class "row flip"}
+     [:div {:class "col-md-3 badge-image modal-left"}
+      [:img {:src (str "/" image_file) :alt name}]]
+     [:div {:class "col-md-9 settings-content settings-tab"}
+      (cond
+        revoked [:div.revoked (t :badge/Revoked)]
+        expired? [:div.expired (t :badge/Expiredon) ": " (date-from-unix-time (* 1000 expires_on))]
+        (and (not revoked) (not expired?)) [:div [:form {:class "form-horizontal"}
+                                                  [:div.form-group
+                                                   [:fieldset {:class "col-md-9 checkbox"}
+                                                    [:legend {:class "col-md-9 sub-heading"}
+                                                     (t :badge/Rating)]
+                                                    [:div.col-md-12
+                                                     {:on-click #(save-raiting id state init-data (get-in @state [:badge-settings :rating]))}
+                                                     [r/rate-it rating (cursor state [:badge-settings :rating])]]]]
+
+                                                  [:div.form-group
+                                                   [:fieldset {:class "col-md-9 checkbox"}
+                                                    [:div.col-md-12 [:label {:for "show-name"}
+                                                                     [:input {:type      "checkbox"
+                                                                              :id        "show-name"
+                                                                              :on-change #(toggle-recipient-name id show-recipient-name-atom)
+                                                                              :checked   @show-recipient-name-atom}]
+                                                                     (t :badge/Showyourname)]]]]
+
+
+                                                  [:div.form-group
+                                                   [:fieldset {:class "col-md-9 checkbox"}
+                                                    [:div.col-md-12 [:label {:for "receive-notifications"}
+                                                                     [:input {:type      "checkbox"
+                                                                              :id        "receive-notifications"
+                                                                              :on-change #(toggle-receive-notifications badge_id notifications-atom)
+                                                                              :checked   @notifications-atom}]
+                                                                    (str (t :social/Followbadge))]]
+                                                    [:div.col-md-12 (t :social/Badgenotificationsinfo)]]]
+
+                                                  [:div
+                                                   [:div {:class "row"}
+                                                    [:label {:class "col-md-12 sub-heading" :for "newtags"}
+                                                     (t :badge/Tags)]]
+                                                   [:div {:class "row"}
+                                                    [:div {:class "col-md-12"}
+                                                     [tag/tags (cursor state [:badge-settings :tags])]]]
+                                                   [:div {:class "form-group"}
+                                                    [:div {:class "col-md-12"}
+                                                     [tag/new-tag-input (cursor state [:badge-settings :tags]) (cursor state [:badge-settings :new-tag])]]]
+                                                   [:div {:class "row"}
+                                                    [:label {:class "col-md-12 sub-heading" :for "evidenceurl"}
+                                                     (t :badge/Evidenceurl)]]
+                                                   [:div {:class "form-group"}
+                                                    [:div {:class "col-md-12"}
+                                                     [:input {:class       "form-control"
+                                                              :type        "text"
+                                                              :id          "evidenceurl"
+                                                              :placeholder (t :badge/EnterevidenceURLstartingwith)
+                                                              :value       (get-in @state [:badge-settings :evidence_url])
+                                                              :on-change   #(swap! state assoc-in [:badge-settings :evidence_url] (-> % .-target .-value))}]]]
+                                                   (if (not-empty (get-in @state [:badge-settings :evidence_url]))
+                                                     [:fieldset {:class "checkbox"}
+                                                      [:legend {:class "sub-heading"}
+                                                       (t :badge/Evidencevisibility)]
+                                                      [:div [:label {:class (str show_evidence)}
+                                                             [:input {:type      "checkbox"
+                                                                      :on-change #(toggle-evidence state)
+                                                                      :checked    (get-in @state [:badge-settings :show_evidence])}]
+                                                             (t :badge/Showevidence)]]])]]
+                                            [:div.modal-footer
+                                             [:button {:type         "button"
+                                                       :class        "btn btn-primary"
+                                                       :on-click     #(save-settings state init-data)}
+                                              (t :badge/Save)]]])]]))
+
+(defn download-tab-content [{:keys [name image_file obf_url assertion_url]} state]
+  [:div {:id "badge-settings" :class "row flip"}
+   [:div {:class "col-md-3 badge-image modal-left"}
+    [:img {:src (str "/" image_file) :alt name}]]
+   [:div {:class "col-md-9 settings-content download-tab"}
+    [:div
+     [:button {:class "btn btn-primary" :on-click  #(export-to-pdf state)} (t :badge/Downloadpdf)]
+     [:div (t :badge/Pdfdownload)]]
+    [:hr]
+    [:div
+     [:a {:class "btn btn-primary" :href (str obf_url "/c/receive/download?url="(js/encodeURIComponent assertion_url))} (t :badge/Downloadbadgeimage)]
+     [:div (t :badge/Downloadbakedbadge)]
+     ]]])


Add cats.labs.channel-spec to testing namespaces.

--- dev/user.clj
+++ dev/user.clj
@@ -9,6 +9,7 @@
   ['cats.core-spec
    'cats.builtin-spec
    'cats.applicative.validation-spec
+   'cats.labs.channel-spec
    'cats.monad.identity-spec
    'cats.monad.either-spec
    'cats.monad.exception-spec


simplified bake macro using defs instead of let. this lets us use require/use in bake

--- src/cake.clj
+++ src/cake.clj
@@ -98,36 +98,27 @@
       socket
       (recur))))

-(defn- quote-if
-  "We need to quote the binding keys so they are not evaluated within the bake syntax-quote and the
-   binding values so they are not evaluated in the bake* syntax-quote. This function makes that possible."
-  [pred bindings]
-  (reduce
-   (fn [v form]
-     (if (pred (count v))
-       (conj v (list 'quote form))
-       (conj v form)))
-   [] bindings))
-
 (defn bake* [bindings body]
-  (if (nil? bake-port)
-    (println "bake not supported. perhaps you don't have a project.clj")
-    (let [form  `(~'let ~(quote-if odd? bindings) ~@body)
-          socket (bake-connect (int bake-port))
-          reader (BufferedReader. (InputStreamReader. (.getInputStream socket)))
-          writer (OutputStreamWriter. (.getOutputStream socket))]
-      (doto writer
-        (.write (prn-str form))
-        (.flush))
-      (while-let [line (.readLine reader)]
-                 (println line))
-      (flush))))
+  (let [defs (for [[sym val] bindings] (list 'def sym (list 'quote val)))]
+    (if (nil? bake-port)
+      (println "bake not supported. perhaps you don't have a project.clj")
+      (let [form  `(do ~@defs ~@body)
+            socket (bake-connect (int bake-port))
+            reader (BufferedReader. (InputStreamReader. (.getInputStream socket)))
+            writer (OutputStreamWriter. (.getOutputStream socket))]
+        (doto writer
+          (.write (prn-str form))
+          (.flush))
+        (while-let [line (.readLine reader)]
+                   (println line))
+        (flush)))))

 (defmacro bake
   "Execute body in a fork of the jvm with the classpath of your project."
   [bindings & body]
-  (let [bindings (into ['opts 'cake/opts, 'project 'cake/project] bindings)]
-    `(bake* ~(quote-if even? bindings) '~body)))
+  (let [bindings (into ['opts 'cake/opts, 'project 'cake/project] bindings)
+        bindings (for [[sym val] (partition 2 bindings)] [(list 'quote sym) val])]
+    `(bake* [~@bindings] '~body)))

 (defmacro task-doc
   "Print documentation for a task."


GAWB-1439 Improve handling of missing storage logs to show "Not Available" message when returned from orchestration/rawls. (#623)

--- src/cljs/org/broadinstitute/firecloud_ui/page/workspace/summary/tab.cljs
+++ src/cljs/org/broadinstitute/firecloud_ui/page/workspace/summary/tab.cljs
@@ -324,7 +324,10 @@
      (when (not (reader? (:workspace props)))
        (endpoints/call-ajax-orch
          {:endpoint (endpoints/storage-cost-estimate (:workspace-id props))
-          :on-done (fn [{:keys [success? status-text get-parsed-response]}]
-                     (if success?
-                       (swap! state update :server-response assoc :storage-cost (get (get-parsed-response false) "estimate"))
-                       (swap! state update :server-response assoc :storage-cost status-text)))})))})
+          :on-done (fn [{:keys [success? status-text raw-response]}]
+                     (let [[response parse-error?] (utils/parse-json-string raw-response false false)]
+                       (swap! state update :server-response assoc :storage-cost
+                              (if parse-error?
+                                (str "Error parsing JSON response with status: " status-text)
+                                (let [key (if success? "estimate" "message")]
+                                  (get response key (str "Error: \"" key "\" not found in JSON response with status: " status-text)))))))})))})


Modification getTranslation to getPosition

--- yaw/yaw/world.clj
+++ yaw/yaw/world.clj
@@ -232,7 +232,7 @@
 (defn myItemToVector [myItem]
 	"Converts a MyItem into a savable vector."
 	(let [rotation (.getRotation myItem)
-				translation (.getTranslation myItem)]
+				translation (.getPosition myItem)]
 	(vector (.getScale myItem) (.x rotation) (.y rotation) (.z rotation) (.x translation) (.y translation) (.z translation))))

 (defn createMyItemVector [itemListVec]


[#200] Decrease cache ttl to 60s

[#200] Decrease cache ttl to 60s

--- api/src/clojure/org/akvo/flow_api/endpoint/sync.clj
+++ api/src/clojure/org/akvo/flow_api/endpoint/sync.clj
@@ -43,7 +43,7 @@
             (if (unilog/valid-offset? offset db-spec)
               (if (= offset (unilog/get-cursor db-spec)) ;; end of the log
                 (-> (status {} 204)
-                    (header "Cache-Control" "max-age=3600"))
+                    (header "Cache-Control" "max-age=60"))
                 (let [changes (->
                                (unilog/process-unilog-events offset db-spec instance-id (:remote-api deps))
                                (select-keys [:form-instance-changed


Finally got around to adding tests around author

--- test/aeolian/composer_test.clj
+++ test/aeolian/composer_test.clj
@@ -26,7 +26,21 @@
                n/minor-octave-4    99            k/minor
                n/minor-octave-5    2000          k/minor))

-       (future-fact "changes to git author produces a change in instrument")
+       (facts "when processing git authors"
+        (fact "a single author uses the same instrument"
+          (let [metrics-for-same-author (c/metrics-to-measure ["Notification.java#1 AU=foo LL=3"
+                                                               "Notification.java#10 AU=foo LL=70"
+                                                               "Notification.java#100 AU=foo LL=99"] k/major 1)
+                instrument-commands (re-seq #"\[I: MIDI program \d+\]" metrics-for-same-author)]
+            (count (distinct instrument-commands)) => 1))
+
+        (fact "multiple authors produces a change in instrument"
+          (let [metrics-for-n-authors (c/metrics-to-measure ["Notification.java#1 AU=foo LL=3"
+                                                             "Notification.java#10 AU=foo LL=70"
+                                                             "Notification.java#100 AU=bar LL=99"] k/major 1)
+                instrument-commands (re-seq #"\[I: MIDI program \d+\]" metrics-for-n-authors)]
+            (count (distinct instrument-commands)) => 2)))
+
        (future-fact "changes to source file name produces a change in lyrics")

        (defn- notes-in-measure [metrics]  (first (:notes (c/build-measure [metrics] k/major 1))))


Refresh billing projects table on updated status (#724)

--- src/cljs/main/broadfcui/page/billing/billing_management.cljs
+++ src/cljs/main/broadfcui/page/billing/billing_management.cljs
@@ -71,7 +71,8 @@
        (nil? (:projects @state)) [comps/Spinner {:text "Loading billing projects..."}]
        :else
        [Table
-        {:body {:behavior {:reorderable-columns? false}
+        {:ref "table"
+         :body {:behavior {:reorderable-columns? false}
                  :style table-style/table-light
                  :data-source (table-utils/local (:projects @state))
                  :columns
@@ -139,13 +140,14 @@
           (swap! state assoc :error-message err-text)
           (swap! state assoc :projects projects)))))
    :-handle-status-change
-   (fn [{:keys [state]} project-name new-status message]
+   (fn [{:keys [state refs after-update]} project-name new-status message]
      (let [project-index (utils/first-matching-index
                           #(= (:projectName %) project-name)
                           (:projects @state))
            project (get-in @state [:projects project-index])
-           updated-project (assoc project "creationStatus" new-status "message" message)]
-       (swap! state assoc-in [:projects project-index] updated-project)))})
+           updated-project (assoc project :creationStatus new-status :message message)]
+       (swap! state assoc-in [:projects project-index] updated-project)
+       (after-update #((@refs "table") :refresh-rows))))})

 (react/defc Page


Fix warnings

Fix warnings

--- src/app/core.cljs
+++ src/app/core.cljs
@@ -8,18 +8,6 @@
 (defonce app-state
   (atom {:nav {:selected :details}
          :rsvp {:input "", :results nil}}))
-
-(defn main-view [{:keys [nav rsvp] :as data} owner]
-  (reify om/IRender
-    (render [_]
-      (println "@app-state" data)
-      (html
-       [:div
-        (om/build nav-view nav)
-        (case (-> data :nav :selected)
-          :details (om/build details-view data)
-          :where-to-stay (om/build where-to-stay-view data)
-          :rsvp (om/build rsvp-view rsvp))]))))

 (defn nav-view [{:keys [selected] :as data} owner]
   (reify om/IRender
@@ -50,7 +38,7 @@
      [:p {:align "center"}
       [:a {:href "https://goo.gl/maps/wXKle"} "Kinfolk 94"]
       [:br] "94 Wythe Ave."
-      [:br] Brooklyn, NY 11249
+      [:br] "Brooklyn, NY 11249"
       [:br] "(near the Bedford L stop, or the Nassau G stop)"]
      [:p
       "We would love it if you could "
@@ -84,13 +72,6 @@
             {:url "http://www.nylofthostel.com/"
              :name "New York Loft Hostel"
              :notes "249 Varet St. ($)"}])]])))
-
-(defn rsvp-view [{:keys [input results] :as data} owner]
-  (reify om/IRender
-    (render [_]
-      (if-not (some? results)
-        (om/build rsvp-search-view data)
-        (om/build rsvp-search-results-view data)))))

 (defn find-results [x]
   [{:guests [{:name "Henry Bean", :email "henry@bean.com"}
@@ -170,13 +151,32 @@
 (defn rsvp-search-results-view [{:keys [results]} owner]
   (reify
     om/IRenderState
-    (render-state [_ {:keys [contact] :as state}]
+    (render-state [_ {:keys [contact input] :as state}]
       (html
        [:main
         (condp <= (count results)
-          2 [:h2 (str "Oops! There are multiple matches for '" query "'")]
+          2 [:h2 (str "Oops! There are multiple matches for '" input "'")]
           1 (om/build rsvp-search-results-one-view (first results))
           0 "Zero!")]))))

+(defn rsvp-view [{:keys [input results] :as data} owner]
+  (reify om/IRender
+    (render [_]
+      (if-not (some? results)
+        (om/build rsvp-search-view data)
+        (om/build rsvp-search-results-view data)))))
+
+(defn main-view [{:keys [nav rsvp] :as data} owner]
+  (reify om/IRender
+    (render [_]
+      (println "@app-state" data)
+      (html
+       [:div
+        (om/build nav-view nav)
+        (case (-> data :nav :selected)
+          :details (om/build details-view data)
+          :where-to-stay (om/build where-to-stay-view data)
+          :rsvp (om/build rsvp-view rsvp))]))))
+
 (defn main []
   (om/root main-view app-state {:target (. js/document (getElementById "app"))}))


map.cljs: Make all functions private.

map.cljs: Make all functions private.

--- src/cljs/map.cljs
+++ src/cljs/map.cljs
@@ -18,7 +18,7 @@
 (def zoomlimit 10)
 (def layers '())

-(defn removelastlayer []
+(defn- removelastlayer []
   (when (seq (last layers))
     (do (.removeLayer mymap (last layers))
         (set! (.-value (dom/by-id "per")) "")
@@ -52,7 +52,7 @@
      :get-center [dbb]
      #(.setView mymap (vector (first %) (last %)) 5))))

-(defn addmarkers-toolserver [map-bounds-string]
+(defn- addmarkers-toolserver [map-bounds-string]
   (let [ch (chan)
         markers (L/MarkerClusterGroup.)]
     (set! layers (conj layers markers))
@@ -76,13 +76,13 @@
     (.setView mymap (vector latitude longitude) 15)
     (addmarkers-toolserver (.toBBoxString (.getBounds mymap)))))

-(defn maybe-show-here []
+(defn- maybe-show-here []
   (let [z (.getZoom mymap)
         sh (dom/by-id "showhere")]
     (when (>= z zoomlimit)
       (set! (.-innerHTML sh) "->?<-"))
     (when (< z zoomlimit)
-      (set! (.-innerHTML sh) "...."))))
+      (set! (.-innerHTML sh) "..."))))

 (.on mymap "zoomend" maybe-show-here)


[clojure] Add a repl helper to get the running system instance

--- etc/repl.clj
+++ etc/repl.clj
@@ -74,7 +74,7 @@
   [pj-ns-root]
   (let [an-ns (symbol (str pj-ns-root ".user"))]
     (if (get @system-status an-ns)
-      (println "!!  System possibly running")
+      (println "!! System possibly running" an-ns)
       (do
         (println "!! Refreshing and reloading " an-ns)
         (refresh)
@@ -92,10 +92,15 @@
     (f)
     (swap! system-status (fn [s] (assoc s an-ns false))))))

+(defn sys
+  "Pull out the system for passing around"
+  []
+   (var-get (ns-resolve (first (keys @system-status)) 'SYS)))
+
 (defn c
   "Pul out a compont from a running system"
   [component-name]
-  (let [sys (var-get (ns-resolve (first (keys @system-status)) 'SYS))]
+  (let [sys (sys)]
     (get sys component-name)))

 (defn add-dependency


Add some more tests

Add some more tests

--- test/superstring/core_test.clj
+++ test/superstring/core_test.clj
@@ -255,7 +255,7 @@
   (str/chop-prefix "foo" "F" :ignore-case) "oo"
   (str/chop-prefix "Åfoo" "Å" :ignore-case) "foo")

-(defexamples contains-test?
+(defexamples contains?
   (str/contains? "" "") ""
   (str/contains? "1" "1") "1"
   (str/contains? "foo" "fo") "foo"
@@ -286,22 +286,30 @@
                  after gen/string]
     (str/contains? (str before needle after) needle :ignore-case)))

-(defexamples contains-all-test?
-  (str/contains-all? "" []) ""
-  (str/contains-all? "" [""]) ""
-  (str/contains-all? "12" ["1" "2"]) "12"
-  (str/contains-all? "foo" ["fo" "o"]) "foo"
-  (str/contains-all? "foobar" ["qux"]) nil
-  (str/contains-all? "foobar" ["foo" "qux"]) nil
-  (str/contains-all? "foobar" ["BAR"]) nil
-  (str/contains-all? "foobar" ["BAR" "Foo"] :ignore-case) "foobar"
-  (str/contains-all? "Albert Åberg" ["åberg" "al"] :ignore-case)   "Albert Åberg")
+(defexamples contains-test?
+  (str/contains? "" "") ""
+  (str/contains? "1" "1") "1"
+  (str/contains? "foo" "fo") "foo"
+  (str/contains? "foobar" "qux") nil
+  (str/contains? "foobar" "BAR") nil
+  (str/contains? "foobar" "BAR" :ignore-case) "foobar"
+  (str/contains? "fooß" "ss" :ignore-case) nil
+  (str/contains? "fooß" "SS" :ignore-case) nil
+  (str/contains? "ß" "SS" :ignore-case) nil
+  (str/contains? "Albert Åberg" "åberg" :ignore-case) "Albert Åberg")

 (defspec contains-all-finds-generated-strings? 100
   (prop/for-all [s1 gen/string
                  s2 gen/string
                  s3 gen/string]
     (str/contains-all? (str s1 s2 s3) [s1 s2 s3])))
+
+(defexamples contains-any?
+  (str/contains-any? "foobar" ["foo"]) "foobar"
+  (str/contains-any? "foobar" ["qux"]) nil
+  (str/contains-any? "foobar" ["qux" "bar"]) "foobar"
+  (str/contains-any? "ß" ["ss" "SS"] :ignore-case) nil
+  (str/contains-any? "foobar" ["BAR"] :ignore-case) "foobar")

 (defspec contains-any-finds-a-needle 100
   (prop/for-all [before (gen/not-empty gen/string)


Add blob store test for re-storing content.

--- test/vault/blob/store_test.clj
+++ test/vault/blob/store_test.clj
@@ -18,15 +18,27 @@
        (into (sorted-map))))

-(defn- test-stored-blob
-  "Determines whether the store contains the data for the given identifier"
-  [store id data]
+(defn- test-blob-content
+  "Determines whether the store contains the content for the given identifier."
+  [store id content]
   (let [status (blob/stat store id)
         stored-content (with-open [stream (blob/open store id)]
                          (slurp stream))]
     (is (and status stored-content) "returns info and content")
     (is (= (:size status) (count (.getBytes stored-content))) "stats contain size info")
-    (is (= data stored-content) "content matches data")))
+    (is (= content stored-content) "stored content matches input")))
+
+
+(defn- test-restore-blob
+  "Tests re-storing an existing blob."
+  [store id content]
+  (is (blob/contains? store id))
+  (let [status     (blob/stat store id)
+        new-id     (blob/store! store content)
+        new-status (blob/stat store id)]
+    (is (= id new-id))
+    (is (= (:created-at status)
+           (:created-at new-status)))))

 (defn test-blob-store
@@ -37,10 +49,12 @@
     (let [blobs (store-test-blobs! store)]
       (is (= (keys blobs) (blob/list store {}))
           "enumerates all ids in sorted order")
-      (doseq [[id data] blobs]
-        (testing (str "for blob " id)
-          (test-stored-blob store id data)
-          (is (blob/remove! store id) "remove returns true")))
+      (doseq [[id content] blobs]
+        (test-blob-content store id content))
+      (let [[id content] (first (seq blobs))]
+        (test-restore-blob store id content))
+      (doseq [id (keys blobs)]
+        (is (blob/remove! store id) "remove returns true"))
       (is (empty? (blob/list store)) "ends empty")
       (is (not (blob/remove! store (first (keys blobs))))
           "gives false when removing a nonexistent blob"))))


Hide quantity by default

Hide quantity by default


Bump clj-time to 0.8.0

Bump clj-time to 0.8.0

--- joplin.elasticsearch/project.clj
+++ joplin.elasticsearch/project.clj
@@ -8,4 +8,4 @@
   :dependencies [[org.clojure/clojure "1.6.0"]
                  [clojurewerkz/elastisch "2.1.0-beta6"]
                  [joplin.core "0.1.12-SNAPSHOT"]
-                 [clj-time "0.7.0"]])
+                 [clj-time "0.8.0"]])


Test against Clojure 1.3-1.6

Test against Clojure 1.3-1.6

1.2.1 can be added the same way as needed, but it hardly matters
much these days.

--- metrics-clojure-core/project.clj
+++ metrics-clojure-core/project.clj
@@ -2,5 +2,18 @@
   :description "A Clojure façade for Coda Hale's metrics library."
   :dependencies [[org.clojure/clojure "[1.2.1,1.4.0]"]
                  [com.yammer.metrics/metrics-core "2.2.0"]]
-  :repositories {"repo.codahale.com" "http://repo.codahale.com"}
+  :repositories {"repo.codahale.com" "http://repo.codahale.com"
+                 ;; to get Clojure snapshots
+                 "sonatype" {:url "http://oss.sonatype.org/content/repositories/releases"
+                             :snapshots false
+                             :releases {:checksum :fail :update :always}}
+                 "sonatype-snapshots" {:url "http://oss.sonatype.org/content/repositories/snapshots"
+                                       :snapshots true
+                                       :releases {:checksum :fail :update :always}}}
+    :profiles {:dev    {}
+               :1.3    {:dependencies [[org.clojure/clojure "1.3.0"]]}
+               :1.4    {:dependencies [[org.clojure/clojure "1.4.0"]]}
+               :1.6    {:dependencies [[org.clojure/clojure "1.6.0-master-SNAPSHOT"]]}
+               :master {:dependencies [[org.clojure/clojure "1.6.0-master-SNAPSHOT"]]}}
+  :aliases  {"all" ["with-profile" "dev:dev,1.3:dev,1.4:dev,1.6:dev,master"]}
   :warn-on-reflection true)


[scamp] remove old comment, schematize 'set-disclude

--- modules/scamp/src/scamp/core.clj
+++ modules/scamp/src/scamp/core.clj
@@ -499,8 +499,7 @@
                                      {:old node-id :new upstream-node-contact-address})])
             new-connections))

-          ;; TODO: filter out dups
-          drop-me-msgs (doall (map #(send-msg-node-removal % node-id) droppers))]
+          drop-me-msgs (doall (map #(msg->envelope % :node-removal node-id) droppers))]

       (timbre/log* logging :trace
                :receive-msg-node-unsubscription
@@ -508,8 +507,9 @@
                :drop-me-msgs drop-me-msgs)
       [(node->removed node) (concatv replacement-messages drop-me-msgs)])))

-(defn- set-disclude
-  [s to-remove]
+(s/defn set-disclude :- #{s/Any}
+  [s :- #{s/Any}
+   to-remove :- s/Any]
   (into #{} (remove #(= % to-remove) s)))

 (s/defmethod receive-msg :node-removal :- CommUpdateSchema


[scamp] add global "clock"

[scamp] add global "clock"

This globally-available clock needs to be broken out into separate per-node
clocks, but this is a start.

--- modules/scamp/src/scamp/core.clj
+++ modules/scamp/src/scamp/core.clj
@@ -24,6 +24,31 @@

 (defn- rand-nth* [coll]
   (nth coll (rand-int* (count coll))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Implement a binding-overridable "millisecond" application clock.
+(def ^:private clock-value-in-millis (atom 0))
+
+(defn tick-clock-millis! [& [num-ticks]]
+  (swap! clock-value-in-millis + (or num-ticks 1)))
+
+(def ^:dynamic *milli-time*
+  ;; TODO: put a time in each node
+  (fn [] @clock-value-in-millis))
+
+(defn reset-clock!
+  "Reset 'clock-value-in-millis back to 0.
+  This should probably only be called from tests that need determinism."
+  []
+  (reset! clock-value-in-millis 0))
+
+(defn jitter-int
+  "Given a 'base-duration in some numerical unit of time, and an
+  'agitation-distance the jitter can cover from that 'base-duration,
+  compute a jittered duration and return it as an integer."
+  [base-duration agitation-distance]
+  (let [agitation (- (*rand* agitation-distance) (/ agitation-distance 2))]
+    (int (+ base-duration agitation))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 (defn- concatv [coll & colls]


Refined Clojure day 18 solution.

Refined Clojure day 18 solution.

--- clojure/src/advent2016/day18.clj
+++ clojure/src/advent2016/day18.clj
@@ -4,19 +4,15 @@
 (def example2 ".^^.^.^^^^")
 (def puzzle (slurp "../day18.data"))

-(defn trap? [xs]
-  (condp = xs
-    [true true false]  true
-    [false true true]  true
-    [true false false] true
-    [false false true] true
-    false))
+(defn trap? [[a _ c]]
+  (and (not= a c)
+       (or a c)))

 (defn rows [previous]
   (lazy-seq
-   (let [tmp        (partition 3 1 (repeat false) previous)
-         next-tiles (map trap? (cons (cons false (butlast (first tmp))) tmp))]
-     (cons (count (filter false? previous)) (rows next-tiles)))))
+   (let [[[_ b] :as xs] (partition 3 1 (repeat false) previous)
+         next-tiles     (cons b (map trap? xs))]
+     (cons (count (remove identity previous)) (rows next-tiles)))))

 (defn parse [s]
   (map (partial = \^) s))


SQS/SNS Hackfest - Address review feedback.

--- dev-system/src/cmr/dev_system/system.clj
+++ dev-system/src/cmr/dev_system/system.clj
@@ -97,8 +97,6 @@
        (map (fn [[app-name app-system]]
               [app-name (update-app-web-server-options app-system)]))
        (into {})))
-  ; (into {} (for [[app-name app-system] app-map]
-  ;            [app-name (update-app-web-server-options app-system)])))

 (defn- set-all-web-server-options
   "Modifies all app server instances to configure web server options. Takes the system


Add lein-typed to Clojure plugins

Add lein-typed to Clojure plugins

--- roles/clojure/files/profiles.clj
+++ roles/clojure/files/profiles.clj
@@ -20,6 +20,7 @@
                   [lein-pprint "1.1.1"]
                   [lein-swank "1.4.4"]
                   [lein-try "0.4.3"]
+                  [lein-typed "0.3.5"]
                   [refactor-nrepl "0.2.2"]]

         :injections [(require


Add docstrings for before/after

Add docstrings for before/after

--- src/main/clojure/lazytest/describe.clj
+++ src/main/clojure/lazytest/describe.clj
@@ -107,10 +107,12 @@
 		  ~@binding-symbols)))))))

 (defmacro before
+  "Returns a context whose teardown function evaluates body."
   [& body]
   `(fn-context (fn [] ~@body) (constantly nil)))

 (defmacro after
+  "Returns a context whose teardown method evaluates body."
   [& body]
   `(fn-context (constantly nil) (fn [] ~@body)))


add alias to build command

add alias to build command

--- ui/project.clj
+++ ui/project.clj
@@ -45,7 +45,7 @@
                 :source-paths ["src"]
                 :compiler {:output-to "resources/public/js/compiled/app.js"
                            :main plant-care-ui.core
-                           :optimizations :simple
+                           :optimizations :advanced
                            :pretty-print false
                            :pseudo-names false}}]}

@@ -64,4 +64,5 @@
                                   :init (do
                                           (require 'dirac.agent)
                                           (dirac.agent/boot!))}}}
-  :aliases {"lint" ["do" ["kibit"] ["bikeshed"]]})
+  :aliases {"lint" ["do" ["kibit"] ["bikeshed"]]
+            "build" ["do" ["clean"] ["cljsbuild" "once" "min"]]})


CMR-8081: Return 413 status code for ES maxClauseCount error.

--- common-app-lib/src/cmr/common_app/services/search/elastic_search_index.clj
+++ common-app-lib/src/cmr/common_app/services/search/elastic_search_index.clj
@@ -140,7 +140,13 @@
           (info "Execute ES query failed due to" body)
           (errors/throw-service-error
            :payload-too-large
-           "The search is creating more buckets than allowed by CMR. Please narrow your search.")))
+           "The search is creating more buckets than allowed by CMR. Please narrow your search."))
+
+        (when (re-find #"too_many_clauses: maxClauseCount" body)
+          (info "Execute ES query failed due to" body)
+          (errors/throw-service-error
+           :payload-too-large
+           "The search is creating more clauses than allowed by CMR. Please narrow your search.")))
       ;; for other errors, rethrow the exception
       (throw e))))


hide private comments where appropriate

hide private comments where appropriate