(SERVER-797) Modify http_client_tests to use jruby-utils helpers

This commit modified the http_client_test tests to use public helpers in
jruby-utils for creating a ScriptingContainer.  Because the default
ScriptingContainer instances which are created do not provide PERSISTENT
LocalVariableBehavior, which the tests had been depending upon, the
tests have also been modified to use global variables instead of local
ones in Ruby.

--- test/unit/puppetlabs/puppetserver/ruby/http_client_test.clj
+++ test/unit/puppetlabs/puppetserver/ruby/http_client_test.clj
@@ -1,10 +1,9 @@
 (ns puppetlabs.puppetserver.ruby.http-client-test
-  (:import (org.jruby.embed EvalFailedException LocalContextScope LocalVariableBehavior)
+  (:import (org.jruby.embed EvalFailedException)
            (org.apache.http ConnectionClosedException)
            (javax.net.ssl SSLHandshakeException)
            (java.util HashMap)
-           (java.io IOException)
-           (com.puppetlabs.jruby_utils.jruby ScriptingContainer))
+           (java.io IOException))
   (:require [clojure.test :refer :all]
             [puppetlabs.trapperkeeper.testutils.logging :as logutils]
             [puppetlabs.trapperkeeper.testutils.webserver :as jetty9]
@@ -14,7 +13,7 @@
             [schema.core :as schema]
             [puppetlabs.services.jruby.jruby-puppet-core :as jruby-puppet-core]
             [puppetlabs.services.jruby-pool-manager.jruby-core :as jruby-core]
-            [puppetlabs.services.jruby-pool-manager.impl.jruby-internal :as jruby-internal]
+            [puppetlabs.services.jruby-pool-manager.impl.jruby-pool-manager-core :as jruby-impl-core]
             [puppetlabs.services.jruby-pool-manager.jruby-schemas :as jruby-schemas]))

 ;; NOTE: this namespace is pretty disgusting.  It'd be much nicer to test this
@@ -98,19 +97,14 @@
          use-ssl?             (true? (:use-ssl options))
          http-client-settings (get-http-client-settings
                                (select-keys options [:ssl-protocols :cipher-suites]))
-         scripting-container (-> (ScriptingContainer. LocalContextScope/SINGLETHREAD
-                                                      LocalVariableBehavior/PERSISTENT)
-                                 (jruby-internal/init-jruby jruby-config))]
-     (doto scripting-container
-       (.setEnvironment (jruby-core/managed-environment (jruby-core/get-system-env) jruby-config))
-       (.setLoadPaths (jruby-puppet-core/managed-load-path jruby-puppet-testutils/ruby-load-path))
-       (.runScriptlet "require 'jar-dependencies'")
-       (.runScriptlet "require 'puppet/server/http_client'"))
-
+         scripting-container (-> (jruby-impl-core/create-pool jruby-config)
+                                 (jruby-core/borrow-from-pool :http-client-test [])
+                                 :scripting-container)]
+     (.runScriptlet scripting-container "require 'puppet/server/http_client'")
      (let [http-client-class (.runScriptlet scripting-container "Puppet::Server::HttpClient")]
        (.callMethod scripting-container http-client-class "initialize_settings" http-client-settings Object))
      (.runScriptlet scripting-container (str "require 'puppet/server/http_client';"
-                                             (format "c = Puppet::Server::HttpClient.new('localhost', %d, {:use_ssl => %s});"
+                                             (format "$c = Puppet::Server::HttpClient.new('localhost', %d, {:use_ssl => %s});"
                                                      port use-ssl?)))
      (doto scripting-container
        (.runScriptlet (format "Puppet[:hostcert] = '%s'" cert-pem))
@@ -127,10 +121,10 @@
   (jetty9/with-test-webserver ring-app port
     (let [scripting-container (create-scripting-container port)]
       (testing "HTTP GET"
-        (is (= "hi" (.runScriptlet scripting-container "c.get('/', {}).body"))))
+        (is (= "hi" (.runScriptlet scripting-container "$c.get('/', {}).body"))))

       (testing "HTTP POST"
-        (is (= "hi" (.runScriptlet scripting-container "c.post('/', 'foo', {}).body"))))
+        (is (= "hi" (.runScriptlet scripting-container "$c.post('/', 'foo', {}).body"))))

       (terminate-scripting-container scripting-container))))

@@ -138,21 +132,21 @@
   (jetty9/with-test-webserver ring-app-with-auth port
     (let [scripting-container (create-scripting-container port)]
       (testing "no credentials"
-        (.runScriptlet scripting-container "response = c.post('/', 'foo', {})")
-        (is (= "401" (.runScriptlet scripting-container "response.code")))
-        (is (= "access denied" (.runScriptlet scripting-container "response.body"))))
+        (.runScriptlet scripting-container "$response = $c.post('/', 'foo', {})")
+        (is (= "401" (.runScriptlet scripting-container "$response.code")))
+        (is (= "access denied" (.runScriptlet scripting-container "$response.body"))))

       (testing "valid credentials"
         (let [auth "{ :basic_auth => { :user => 'foo', :password => 'bar' }}"]
-          (.runScriptlet scripting-container (format "response = c.post('/', 'foo', {}, %s)" auth)))
-        (is (= "200" (.runScriptlet scripting-container "response.code")))
-        (is (= "hi" (.runScriptlet scripting-container "response.body"))))
+          (.runScriptlet scripting-container (format "$response = $c.post('/', 'foo', {}, %s)" auth)))
+        (is (= "200" (.runScriptlet scripting-container "$response.code")))
+        (is (= "hi" (.runScriptlet scripting-container "$response.body"))))

       (testing "invalid credentials"
         (let [auth "{ :basic_auth => { :user => 'foo', :password => 'baz' }}"]
-          (.runScriptlet scripting-container (format "response = c.post('/', 'foo', {}, %s)" auth)))
-        (is (= "401" (.runScriptlet scripting-container "response.code")))
-        (is (= "access denied" (.runScriptlet scripting-container "response.body"))))
+          (.runScriptlet scripting-container (format "$response = $c.post('/', 'foo', {}, %s)" auth)))
+        (is (= "401" (.runScriptlet scripting-container "$response.code")))
+        (is (= "access denied" (.runScriptlet scripting-container "$response.body"))))

       (terminate-scripting-container scripting-container))))

@@ -190,7 +184,7 @@
       (let [sc (create-scripting-container 10080)]
         (logutils/with-test-logging
           (try
-            (.runScriptlet sc (raise-caught-http-error "c.get('/', {})"))
+            (.runScriptlet sc (raise-caught-http-error "$c.get('/', {})"))
             (is false "Expected HTTP connection to HTTPS port to fail")
            (catch EvalFailedException e
              (is (instance? ConnectionClosedException (.getCause e))))))
@@ -199,25 +193,25 @@
   (testing "Can connect via TLSv1 by default"
     (with-webserver-with-protocols ["TLSv1"] nil
        (let [sc (create-scripting-container 10080 {:use-ssl true})]
-         (.runScriptlet sc "response = c.get('/', {})")
-         (is (= "200" (.runScriptlet sc "response.code")))
-         (is (= "hi" (.runScriptlet sc "response.body")))
+         (.runScriptlet sc "$response = $c.get('/', {})")
+         (is (= "200" (.runScriptlet sc "$response.code")))
+         (is (= "hi" (.runScriptlet sc "$response.body")))
          (terminate-scripting-container sc))))

   (testing "Can connect via TLSv1.1 by default"
     (with-webserver-with-protocols ["TLSv1.1"] nil
        (let [sc (create-scripting-container 10080 {:use-ssl true})]
-         (.runScriptlet sc "response = c.get('/', {})")
-         (is (= "200" (.runScriptlet sc "response.code")))
-         (is (= "hi" (.runScriptlet sc "response.body")))
+         (.runScriptlet sc "$response = $c.get('/', {})")
+         (is (= "200" (.runScriptlet sc "$response.code")))
+         (is (= "hi" (.runScriptlet sc "$response.body")))
          (terminate-scripting-container sc))))

   (testing "Can connect via TLSv1.2 by default"
     (with-webserver-with-protocols ["TLSv1.2"] nil
        (let [sc (create-scripting-container 10080 {:use-ssl true})]
-         (.runScriptlet sc "response = c.get('/', {})")
-         (is (= "200" (.runScriptlet sc "response.code")))
-         (is (= "hi" (.runScriptlet sc "response.body")))
+         (.runScriptlet sc "$response = $c.get('/', {})")
+         (is (= "200" (.runScriptlet sc "$response.code")))
+         (is (= "hi" (.runScriptlet sc "$response.body")))
          (terminate-scripting-container sc)))))

 (deftest https-sslv3
@@ -226,7 +220,7 @@
       (testing "Cannot connect via SSLv3 by default"
         (let [sc (create-scripting-container 10080 {:use-ssl true})]
           (try
-            (.runScriptlet sc (raise-caught-http-error "c.get('/', {})"))
+            (.runScriptlet sc (raise-caught-http-error "$c.get('/', {})"))
             (is false "Expected HTTP connection to HTTPS port to fail")
             (catch EvalFailedException e
               (is (ssl-connection-exception? (.. e getCause getCause)))))
@@ -237,9 +231,9 @@
                   10080
                   {:ssl-protocols ["SSLv3" "TLSv1"]
                    :use-ssl true})]
-          (.runScriptlet sc "response = c.get('/', {})")
-          (is (= "200" (.runScriptlet sc "response.code")))
-          (is (= "hi" (.runScriptlet sc "response.body")))
+          (.runScriptlet sc "$response = $c.get('/', {})")
+          (is (= "200" (.runScriptlet sc "$response.code")))
+          (is (= "hi" (.runScriptlet sc "$response.body")))
           (terminate-scripting-container sc))))))

 (deftest https-cipher-suites
@@ -252,7 +246,7 @@
                    :cipher-suites ["SSL_RSA_WITH_RC4_128_MD5"]
                    :use-ssl true})]
           (try
-            (.runScriptlet sc (raise-caught-http-error "c.get('/', {})"))
+            (.runScriptlet sc (raise-caught-http-error "$c.get('/', {})"))
             (is false "Expected HTTP connection to HTTPS port to fail")
             (catch EvalFailedException e
               (is (ssl-connection-exception? (.. e getCause)))))
@@ -264,9 +258,9 @@
                   {:ssl-protocols ["SSLv3"]
                    :cipher-suites ["SSL_RSA_WITH_RC4_128_SHA"]
                    :use-ssl true})]
-          (.runScriptlet sc "response = c.get('/', {})")
-          (is (= "200" (.runScriptlet sc "response.code")))
-          (is (= "hi" (.runScriptlet sc "response.body")))
+          (.runScriptlet sc "$response = $c.get('/', {})")
+          (is (= "200" (.runScriptlet sc "$response.code")))
+          (is (= "hi" (.runScriptlet sc "$response.body")))
           (terminate-scripting-container sc))))))

 (deftest clients-persist
@@ -274,18 +268,18 @@
     (logutils/with-test-logging
       (jetty9/with-test-webserver ring-app port
         (let [sc (create-scripting-container port)
-              client1 (.runScriptlet sc "c.get('/', {}); c.class.client")
-              client2 (.runScriptlet sc "c.post('/', 'foo', {}); c.class.client")]
+              client1 (.runScriptlet sc "$c.get('/', {}); $c.class.client")
+              client2 (.runScriptlet sc "$c.post('/', 'foo', {}); $c.class.client")]
           (is (= client1 client2))
           (terminate-scripting-container sc)))))
   (testing "all instances of HttpClient have the same underlying client object"
     (logutils/with-test-logging
       (jetty9/with-test-webserver ring-app port
         (let [sc (create-scripting-container port)
-              client1 (.runScriptlet sc "c.class.client")
-              client2 (.runScriptlet sc (str (format "c2 = Puppet::Server::HttpClient.new('localhost', %d, {:use_ssl => %s});"
+              client1 (.runScriptlet sc "$c.class.client")
+              client2 (.runScriptlet sc (str (format "$c2 = Puppet::Server::HttpClient.new('localhost', %d, {:use_ssl => %s});"
                                                   port false)
-                                          "c2.class.client"))]
+                                          "$c2.class.client"))]
           (is (= client1 client2))
           (terminate-scripting-container sc))))))

@@ -294,23 +288,23 @@
     (logutils/with-test-logging
       (jetty9/with-test-webserver ring-app-connection-closed port
         (let [sc (create-scripting-container port)]
-          (is (= "The Connection header has value close" (.runScriptlet sc "c.get('/', {}).body")))
+          (is (= "The Connection header has value close" (.runScriptlet sc "$c.get('/', {}).body")))
           (terminate-scripting-container sc)))))
   (testing "connection header always set to close on post"
     (logutils/with-test-logging
       (jetty9/with-test-webserver ring-app-connection-closed port
         (let [sc (create-scripting-container port)]
-          (is (= "The Connection header has value close" (.runScriptlet sc "c.post('/', 'foo', {}).body")))
+          (is (= "The Connection header has value close" (.runScriptlet sc "$c.post('/', 'foo', {}).body")))
           (terminate-scripting-container sc)))))
   (testing "client's terminate function closes the client"
     (logutils/with-test-logging
       (jetty9/with-test-webserver ring-app-connection-closed port
         (let [sc (create-scripting-container port)]
-          (.runScriptlet sc "response = c.get('/', {})")
-          (is (= "200" (.runScriptlet sc "response.code")))
-          (.runScriptlet sc "c.class.terminate")
+          (.runScriptlet sc "$response = $c.get('/', {})")
+          (is (= "200" (.runScriptlet sc "$response.code")))
+          (.runScriptlet sc "$c.class.terminate")
           (try
-            (.runScriptlet sc "response = c.get('/', {})")
+            (.runScriptlet sc "$response = $c.get('/', {})")
             (catch EvalFailedException e
               (let [wrapped-exception (.getCause e)
                     message           (.getMessage e)]
@@ -325,14 +319,14 @@
       (jetty9/with-test-webserver ring-app-alternate port
         (with-webserver-with-protocols nil nil
           (let [sc (create-scripting-container 10080 {:use-ssl true})]
-            (.runScriptlet sc "response = c.get('/', {})")
-            (is (= "200" (.runScriptlet sc "response.code")))
-            (is (= "hi" (.runScriptlet sc "response.body")))
-            (.runScriptlet sc (str (format "c = Puppet::Server::HttpClient.new('localhost', %d, {:use_ssl => %s});"
+            (.runScriptlet sc "$response = $c.get('/', {})")
+            (is (= "200" (.runScriptlet sc "$response.code")))
+            (is (= "hi" (.runScriptlet sc "$response.body")))
+            (.runScriptlet sc (str (format "$c = Puppet::Server::HttpClient.new('localhost', %d, {:use_ssl => %s});"
                                            port false)
-                                   "response = c.get('/', {})"))
-            (is (= "200" (.runScriptlet sc "response.code")))
-            (is (= "bye" (.runScriptlet sc "response.body")))
+                                   "$response = $c.get('/', {})"))
+            (is (= "200" (.runScriptlet sc "$response.code")))
+            (is (= "bye" (.runScriptlet sc "$response.body")))
             (terminate-scripting-container sc))))))

   (testing "can make https calls after http calls without a new scripting container"
@@ -340,13 +334,13 @@
       (jetty9/with-test-webserver ring-app-alternate port
         (with-webserver-with-protocols nil nil
           (let [sc (create-scripting-container port)]
-            (.runScriptlet sc "response = c.get('/', {})")
-            (is (= "200" (.runScriptlet sc "response.code")))
-            (is (= "bye" (.runScriptlet sc "response.body")))
-            (.runScriptlet sc (str (format "c = Puppet::Server::HttpClient.new('localhost', %d, {:use_ssl => %s});"
+            (.runScriptlet sc "$response = $c.get('/', {})")
+            (is (= "200" (.runScriptlet sc "$response.code")))
+            (is (= "bye" (.runScriptlet sc "$response.body")))
+            (.runScriptlet sc (str (format "$c = Puppet::Server::HttpClient.new('localhost', %d, {:use_ssl => %s});"
                                            10080 true)
-                                   "response = c.get('/', {})"))
-            (is (= "200" (.runScriptlet sc "response.code")))
-            (is (= "hi" (.runScriptlet sc "response.body")))
+                                   "$response = $c.get('/', {})"))
+            (is (= "200" (.runScriptlet sc "$response.code")))
+            (is (= "hi" (.runScriptlet sc "$response.body")))
             (terminate-scripting-container sc)))))))


Null pointer fix to case when tracker is not found in database. Improved logging.

--- src/ruuvi_server/api.clj
+++ src/ruuvi_server/api.clj
@@ -104,18 +104,36 @@
         (app request)))))

 (defn wrap-create-event-auth
-  "Sets key :create-event-auth"
+"Marks authentication status to request:
+Sets keys
+- :authenticated-tracker, if properly authenticated.
+- :not-authenticated, if client chooses not to use autentication.
+- :unknown-tracker, if client tracker is not known in database.
+- :authentication-failed, autentication was attempted, but macs do not match.
+"
   [app]
   (fn [request]
-    (let [params (request :form-params)]
-      (if (not (params "mac"))
-        (app request)
-        (let [computed-mac (compute-mac params (request :tracker))
-              request-mac (params "mac")]
-          (if (= computed-mac request-mac)
-            (app (merge request {:authenticated-tracker true}))
-            (app request)
-            ))))))
+    (let [params (request :form-params)
+          tracker (request :tracker)]
+      (cond
+       (not (params "mac")) (do
+                              (.debug logger "Client does not use authentication")
+                              (app (merge request {:not-authenticated true} )))
+       (not tracker) (do
+                       (.debug logger "Tracker does not exist in system")
+                       (app (merge request {:unknown-tracker true})))
+
+       :else
+       (let [computed-mac (compute-mac params (request :tracker))
+             request-mac (params "mac")]
+         (if (= computed-mac request-mac)
+           (do
+             (.debug logger "Tracker is authenticated successfully")
+             (app (merge request {:authenticated-tracker true})))
+           (do
+             (.debug logger "Tracker failed authentication")
+             (app (merge request {:authentication-failed true})))
+           ))))))

 (defn wrap-request-logger
   "Logs each incoming request"


A project now has its own page (just an H1 for now)

--- src/kixi/hecuba/web/project.clj
+++ src/kixi/hecuba/web/project.clj
@@ -18,7 +18,11 @@
   :handle-ok (fn [{projects ::projects {mt :media-type} :representation :as ctx}]
                (case mt
                  "text/html"
-                 (html [:table (for [p projects] [:tr [:td [:a {:href (:href p)} (:name p)]]])])
+                 (html [:table
+                        (for [p projects]
+                          [:tr
+                           [:td [:a {:href (:href p)} (:name p)]]
+                           [:td (:project-code p)]])])
                  projects))
   :post! (fn [{{body :body} :request}]
            (let [payload (io! (edn/read (java.io.PushbackReader. (io/reader body))))]
@@ -29,7 +33,10 @@
   :available-media-types base-media-types
   :exists? (fn [{{{id :id} :route-params body :body routes :jig.bidi/routes} :request :as ctx}]
              (if-let [p (item querier id)] {::project p} false))
-  :handle-ok (fn [ctx] (::project ctx)))
+  :handle-ok (fn [{project ::project {mt :media-type} :representation :as ctx}]
+               (case mt
+                 "text/html" (html [:h1 (:name project)])
+                 project)))

 (defn create-routes [querier commander]
   (let [project (project-resource querier)


defmacro is a macro

defmacro is a macro

--- src/main/clojure/cljs/core.cljc
+++ src/main/clojure/cljs/core.cljc
@@ -2827,3 +2827,5 @@
     (core/list 'do
       (cons `defn decl)
       (core/list 'set! `(. ~name ~'-cljs$lang$macro) true))))
+
+#?(:cljs (set! (. defmacro -cljs$lang$macro) true))


minor

minor

--- cljs-client/tourneybot_client/core.cljs
+++ cljs-client/tourneybot_client/core.cljs
@@ -76,13 +76,12 @@

 ;; load any existing client state on startup
 (try
-  (when-let [state-string (js/window.localStorage.getItem ls-key)]
-    (let [js-state (try (js/JSON.parse state-string)
-                     (catch js/Error _error nil))]
-      (when (object? js-state)
-        (let [clj-state (js->clj js-state :keywordize-keys true)]
-          (swap! page-state merge clj-state)))))
-  (catch js/Error e nil))
+  (let [state-string (js/window.localStorage.getItem ls-key)
+        js-state (js/JSON.parse state-string)]
+    (when (object? js-state)
+      (let [clj-state (js->clj js-state :keywordize-keys true)]
+        (swap! page-state merge clj-state))))
+  (catch js/Error err nil))

 (def ui-only-page-state-keys (keys initial-page-state))

@@ -92,7 +91,7 @@
         js-state-string (js/JSON.stringify js-state)]
     (try
       (js/window.localStorage.setItem ls-key js-state-string)
-      (catch js/Error e nil))))
+      (catch js/Error err nil))))

 (add-watch page-state :client-state save-client-state)


CMR-2318: Addressed review comments.

CMR-2318: Addressed review comments.

--- umm-spec-lib/src/cmr/umm_spec/umm_to_xml_mappings/dif10.clj
+++ umm-spec-lib/src/cmr/umm_spec/umm_to_xml_mappings/dif10.clj
@@ -225,29 +225,30 @@
   determined."
   [c]
   (when-let [data-language (:DataLanguage c)]
-    [:Dataset_Language (if (contains? dif10-dataset-languages data-language)
+    [:Dataset_Language (if (dif10-dataset-languages data-language)
                          data-language
                          (get iso-639-2->dif10-dataset-language data-language "English"))]))

 (def collection-progress->dif10-dataset-progress
   "Mapping from known collection progress values to values supported for DIF10 Dataset_Progress."
-  {"ONGOING" "IN WORK"
+  {"PLANNED" "PLANNED"
+   "ONGOING" "IN WORK"
    "ONLINE" "IN WORK"
    "COMPLETED" "COMPLETE"
    "FINAL" "COMPLETE"})

 (def dif10-dataset-progress-values
   "Set of Dataset_Progress values supported in DIF10"
-  #{"PLANNED" "IN WORK" "COMPLETE"})
+  (set (distinct (vals collection-progress->dif10-dataset-progress))))

 (defn- generate-dataset-progress
   "Return Dataset_Progress attribute by translating from the UMM CollectionProgress to one of the
   DIF10 enumerations. Defaults to generating a Dataset_Progress of IN WORK if translation cannot be
   determined."
   [c]
-  (when-let [c-progress (when (:CollectionProgress c)
-                          (str/upper-case (:CollectionProgress c)))]
-    [:Dataset_Progress (if (contains? dif10-dataset-progress-values (str/upper-case c-progress))
+  (when-let [c-progress (when-let [coll-progress (:CollectionProgress c)]
+                          (str/upper-case coll-progress))]
+    [:Dataset_Progress (if (dif10-dataset-progress-values c-progress)
                          c-progress
                          (get collection-progress->dif10-dataset-progress c-progress "IN WORK"))]))


Fix task states ordering in info model.

Fix task states ordering in info model.

--- src/onyx/information_model.cljc
+++ src/onyx/information_model.cljc
@@ -2030,7 +2030,7 @@
    :state-refinement [:refinement/create-state-update :refinement/apply-state-update]
    :state-event [:event-type :task-event :segment :grouped?  :group-key :lower-bound
                  :upper-bound :log-type :trigger-update :aggregation-update :window :next-state]
-   :task-states [:recover :processing :start-iteration :barriers :process-batch :heartbeat]
+   :task-states [:recover :start-iteration :barriers :process-batch :heartbeat]
    :event-map [:onyx.core/task-map
                :onyx.core/catalog
                :onyx.core/workflow


Grammar fix

Grammar fix

--- src/onyx/information_model.cljc
+++ src/onyx/information_model.cljc
@@ -384,7 +384,7 @@
                                                :optional? true
                                                :added "0.8.0"}}}
    :trigger-entry
-   {:summary "Triggers are a feature that interact with Windows. Windows capture and bucket data over time. Triggers let you release the captured data over a variety stimuli."
+   {:summary "Triggers are a feature that interact with Windows. Windows capture and bucket data over time. Triggers let you release the captured data over a variety of stimuli."
     :link nil
     :model {:trigger/window-id
             {:doc "The name of a `:window/id` window to fire the trigger against."


Debuging mapbox foreign lib namespace

Debuging mapbox foreign lib namespace

--- src/pasmo_gigi/geo/ui/core.cljs
+++ src/pasmo_gigi/geo/ui/core.cljs
@@ -11,7 +11,7 @@
             [mapbox.L :as L])
   (:require-macros [cljs.core.async.macros :refer [go]]))

-(.log js/console "access token: " (-> js/L .-mapbox .-accessToken))
+(.log js/console "access token: " L)

 (set! (-> js/L .-mapbox .-accessToken) "pk.eyJ1IjoidXJpczc3IiwiYSI6InRuYTZRa3MifQ._Bo-JRcA7QVGocCJvdSoJg")


Switch to js/L

Switch to js/L

--- src/pasmo_gigi/geo/ui/core.cljs
+++ src/pasmo_gigi/geo/ui/core.cljs
@@ -11,7 +11,7 @@
             [mapbox.L :as L])
   (:require-macros [cljs.core.async.macros :refer [go]]))

-(.log js/console "access token: " L)
+(.log js/console "access token: " js/L)

 (set! (-> js/L .-mapbox .-accessToken) "pk.eyJ1IjoidXJpczc3IiwiYSI6InRuYTZRa3MifQ._Bo-JRcA7QVGocCJvdSoJg")


(maint) Add testutils for generating CRLs with bad signatures

This commit adds test utilities for generating and writing a CRL that was not
signed by its issuer. This will be used for testing that these kinds of CRLs are
considered invalid and rejected appropriately.

--- test/puppetlabs/ssl_utils/testutils.clj
+++ test/puppetlabs/ssl_utils/testutils.clj
@@ -105,6 +105,13 @@
   [issuer issuer-private-key issuer-public-key]
   (SSLUtils/generateCRL issuer issuer-private-key issuer-public-key
                         (generate-future-date) (generate-future-date)))
+
+(defn generate-crl-with-bad-signature
+  [issuer _ _]
+  (let [random-keys (generate-key-pair 2048)
+        public-key (get-public-key random-keys)
+        private-key (get-private-key random-keys)]
+    (SSLUtils/generateCRL issuer private-key public-key)))

 (defn generate-ca-cert
   [issuer-name issuer-key-pair serial root?]
@@ -197,4 +204,15 @@
         [cert crl] (generate-cert-chain-with-crls 1 generate-not-yet-valid-crl)]
     (fs/mkdirs dir-path)
     (objs->pem! cert cert-path)
-    (objs->pem! crl crl-path)))+    (objs->pem! crl crl-path)))
+
+(defn write-crl-with-bad-sig
+  [test-subpath]
+  (let [dir-path (fs/file test-files-path test-subpath)
+        cert-path (fs/file dir-path "cert-with-crl-bad-sig.pem")
+        crl-path (fs/file dir-path "crl-with-bad-signature.pem")
+        [cert bad-crl] (generate-cert-chain-with-crls
+                        1 generate-crl-with-bad-signature)]
+    (fs/mkdirs dir-path)
+    (objs->pem! cert cert-path)
+    (objs->pem! bad-crl crl-path)))


CMR-1711 Defines vars for mime types

CMR-1711 Defines vars for mime types

--- common-lib/src/cmr/common/mime_types.clj
+++ common-lib/src/cmr/common/mime_types.clj
@@ -1,5 +1,6 @@
 (ns cmr.common.mime-types
   "Provides functions for handling mime types."
+  (:refer-clojure :exclude [atom])
   (:require [clojure.string :as str]
             [cmr.common.util :as util]
             [cmr.common.services.errors :as svc-errors]
@@ -7,35 +8,43 @@

 (def base-mime-type-to-format
   "A map of base mime types to the format symbols supported"
-  {"application/json" :json
-   "application/xml" :xml
-   "application/echo10+xml" :echo10
-   "application/iso:smap+xml" :iso-smap
-   "application/iso19115+xml" :iso19115
-   "application/dif+xml" :dif
-   "application/dif10+xml" :dif10
-   "text/csv" :csv
-   "application/atom+xml" :atom
-   "application/vnd.google-earth.kml+xml" :kml
-   "application/opendata+json" :opendata
-   "application/metadata+xml" :native})
+  {})

 (def format->mime-type
   "A map of format symbols to their mime type."
-  {:json "application/json"
-   :xml "application/xml"
-   :echo10 "application/echo10+xml"
-   :iso_smap "application/iso:smap+xml"
-   :iso-smap "application/iso:smap+xml"
-   :iso "application/iso19115+xml"
-   :iso19115 "application/iso19115+xml"
-   :dif "application/dif+xml"
-   :dif10 "application/dif10+xml"
-   :csv "text/csv"
-   :atom "application/atom+xml"
-   :kml "application/vnd.google-earth.kml+xml"
-   :opendata "application/opendata+json"
-   :native "application/metadata+xml"})
+  {})
+
+(defmacro defmimetype
+  "An elegant DSL for crafting beautiful mime-type definitions."
+  [name string format-kw & format-aliases]
+  (alter-var-root #'base-mime-type-to-format assoc string format-kw)
+  (doseq [kw (conj format-aliases format-kw)]
+    (alter-var-root #'format->mime-type assoc kw string))
+  `(def ~name ~string))
+
+(defmimetype json "application/json" :json)
+
+(defmimetype xml "application/xml" :xml)
+
+(defmimetype echo10 "application/echo10+xml" :echo10)
+
+(defmimetype iso-smap "application/iso:smap+xml" :iso-smap :iso_smap)
+
+(defmimetype iso "application/iso19115+xml" :iso19115 :iso)
+
+(defmimetype dif "application/dif+xml" :dif)
+
+(defmimetype dif10 "application/dif10+xml" :dif10)
+
+(defmimetype csv "text/csv" :csv)
+
+(defmimetype atom  "application/atom+xml" :atom)
+
+(defmimetype kml "application/vnd.google-earth.kml+xml" :kml)
+
+(defmimetype opendata "application/opendata+json" :opendata)
+
+(defmimetype native "application/metadata+xml" :native)

 (def all-supported-mime-types
   "A superset of all mime types supported by any CMR applications."


Mark `with-parser` and `with-mparser` as alpha

--- src/taoensso/carmine.clj
+++ src/taoensso/carmine.clj
@@ -64,7 +64,8 @@
 ;;;; Misc

 (defmacro with-parser
-  "Wraps body so that replies to any wrapped Redis commands will be parsed with
+  "Alpha - subject to change.
+  Wraps body so that replies to any wrapped Redis commands will be parsed with
   (parser-fn reply). Composable. When `parser-fn` is nil, clears any current
   parsers."
   [parser-fn & body]
@@ -75,7 +76,8 @@
        (binding [protocol/*parser* ~parser-fn] ~@body))))

 (defmacro with-mparser
-  "Wraps body so that multi-bulk (vector) replies to any wrapped Redis commands
+  "Alpha - subject to change.
+  Wraps body so that multi-bulk (vector) replies to any wrapped Redis commands
   will be parsed with (parser-fn reply)."
   [parser-fn & body]
   `(with-parser


[#76] Housekeeping

[#76] Housekeeping

--- src/taoensso/faraday.clj
+++ src/taoensso/faraday.clj
@@ -565,7 +565,7 @@

 (comment (time (create-table mc "delete-me7" [:id :s] {:block? true})))

-(defn ensure-table "Creates a table if it doesn't already exist."
+(defn ensure-table "Creates a table iff it doesn't already exist."
   [client-opts table-name hash-keydef & [opts]]
   (when-not (describe-table client-opts table-name)
     (create-table client-opts table-name hash-keydef opts)))


Some further poller cleanup (error logging)

--- src/polismath/poller.clj
+++ src/polismath/poller.clj
@@ -24,8 +24,8 @@
       (ko/select "votes"
         (ko/where {:created [> last-timestamp]})
         (ko/order [:zid :tid :pid :created] :asc))) ; ordering by tid is important, since we rely on this ordering to determine the index within the comps, which needs to correspond to the tid
-    (catch Exception e (do
-        (println (str "polling failed " (.getMessage e)))
-        []))))
+    (catch Exception e
+      (log/error "polling failed " (.getMessage e))
+      [])))


update mongo buckets

update mongo buckets

--- src/polismath/poller.clj
+++ src/polismath/poller.clj
@@ -148,7 +148,7 @@
               (meter
                 "db.math.bidToPid.put"
                 (mongo-upsert-results
-                 "polismath_bidToPid_april9"
+                 "polismath_bidToPid_july30"
                  zid
                  lastVoteTimestamp
                  (assoc obj
@@ -166,7 +166,7 @@
               (meter
                "db.math.pca.put"
                (mongo-upsert-results
-                "polismath_test_april9"
+                "polismath_july30"
                 zid
                 lastVoteTimestamp
                 (assoc obj


Update tests

Update tests

--- tests/symbols-lint.clj
+++ tests/symbols-lint.clj
@@ -3,6 +3,7 @@
             [tests.ext2 :as ext2]
             [tests.ext3 :as ext3 :refer [e3]]
             [spec :as s]
+            [some.core :as core]
             [clojure.test :refer [testing]])
   (:import [java.security Security]))

@@ -39,5 +40,5 @@
 (test-macro (f u2))
 (test-macro (load u3))
 (test-macro (ext2/f u4))
-(testing u8)
+(testing u9)


Tests are working.

Tests are working.

--- src/re_com/datetime.cljs
+++ src/re_com/datetime.cljs
@@ -148,25 +148,27 @@
   "Starting at the first character, perform the validation for each character until we have
   reached the end (which might come sooner than originally expected because if an invalid
   value is encountered the model will be truncated)."
-  [char min max n]
+  [chars min max n]
   (let [funcs [first-char second-char third-char fourth-char fifth-char]]
-    (if (< n (count char))
-       ((nth funcs n) char min max))))
-
-(defn validate-each-character [tmp-model min max n]
-  (let [char (nth @tmp-model n)
-        new-val (validated-time-change char min max n)]
-    (if-not (= new-val char)
-      (reset! tmp-model new-val))))
+    (if (< n (count chars))
+       ((nth funcs n) chars min max))))
+
+(defn validate-each-character [tmp-model min max]
+  (loop [i 0]
+    (let [chars (subs @tmp-model 0 (+ i 1))
+          new-val (validated-time-change chars min max i)]
+      (if (= new-val chars)
+        (if (and (< i 4))
+          (recur (inc i)))
+        (reset! tmp-model new-val)))))

 (defn time-changed [ev tmp-model min max]
   (let [target (.-target ev)
         input-val (.-value target)]
      (reset! tmp-model input-val)
-     (map (validate-each-character tmp-model min max %) (range 5))
+     (validate-each-character tmp-model min max)))
     ;;(set! (.-value target) new-val)
     ;;(when (= 5 (count new-val)) ;; tiem is complete - lose focus?
-    ))

 (defn time-updated
   "Check what has been entered is complete. If not, and if possible, complete it. Then update the model."


Add graphite client protocol, add UDP support

--- src/riemann/graphite.clj
+++ src/riemann/graphite.clj
@@ -2,7 +2,10 @@
   "Forwards events to Graphite."
   (:refer-clojure :exclude [replace])
   (:import
-   (java.net Socket)
+   (java.net Socket
+             DatagramSocket
+             DatagramPacket
+             InetAddress)
    (java.io Writer
             OutputStreamWriter)
    (org.jboss.netty.channel Channels)
@@ -16,6 +19,44 @@
         riemann.pool
         riemann.common))

+(defprotocol GraphiteClient
+  (open [client]
+        "Creates a Graphite client")
+  (send! [client line]
+        "Sends a formatted line to Graphite")
+  (close [client]
+         "Cleans up"))
+
+(defrecord GraphiteTCPClient [host port]
+  GraphiteClient
+  (open [this]
+    (let [sock (Socket. host port)]
+      (assoc this
+             :socket sock
+             :out (OutputStreamWriter. (.getOutputStream sock)))))
+  (send! [this line]
+    (let [out (:out this)]
+      (.write ^OutputStreamWriter out line)
+      (.flush ^OutputStreamWriter out)))
+  (close [this]
+    (.close (:out this))
+    (.close (:socket this))))
+
+(defrecord GraphiteUDPClient [host port]
+  GraphiteClient
+  (open [this]
+    (assoc this
+           :socket (DatagramSocket.)
+           :host host
+           :port port))
+  (send! [this line]
+    (let [bytes (.getBytes line)
+          length (count line)
+          addr (InetAddress/getByName (:host this))
+          datagram (DatagramPacket. bytes length addr (:port this))]
+      (.send (:socket this) datagram)))
+  (close [this]
+    (.close (:socket this))))

 (defn graphite-path-basic
   "Constructs a path for an event. Takes the hostname fqdn, reversed,
@@ -65,19 +106,23 @@
   [opts]
   (let [opts (merge {:host "127.0.0.1"
                      :port 2003
+                     :protocol :tcp
                      :path graphite-path-percentiles} opts)
         pool (fixed-pool
-               (fn open []
+               (fn []
                  (info "Connecting to " (select-keys opts [:host :port]))
-                 (let [sock (Socket. (:host opts) (:port opts))
-                       out  (OutputStreamWriter. (.getOutputStream sock))]
+                 (let [host (:host opts)
+                       port (:port opts)
+                       client (open (condp = (:protocol opts)
+                                      :tcp (GraphiteTCPClient. host port)
+                                      :udp (GraphiteUDPClient. host port)))]
                    (info "Connected")
-                   [sock out]))
-               (fn close [[sock out]]
+                   client))
+               (fn [client]
                  (info "Closing connection to "
                        (select-keys opts [:host :port]))
-                 (.close out)
-                 (.close sock))
+                 (prn client)
+                 (close client))
                {:size                 (:pool-size opts)
                 :block-start          (:block-start opts)
                 :regenerate-interval  (:reconnect-interval opts)})
@@ -85,12 +130,10 @@

     (fn [event]
       (when (:metric event)
-        (with-pool [[sock out] pool (:claim-timeout opts)]
+        (with-pool [client pool (:claim-timeout opts)]
                    (let [string (str (join " " [(path event)
                                                 (float (:metric event))
                                                 (int (:time event))])
                                      "\n")]
-                     (.write ^OutputStreamWriter out string)
-                     (.flush ^OutputStreamWriter out)))))))
-
-
+                     (prn "sending " client string)
+                     (send! client string)))))))


Display the list of Incorrect/Preferred Forms in the web UI

--- src/zg/html_renderer.clj
+++ src/zg/html_renderer.clj
@@ -363,6 +363,10 @@
 (defn handle-null
     [key-name search-results]
     (or (get search-results key-name) "N/A"))
+
+(defn get-correct-or-preffered-forms
+    [search-result]
+    (str (:incorrect_forms search-result) (:correct_forms search-result)))

 (defn render-front-page
     "Render front page of this application."
@@ -403,6 +407,8 @@
                              [:th "Internal"]
                              [:th "Copyright"]
                              [:th "Verified"]
+                             (if (= mode :glossary)
+                                 [:th "Incorrect/preffered forms"])
                              [:th "Source"]
                              [:th "Status"]
                              [:th "Operation"]]
@@ -423,6 +429,8 @@
                                      [:td (yes-no :internal search-result)]
                                      [:td (yes-no :copyrighted search-result)]
                                      [:td (yes-no :verified search-result)]
+                                     (if (= mode :glossary)
+                                         [:td (get-correct-or-preffered-forms search-result)])
                                      [:td (get-source sources-map :source search-result)]
                                      [:td {:style (if deleted "color:red" "color:green")} (if deleted "deleted" "active")]
                                      [:td (if deleted [:a {:href (str "?undelete=" word) :class "btn btn-default"} "undelete"]


don't let replay break the sharing menu

don't let replay break the sharing menu

--- src-cljs/frontend/components/overlay.cljs
+++ src-cljs/frontend/components/overlay.cljs
@@ -31,18 +31,17 @@
     om/IRender
     (render [_]
       (html
-       [:div.make
-        [:form.menu-invite-form.make
-         [:input {:type "text"
-                  :required "true"
-                  :data-adaptive ""
-                  :onMouseDown (fn [e]
-                                 (.focus (.-target e))
-                                 (goog.dom.selection/setStart (.-target e) 0)
-                                 (goog.dom.selection/setEnd (.-target e) 10000)
-                                 (utils/stop-event e))
-                  :value (urls/absolute-doc-url (:document/id app))}]
-         [:label {:data-placeholder "Copy the url to share"}]]]))))
+       [:form.menu-invite-form.make
+        [:input {:type "text"
+                 :required "true"
+                 :data-adaptive ""
+                 :onMouseDown (fn [e]
+                                (.focus (.-target e))
+                                (goog.dom.selection/setStart (.-target e) 0)
+                                (goog.dom.selection/setEnd (.-target e) 10000)
+                                (utils/stop-event e))
+                 :value (urls/absolute-doc-url (:document/id app))}]
+        [:label {:data-placeholder "Copy the url to share"}]]))))

 (defn auth-link [app owner {:keys [source] :as opts}]
   (reify
@@ -399,6 +398,25 @@
            ;; TODO: keep track of invites
            ])))))

+(defn unknown-sharing [app owner]
+  (reify
+    om/IDisplayName (display-name [_] "Unknown Sharing")
+    om/IRender
+    (render [_]
+      (let [cast! (om/get-shared owner :cast!)
+            invite-to (or (get-in app state/invite-to-path) "")])
+      (html
+       [:div.content
+        [:h2.make "Share this document"]
+        (if-not (:cust app)
+          (list
+           [:p.make
+            "Sign in with your Google account to send an invite or give someone your url."]
+           [:div.calls-to-action.make
+            (om/build common/google-login {:source "Public Sharing Menu"})])
+
+          (om/build share-url-input app))]))))
+
 (defn sharing [app owner]
   (reify
     om/IDisplayName (display-name [_] "Overlay Sharing")
@@ -435,7 +453,7 @@
             :document.privacy/private (om/build private-sharing app)
             ;;read-only sharing needs to know the user's permission for the doc
             :document.privacy/read-only (om/build read-only-sharing app)
-            nil)
+            (om/build unknown-sharing app))

           (case cant-edit-reason
             :no-private-docs-flag


format

format

--- test/corpusmaker/test_wikipedia.clj
+++ test/corpusmaker/test_wikipedia.clj
@@ -24,6 +24,8 @@
     (is (= "{{pp-move-indef}}{{Anarchism s" (.substring (first articles) 0 30 )))
     (let [anarchism (parse-markup (first articles))]
       (is (= #{"Anarchism" "Political culture"
-               "Social theories" "Political ideologies"} (:categories anarchism)))
+               "Social theories"
+               "Political ideologies"} (:categories anarchism)))
       (is (= 465 (count (:links anarchism))))
       (is (= "political philosophy" (:label (first (:links anarchism))))))))
+


Remove old time ns.

Remove old time ns.

--- src/uxbox/util/time.cljs
+++ src/uxbox/util/time.cljs
@@ -1,39 +0,0 @@
-(ns uxbox.util.time
-  (:require [cljsjs.moment]))
-
-(defn parse
-  ([v]
-   (js/moment v))
-  ([v format]
-   (case format
-     :unix (js/moment.unix v)
-     (js/moment v format))))
-
-(defn iso
-  [v]
-  (.toISOString v))
-
-(defn unix
-  [v]
-  (.unix v))
-
-(defn now
-  ([]
-   (js/moment))
-  ([format]
-   (case format
-     :unix (unix (now))
-     :iso (iso (now)))))
-
-(defn ago
-  [time]
-  (.fromNow (parse time)))
-
-(defn day
-  [time]
-  (.calendar (parse time)
-             nil
-             #js {:sameDay "[Today]"
-                  :sameElse "[Today]"
-                  :lastDay "[Yesterday]"
-                  :lastWeek "[Last] dddd"}))


Added testing note.

Added testing note.

--- test/od117_walker/core_test.clj
+++ test/od117_walker/core_test.clj
@@ -51,6 +51,10 @@
 (def test-author-colours {"/alice" "brown1", "/bob" "aquamarine"})
 (def test-turns [#{\a \b \c} #{\d \e \f}])

+;; Note about these graph tests - the line order doesn't matter and could
+;; change. If they break for that reason it may be worth rewriting to
+;; be independent of order.
+
 (t/deftest test-graphify-ranked
   (t/is (= (graphify-ranked test-graph
                             test-author-colours


Three tests for substring function (helper)

--- test/emender_jenkins/utils_test.clj
+++ test/emender_jenkins/utils_test.clj
@@ -148,3 +148,30 @@
         (are [x y] (= x y)
             nil (third nil))))

+(deftest test-substring-1
+    "Check the function clouseau.utils/substring."
+    (testing "the function clouseau.utils/substring."
+        (are [x y] (= x y)
+            "H"      (substring "Hello world!" 0 1)
+            "He"     (substring "Hello world!" 0 2)
+            "Hello"  (substring "Hello world!" 0 5)
+            "Hello " (substring "Hello world!" 0 6))))
+
+(deftest test-substring-2
+    "Check the function clouseau.utils/substring."
+    (testing "the function clouseau.utils/substring."
+        (are [x y] (= x y)
+            "w"      (substring "Hello world!" 6 7)
+            "wo"     (substring "Hello world!" 6 8)
+            "world"  (substring "Hello world!" 6 11)
+            "world!" (substring "Hello world!" 6 12))))
+
+(deftest test-substring-empty-result
+    "Check the function clouseau.utils/substring."
+    (testing "the function clouseau.utils/substring."
+        (are [x y] (= x y)
+            "" (substring "Hello world!" 0 0)
+            "" (substring "Hello world!" 1 1)
+            "" (substring "Hello world!" 2 2)
+            "" (substring "Hello world!" 10 10))))
+


Fix test of macroexpansion

Fix test of macroexpansion

--- test/flatland/useful/utils_test.clj
+++ test/flatland/useful/utils_test.clj
@@ -130,7 +130,7 @@

 (deftest test-pair
   (testing "map-entry is a macro (for performance)"
-    (let [form '(map-entry 1 2)]
+    (let [form `(map-entry 1 2)]
       (is (not= form (macroexpand form)))))
   (testing "map-entry works, and is a MapEntry"
     (let [p (map-entry 1 2)


review changes

review changes

--- src/clj/org/openforis/ceo/db/projects.clj
+++ src/clj/org/openforis/ceo/db/projects.clj
@@ -460,8 +460,6 @@
                                                           (str "project-" project-id "-samples"))))]
     (if (#{"csv" "shp"} plot-distribution)
       (do
-        (try-catch-throw #(call-sql "cleanup_project_tables" project-id plot-size)
-                         "SQL Error: cannot clean external tables.")
         (let [plot-table       (load-external-data plot-distribution project-id plots-file "plots" #{"PLOTID"})
               sample-table     (load-external-data sample-distribution project-id samples-file "samples" #{"PLOTID" "SAMPLEID"})
               counts           (try-catch-throw #(first (call-sql "ext_table_count" project-id))
@@ -492,6 +490,8 @@
                                                       samples-per-plot
                                                       sample-resolution))
                            "Error adding plot file with generated samples."))
+        (try-catch-throw #(call-sql "cleanup_project_tables" project-id plot-size)
+                         "SQL Error: cannot clean external tables.")
         ;; The SQL function only checks against plots with external tables.
         (when (not allow-drawn-samples?)
           (let [bad-plots (map :plot_id (call-sql "plots_missing_samples" project-id))]
@@ -670,32 +670,35 @@
                         sample-resolution
                         sample-file-name
                         sample-file-base64]
-  (try (if (#{"csv" "shp"} sample-distribution)
-         (let [write-dir     (str tmp-dir "/ceo-tmp-" project-id "/")
-               samples-file  (str write-dir
-                                  (pu/write-file-part-base64 sample-file-name
-                                                             sample-file-base64
-                                                             write-dir
-                                                             (str "project-" project-id "-samples")))
-               samples-table (load-external-data sample-distribution
-                                                 project-id
-                                                 samples-file
-                                                 "samples"
-                                                 #{"PLOTID" "SAMPLEID"})]
-           (try-catch-throw #(call-sql "update_project_sample_table" project-id samples-table)
-                            "SQL Error: cannot update project table."))
-         (doseq [{:keys [plot_id lon lat]} (call-sql "get_plot_centers_by_project" project-id)]
-           (create-project-samples plot_id
-                                   sample-distribution
-                                   [lon lat]
-                                   plot-shape
-                                   plot-size
-                                   samples-per-plot
-                                   sample-resolution)))
-       (catch Exception e
-         (data-response (if-let [causes (:causes (ex-data e))]
-                          (str/join "\n" causes)
-                          "Unknown server error.")))))
+  (try
+    (if (#{"csv" "shp"} sample-distribution)
+      (let [write-dir     (str tmp-dir "/ceo-tmp-" project-id "/")
+            samples-file  (str write-dir
+                               (pu/write-file-part-base64 sample-file-name
+                                                          sample-file-base64
+                                                          write-dir
+                                                          (str "project-" project-id "-samples")))
+            samples-table (load-external-data sample-distribution
+                                              project-id
+                                              samples-file
+                                              "samples"
+                                              #{"PLOTID" "SAMPLEID"})]
+        (try-catch-throw #(call-sql "samples_from_plots_with_files" project-id)
+                         "Error importing samples file.")
+        (try-catch-throw #(call-sql "update_project_sample_table" project-id samples-table)
+                         "SQL Error: cannot update project table."))
+      (doseq [{:keys [plot_id lon lat]} (call-sql "get_plot_centers_by_project" project-id)]
+        (create-project-samples plot_id
+                                sample-distribution
+                                [lon lat]
+                                plot-shape
+                                plot-size
+                                samples-per-plot
+                                sample-resolution)))
+    (catch Exception e
+      (data-response (if-let [causes (:causes (ex-data e))]
+                       (str/join "\n" causes)
+                       "Unknown server error.")))))

 (defn- exterior-ring [coords]
   (map (fn [[a b]] [(tc/val->double a) (tc/val->double b)])


Fix data validation message.

Fix data validation message.

--- src/cljs/hatnik/web/client/z_actions.cljs
+++ src/cljs/hatnik/web/client/z_actions.cljs
@@ -5,6 +5,8 @@
             [hatnik.schema :as schm]
             [schema.core :as s])
   (:use [jayq.core :only [$]]))
+
+(def default-error-message "Data is wrong! Check out highlighted fields please.")

 (defn get-data-from-input [id]
   (.-value (.getElementById js/document id)))
@@ -46,7 +48,7 @@
 (defn ^:export send-new-project-request []
   (let [name (.-value (.getElementById js/document "project-name-input"))]
     (if (s/check schm/Project {:name name})
-      (msg/danger "Project name must be not empty!")
+      (msg/danger default-error-message)
       (do
         (.modal ($ :#iModalProject) "hide")
         (ajax  "/api/projects" "POST" {:name name} #(create-new-project-callback name %))))))
@@ -66,7 +68,7 @@
               :template (:email-template data-pack)
               :library (:artifact-value data-pack)}]
     (if (s/check schm/EmailAction data)
-      (msg/danger "Data is wrong! Check out it please.")
+      (msg/danger default-error-message)
       (do
         (.modal ($ :#iModalAddAction) "hide")
         (ajax "/api/actions" "POST" data
@@ -77,7 +79,7 @@
               :project-id (:project-id data-pack)
               :library (:artifact-value data-pack)}]
     (if (s/check schm/NoopAction data)
-      (msg/danger "Data is wrong! Check out it please.")
+      (msg/danger default-error-message)
       (do
         (.modal ($ :#iModalAddAction) "hide")
         (ajax "/api/actions" "POST" data
@@ -91,7 +93,7 @@
               :body (:gh-issue-body data-pack)
               :library (:artifact-value data-pack)}]
     (if (s/check schm/GithubIssueAction data)
-      (msg/danger "Data is wrong! Check out it please.")
+      (msg/danger default-error-message)
       (do
         (.modal ($ :#iModalAddAction) "hide")
         (ajax "/api/actions" "POST" data
@@ -106,7 +108,7 @@
               :template (:email-template data-pack)
               :library (:artifact-value data-pack)}]
     (if (s/check schm/EmailAction data)
-      (msg/danger "Data is wrong! Check out it please.")
+      (msg/danger default-error-message)
       (do
         (msg/info "We are trying to send email to you...")
        (ajax "/api/actions/test" "POST" data
@@ -120,7 +122,7 @@
               :body (:gh-issue-body data-pack)
               :library (:artifact-value data-pack)}]
     (if (s/check schm/GithubIssueAction data)
-      (msg/danger "Data is wrong! Check out it please.")
+      (msg/danger default-error-message)
       (do
         (msg/info "We are trying to create issue on Github...")
         (ajax "/api/actions/test" "POST" data
@@ -135,7 +137,7 @@
               :template (:email-template data-pack)
               :library (:artifact-value data-pack)}]
     (if (s/check schm/EmailAction data)
-      (msg/danger "Data is wrong! Check out it please.")
+      (msg/danger default-error-message)
       (do
         (.modal ($ :#iModalAddAction) "hide")
         (ajax
@@ -148,7 +150,7 @@
               :type "noop"
               :library (:artifact-value data-pack)}]
     (if (s/check schm/NoopAction data)
-      (msg/danger "Data is wrong! Check out it please.")
+      (msg/danger default-error-message)
       (do
         (.modal ($ :#iModalAddAction) "hide")
         (ajax
@@ -164,7 +166,7 @@
               :body (:gh-issue-body data-pack)
               :library (:artifact-value data-pack)}]
     (if (s/check schm/GithubIssueAction data)
-      (msg/danger "Data is wrong! Check out it please.")
+      (msg/danger default-error-message)
       (do
         (.modal ($ :#iModalAddAction) "hide")
         (ajax
@@ -189,7 +191,7 @@
 (defn ^:export update-project [project-id new-name]
   (let [data {:name new-name}]
     (if (s/check schm/Project data)
-      (msg/danger "Data is wrong! Check out it please.")
+      (msg/danger default-error-message)
       (do
         (.modal ($ :#iModalProjectMenu) "hide")
         (ajax


CMR-603: Corrected te original special case polygon as it only covers half of the world. Added additional special cases.

--- src/cmr/indexer/data/concepts/spatial.clj
+++ src/cmr/indexer/data/concepts/spatial.clj
@@ -5,7 +5,7 @@
             ;; Must be required for derived calculations
             [cmr.spatial.geodetic-ring :as gr]
             [cmr.spatial.ring-relations :as rr]
-            [cmr.spatial.polygon :as p]
+            [cmr.spatial.polygon :as poly]
             [cmr.spatial.mbr :as mbr]
             [cmr.spatial.serialize :as srl]
             [cmr.common.services.errors :as errors]
@@ -23,13 +23,31 @@
      (with-prefix :south) (:south mbr)
      (with-prefix :crosses-antimeridian) (mbr/crosses-antimeridian? mbr)}))

+(def west-hemisphere
+  "an mbr that covers the western hemispher"
+  (mbr/mbr -180 90 0 -90))
+
+(def east-hemisphere
+  "an mbr that covers the eastern hemisphere"
+  (mbr/mbr 0 90 180 -90))
+
 (def special-cases
   "Created for CMR-724. It has mappings of specific spatial areas which cause problems to an equivalent
   representation."
-  {(p/polygon :geodetic [(rr/ords->ring :geodetic
-                                        -179.9999 0.0, -179.9999 -89.9999, 0.0 -89.9999, 0.0 0.0,
-                                        0.0 89.9999, -179.9999 89.9999, -179.9999 0.0)])
-   mbr/whole-world})
+  {(poly/polygon :geodetic [(rr/ords->ring :geodetic
+                                           -179.9999 0.0, -179.9999 -89.9999, 0.0 -89.9999, 0.0 0.0,
+                                           0.0 89.9999, -179.9999 89.9999, -179.9999 0.0)])
+   west-hemisphere
+
+   (poly/polygon :geodetic [(rr/ords->ring :geodetic
+                                           -179.9999 -89.9999, 0.0 -89.9999,  0.0 89.9999,
+                                           -179.9999 89.9999, -179.9999 -89.9999)])
+   west-hemisphere
+
+   (poly/polygon :geodetic [(rr/ords->ring :geodetic
+                                           0.0001 -89.9999, 180 -89.9999, 180 89.9999, 0.0001 89.9999,
+                                           0.0001 -89.9999)])
+   east-hemisphere})

 (defn shapes->elastic-doc
   "Converts a spatial shapes into the nested elastic attributes"


Work around asynchronous behavior properly

--- test/icecap/handlers/delay_test.clj
+++ test/icecap/handlers/delay_test.clj
@@ -3,7 +3,8 @@
             [icecap.handlers.core :refer [execute get-schema]]
             [clojure.core.async :refer [go take! put! <!! <! chan close! timeout]]
             [icecap.handlers.delay :refer :all]
-            [clojure.test :refer :all]))
+            [clojure.test :refer :all])
+  (:import (java.lang Thread)))

 (defn fake-clock
   "Creates a fake clock, allowing you to add waiter functions (which
@@ -63,5 +64,7 @@
                       (advance 5)
                       (assert (still-open?) "before trigger")
                       (advance 10)
-                      (<!! c) ;; wait until definitely closed
-                      (assert (not (still-open?)) "past trigger")))))))))
+                      (while (still-open?)
+                        ;; The fn attached with take! will fire
+                        ;; asynchronously, outside of our control.
+                        (Thread/sleep 50))))))))))


things drawing again after bumping versions

--- clojure/src/dnd/showScreen.cljs
+++ clojure/src/dnd/showScreen.cljs
@@ -74,18 +74,17 @@
                :attr #js {:r r :g g :b b :bgR bgR :bgG bgG :bgB bgB}}
           char)))

-
 (defn draw-block [term block]
   (let [{:keys [x y solid inhabitants color visible]} block
         has-inhabitant (boolean (seq inhabitants))
-        fgcolor (or (:color (first inhabitants)) [0 0 0])
+        [fgR fgG fgB] (or (:color (first inhabitants)) [0 0 0])
         bgcolor (.rgb COLOR color)
-        bgcolor (color-to-vec bgcolor)
+        [bgR bgG bgB] (color-to-vec bgcolor)
         char    (if has-inhabitant
                   (:char (first inhabitants))
                   (if solid "▒" " "))]
-    (apply (.-colorRgb term) fgcolor)
-    (apply (.-bgColorRgb term) bgcolor)
+    (.colorRgb term fgR fgG fgB)
+    (.bgColorRgb term bgR bgG bgB)
     (.moveTo term x y char)))

 (defn fov [character]
@@ -110,7 +109,8 @@
     (->> level
          (viewable-coords character)
          (map get-in-level)
-         (run! #(draw-block term %)))))
+         (run! #(draw-block term %))
+         )))

 (defn show-map-with-buffer [term level character]
   (let [
@@ -134,9 +134,13 @@

 (defn show-screen [term level character]
+  (.clear term)
+
   (if (-> (.-support term) (aget "trueColor"))
     (show-map-with-buffer term level character)
     (show-map-direct term level character))
+
+  (show-map-direct term level character)

   (doto term
     (.color256    7)


Update events.cljs

Update events.cljs

fixed typo

--- examples/todomvc/src/todomvc/events.cljs
+++ examples/todomvc/src/todomvc/events.cljs
@@ -26,7 +26,7 @@
 (def ->local-store (after todos->local-store))

 ;; Each event handler can have its own set of interceptors (middleware)
-;; But we use the same set of interceptors for all event habdlers related
+;; But we use the same set of interceptors for all event handlers related
 ;; to manipulating todos.
 ;; A chain of interceptors is a vector.
 (def todo-interceptors [check-spec-interceptor               ;; ensure the spec is still valid


Fix up core.async require declaration

Fix up core.async require declaration

--- src/io/aviso/rook/jetty_async_adapter.clj
+++ src/io/aviso/rook/jetty_async_adapter.clj
@@ -6,7 +6,7 @@
            (org.eclipse.jetty.continuation ContinuationSupport Continuation))
   (:require
     [clojure.tools.logging :as l]
-    [clojure.core.async :refer [go <! timeout alts! take! close!]]
+    [clojure.core.async :refer [go timeout alt! close!]]
     [io.aviso.rook.utils :as utils]
     [io.aviso.toolchest.collections :refer [pretty-print pretty-print-brief]]
     [ring.util


add missing filter/sort stuff

add missing filter/sort stuff

--- src/cljs/org/broadinstitute/firecloud_ui/common/table.cljs
+++ src/cljs/org/broadinstitute/firecloud_ui/common/table.cljs
@@ -295,9 +295,11 @@
           {:key (:selected-entity-type @state)
            :columns (concat
                       [{:header "Entity Type" :starting-width 100
+                        :as-text #(% "entityType") :sort-by :text
                         :content-renderer (or (:entity-type-renderer props)
                                             (fn [entity] (entity "entityType")))}
                        {:header "Entity Name" :starting-width 200
+                        :as-text #(% "name") :sort-by :text
                         :content-renderer (or (:entity-name-renderer props)
                                             (fn [entity] (entity "name")))}]
                       (map (fn [k] {:header k :starting-width attr-col-width


add type hint

add type hint

--- src/main/clojure/org/dada/demo/whales.clj
+++ src/main/clojure/org/dada/demo/whales.clj
@@ -180,8 +180,8 @@
 ;;----------------------------------------

 (let [type-to-route (apply hash-map (interleave types (range (count types))))
-      route-to-type (into-array String types)]
-  (do-split whales :type false type-to-route #(aget route-to-type %) #(insert *metamodel* %)))
+      #^"[Ljava.lang.String;" route-to-type (into-array String types)]
+  (do-split whales :type false type-to-route #(aget route-to-type #^Integer %) #(insert *metamodel* %)))

 ;;----------------------------------------
 ;; demonstrate reduction


cleanup test-util

cleanup test-util

--- test/midje/test_util.clj
+++ test/midje/test_util.clj
@@ -1,34 +1,29 @@
 ;; -*- indent-tabs-mode: nil -*-

 (ns midje.test-util
-  (:use [clojure.test])
-  (:use midje.checkers)
-  (:use [clojure.set :only [subset?]]))
+  (:use [clojure.test]
+        midje.checkers
+        [clojure.set :only [subset?]]
+        [midje.util.form-utils :only [macro-for]]))

 (defmacro testable-privates [namespace & symbols]
-  (let [forms (for [sym symbols]
-                `(def ~sym (intern '~namespace '~sym)))]
-  `(do ~@forms)))
+  (macro-for [sym symbols]
+    `(def ~sym (intern '~namespace '~sym))))

 (def reported (atom []))
-
-(defmacro run-silently [run-form]
-  `(run-without-reporting (fn [] ~run-form)))

 (defn run-without-reporting [function]
   (binding [report (fn [report-map#] (swap! reported conj report-map#))]
     (reset! reported [])
     (function)))

-(defn run-and-check [run-form check-forms]
-  `(do
-     (run-without-reporting (fn [] ~run-form))
+(defmacro run-silently [run-form]
+  `(run-without-reporting (fn [] ~run-form)))
+
+(defmacro after-silently [example-form & check-forms]
+   `(do
+     (run-without-reporting (fn [] ~example-form))
      ~@check-forms))
-
-(defmacro after-silently
-  [example-form & check-forms]
-  (run-and-check example-form check-forms))
-

 (defn only-passes? [expected-count]
   (cond (not (= (count @reported) expected-count))
@@ -67,6 +62,4 @@

 (defmacro user-error-with-notes [& notes]
   `(just (contains {:notes (just ~@notes)
-                    :type :user-error})))
-
-
+                    :type :user-error})))


Snapshot version

Snapshot version

--- scheduler/project.clj
+++ scheduler/project.clj
@@ -13,7 +13,7 @@
 ;; See the License for the specific language governing permissions and
 ;; limitations under the License.
 ;;
-(defproject cook "1.14.1"
+(defproject cook "1.14.2-SNAPSHOT"
   :description "This launches jobs on a Mesos cluster with fair sharing and preemption"
   :license {:name "Apache License, Version 2.0"}
   :dependencies [[org.clojure/clojure "1.8.0"]


CMR-2717: Adding logout-all function.

CMR-2717: Adding logout-all function.

--- transmit-lib/src/cmr/transmit/echo/soap/authentication.clj
+++ transmit-lib/src/cmr/transmit/echo/soap/authentication.clj
@@ -40,6 +40,11 @@
     (soap/post-soap :authentication body)
     nil))

+(defn logout-all
+  [& tokens]
+  (doseq [token tokens]
+    (logout token)))
+
 (defn get-security-token-informaton
   "Perform a security token information request against the SOAP API using the specified token."
   [admin-token tokens]


Fixed indentation.

Fixed indentation.

--- umm-spec-lib/src/cmr/umm_spec/umm_to_xml_mappings/dif9.clj
+++ umm-spec-lib/src/cmr/umm_spec/umm_to_xml_mappings/dif9.clj
@@ -40,14 +40,14 @@
       [:Version (:Version c)]]
      (if-let [sks (:ScienceKeywords c)]
        (for [sk sks]
-       [:Parameters
-        [:Category (:Category sk)]
-        [:Topic (:Topic sk)]
-        [:Term (:Term sk)]
-        [:Variable_Level_1 (:VariableLevel1 sk)]
-        [:Variable_Level_2 (:VariableLevel2 sk)]
-        [:Variable_Level_3 (:VariableLevel3 sk)]
-        [:Detailed_Variable (:DetailedVariable sk)]])
+         [:Parameters
+          [:Category (:Category sk)]
+          [:Topic (:Topic sk)]
+          [:Term (:Term sk)]
+          [:Variable_Level_1 (:VariableLevel1 sk)]
+          [:Variable_Level_2 (:VariableLevel2 sk)]
+          [:Variable_Level_3 (:VariableLevel3 sk)]
+          [:Detailed_Variable (:DetailedVariable sk)]])
        ;; Default element
        [:Parameters
         [:Category u/not-provided]


Test `look at myself`.

Test `look at myself`.

--- test/isla/test/story.clj
+++ test/isla/test/story.clj
@@ -37,3 +37,10 @@
         story (init-story story-str)]
     (is (= (run-command story "look")
            summary))))
+
+(deftest test-look-at-myself
+  (let [summary "You have no shoes on."
+        story-str (str "my summary is '" summary "'")
+        story (init-story story-str)]
+    (is (= (run-command story "look at myself")
+           summary))))


Fix little bug

Fix little bug


Acceptance tests for deleting metadata items.

--- test/onix/acceptance.clj
+++ test/onix/acceptance.clj
@@ -195,4 +195,44 @@
           (let [response (client/get (url+ "/applications/myapp/mykey"))
                 body (read-body response)]
             response => (contains {:status 200})
-            body => {:mykey "myvalue"}))))
+            body => {:mykey "myvalue"})))
+
+   (fact "Deleting a metadata item where application doesn't exist returns 204 No Content"
+         (rest-driven
+          [(dynamo-get-request :table "onix-applications" :key "myapp")
+           (dynamo-get-response)]
+          (let [response (client/delete (url+ "/applications/myapp/mykey") {:throw-exceptions false})]
+            response => (contains {:status 204}))))
+
+   (fact "Deleting a metadata item that doesn't exist returns 204 No Content"
+         (rest-driven
+          [(dynamo-get-request :table "onix-applications" :key "myapp")
+           (dynamo-get-response :item {"name" {"S" "myapp"}
+                                       "metadata" {"S" "{\"anotherkey\":\"value\"}"}})]
+          (let [response (client/delete (url+ "/applications/myapp/mykey") {:throw-exceptions false})]
+            response => (contains {:status 204}))))
+
+   (fact "Deleting a metadata item where app has no metadata returns 204 No Content"
+         (rest-driven
+          [(dynamo-get-request :table "onix-applications" :key "myapp")
+           (dynamo-get-response :item {"name" {"S" "myapp"}})]
+          (let [response (client/delete (url+ "/applications/myapp/mykey") {:throw-exceptions false})]
+            response => (contains {:status 204}))))
+
+   (fact "Deleting a metadata item where app has empty metadata returns 204 No Content"
+         (rest-driven
+          [(dynamo-get-request :table "onix-applications" :key "myapp")
+           (dynamo-get-response :item {"name" {"S" "myapp"}
+                                       "metadata" {"S" "{}"}})]
+          (let [response (client/delete (url+ "/applications/myapp/mykey") {:throw-exceptions false})]
+            response => (contains {:status 204}))))
+
+   (fact "Deleting a metadata item is successful and returns 204 No Content"
+         (rest-driven
+          [(dynamo-get-request :table "onix-applications" :key "myapp")
+           (dynamo-get-response :item {"name" {"S" "myapp"}
+                                       "metadata" {"S" "{\"mykey\":\"value\",\"key2\":\"value2\"}"}})
+           (dynamo-request :table "onix-applications" :action "PutItem")
+           (dynamo-put-response)]
+          (let [response (client/delete (url+ "/applications/myapp/mykey") {:throw-exceptions false})]
+            response => (contains {:status 204})))))


Update experimental nanoKONTROL2 device code to work with new event system. Also create a bus for each control.

--- src/overtone/device/midi/nanoKONTROL2.clj
+++ src/overtone/device/midi/nanoKONTROL2.clj
@@ -1,110 +1,132 @@
 (ns overtone.device.midi.nanoKONTROL2
   (:use [overtone.midi]
-        [overtone.libs.event :only [event]]))
-
-(defrecord NanoKontrol2 [name in out interfaces state])
-
-(def event-handle "/overtone/midi/nanokontrol2")
+        [overtone.libs.event :only [event on-event on-latest-event]]
+        [overtone.core :only [control-bus bus-set!]]))
+
+(defrecord NanoKontrol2 [name out interfaces state busses])
+
+(def event-handle [:midi-device "KORG INC." "SLIDER/KNOB" "nanoKONTROL2 SLIDER/KNOB" :control-change])
+
+(defn- merge-control-defaults
+  "Returns config map where control info maps are merged
+  with :control-defaults map."
+  [config]
+  (assoc config
+    :interfaces
+    (into {}
+          (map (fn [[i-name i-info]]
+                 [i-name (assoc (dissoc i-info :control-defaults)
+                           :controls (into {}
+                                           (map (fn [[c-name c-info]]
+                                                  [c-name (merge (:control-defaults i-info)
+                                                                 c-info)])
+                                                (:controls i-info))))])
+               (:interfaces config)))))
+
+(def default-event-type
+  {:button :on-event
+   :slider :on-latest-event
+   :pot    :on-latest-event})

 (def config
-  {:name "nanoKONTROL2"
-   :interfaces {:input-controls {:name "Input Controls"
-                                 :type :midi-in
-                                 :midi-handle "nanoKONTROL2"
-                                 :control-defaults {:chan 0 :cmd 176 :type :button}
-                                 :controls {:track-left {:note 58}
-                                            :track-right {:note 59}
-                                            :cycle {:note 46}
-                                            :marker-set {:note 60}
-                                            :marker-left {:note 61}
-                                            :marker-right {:note 62}
-                                            :rewind {:note 43}
-                                            :fast-forward {:note 44}
-                                            :stop {:note 42}
-                                            :play {:note 41}
-                                            :record {:note 45}
-                                            :s0 {:note 32}
-                                            :m0 {:note 48}
-                                            :r0 {:note 64}
-                                            :slider0 {:note 0 :type :slider}
-                                            :pot0 {:note 16 :type :pot}
-
-                                            :s1 {:note 33}
-                                            :m1 {:note 49}
-                                            :r1 {:note 65}
-                                            :slider1 {:note 1 :type :slider}
-                                            :pot1 {:note 17 :type :pot}
-
-                                            :s2 {:note 34}
-                                            :m2 {:note 50}
-                                            :r2 {:note 66}
-                                            :slider2 {:note 2 :type :slider}
-                                            :pot2 {:note 18 :type :pot}
-
-                                            :s3 {:note 35}
-                                            :m3 {:note 51}
-                                            :r3 {:note 67}
-                                            :slider3 {:note 3 :type :slider}
-                                            :pot3 {:note 19 :type :pot}
-
-                                            :s4 {:note 36}
-                                            :m4 {:note 52}
-                                            :r4 {:note 68}
-                                            :slider4 {:note 4 :type :slider}
-                                            :pot4 {:note 20 :type :pot}
-
-                                            :s5 {:note 37}
-                                            :m5 {:note 53}
-                                            :r5 {:note 69}
-                                            :slider5 {:note 5 :type :slider}
-                                            :pot5 {:note 21 :type :pot}
-
-                                            :s6 {:note 38}
-                                            :m6 {:note 54}
-                                            :r6 {:note 70}
-                                            :slider6 {:note 6 :type :slider}
-                                            :pot6 {:note 22 :type :pot}
-
-                                            :s7 {:note 39}
-                                            :m7 {:note 55}
-                                            :r7 {:note 71}
-                                            :slider7 {:note 7 :type :slider}
-                                            :pot7 {:note 23 :type :pot}}}
-                :leds {:name "LEDs"
-                       :type :midi-out
-                       :midi-handle "nanoKONTROL2"
-                       :control-defaults {:type :led}
-                       :controls {:cycle {:note 46}
-                                  :rewind {:note 43}
-                                  :fast-forward {:note 44}
-                                  :stop {:note 42}
-                                  :play {:note 41}
-                                  :record {:note 45}
-                                  :s0 {:note 32}
-                                  :m0 {:note 48}
-                                  :r0 {:note 64}
-                                  :s1 {:note 33}
-                                  :m1 {:note 49}
-                                  :r1 {:note 65}
-                                  :s2 {:note 34}
-                                  :m2 {:note 50}
-                                  :r2 {:note 66}
-                                  :s3 {:note 35}
-                                  :m3 {:note 51}
-                                  :r3 {:note 67}
-                                  :s4 {:note 36}
-                                  :m4 {:note 52}
-                                  :r4 {:note 68}
-                                  :s5 {:note 37}
-                                  :m5 {:note 53}
-                                  :r5 {:note 69}
-                                  :s6 {:note 38}
-                                  :m6 {:note 54}
-                                  :r6 {:note 70}
-                                  :s7 {:note 39}
-                                  :m7 {:note 55}
-                                  :r7 {:note 71}}}}})
-
+  (merge-control-defaults
+   {:name "nanoKONTROL2"
+    :interfaces {:input-controls {:name "Input Controls"
+                                  :type :midi-in
+                                  :midi-handle "nanoKONTROL2"
+                                  :control-defaults {:chan 0 :cmd 176 :type :button}
+                                  :controls {:track-left {:note 58}
+                                             :track-right {:note 59}
+                                             :cycle {:note 46}
+                                             :marker-set {:note 60}
+                                             :marker-left {:note 61}
+                                             :marker-right {:note 62}
+                                             :rewind {:note 43}
+                                             :fast-forward {:note 44}
+                                             :stop {:note 42}
+                                             :play {:note 41}
+                                             :record {:note 45}
+                                             :s0 {:note 32}
+                                             :m0 {:note 48}
+                                             :r0 {:note 64}
+                                             :slider0 {:note 0 :type :slider}
+                                             :pot0 {:note 16 :type :pot}
+
+                                             :s1 {:note 33}
+                                             :m1 {:note 49}
+                                             :r1 {:note 65}
+                                             :slider1 {:note 1 :type :slider}
+                                             :pot1 {:note 17 :type :pot}
+
+                                             :s2 {:note 34}
+                                             :m2 {:note 50}
+                                             :r2 {:note 66}
+                                             :slider2 {:note 2 :type :slider}
+                                             :pot2 {:note 18 :type :pot}
+
+                                             :s3 {:note 35}
+                                             :m3 {:note 51}
+                                             :r3 {:note 67}
+                                             :slider3 {:note 3 :type :slider}
+                                             :pot3 {:note 19 :type :pot}
+
+                                             :s4 {:note 36}
+                                             :m4 {:note 52}
+                                             :r4 {:note 68}
+                                             :slider4 {:note 4 :type :slider}
+                                             :pot4 {:note 20 :type :pot}
+
+                                             :s5 {:note 37}
+                                             :m5 {:note 53}
+                                             :r5 {:note 69}
+                                             :slider5 {:note 5 :type :slider}
+                                             :pot5 {:note 21 :type :pot}
+
+                                             :s6 {:note 38}
+                                             :m6 {:note 54}
+                                             :r6 {:note 70}
+                                             :slider6 {:note 6 :type :slider}
+                                             :pot6 {:note 22 :type :pot}
+
+                                             :s7 {:note 39}
+                                             :m7 {:note 55}
+                                             :r7 {:note 71}
+                                             :slider7 {:note 7 :type :slider}
+                                             :pot7 {:note 23 :type :pot}}}
+                 :leds {:name "LEDs"
+                        :type :midi-out
+                        :midi-handle "nanoKONTROL2"
+                        :control-defaults {:type :led}
+                        :controls {:cycle {:note 46}
+                                   :rewind {:note 43}
+                                   :fast-forward {:note 44}
+                                   :stop {:note 42}
+                                   :play {:note 41}
+                                   :record {:note 45}
+                                   :s0 {:note 32}
+                                   :m0 {:note 48}
+                                   :r0 {:note 64}
+                                   :s1 {:note 33}
+                                   :m1 {:note 49}
+                                   :r1 {:note 65}
+                                   :s2 {:note 34}
+                                   :m2 {:note 50}
+                                   :r2 {:note 66}
+                                   :s3 {:note 35}
+                                   :m3 {:note 51}
+                                   :r3 {:note 67}
+                                   :s4 {:note 36}
+                                   :m4 {:note 52}
+                                   :r4 {:note 68}
+                                   :s5 {:note 37}
+                                   :m5 {:note 53}
+                                   :r5 {:note 69}
+                                   :s6 {:note 38}
+                                   :m6 {:note 54}
+                                   :r6 {:note 70}
+                                   :s7 {:note 39}
+                                   :m7 {:note 55}
+                                   :r7 {:note 71}}}}}))

 (defn- byte-seq-to-array
   "Turn a seq of bytes into a native byte-array."
@@ -210,39 +232,12 @@
          (smr-col-off out id)
          (Thread/sleep (nth intro-times id))))))

-(defn- merge-control-defaults
-  "Returns config map where control info maps are merged
-  with :control-defaults map."
-  [config]
-  (assoc config
-    :interfaces
-    (into {}
-          (map (fn [[i-name i-info]]
-                 [i-name (assoc (dissoc i-info :control-defaults)
-                           :controls (into {}
-                                           (map (fn [[c-name c-info]]
-                                                  [c-name (merge (:control-defaults i-info)
-                                                                 c-info)])
-                                                (:controls i-info))))])
-               (:interfaces config)))))
-
 (defn note-controls-map
   [config]
   (let [controls (-> config :interfaces :input-controls :controls)]
     (into {}
           (map (fn [[k v]] [(:note v) k])
                controls))))
-
-(defn mk-midi-in-handler
-  [config state event-name]
-  (let [ncm (note-controls-map config)]
-    (fn [msg ts]
-      (let [note   (:note msg)
-            vel    (:vel msg)
-            at-key (get ncm note)
-            atm    (get state at-key)]
-        (reset! atm vel)
-        (event event-name :msg msg :ts ts :val vel :id at-key)))))

 (defn connect
   "Connect to a connected nanoKONTROL2 midi device. By default, it
@@ -258,13 +253,32 @@
               (-> config :interfaces :leds :midi-handle)))
   ([midi-in-str midi-out-str] (connect true midi-in-str midi-out-str))
   ([force-external-led-mode? midi-in-str midi-out-str]
-     (let [in         (midi-in midi-in-str)
-           out        (midi-out midi-out-str)
-           config     (merge-control-defaults config)
+     (let [out        (midi-out midi-out-str)
            interfaces (-> config :interfaces)
-           state      (into {} (map (fn [[k v]] [k (atom nil)]) (-> config :interfaces :input-controls :controls)))]
+           state      (into {}
+                            (map (fn [[k v]] [k (atom nil)])
+                                 (-> config :interfaces :input-controls :controls)))
+           busses     (into {}
+                            (map (fn [[k v]] [k (control-bus)])
+                                 (-> config :interfaces :input-controls :controls)))]
        (when force-external-led-mode?
          (set-external-led-mode! out))
-       (midi-handle-events in (mk-midi-in-handler config state event-handle))
+
+       (doseq [[k v] (-> config :interfaces :input-controls :controls)]
+         (let [type      (:type v)
+               note      (:note v)
+               handle    (concat event-handle [note])
+               update-fn (fn [{:keys [data2-f]}]
+                           (println "updating bus: " (busses k) data2-f)
+                           (bus-set! (busses k) data2-f)
+
+                           (reset! (state k) data2-f))]
+           (cond
+            (= :on-event (default-event-type type))
+            (on-event handle update-fn (str "update-state-for" handle))
+
+            (= :on-latest-event (default-event-type type))
+            (on-latest-event handle update-fn (str "update-state-for" handle)))))
+
        (intromation out)
-       (NanoKontrol2. (:name config) in out interfaces state))))
+       (NanoKontrol2. (:name config) out interfaces state busses))))


Fix parsing exception

Fix parsing exception

--- pp-cljs-client/project.clj
+++ pp-cljs-client/project.clj
@@ -5,7 +5,7 @@

   :dependencies [
     [org.clojure/clojure "1.6.0"]
-    [org.clojure/clojurescript "0.0-2913"]
+    [org.clojure/clojurescript "0.0-2985"]
     [cljsjs/react "0.12.2-7"]
     [cljs-ajax "0.3.10"]
     [sablono "0.3.4"]
@@ -16,7 +16,7 @@

   :source-paths ["src"]

-  :clean-targets ["target" "public/out" "public/js/pretty-print.js" "public/js/pretty-print.min.js"]
+  :clean-targets ["target" "public/out" "public/out-min" "public/js/pretty-print.js" "public/js/pretty-print.min.js"]

   :cljsbuild {
     :builds {
@@ -31,5 +31,6 @@
         :source-paths ["src-cljs"]
         :compiler {
           :output-to "public/js/pretty-print.min.js"
+          :output-dir "public/out-min"
           :optimizations :advanced
           :pretty-print false }}}})


Fix user-manual

Fix user-manual

Caused by latest data-map :last-modified value not being coerced - need
to fix this soon.

--- dev/src/yada/dev/user_manual.clj
+++ dev/src/yada/dev/user_manual.clj
@@ -222,7 +222,8 @@
                                      (post-process-doc component xbody config)
                                      config))
                              {:representations [{:media-type #{"text/html"} :charset #{"utf-8"}}]
-                              :last-modified (io/file "dev/resources/user-manual.md")
+                              ;; TODO: Should cope with a file - should interpret the result
+                              :last-modified (java.util.Date. (.lastModified (io/file "dev/resources/user-manual.md")))
                               :id ::user-manual})))]

 ]]]])))


Correct docstring of login-authenticate

Correct docstring of login-authenticate

The keyword access was given in the wrong order.

--- examples/session/src/authexample/web.clj
+++ examples/session/src/authexample/web.clj
@@ -65,7 +65,7 @@

   On successful authentication, set appropriate user
   into the session and redirect to the value of
-  (:query-params (:next request)). On failed
+  (:next (:query-params request)). On failed
   authentication, renders the login page."
   [request]
   (let [username (get-in request [:form-params "username"])


delaney3d.clj: more work on pseudo-toroidal cover function

--- clojure/org/gavrog/clojure/delaney3d.clj
+++ clojure/org/gavrog/clojure/delaney3d.clj
@@ -4,6 +4,7 @@
           delaney
           fundamental
           cosets
+          covers
           [generators :only [results]])))

 (defn massoc [m k v]
@@ -16,26 +17,33 @@
   (every? true? (for [row (vals ct), g (keys row)] (= (row g) (row (- g))))))

 (defn- trace-word [ct k wd]
-  (reduce (fn [[k g]] ((ct k) g)) k wd))
+  (reduce (fn [k g] ((ct k) g)) k wd))
+
+(defn- degree [ct wd]
+  (some (fn [[i k]] (when (zero? k) i))
+        (rest (reductions (fn [[_ k] i] [(inc i) (trace-word ct k wd)])
+                          [0 0] (range)))))

 (defn- flattens? [ct [wd deg]]
-  (= deg (some (fn [[i k]] (when (zero? k) i))
-               (reductions (fn [[i k]] [(inc i) (trace-word ct k wd)])
-                           [0 0]
-                           (range (inc deg))))))
+  (= deg (degree ct wd)))

 (defn- flattens-all? [ct cones]
   (every? (partial flattens? ct) cones))

 (defn pseudo-toroidal-cover [ds]
-  (let [{:keys [nr-gens relators cones edge-to-word]} (fundamental-group ds)
+  (let [ds (oriented-cover ds)
+        {:keys
+         [nr-generators relators cones edge-to-word]} (fundamental-group ds)
         cones2 (filter (fn [[wd deg]] (= deg 2)) cones)
         cones3 (filter (fn [[wd deg]] (= deg 3)) cones)
-        base (map core-table (results (table-generator nr-gens relators 4)))
-        good (for [ct base :when (flattens-all? ct cones)
-                   type (if (= (count ct) 4)
-                          (if (not (fully-involutive? ct)) :z4 :v4)
-                          (map core-type (count ct)))]
-               [type ct])
+        base (map core-table
+                  (results (table-generator nr-generators relators 4)))
+        good (for [ct base :when (flattens-all? ct cones)]
+               (let [type (if (= (count ct) 4)
+                            (if (fully-involutive? ct) :v4 :z4)
+                            (core-type (count ct)))]
+                 [type ct]))
         candidates (reduce (fn [m [k v]] (massoc m k v)) {} good)
-        ]))
+
+        ]
+    candidates))


fix cli uberjar source-paths

fix cli uberjar source-paths

didn't use default when using "dependencies"

--- npm-package-jar/src/shadow/cljs/cli.clj
+++ npm-package-jar/src/shadow/cljs/cli.clj
@@ -37,6 +37,8 @@
         (io/file "package.json")

         {:strs [repositories dependencies source-paths]
+         :or {dependencies []
+              source-paths ["src-cljs"]}
          :as config}
         (or (when (.exists package-json)
               (-> (slurp package-json)


Add namespace to apply-resource

Add namespace to apply-resource

--- src/puppeteer/infra/repository/deploy.clj
+++ src/puppeteer/infra/repository/deploy.clj
@@ -21,6 +21,7 @@
   (-> k8s-client
       :client
       (.resource resource)
+      (.inNamespace "default")
       .apply))

 (defn get-resource
@@ -44,10 +45,10 @@
                  yaml/generate-string
                  .getBytes
                  io/input-stream))
+      (.inNamespace "default")
       .apply))

-(defn delete-resource
-  [{:keys [k8s-client] :as comp}
+(defn delete-resource [{:keys [k8s-client] :as comp}
    {:keys [resource]}]
   (-> k8s-client
       :client


do not use the same local-name in different contexts

--- src/asphalt/param.clj
+++ src/asphalt/param.clj
@@ -144,12 +144,12 @@
             (let [t (first ts)
                   v (get params k)]
               (if-let [single-type (get t/multi-typemap t)]  ; multi-value param?
-                (let [k (count v)]  ; iterate over all values of multi-value param
+                (let [m (count v)]  ; iterate over all values of multi-value param
                   (loop [i 0]
-                    (when (< i k)
+                    (when (< i m)
                       (iparam/set-param-value prepared-stmt single-type (unchecked-add pi i) (get v i))
                       (recur (unchecked-inc i))))
-                  (recur (unchecked-add pi k) (next ks) (next ts)))
+                  (recur (unchecked-add pi m) (next ks) (next ts)))
                 (do
                   (iparam/set-param-value prepared-stmt t pi v)
                   (recur (unchecked-inc pi) (next ks) (next ts)))))


add a hover class to the interactive layer when you mouse in and out

--- src-cljs/frontend/components/canvas.cljs
+++ src-cljs/frontend/components/canvas.cljs
@@ -76,7 +76,10 @@

 (defn svg-layers [{:keys [editing-eids selected-eid selected-eids tool]} owner]
   (reify
-    om/IInitState (init-state [_] {:listener-key (.getNextUniqueId (.getInstance IdGenerator))})
+    om/IInitState
+    (init-state [_]
+      {:listener-key (.getNextUniqueId (.getInstance IdGenerator))
+       :hovered-eids #{}})
     om/IDidMount
     (did-mount [_]
       (d/listen! (om/get-shared owner :db)
@@ -106,7 +109,10 @@
                       (mapv (fn [layer]
                               (dom/g #js {:className (str (when (= :select tool) "selectable-group ")
                                                           (when (and (= :select tool) (:layer/ui-target layer))
-                                                            "interactive"))
+                                                            "interactive ")
+                                                          (when (contains? (om/get-state owner :hovered-eids)
+                                                                           (:db/id layer))
+                                                            "hover"))
                                           :key (:db/id layer)}
                                      ;; The order of selectable-layer and non-selectable-layer is important!
                                      ;; If the non-selectable-layer comes last in the DOM it render above the selectable-layer,
@@ -180,6 +186,10 @@
                                                    " Right-click on a shape's border to name it " (:layer/ui-target layer))))
                                  (svg-element selected-eids
                                               (assoc layer
+                                                :onMouseEnter #(om/update-state! owner :hovered-eids
+                                                                                (fn [eids] (conj eids (:db/id layer))))
+                                                :onMouseLeave #(om/update-state! owner :hovered-eids
+                                                                                (fn [eids] (disj eids (:db/id layer))))
                                                 :onMouseDown #(do
                                                                 (.stopPropagation %)
                                                                 (cond


Remove line

Remove line

--- src-cljs/frontend/components/header.cljs
+++ src-cljs/frontend/components/header.cljs
@@ -230,8 +230,7 @@
                      [:i.fa.fa-caret-down]]
                     [:ul.dropdown-menu
                      [:li {:role "presentation"}
-                      [:a.sub.menu-item (
-                                         merge
+                      [:a.sub.menu-item (merge
                                           (maybe-active nav-point :documentation)
                                           (open-ext {:role "menuitem"
                                                      :tabIndex "-1"


port 3000

port 3000

--- src/blogiseq/core.clj
+++ src/blogiseq/core.clj
@@ -115,7 +115,7 @@
   (compojure-route/not-found (hiccup/html (site "Stuff not found."))))

 (defn start []
-  (reset! server (server/run-server (fn [r] (routes r)) {:port 3001})))
+  (reset! server (server/run-server (fn [r] (routes r)) {:port 3000})))

 (defn stop []
   (if (not (nil? @server))


The OneOf test was missing

The OneOf test was missing

--- damp.ekeko.aspectj.plugin.test/src/test/damp/ekeko/aspectj.clj
+++ damp.ekeko.aspectj.plugin.test/src/test/damp/ekeko/aspectj.clj
@@ -308,7 +308,7 @@
   ;;Annotation assumptions
   (test/against-project-named "AJ-LMP-Annotations" false test-logic-requires)
   (test/against-project-named "AJ-LMP-Annotations" false test-logic-excludes)
-  ;(test/against-project-named "AJ-LMP-Annotations" false test-logic-oneOf)
+  (test/against-project-named "AJ-LMP-Annotations" false test-logic-oneOf)

     )