CMR-2013: Refactor based on review comment.

--- system-int-test/test/cmr/system_int_test/search/collection_facets_search_test.clj
+++ system-int-test/test/cmr/system_int_test/search/collection_facets_search_test.clj
@@ -156,6 +156,184 @@
      :json-facets (get-in (search/find-concepts-json :collection search-options)
                           [:results :facets])}))

+(def expected-all-hierarchical-facets
+  "Expected value for the all-hierarchical-fields-test."
+  [{:field "project", :value-counts [["PROJ2" 2] ["proj1" 2]]}
+   {:field "sensor",
+    :value-counts
+    [["FROM_KMS-p0-i0-s0" 2]
+     ["FROM_KMS-p0-i1-s0" 2]
+     ["FROM_KMS-p1-i0-s0" 2]
+     ["FROM_KMS-p1-i1-s0" 2]]}
+   {:field "two_d_coordinate_system_name",
+    :value-counts [["Alpha" 2]]}
+   {:field "processing_level_id", :value-counts [["PL1" 2]]}
+   {:field "detailed_variable",
+    :value-counts [["Detail1" 2] ["UNIVERSAL" 2]]}
+   {:field "archive_centers",
+    :subfields ["level-0"],
+    :level-0
+    [{:value "GOVERNMENT AGENCIES-U.S. FEDERAL AGENCIES",
+      :count 2,
+      :subfields ["level-1"],
+      :level-1
+      [{:value "DOI",
+        :count 2,
+        :subfields ["level-2"],
+        :level-2
+        [{:value "USGS",
+          :count 2,
+          :subfields ["level-3"],
+          :level-3
+          [{:value "Added level 3 value",
+            :count 2,
+            :subfields ["short-name"],
+            :short-name
+            [{:value "DOI/USGS/CMG/WHSC",
+              :count 2,
+              :subfields ["long-name"],
+              :long-name
+              [{:value
+                "Woods Hole Science Center, Coastal and Marine Geology, U.S. Geological Survey, U.S. Department of the Interior",
+                :count 2}]}]}]}]}]}]}
+   {:field "platforms",
+    :subfields ["category"],
+    :category
+    [{:value "Earth Observation Satellites",
+      :count 2,
+      :subfields ["series-entity"],
+      :series-entity
+      [{:value "DIADEM",
+        :count 2,
+        :subfields ["short-name"],
+        :short-name
+        [{:value "diadem-1D",
+          :count 2,
+          :subfields ["long-name"],
+          :long-name [{:value "Not Provided", :count 2}]}]}
+       {:value
+        "DMSP (Defense Meteorological Satellite Program)",
+        :count 2,
+        :subfields ["short-name"],
+        :short-name
+        [{:value "DMSP 5B/F3",
+          :count 2,
+          :subfields ["long-name"],
+          :long-name
+          [{:value
+            "Defense Meteorological Satellite Program-F3",
+            :count 2}]}]}]}]}
+   {:field "instruments",
+    :subfields ["category"],
+    :category
+    [{:value "Earth Remote Sensing Instruments",
+      :count 2,
+      :subfields ["class"],
+      :class
+      [{:value "Active Remote Sensing",
+        :count 2,
+        :subfields ["type"],
+        :type
+        [{:value "Altimeters",
+          :count 2,
+          :subfields ["subtype"],
+          :subtype
+          [{:value "Lidar/Laser Altimeters",
+            :count 2,
+            :subfields ["short-name"],
+            :short-name
+            [{:value "ATM",
+              :count 2,
+              :subfields ["long-name"],
+              :long-name
+              [{:value "Airborne Topographic Mapper",
+                :count 2}]}
+             {:value "lVIs",
+              :count 2,
+              :subfields ["long-name"],
+              :long-name
+              [{:value "Land, Vegetation, and Ice Sensor",
+                :count 2}]}]}]}]}]}]}
+   {:field "science_keywords",
+    :subfields ["category"],
+    :category
+    [{:value "Hurricane",
+      :count 2,
+      :subfields ["topic"],
+      :topic
+      [{:value "Popular",
+        :count 2,
+        :subfields ["term"],
+        :term
+        [{:value "Extreme",
+          :count 2,
+          :subfields ["variable-level-1"],
+          :variable-level-1
+          [{:value "Level2-1",
+            :count 2,
+            :subfields ["variable-level-2"],
+            :variable-level-2
+            [{:value "Level2-2",
+              :count 2,
+              :subfields ["variable-level-3"],
+              :variable-level-3
+              [{:value "Level2-3", :count 2}]}]}]}
+         {:value "UNIVERSAL", :count 2}]}
+       {:value "Cool",
+        :count 2,
+        :subfields ["term"],
+        :term
+        [{:value "Term4",
+          :count 2,
+          :subfields ["variable-level-1"],
+          :variable-level-1
+          [{:value "UNIVERSAL", :count 2}]}]}]}
+     {:value "Cat1",
+      :count 2,
+      :subfields ["topic"],
+      :topic
+      [{:value "Topic1",
+        :count 2,
+        :subfields ["term"],
+        :term
+        [{:value "Term1",
+          :count 2,
+          :subfields ["variable-level-1"],
+          :variable-level-1
+          [{:value "Level1-1",
+            :count 2,
+            :subfields ["variable-level-2"],
+            :variable-level-2
+            [{:value "Level1-2",
+              :count 2,
+              :subfields ["variable-level-3"],
+              :variable-level-3
+              [{:value "Level1-3", :count 2}]}]}]}]}]}
+     {:value "Tornado",
+      :count 2,
+      :subfields ["topic"],
+      :topic
+      [{:value "Popular",
+        :count 2,
+        :subfields ["term"],
+        :term [{:value "Extreme", :count 2}]}]}
+     {:value "UPCASE",
+      :count 2,
+      :subfields ["topic"],
+      :topic
+      [{:value "Popular",
+        :count 2,
+        :subfields ["term"],
+        :term [{:value "Mild", :count 2}]}]}
+     {:value "upcase",
+      :count 2,
+      :subfields ["topic"],
+      :topic
+      [{:value "Cool",
+        :count 2,
+        :subfields ["term"],
+        :term [{:value "Mild", :count 2}]}]}]}])
+
 (deftest all-hierarchical-fields-test
   (grant-permissions)
   (let [coll1 (make-coll 1 "PROV1"
@@ -172,185 +350,9 @@
                          (twod-coords "Alpha")
                          (processing-level-id "PL1")
                          {:organizations [(dc/org :archive-center "DOI/USGS/CMG/WHSC")]})
-
-        expected-facets [{:field "project", :value-counts [["PROJ2" 2] ["proj1" 2]]}
-                         {:field "sensor",
-                          :value-counts
-                          [["FROM_KMS-p0-i0-s0" 2]
-                           ["FROM_KMS-p0-i1-s0" 2]
-                           ["FROM_KMS-p1-i0-s0" 2]
-                           ["FROM_KMS-p1-i1-s0" 2]]}
-                         {:field "two_d_coordinate_system_name",
-                          :value-counts [["Alpha" 2]]}
-                         {:field "processing_level_id", :value-counts [["PL1" 2]]}
-                         {:field "detailed_variable",
-                          :value-counts [["Detail1" 2] ["UNIVERSAL" 2]]}
-                         {:field "archive_centers",
-                          :subfields ["level-0"],
-                          :level-0
-                          [{:value "GOVERNMENT AGENCIES-U.S. FEDERAL AGENCIES",
-                            :count 2,
-                            :subfields ["level-1"],
-                            :level-1
-                            [{:value "DOI",
-                              :count 2,
-                              :subfields ["level-2"],
-                              :level-2
-                              [{:value "USGS",
-                                :count 2,
-                                :subfields ["level-3"],
-                                :level-3
-                                [{:value "Added level 3 value",
-                                  :count 2,
-                                  :subfields ["short-name"],
-                                  :short-name
-                                  [{:value "DOI/USGS/CMG/WHSC",
-                                    :count 2,
-                                    :subfields ["long-name"],
-                                    :long-name
-                                    [{:value
-                                      "Woods Hole Science Center, Coastal and Marine Geology, U.S. Geological Survey, U.S. Department of the Interior",
-                                      :count 2}]}]}]}]}]}]}
-                         {:field "platforms",
-                          :subfields ["category"],
-                          :category
-                          [{:value "Earth Observation Satellites",
-                            :count 2,
-                            :subfields ["series-entity"],
-                            :series-entity
-                            [{:value "DIADEM",
-                              :count 2,
-                              :subfields ["short-name"],
-                              :short-name
-                              [{:value "diadem-1D",
-                                :count 2,
-                                :subfields ["long-name"],
-                                :long-name [{:value "Not Provided", :count 2}]}]}
-                             {:value
-                              "DMSP (Defense Meteorological Satellite Program)",
-                              :count 2,
-                              :subfields ["short-name"],
-                              :short-name
-                              [{:value "DMSP 5B/F3",
-                                :count 2,
-                                :subfields ["long-name"],
-                                :long-name
-                                [{:value
-                                  "Defense Meteorological Satellite Program-F3",
-                                  :count 2}]}]}]}]}
-                         {:field "instruments",
-                          :subfields ["category"],
-                          :category
-                          [{:value "Earth Remote Sensing Instruments",
-                            :count 2,
-                            :subfields ["class"],
-                            :class
-                            [{:value "Active Remote Sensing",
-                              :count 2,
-                              :subfields ["type"],
-                              :type
-                              [{:value "Altimeters",
-                                :count 2,
-                                :subfields ["subtype"],
-                                :subtype
-                                [{:value "Lidar/Laser Altimeters",
-                                  :count 2,
-                                  :subfields ["short-name"],
-                                  :short-name
-                                  [{:value "ATM",
-                                    :count 2,
-                                    :subfields ["long-name"],
-                                    :long-name
-                                    [{:value "Airborne Topographic Mapper",
-                                      :count 2}]}
-                                   {:value "lVIs",
-                                    :count 2,
-                                    :subfields ["long-name"],
-                                    :long-name
-                                    [{:value "Land, Vegetation, and Ice Sensor",
-                                      :count 2}]}]}]}]}]}]}
-                         {:field "science_keywords",
-                          :subfields ["category"],
-                          :category
-                          [{:value "Hurricane",
-                            :count 2,
-                            :subfields ["topic"],
-                            :topic
-                            [{:value "Popular",
-                              :count 2,
-                              :subfields ["term"],
-                              :term
-                              [{:value "Extreme",
-                                :count 2,
-                                :subfields ["variable-level-1"],
-                                :variable-level-1
-                                [{:value "Level2-1",
-                                  :count 2,
-                                  :subfields ["variable-level-2"],
-                                  :variable-level-2
-                                  [{:value "Level2-2",
-                                    :count 2,
-                                    :subfields ["variable-level-3"],
-                                    :variable-level-3
-                                    [{:value "Level2-3", :count 2}]}]}]}
-                               {:value "UNIVERSAL", :count 2}]}
-                             {:value "Cool",
-                              :count 2,
-                              :subfields ["term"],
-                              :term
-                              [{:value "Term4",
-                                :count 2,
-                                :subfields ["variable-level-1"],
-                                :variable-level-1
-                                [{:value "UNIVERSAL", :count 2}]}]}]}
-                           {:value "Cat1",
-                            :count 2,
-                            :subfields ["topic"],
-                            :topic
-                            [{:value "Topic1",
-                              :count 2,
-                              :subfields ["term"],
-                              :term
-                              [{:value "Term1",
-                                :count 2,
-                                :subfields ["variable-level-1"],
-                                :variable-level-1
-                                [{:value "Level1-1",
-                                  :count 2,
-                                  :subfields ["variable-level-2"],
-                                  :variable-level-2
-                                  [{:value "Level1-2",
-                                    :count 2,
-                                    :subfields ["variable-level-3"],
-                                    :variable-level-3
-                                    [{:value "Level1-3", :count 2}]}]}]}]}]}
-                           {:value "Tornado",
-                            :count 2,
-                            :subfields ["topic"],
-                            :topic
-                            [{:value "Popular",
-                              :count 2,
-                              :subfields ["term"],
-                              :term [{:value "Extreme", :count 2}]}]}
-                           {:value "UPCASE",
-                            :count 2,
-                            :subfields ["topic"],
-                            :topic
-                            [{:value "Popular",
-                              :count 2,
-                              :subfields ["term"],
-                              :term [{:value "Mild", :count 2}]}]}
-                           {:value "upcase",
-                            :count 2,
-                            :subfields ["topic"],
-                            :topic
-                            [{:value "Cool",
-                              :count 2,
-                              :subfields ["term"],
-                              :term [{:value "Mild", :count 2}]}]}]}]
         actual-facets (get-facet-results :hierarchical)]
-    (is (= expected-facets (:xml-facets actual-facets)))
-    (is (= expected-facets (:json-facets actual-facets)))))
+    (is (= expected-all-hierarchical-facets (:xml-facets actual-facets)))
+    (is (= expected-all-hierarchical-facets (:json-facets actual-facets)))))

 ;; The purpose of the test is to make sure when the same topic "Popular" is used under two different
 ;; categories, the flat facets correctly say 2 collections have the "Popular topic and the


CMR-3702 fix comment

CMR-3702 fix comment

--- system-int-test/test/cmr/system_int_test/ingest/granule_parent_dependency_test.clj
+++ system-int-test/test/cmr/system_int_test/ingest/granule_parent_dependency_test.clj
@@ -634,7 +634,7 @@
              (is (= 201 status)))))

 ;; Test specific to an issue ingesting an echo10 granule with a polygon in spatial data with
-;; a parent collection with a nil Granule Spatial representation
+;; an iso-19115 parent collection with a nil Granule Spatial representation
 ;; An exception would be seen when ingesting the granule and processing the polygon with a default
 ;; GSR
 (deftest no-spatial-test


Updated test to be more robust.

Updated test to be more robust.

--- system-int-test/test/cmr/system_int_test/search/granule_concept_retrieval_test.clj
+++ system-int-test/test/cmr/system_int_test/search/granule_concept_retrieval_test.clj
@@ -1,27 +1,28 @@
 (ns cmr.system-int-test.search.granule-concept-retrieval-test
   "Integration test for granule retrieval via the /concepts/:concept-id and
   /concepts/:concept-id/:revision-id endpoints."
-  (:require [clojure.test :refer :all]
-            [cmr.system-int-test.utils.ingest-util :as ingest]
-            [cmr.system-int-test.utils.search-util :as search]
-            [cmr.system-int-test.utils.index-util :as index]
-            [cmr.system-int-test.data2.collection :as dc]
-            [cmr.system-int-test.data2.granule :as dg]
-            [cmr.system-int-test.data2.core :as d]
-            [cmr.umm.echo10.echo10-collection :as c]
-            [cmr.common.util :refer [are2] :as util]
-            [cmr.transmit.config :as transmit-config]
-            [cmr.common.mime-types :as mt]
-            [cmr.umm.umm-core :as umm]
-            [cheshire.core :as json]
-            [cmr.mock-echo.client.echo-util :as e]
-            [cmr.system-int-test.system :as s]
-            [cmr.umm.iso-mends.iso-mends-collection :as umm-c]
-            [clojure.string :as str]
-            [cmr.common.mime-types :as mt]
-            [clj-time.format :as f]
-            [cmr.common.xml :as cx]
-            [cmr.system-int-test.utils.fast-xml :as fx]))
+  (:require
+   [cheshire.core :as json]
+   [clj-time.format :as f]
+   [clojure.string :as str]
+   [clojure.test :refer :all]
+   [cmr.common.mime-types :as mt]
+   [cmr.common.mime-types :as mt]
+   [cmr.common.util :refer [are3] :as util]
+   [cmr.common.xml :as cx]
+   [cmr.mock-echo.client.echo-util :as e]
+   [cmr.system-int-test.data2.collection :as dc]
+   [cmr.system-int-test.data2.core :as d]
+   [cmr.system-int-test.data2.granule :as dg]
+   [cmr.system-int-test.system :as s]
+   [cmr.system-int-test.utils.fast-xml :as fx]
+   [cmr.system-int-test.utils.index-util :as index]
+   [cmr.system-int-test.utils.ingest-util :as ingest]
+   [cmr.system-int-test.utils.search-util :as search]
+   [cmr.transmit.config :as transmit-config]
+   [cmr.umm.echo10.echo10-collection :as c]
+   [cmr.umm.iso-mends.iso-mends-collection :as umm-c]
+   [cmr.umm.umm-core :as umm]))

 (use-fixtures
   :each
@@ -98,6 +99,7 @@
         ;; ingest granule twice
         gran1-1 (d/ingest "PROV1" umm-gran1-1)
         gran1-2 (d/ingest "PROV1" umm-gran1-2)
+        gran-concept-id (:concept-id gran1-1)

         guest-token (e/login-guest (s/context))
         user1-token (e/login (s/context) "user1")]
@@ -105,20 +107,20 @@

     (testing "retrieve metadata from search by concept-id/revision-id"
       (testing "collections and granules"
-        (are2 [item format-key accept concept-id revision-id]
+        (are3 [item format-key accept concept-id revision-id]
           (let [headers {transmit-config/token-header user1-token
                          "Accept" accept}
                 response (search/retrieve-concept concept-id revision-id {:headers headers})]
             (result-matches? format-key item response))

           "echo10 granule revision 1"
-          umm-gran1-1 :echo10 mt/echo10 "G1200000004-PROV1" 1
+          umm-gran1-1 :echo10 mt/echo10 gran-concept-id 1

           "echo10 granule revision 2"
-          umm-gran1-2 :echo10 mt/echo10 "G1200000004-PROV1" 2)))
+          umm-gran1-2 :echo10 mt/echo10 gran-concept-id 2)))
     (testing "unsupported formats"
       (let [response (search/retrieve-concept
-                      "G1200000004-PROV1" nil
+                      gran-concept-id nil
                       {:headers {transmit-config/token-header user1-token}
                        :accept mt/html})
             err-msg (first (:errors (json/decode (:body response) true)))]
@@ -127,12 +129,10 @@
                     mt/html "] are not supported.")
                err-msg)))
       (let [response (search/retrieve-concept
-                      "G1200000004-PROV1" nil
+                      gran-concept-id nil
                       {:headers {transmit-config/token-header user1-token}
                        :url-extension "html"})
             err-msg (first (:errors (json/decode (:body response) true)))]
         (is (= 400 (:status response)))
         (is (= "The URL extension [html] is not supported."
                err-msg))))))
-
-


Added testing code.

Added testing code.

--- src/api_test/xml.clj
+++ src/api_test/xml.clj
@@ -24,6 +24,93 @@

 ;(println (pr-str test-values))

+(def test-request "<?xml version='1.0'?><newPpSocInfo>
+          <pricePlanSocCode>PGCDM1090</pricePlanSocCode>
+          <featureApiInfoList>
+            <FeatureApiInfo>
+              <featureCode>CHSDA</featureCode>
+            </FeatureApiInfo>
+            <FeatureApiInfo>
+              <featureCode>CLIP</featureCode>
+            </FeatureApiInfo>
+
+          </featureApiInfoList>
+        </newPpSocInfo>
+")
+
+
+(def test-request "<?xml version='1.0'?><e>
+          PGCDM1090
+
+            <c>
+              <d>CHSDA</d>
+            </c>
+            <c>
+              <d>CLIP</d>
+            </c>
+
+
+        </e>
+")
+
+
+(def zipper (zip/xml-zip (parse test-request)))
+
+
+(defn test-set-values
+  "given a lazy sequence of cucumber table values of :tag path and :content reset the :content of the matching paths in the message"
+  [values message]
+  (loop [zipper (zip/xml-zip (parse message)) line values]
+    (if (= () line)
+      (xml/indent-str (zip/root zipper))
+      (do
+        (let [paths (str/split (:tag (first line)) #">")
+              matches (map #(zx/tag= (keyword %)) paths)
+              edit { :tag (keyword (last paths)) :content (:content (first line)) }
+              new-loc (apply zx/xml-> zipper matches)]
+          (println (class new-loc) " : " new-loc)
+          (let [loc (if (not= nil new-loc)
+                      (zip/root (zip/replace new-loc edit))
+                      (zip/root zipper))]
+            (recur (zip/xml-zip loc) (rest line))))))))
+
+(pr (test-set-values  (lazy-seq '({:tag "a" :content "arglebargle" }
+                              {:tag "b>c>d" :content "foo" }
+                              {:tag "b>c>d" :content "bar" })) test-request))

 (defn set-values
   "given a lazy sequence of cucumber table values of :tag path and :content reset the :content of the matching paths in the message"


fix typo

fix typo

--- src/babel/engine.clj
+++ src/babel/engine.clj
@@ -30,7 +30,7 @@
   (let [do-enrich (if do-enrich do-enrich true)
         spec (if (or (= false add-subcat)
                      (fail? (unify spec {:synsem {:subcat '()}}))
-                     (not (:none (get-in spec [:synsem :subcat] :none))))
+                     (not (= :none (get-in spec [:synsem :subcat] :none))))
                spec

                ;; else:


logging

logging

--- src/babel/writer.clj
+++ src/babel/writer.clj
@@ -484,7 +484,7 @@
   "Take one or more 'units' composed of a command and arguments and perform the command on the arguments. A command is one of:
     {:fill,:fill-one-language,:fill-verb}."
   [units source-language & [no-older-than]]
-  (log/debug "Starting processing with: " (.size units) " instruction(s) with source language " source-language)
+  (log/debug "Starting processing with: " (.size units) " instruction(s) with source language: '" source-language "'")
   (let []
     (log/debug (str "Units: " (.size units)))
     (doall (map (fn [unit]


Cast line metadata to an int for the compiler

--- src/blind/reader.clj
+++ src/blind/reader.clj
@@ -425,7 +425,7 @@
       '()
       (if-not line
         (clojure.lang.PersistentList/create the-list)
-        (with-meta (clojure.lang.PersistentList/create the-list) {:line line :column column})))))
+        (with-meta (clojure.lang.PersistentList/create the-list) {:line (int line) :column column})))))

 (defn read-vector
   [rdr _]


asyncify the event loop

asyncify the event loop

--- src/bolt/speech.cljs
+++ src/bolt/speech.cljs
@@ -1,4 +1,6 @@
-(ns bolt.speech)
+(ns bolt.speech
+  (:require-macros [cljs.core.async.macros :refer [go]])
+  (:require [cljs.core.async :refer [put! <! >! chan timeout]]))

 (declare recognizing recognition)

@@ -34,15 +36,30 @@
       (-> (.querySelector js/document "#search_term") .-value (set! result))
       (def results (str results result)))))

+(defn event-loop [ch]
+  (go (while true
+        (let [[event event-data] (<! ch)]
+          #_(.log js/console (pr-str event event-data))
+          (case event
+            :start (start event-data)
+            :error (error event-data)
+            :result (result event-data)
+            :end (end event-data)
+            (println "Unknown event" event))))))
+
 (defn ->recognition
   []
-  (doto (js/webkitSpeechRecognition.)
-    #_(-> .-continuous (set! true)) ;; TODO
-    (-> .-interimResults (set! true))
-    (-> .-onstart (set! start))
-    (-> .-onerror (set! error))
-    (-> .-onresult (set! result))
-    (-> .-onend (set! end))))
+  (let [recognition (js/webkitSpeechRecognition.)
+        ch (chan)]
+    (doto recognition
+      #_(-> .-continuous (set! true)) ;; TODO
+      (-> .-interimResults (set! true))
+      (-> .-onstart (set! #(put! ch [:start %])))
+      (-> .-onerror (set! #(put! ch [:error %])))
+      (-> .-onresult (set! #(put! ch [:result %])))
+      (-> .-onend (set! #(put! ch [:end %]))))
+    (event-loop ch)
+    recognition))

 (defn toggle-speech [event]
   (if (.-webkitSpeechRecognition js/window)


fix missing links in footer

fix missing links in footer

--- frontend/components/landing_b.cljs
+++ frontend/components/landing_b.cljs
@@ -492,7 +492,7 @@
           (common/ico :logo)]
          [:nav.home-footer-about
           [:h5 "CircleCI"]
-          [:a {:href "/tour"} "Tour"]
+          ; [:a {:href "/tour"} "Tour"]
           [:a {:href "/about"} "About"]
           [:a "Support"]
           [:a {:href "/about#contact"} "Press"]
@@ -510,7 +510,7 @@
           [:h5 "Contact"]
           [:a {:href "https://twitter.com/circleci"} "Twitter"]
           [:a {:href "mailto:sayhi@circleci.com"} "Email"]
-          [:a {:href ""} "Support Chat"]
+          [:a {:href "https://www.hipchat.com/gjwkHcrD5"} "Support Chat"]
           [:a {:href ""} "Phone"]
           [:a {:href "https://goo.gl/maps/uhkLn"} "San Francisco, CA"]]]))


Issue 9729: Relocated directories

Issue 9729: Relocated directories

git-svn-id: b7e9aa1d6cd963481915708f70423d437278b157@18094 bd66a97b-2aff-0310-9095-89ca5cabf5a6

--- src/main/clojure/com/imcode/imcms/maintenance/MaintenanceFilter.clj
+++ src/main/clojure/com/imcode/imcms/maintenance/MaintenanceFilter.clj
@@ -5,7 +5,7 @@
     :init init-instance)

   (:require
-    [com.imcode.imcms.backdoor.controller :as controller]))
+    [com.imcode.imcms.maintenance.controller :as controller]))

 (defn -init-instance []
   [[] nil])


Use alias instead of full ns

Use alias instead of full ns

--- src/testdouble/cljs/csv.cljs
+++ src/testdouble/cljs/csv.cljs
@@ -8,7 +8,7 @@
   (str "\"" (escape-quotes s) "\""))

 (defn- needs-quote? [s separator]
-  (clojure.string/includes? s separator))
+  (str/includes? s separator))

 (defn- auto-quote [s separator]
   (if (needs-quote? s separator)


Logger - test file not used

Logger - test file not used

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


API endpoint should also return recipients

--- src/metabase/api/emailreport.clj
+++ src/metabase/api/emailreport.clj
@@ -44,7 +44,7 @@
         (where {:organization_id org})
         (where {:public_perms [> common/perms-none]})
         (order :name :ASC))
-    (hydrate :creator :organization :can_read :can_write)))
+    (hydrate :creator :organization :can_read :can_write :recipients)))

 (defendpoint POST "/" [:as {{:keys [dataset_query description email_addresses mode name organization public_perms schedule] :as body} :body}]


Added label to log messages

Added label to log messages

--- src/ctia/logging.clj
+++ src/ctia/logging.clj
@@ -9,5 +9,5 @@
   "Logging an event channel indefinitely. Returns the channel for a go loop that never ends."
   [{m :mult :as ev} :- e/EventChannel]
   (go (loop [ev (<! m)]
-        (log/info ev)
+        (log/info "event: " ev)
         (recur (<! m)))))


add the time calculation; Wayde

add the time calculation; Wayde

--- src/northern_hemisphere/user.clj
+++ src/northern_hemisphere/user.clj
@@ -24,7 +24,7 @@
 (defn isUserLoggedIn [username token]
   (infinite-loop
     #(do
-       (Thread/sleep 1000 * 60 * 60 * 24)
+       (Thread/sleep (reduce * (list 1000 60 60 24)))
        (log/info (swap! counter inc))))

   (http/request-post


Pass killed test.

Pass killed test.

--- src/onyx/log/commands/common.clj
+++ src/onyx/log/commands/common.clj
@@ -359,7 +359,7 @@

 (defmethod volunteer-via-killed-job? :onyx.job-scheduler/greedy
   [old new diff state]
-  (let [peers (apply concat (vals (get-in [old :allocations (first diff)])))]
+  (let [peers (apply concat (vals (get-in old [:allocations (first diff)])))]
     (when (some #{(:id state)} (into #{} peers))
       (any-coverable-jobs? new))))


Small improvements to netty code

Small improvements to netty code

--- src/onyx/messaging/netty_tcp.clj
+++ src/onyx/messaging/netty_tcp.clj
@@ -1,5 +1,5 @@
 (ns ^:no-doc onyx.messaging.netty-tcp
-    (:require [clojure.core.async :refer [chan >!! >! <!! alts!! timeout close! go-loop dropping-buffer]]
+    (:require [clojure.core.async :refer [chan >!! >! <!! alts!! timeout close! thread go-loop dropping-buffer]]
               [com.stuartsierra.component :as component]
               [taoensso.timbre :as timbre]
               [onyx.messaging.protocol-netty :as protocol]
@@ -102,7 +102,7 @@
                         set)
         port (first (remove used-ports
                             (:netty/ports peer-site)))]
-    (assert port)
+    (assert port "Couldn't assign port - ran out of available ports.")
     {:netty/port port}))

 (defn int32-frame-decoder
@@ -170,7 +170,6 @@
       (.childOption ChannelOption/TCP_NODELAY true)
       (.childOption ChannelOption/SO_KEEPALIVE true)
       (.childHandler initializer))
-                                        ; Start bootstrap
     (let [ch (->> (InetSocketAddress. host port)
                   (.bind bootstrap)
                   (.sync)
@@ -187,7 +186,7 @@
     (handlerAdded [ctx])
     (handlerRemoved [ctx])
     (exceptionCaught [context cause]
-      (.printStackTrace cause)
+      (timbre/error cause "TCP client exception.")
       (.close context))))

 (defn client-channel-initializer [handler]
@@ -216,11 +215,13 @@
         (.channel ^ChannelFuture (.connect b host port))))))

 (defn app [daemon messenger buf-recv-ch inbound-ch release-ch retry-ch shutdown-ch]
-  (go-loop []
+  (thread
+    (loop []
           (let [[buf ch] (alts!! [buf-recv-ch shutdown-ch])]
             (when buf
               (try
                 (let [msg (protocol/read-buf (:decompress-f messenger) buf)]
+                  ;(taoensso.timbre/info "Message buf: " buf msg)
                   ;; undo retain added in server handler
                   (.release ^ByteBuf buf)
                   (let [t ^byte (:type msg)]
@@ -245,7 +246,7 @@
                 (catch Exception e
                   (taoensso.timbre/error e)
                   (throw e)))
-              (recur)))))
+              (recur))))))

 (defrecord NettyTcpSockets [peer-group]
   component/Lifecycle
@@ -276,9 +277,10 @@
     (taoensso.timbre/info "Stopping Netty TCP Sockets")
     (try
       (when-let [rs @resources]
-        (let [{:keys [shutdown-fn shutdown-ch]} rs]
+        (let [{:keys [shutdown-fn shutdown-ch app-loop]} rs]
+          (shutdown-fn)
           (close! shutdown-ch)
-          (shutdown-fn))
+          (<!! app-loop))
         (reset! resources nil))
       (catch Exception e (timbre/fatal e)))
     (assoc component :bind-addr nil :external-addr nil
@@ -331,12 +333,14 @@

 (defmethod extensions/send-messages NettyTcpSockets
   [messenger event ^Channel peer-link messages]
+  ;(taoensso.timbre/info "SENDING messages " messages)
   (.writeAndFlush peer-link
                   ^ByteBuf (protocol/build-messages-msg-buf (:compress-f messenger) messages)
                   (.voidPromise ^Channel peer-link)))

 (defmethod extensions/internal-ack-message NettyTcpSockets
   [messenger event ^Channel peer-link message-id completion-id ack-val]
+  ;(taoensso.timbre/info "SENDING ACK: " message-id ack-val)
   (.writeAndFlush peer-link
                   ^ByteBuf (protocol/build-ack-msg-buf message-id completion-id ack-val)
                   (.voidPromise ^Channel peer-link)))


Old unused fn.

Old unused fn.

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -433,17 +433,6 @@
       (catch Throwable e
         (ex-f e)))))

-(defn resolve-compression-fn-impls [opts]
-  (assoc opts
-    :onyx.peer-decompress-fn-impl
-    (if-let [f (:onyx.peer-decompress-fn opts)]
-      (operation/resolve-fn f)
-      onyx.compression.nippy/decompress)
-    :onyx.peer-compress-fn-impl
-    (if-let [f (:onyx.peer-compress-fn opts)]
-      (operation/resolve-fn f)
-      onyx.compression.nippy/compress)))
-
 (defn gc-peer-links [event state opts]
   (let [interval (arg-or-default :onyx.messaging/peer-link-gc-interval opts)
         idle (arg-or-default :onyx.messaging/peer-link-idle-timeout opts)


Remove unused resolve-compression-fn-impls fn

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -435,17 +435,6 @@
       (catch Throwable e
         (ex-f e)))))

-(defn resolve-compression-fn-impls [opts]
-  (assoc opts
-    :onyx.peer-decompress-fn-impl
-    (if-let [f (:onyx.peer-decompress-fn opts)]
-      (operation/resolve-fn f)
-      onyx.compression.nippy/decompress)
-    :onyx.peer-compress-fn-impl
-    (if-let [f (:onyx.peer-compress-fn opts)]
-      (operation/resolve-fn f)
-      onyx.compression.nippy/compress)))
-
 (defn gc-peer-links [event state opts]
   (let [interval (arg-or-default :onyx.messaging/peer-link-gc-interval opts)
         idle (arg-or-default :onyx.messaging/peer-link-idle-timeout opts)
@@ -669,7 +658,7 @@
                            :onyx.core/monitoring monitoring
                            :onyx.core/outbox-ch outbox-ch
                            :onyx.core/seal-ch seal-resp-ch
-                           :onyx.core/peer-opts (resolve-compression-fn-impls opts)
+                           :onyx.core/peer-opts opts
                            :onyx.core/max-downstream-links (arg-or-default :onyx.messaging/max-downstream-links opts)
                            :onyx.core/max-acker-links (arg-or-default :onyx.messaging/max-acker-links opts)
                            :onyx.core/fn (resolve-task-fn catalog-entry)


Clean up task lifecycle.

Clean up task lifecycle.

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -33,26 +33,6 @@
 (defn add-completion-id [event m]
   (assoc m :completion-id (:onyx.core/id event)))

-(defn tag-each-message [event]
-  (if (= (:onyx/type (:onyx.core/task-map event)) :input)
-    (let [event (update-in event
-                           [:onyx.core/batch]
-                           (fn [batch]
-                             (map (comp (partial add-completion-id event)
-                                        (partial add-acker-id event)
-                                        add-ack-value)
-                                  batch)))]
-      (doseq [raw-segment (:onyx.core/batch event)]
-        (extensions/internal-ack-message
-         (:onyx.core/messenger event)
-         event
-         (operation/peer-link event (:acker-id raw-segment) :acker-peer-site)
-         (:id raw-segment)
-         (:completion-id raw-segment)
-         (:ack-val raw-segment)))
-      event)
-    event))
-
 (defn sentinel-found? [event]
   (seq (filter (partial = :done) (map :message (:onyx.core/decompressed event)))))

@@ -65,11 +45,6 @@

 (defn drop-nth [n coll]
   (keep-indexed #(if (not= %1 n) %2) coll))
-
-(defn strip-sentinel [{:keys [onyx.core/batch onyx.core/decompressed] :as event}]
-  (if-let [k (.indexOf (map :message decompressed) :done)]
-    (merge event {:onyx.core/batch (drop-nth k batch)
-                  :onyx.core/decompressed (drop-nth k decompressed)})))

 (defn fuse-ack-vals [task parent-ack child-ack]
   (if (= (:onyx/type task) :output)
@@ -77,17 +52,22 @@
     (acker/prefuse-vals parent-ack child-ack)))

 (defn ack-messages [{:keys [onyx.core/acking-daemon onyx.core/children] :as event}]
-  (if children
-    (doseq [raw-segment (keys children)]
-      (when (:ack-val raw-segment)
-        (let [link (operation/peer-link event (:acker-id raw-segment) :acker-peer-site)]
-          (extensions/internal-ack-message
-           (:onyx.core/messenger event)
-           event
-           link
-           (:id raw-segment)
-           (:completion-id raw-segment)
-           (fuse-ack-vals (:onyx.core/task-map event) (:ack-val raw-segment) (get children raw-segment))))))))
+  (merge
+   event
+   (if children
+     (do
+       (doseq [raw-segment (keys children)]
+         (when (:ack-val raw-segment)
+           (let [link (operation/peer-link event (:acker-id raw-segment) :acker-peer-site)]
+             (extensions/internal-ack-message
+              (:onyx.core/messenger event)
+              event
+              link
+              (:id raw-segment)
+              (:completion-id raw-segment)
+              (fuse-ack-vals (:onyx.core/task-map event) (:ack-val raw-segment) (get children raw-segment))))))
+       {})
+     {})))

 (defn segments->ack-values [event segments]
   (if (= :output (:onyx/type (:onyx.core/task-map event)))
@@ -99,98 +79,109 @@
         (= to-add :none) #{}
         :else (clojure.set/union (into #{} all) (into #{} to-add))))

-(defn choose-output-paths [flow-conditions event new downstream]
-  (if (seq flow-conditions)
-    (reduce
-     (fn [{:keys [paths exclusions] :as all} entry]
-       (if ((:flow/predicate entry) [event new])
-         (if (:flow/short-circuit? entry)
-           (reduced {:paths (join-output-paths paths (:flow/to entry) downstream)
-                     :exclusions (clojure.set/union (into #{} exclusions) (into #{} (:flow/exclude-keys entry)))})
-           {:paths (join-output-paths paths (:flow/to entry) downstream)
-            :exclusions (clojure.set/union (into #{} exclusions) (into #{} (:flow/exclude-keys entry)))})
-         all))
-     {:paths #{} :exclusions #{}}
-     flow-conditions)
-    {:paths downstream}))
-
-(defn output-paths
+(defn route-output-paths
   [{:keys [onyx.core/serialized-task onyx.core/compiled-flow-conditions] :as event}]
   (merge
    event
    {:onyx.core/result-paths
-    (map
-     (fn [segment]
-       (choose-output-paths compiled-flow-conditions event segment
-                            (keys (:egress-ids serialized-task))))
-     (:onyx.core/results event))}))
+    (let [downstream (keys (:egress-ids serialized-task))]
+      (map
+       (fn [segment]
+         (reduce
+          (fn [{:keys [paths exclusions] :as all} entry]
+            (if ((:flow/predicate entry) [event segment])
+              (if (:flow/short-circuit? entry)
+                (reduced {:paths (join-output-paths paths (:flow/to entry) downstream)
+                          :exclusions (clojure.set/union (into #{} exclusions) (into #{} (:flow/exclude-keys entry)))})
+                {:paths (join-output-paths paths (:flow/to entry) downstream)
+                 :exclusions (clojure.set/union (into #{} exclusions) (into #{} (:flow/exclude-keys entry)))})
+              all))
+          {:paths #{} :exclusions #{}}
+          compiled-flow-conditions)
+         {:paths downstream})
+       (:onyx.core/results event)))}))

 (defn inject-batch-resources [event]
   (let [cycle-params {:onyx.core/lifecycle-id (java.util.UUID/randomUUID)}]
     (merge event cycle-params (l-ext/inject-batch-resources* event))))

 (defn read-batch [event]
-  (let [rets (tag-each-message (merge event (p-ext/read-batch event)))]
-    (when (= (:onyx/type (:onyx.core/task-map event)) :input)
-      (doseq [m (:onyx.core/batch rets)]
-        (go (try (<! (timeout (or (:onyx/pending-timeout (:onyx.core/task-map event)) 60000)))
-                 (when (p-ext/pending? rets (:id m))
-                   (p-ext/retry-message event (:id m)))
-                 (catch Exception e
-                   (taoensso.timbre/warn e))))))
-    rets))
+  (merge event (p-ext/read-batch event)))
+
+(defn tag-messages [event]
+  (merge
+   event
+   (if (= (:onyx/type (:onyx.core/task-map event)) :input)
+     (let [event (update-in event
+                            [:onyx.core/batch]
+                            (fn [batch]
+                              (map (comp (partial add-completion-id event)
+                                         (partial add-acker-id event)
+                                         add-ack-value)
+                                   batch)))]
+       (doseq [raw-segment (:onyx.core/batch event)]
+         (extensions/internal-ack-message
+          (:onyx.core/messenger event)
+          event
+          (operation/peer-link event (:acker-id raw-segment) :acker-peer-site)
+          (:id raw-segment)
+          (:completion-id raw-segment)
+          (:ack-val raw-segment)))
+       event)
+     event)))
+
+(defn start-message-timeout-monitors [event]
+  (when (= (:onyx/type (:onyx.core/task-map event)) :input)
+    (doseq [m (:onyx.core/batch event)]
+      (go (try (<! (timeout (or (:onyx/pending-timeout (:onyx.core/task-map event)) 60000)))
+               (when (p-ext/pending? event (:id m))
+                 (p-ext/retry-message event (:id m)))
+               (catch Exception e
+                 (taoensso.timbre/warn e))))))
+  event)

 (defn decompress-batch [event]
-  ;; TODO: Messages are already decompressed, need to rework the interface.
-  (let [rets (merge event {:onyx.core/decompressed (:onyx.core/batch event)})]
-    (if (sentinel-found? rets)
-      (do (if (p-ext/drained? rets)
-            (complete-job rets)
-            (p-ext/retry-message rets (sentinel-id rets)))
-          (strip-sentinel rets))
-      rets)))
-
-(defn apply-fn* [{:keys [onyx.core/batch onyx.core/decompressed] :as event} batch-f single-f]
-  (if (seq decompressed)
-    (let [batch-result (batch-f event)
-          rets
-          (merge event
-                 (reduce
-                  (fn [rets [raw thawed]]
-                    (let [new-segments (single-f event thawed batch-result)
-                          new-ack-vals (map (fn [x] (acker/gen-ack-value)) new-segments)
-                          tagged (apply acker/prefuse-vals new-ack-vals)
-                          results (map (fn [segment ack-val]
-                                         {:id (:id raw)
-                                          :acker-id (:acker-id raw)
-                                          :completion-id (:completion-id raw)
-                                          :message segment
-                                          :ack-val ack-val})
-                                       new-segments new-ack-vals)]
-                      (-> rets
-                          (update-in [:onyx.core/results] concat results)
-                          (assoc-in [:onyx.core/children raw] tagged))))
-                  {:onyx.core/results [] :onyx.core/children {}}
-                  (map vector batch decompressed)))]
-      (ack-messages rets)
-      (merge rets (output-paths rets)))
-    (merge event {:onyx.core/results []})))
-
-(defn apply-fn [event]
-  (if (:onyx/batch? (:onyx.core/task-map event))
-    (apply-fn*
-     event
-     (fn [{:keys [onyx.core/decompressed] :as event}]
-       (let [new-segments (p-ext/apply-fn event (map :message decompressed))]
-         (if (sequential? new-segments) new-segments (vector new-segments))))
-     (fn [event thawed batch-result]
-       batch-result))
-    (apply-fn*
-     event
-     (fn [_] nil)
-     (fn [event thawed batch-result]
-       (let [new-segments (p-ext/apply-fn event (:message thawed))]
-         (if (sequential? new-segments) new-segments (vector new-segments)))))))
+  (merge event {:onyx.core/decompressed (:onyx.core/batch event)}))
+
+(defn try-complete-job [event]
+  (when (sentinel-found? event)
+    (if (p-ext/drained? event)
+      (complete-job event)
+      (p-ext/retry-message event (sentinel-id event))))
+  event)
+
+(defn strip-sentinel [{:keys [onyx.core/batch onyx.core/decompressed] :as event}]
+  (merge
+   event
+   (when-let [k (.indexOf (map :message decompressed) :done)]
+     {:onyx.core/batch (drop-nth k batch)
+      :onyx.core/decompressed (drop-nth k decompressed)})))
+
+(defn build-next-segment [prev-seg next-seg]
+  {:id (:id prev-seg)
+   :acker-id (:acker-id prev-seg)
+   :completion-id (:completion-id prev-seg)
+   :message next-seg
+   :ack-val (acker/gen-ack-value)})
+
+(defn collect-next-segments [event seg]
+  (let [segments (p-ext/apply-fn event (:message seg))]
+    (if (sequential? segments) segments (vector segments))))
+
+(defn apply-fn [{:keys [onyx.core/batch onyx.core/decompressed] :as event}]
+  (merge
+   event
+   (reduce
+    (fn [rets thawed]
+      (let [segments (collect-next-segments event thawed)
+            results (map (partial build-next-segment thawed) segments)
+            tagged (apply acker/prefuse-vals (map :ack-val results))]
+        (-> rets
+            (update-in [:onyx.core/results] concat results)
+            (assoc-in [:onyx.core/children thawed] tagged))))
+    {:onyx.core/results []
+     :onyx.core/children {}}
+    decompressed)))

 (defn compress-batch [event]
   (merge event (p-ext/compress-batch event)))
@@ -228,26 +219,36 @@
 (defn only-relevant-branches [flow task]
   (filter #(= (:flow/from %) task) flow))

-(defn compile-flow-conditions [flow-conditions task-name]
-  (let [conditions (only-relevant-branches flow-conditions task-name)]
+(defn compile-flow-conditions [flow-conditions task-name f]
+  (let [conditions (filter f (only-relevant-branches flow-conditions task-name))]
     (map
      (fn [condition]
        (assoc condition :flow/predicate (build-pred-fn (:flow/predicate condition) condition)))
-          conditions)))
+     conditions)))
+
+(defn compile-fc-norms [flow-conditions task-name]
+  (compile-flow-conditions flow-conditions task-name (comp not :flow/thrown-exception?)))
+
+(defn compile-fc-exs [flow-conditions task-name]
+  (compile-flow-conditions flow-conditions task-name :flow/thrown-exception?))

 (defn run-task-lifecycle [init-event kill-ch ex-f]
   (try
-    (loop [event init-event]
-      (when (first (alts!! [kill-ch] :default true))
-        (-> event
-            (inject-batch-resources)
-            (read-batch)
-            (decompress-batch)
-            (apply-fn)
-            (compress-batch)
-            (write-batch)
-            (close-batch-resources))
-        (recur init-event)))
+    (while (first (alts!! [kill-ch] :default true))
+      (-> init-event
+          (inject-batch-resources)
+          (read-batch)
+          (tag-messages)
+          (decompress-batch)
+          (start-message-timeout-monitors)
+          (try-complete-job)
+          (strip-sentinel)
+          (apply-fn)
+          (ack-messages)
+          (route-output-paths)
+          (compress-batch)
+          (write-batch)
+          (close-batch-resources)))
     (catch Exception e
       (ex-f e))))

@@ -281,7 +282,8 @@
                            :onyx.core/catalog catalog
                            :onyx.core/workflow (extensions/read-chunk log :workflow job-id)
                            :onyx.core/flow-conditions flow-conditions
-                           :onyx.core/compiled-flow-conditions (compile-flow-conditions flow-conditions (:name task))
+                           :onyx.core/compiled-norm-fcs (compile-fc-norms flow-conditions (:name task))
+                           :onyx.core/compiled-ex-fcs (compile-fc-exs flow-conditions (:name task))
                            :onyx.core/task-map catalog-entry
                            :onyx.core/serialized-task task
                            :onyx.core/params (resolve-calling-params catalog-entry  opts)


finished up swing repl

finished up swing repl

--- src/overtone/gui/repl.clj
+++ src/overtone/gui/repl.clj
@@ -15,8 +15,9 @@
    )

   (:import
-   (java.awt.BorderLayout)
-   (javax.swing JEditorPane JScrollPane JPanel SwingUtilities)
+   (java.awt Color BorderLayout Dimension)
+   (javax.swing JEditorPane JFrame JScrollPane JPanel SwingUtilities AbstractAction)
+   (javax.swing.border LineBorder)
    )

   (:require [clojure.main :as r])
@@ -25,7 +26,7 @@
   (:use [clojure.stacktrace :only (e)])

   (:use (overtone.core time-utils sc ugen synth synthdef envelope event)
-        (overtone.gui utils)
+        (overtone.gui swing)
         (overtone.music rhythm pitch tuning))

   (:use clj-scenegraph.core))
@@ -284,75 +285,73 @@
     (fn [pair] (-> pair set (filter string) count (mod 2) zero?))
     pairs)))

-(comment
-  (defn repl []
-    (let [group (sg-group)
-          history (javax.swing.JEditorPane.)
-          input (javax.swing.JEditorPane.)
-          scroll (JScrollPane. history)
-
-          println-history #(EDT (let [ doc (.getDocument history)
-                                      length (.getLength doc)]
-                                  (.insertString doc length % nil)))
-
-          bb (CircularByteBuffer.)
-          ps (java.io.PrintStream. (.getOutputStream bb) true)
-          cr (ConsoleReader. (.getInputStream bb) (PrintWriter. (System/out)))
-          ]
-
-      (EDT (.setEditable input false)
-           (.setEditable history false)
-           (.setVerticalScrollBarPolicy scroll (JScrollPane/VERTICAL_SCROLLBAR_ALWAYS))
-           (.setHorizontalScrollBarPolicy scroll (JScrollPane/HORIZONTAL_SCROLLBAR_NEVER)))
-
-      (doto group
-        (add! (sg-component scroll 500 300))
-        (add! (translate 0 305 (sg-component input 500 25))))
-
-      (doto (.getKeymap input)
-        (.addActionForKeyStroke
-         (javax.swing.KeyStroke/getKeyStroke (java.awt.event.KeyEvent/VK_ENTER) 0)
-         (proxy [javax.swing.AbstractAction] [] (actionPerformed [evt]  (let [text (.getText input)]
-                                                                          (if (and (not (empty? text))
-                                                                                (balanced? text))
-                                                                            (do (event ::repl-write :text text)
-                                                                                (EDT
-                                                                                (.setText input "")
-                                                                                (.requestFocus input)))))))))
-
-
-
-      (on ::repl-print #(println-history (:text %) ))
-
-      (on ::repl-ready #((println-history "repl ready\r\n")
-                         (event ::repl-write :text "(in-ns 'user)\r\n(use 'overtone.live)")
-                         (EDT (.setEditable input true))))
-
-      (on ::repl-exited #((println-history "repl exited\r\n")
-                          (EDT (.setEditable input false))))
-
-      (if (repl-thread-running?)
-        (do (EDT (.setEditable input true))
-            (println-history "repl thread allready running\r\n"))
-        (start-repl-thread))
+(defn repl []
+  (let [group (sg-group)
+        ]

-      group)))
-
+    group))

 (defn repl-panel []
   (let [panel (javax.swing.JPanel.)

-        history (javax.swing.JEditorPane.)
-        input (javax.swing.JEditorPane.)
-        scroll (javax.swing.JScrollPane. history)
+        history (JEditorPane.)
+        input (JEditorPane.)
+        scroll (JScrollPane. history)

         println-history #(in-swing (let [ doc (.getDocument history)
                                          length (.getLength doc)]
                                      (.insertString doc length % nil)))
-
+        layout (BorderLayout.)
         ]

-
-
+    (in-swing (.setEditable input false)
+              (.setEditable history false)
+              (.setVerticalScrollBarPolicy scroll (JScrollPane/VERTICAL_SCROLLBAR_ALWAYS))
+              (.setHorizontalScrollBarPolicy scroll (JScrollPane/HORIZONTAL_SCROLLBAR_NEVER))
+
+              (.setLayout panel layout)
+              (.add panel scroll BorderLayout/CENTER)
+              (.add panel input BorderLayout/SOUTH)
+              (.setBorder history (LineBorder. Color/BLACK))
+              (.setBorder input (LineBorder. java.awt.Color/BLACK))
+              (.setMinimumSize input (Dimension. 100 30))
+              (.setMinimumSize history (Dimension. 100 100))
+
+              (.doLayout layout))
+
+
+    (doto (.getKeymap input)
+      (.addActionForKeyStroke
+       (javax.swing.KeyStroke/getKeyStroke (java.awt.event.KeyEvent/VK_ENTER) 0)
+       (proxy [javax.swing.AbstractAction] [] (actionPerformed [evt]  (let [text (.getText input)]
+                                                                        (if (and (not (empty? text))
+                                                                                (balanced? text))
+                                                                          (do (event ::repl-write :text text)
+                                                                              (in-swing
+                                                                               (.setText input "")
+                                                                               (.requestFocus input)))))))))
+
+    (on ::repl-print #(println-history (:text %) ))
+
+    (on ::repl-ready #((println-history "repl ready\r\n")
+                       (event ::repl-write :text "(in-ns 'user)\r\n(use 'overtone.live)")
+                       (in-swing (.setEditable input true))))
+
+    (on ::repl-exited #((println-history "repl exited\r\n")
+                        (in-swing (.setEditable input false))))
+
+    (if (repl-thread-running?)
+      (do (in-swing (.setEditable input true))
+          (println-history "repl thread allready running\r\n"))
+      (start-repl-thread))
+
+    (in-swing (.requestFocus input))
+
     panel))
-
+
+
+(def frame (JFrame.))
+(.add frame (repl-panel))
+(.setVisible frame true)
+(.pack frame)
+


add a route to scale-to-width-down

add a route to scale-to-width-down

--- src/vignette/http/routes.clj
+++ src/vignette/http/routes.clj
@@ -76,6 +76,17 @@
                   :thumbnail-mode "scale-to-width"
                   :width size-regex}))

+(def scale-to-width-down-route
+  (route-compile "/:wikia:image-type/:top-dir/:middle-dir/:original/revision/:revision/:thumbnail-mode/:width"
+                 {:wikia wikia-regex
+                  :image-type image-type-regex
+                  :top-dir top-dir-regex
+                  :middle-dir middle-dir-regex
+                  :original original-regex
+                  :revision revision-regex
+                  :thumbnail-mode "scale-to-width-down"
+                  :width size-regex}))
+
 (defn create-request-handlers
   "Creates request handlers for a given route for GET & HEAD using the given route and
   map generation function."


Refactor for idiom

Refactor for idiom

--- src/deadman/core.clj
+++ src/deadman/core.clj
@@ -32,7 +32,7 @@
       (send-sms number message))))

 (defn maybe-kill-thread [thread]
-  (if thread
+  (when thread
     (.stop thread)))

 ; timers become {:data <what they PUT> :timer <the timer thing>}
@@ -53,7 +53,7 @@

 (defn get-timer [{rp :route-params}]
   (let [timer (get @timers (:id rp))]
-    (if timer {:body (:data timer)}
+    (when timer {:body (:data timer)}
               (route/not-found {:message "Not found"}))))

 (defn reflect [request]


Adding some comments to delegates

Adding some comments to delegates

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -149,12 +149,17 @@
   (fn [e]
     (create-wishlist-rem)))

+; When wishlist title is changed and not empty, update the title on remote.
 (delegate $header wishlist-title :change
   (fn [e]
     (this-as me
       (when-not (empty? (val ($ me)))
         (update-wishlist-title-rem)))))

+; When the value has changed (we keep track of this using the JQuery data
+; object), check whether or not this is the last wish on the page and
+; update or create accordingly. Also remove wishes with empty descriptions
+; unless they are children of a li.last.
 (delegate $content ".description" :change
   (fn [e]
     (this-as me


create-wish-last-rem

create-wish-last-rem

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -87,6 +87,12 @@
     (letrem [neu (create-wish clean)]
       (fn [e] nil))))

+(defn create-wish-last-rem [$elem]
+  (let [wish (wish-from-elem $elem)
+        clean (dissoc wish :id)]
+    (letrem [neu (create-wish clean)]
+      (read-wishlist-rem (get-path)))))
+

 ; DELEGATES


NS Fiddlings

NS Fiddlings

--- src/doctopus/web.clj
+++ src/doctopus/web.clj
@@ -1,22 +1,23 @@
 (ns doctopus.web
-  (:require [bidi.ring :as bidi :refer [->Resources]]
+  (:require [cheshire.core :as json]
             [clojure.java.io :as io]
-            [doctopus.configuration :refer [server-config]]
-            [doctopus.doctopus :refer [load-routes bootstrap-heads list-heads]]
-            [doctopus.template :as templates]
-            [doctopus.files.predicates :refer [html?]]
+            [clojure.string :as str]
+            [clojure.walk :refer [keywordize-keys]]
+            [compojure.core :refer [routes defroutes context GET POST ANY]]
+            [doctopus.configuration :refer [server-config docs-uri-prefix]]
             [doctopus.db :as db]
             [doctopus.db.schema :as schema]
+            [doctopus.doctopus :refer [load-routes bootstrap-heads list-heads]]
+            [doctopus.files.predicates :refer [html?]]
+            [doctopus.template :as templates]
             [org.httpkit.server :as server]
+            [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
             [ring.middleware.json :refer [wrap-json-body]]
-            [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
             [ring.middleware.reload :as reload]
+            [ring.middleware.resource :refer [wrap-resource]]
             [ring.middleware.stacktrace :as trace]
             [ring.util.response :as ring-response]
-            [taoensso.timbre :as log]
-            [cheshire.core :as json]
-            [clojure.walk :refer [keywordize-keys]]
-            [clojure.string :as str])
+            [taoensso.timbre :as log])
   (:import [doctopus.doctopus Doctopus]))

 (defn wrap-error-page


Get a basic deadman switch working that only prints out a message

--- src/deadman/core.clj
+++ src/deadman/core.clj
@@ -7,19 +7,39 @@

 (def timers (atom {}))

-(defn put-timer [key data]
-  (swap! timers (fn [map] (assoc map key data)))
-  data)
+(defn send-sms [number message]
+  (prn [number message])
+  nil)
+
+(defn build-timer-thread [{timeout "timeout", number "number", message "message", :as timer-data}]
+  (Thread.
+    (fn []
+      (Thread/sleep timeout)
+      (send-sms number message))))
+
+(defn maybe-kill-thread [thread]
+  (if thread
+    (.stop thread)))
+
+; timers become {:data <what they PUT> :timer <the timer thing>}
+(defn build-timer [new-timer old-timer]
+  (maybe-kill-thread (:thread old-timer))
+  (let [thread (build-timer-thread new-timer)]
+    (.start thread)
+    {:data new-timer :thread thread}))
+
+(defn put-timer [key new-timer]
+  (swap! timers
+         (fn [map]
+             (update-in map [key] (partial build-timer new-timer))))
+  new-timer)

 (defn handle-timer-request [{body :body rp :route-params :as request}]
-  {:status 200
-   :headers {"Content-Type" "application/json"}
-   :body (put-timer (:id rp) body)})
+  {:body (put-timer (:id rp) body)})

 (defn get-timer [{rp :route-params}]
   (let [timer (get @timers (:id rp))]
-    (if timer {:status 200
-               :body timer}
+    (if timer {:body (:data timer)}
               (route/not-found {:message "Not found"}))))

 (defn reflect [request]
@@ -29,7 +49,7 @@
   (POST "/timers/:id" request (reflect request))
   (PUT "/timers/:id" request (handle-timer-request request))
   (GET "/timers/:id" request (get-timer request))
-  (GET "/timers" request (fn [r] timers))
+  (GET "/timers" request (fn [r] @timers))
   (route/not-found {:message "Not found"}))

 (def app
@@ -44,6 +64,5 @@
 (run-jetty app {:port 3000})
 )

-; Need a service to accept a PUT
-; PUT /timer/<uid>
-; form vars: timeout, action
+; TODO: persist/load timers
+; TODO: error handling for missing params


Fixed bung if.

Fixed bung if.

--- src/depends/core.clj
+++ src/depends/core.clj
@@ -41,32 +41,33 @@
           help                  (:help  options)]
       (if (or help (nil? source))
         (println (str banner "\n Args\t\t\tDesc\n ----\t\t\t----\n source\t\t\tDetermines the dependencies of all class files in the given location (which may be a .class file, a directory or an archive). Must be provided.\n"))
-        (log/info "Starting...")
+        (do
+          (log/info "Starting...")

-        ; Look at the crap TrueVFS makes us do, just to add support for .AMP files (ZIP files under another name) #fail
-        (.setArchiveDetector (net.java.truevfs.access.TConfig/current)
-                             (net.java.truevfs.access.TArchiveDetector. "zip|jar|war|ear|amp"
-                                                                        (net.java.truevfs.comp.zipdriver.ZipDriver.)))
-        (log/info (str "Calculating dependencies from " source "..."))
-        (let [dependencies (dr/classes-info source)]
-          (if edn
-            (do
-              (log/info (str "Writing dependencies to stdout as EDN..."))
-              (pprint dependencies)))   ; Is this the right way to emit EDN?
-          (if json
-            (do
-              (log/info (str "Writing dependencies to stdout as JSON..."))
-              (json/pprint dependencies :escape-unicode false)))
-          (if neo4j-coords
-            (do
-              (log/info (str "Writing dependencies to Neo4J..."))
-              (neo/write-dependencies! neo4j-coords dependencies)))
-;            (if svg
-;              (do
-;                (log/info (str "Writing dependencies to Neo4J..."))
-;                (svg/write-dependencies dependencies)))
-          (log/info "Complete.")
-          nil)))
+          ; Look at the crap TrueVFS makes us do, just to add support for .AMP files (ZIP files under another name) #fail
+          (.setArchiveDetector (net.java.truevfs.access.TConfig/current)
+                               (net.java.truevfs.access.TArchiveDetector. "zip|jar|war|ear|amp"
+                                                                          (net.java.truevfs.comp.zipdriver.ZipDriver.)))
+          (log/info (str "Calculating dependencies from " source "..."))
+          (let [dependencies (dr/classes-info source)]
+            (if edn
+              (do
+                (log/info (str "Writing dependencies to stdout as EDN..."))
+                (pprint dependencies)))   ; Is this the right way to emit EDN?
+            (if json
+              (do
+                (log/info (str "Writing dependencies to stdout as JSON..."))
+                (json/pprint dependencies :escape-unicode false)))
+            (if neo4j-coords
+              (do
+                (log/info (str "Writing dependencies to Neo4J..."))
+                (neo/write-dependencies! neo4j-coords dependencies)))
+;              (if svg
+;                (do
+;                  (log/info (str "Writing dependencies to Neo4J..."))
+;                  (svg/write-dependencies dependencies)))
+            (log/info "Complete.")
+            nil))))
     (catch Exception e
       (log/error e)
       (aviso/write-exception e))))


Add funs to enable a persistent list of tasks.

Add a fun that gives a ref to a persistent list.
Add a fun that allows you to add a new task to the persistent list.

--- src/todo_repl_webapp/handler.clj
+++ src/todo_repl_webapp/handler.clj
@@ -32,16 +32,24 @@
   (html [:h1 "Eval"]
         [:h2 x]))

+(def *tasks-ref* (ref []))
+(defn tasks [] (deref *tasks-ref*))
+(defn add-new-task [x]
+  (dosync (alter *tasks-ref* #(cons
+                                (todo/new-task-better x)
+                                %1))))
+(defn add-to-tasks [x]
+  (dosync (alter *tasks-ref* #(cons x %1))))
+
 (defroutes app-routes
   (GET "/" [] (do (println "get /")
                   (home-page)))
   (POST "/eval" [evalInput]
     (do (println "/eval " evalInput)
-        (println "evals to: "
-                 (binding [*ns* (find-ns 'todo-repl-webapp.handler)]
-                          (load-string evalInput)))
-        (eval-page (str (binding [*ns* (find-ns 'todo-repl-webapp.handler)]
-                            (load-string evalInput))))))
+        (binding [*ns* (find-ns 'todo-repl-webapp.handler)]
+          (let [result (load-string evalInput)]
+            (println "evals to: " result)
+            (eval-page (str result))))))
   (route/resources "/")
   (route/not-found "Not Found"))


Fixup donate link

Fixup donate link

--- src/grimoire/api.clj
+++ src/grimoire/api.clj
@@ -308,7 +308,7 @@
   - :column   -> integer being colunm number
   - :line     -> integer being line number
   - :file     -> string being file name
-  - :redirect -> string being symbol name for implementing macro. only for {:type :sentinel}
+  - :target   -> string being symbol name for implementing macro. only for {:type :sentinel}
   - :type     -> one of #{:macro :fn :var :special :sentinel}

   Expected keys for namespaces:


Updating remotes to use sql backend

Updating remotes to use sql backend

--- src/wishlistd/views/wishlist.clj
+++ src/wishlistd/views/wishlist.clj
@@ -1,22 +1,10 @@
 (ns wishlistd.views.wishlist
   (:require [wishlistd.views.common :as common]
-            [wishlistd.json :as response]
-            [wishlistd.models.redis :as model])
+            [wishlistd.models.sql :as model])
   (:use noir.fetch.remotes))

 (defn main-page []
   (common/new-layout))
-
-(defn create-wishlist-json [wishlist]
-  (let [wishlist (model/create-wishlist wishlist)]
-    (response/json wishlist)))
-
-(defn get-wishlist-json [code]
-  (let [wishlist (model/read-wishlist code)]
-    (response/json wishlist)))
-
-(defn update-wishlist-json [wishlist]
-  (response/json (model/update-wishlist wishlist)))

 (defremote create-wishlist [wishlist]
   (model/create-wishlist wishlist))
@@ -26,3 +14,9 @@

 (defremote read-wishlist [code]
   (model/read-wishlist code))
+
+(defremote update-wish [wish]
+  (model/update-wish wish))
+
+(defremote delete-wish [id]
+  (model/delete-wish id))


Fix in ifup plugin

Fix in ifup plugin

Signed-off-by: trauf <b8cc4d695074a5c55e7046612ecaa2660307ac88@plumgrid.com>


Resolver can return a promise of a channel

--- test-cljs/frontend/test_send.cljs
+++ test-cljs/frontend/test_send.cljs
@@ -303,16 +303,18 @@
   (implements? async-impl/ReadPort x))

 (defn- pipe-values
-  "Pipes value(s) from `from` to `to`, returning `to`. If `from` is a channel,
-  pipes as with core.async/pipe. If `from` is a promise, puts the promise's
-  value on `to` and closes it. If `from` is a value, puts that value on `to` and
-  closes it."
+  "Pipes value(s) from `from` to `to`, returning `to`. If `from` is a channel or
+  a promise of a channel, pipes to that channel as with core.async/pipe. If
+  `from` is a value or a promise of a value, puts that value on `to` and closes
+  `to`."
   [from to]
-  (if (read-port? from)
-    (async/pipe from to)
-    (do
-      (p/then from #(doto to (put! %) (close!)))
-      to)))
+  (p/then
+   from
+   (fn [v]
+     (if (read-port? v)
+       (async/pipe v to)
+       (doto to (put! v) (close!)))))
+  to)

 (defn resolve* [context mapping children]
   (async/pipe
@@ -381,15 +383,13 @@

    :user/favorite-fellow-user
    (fn [context ast]
-     (let [c (chan)]
-       (p/alet [get-user (get-in context [:apis :get-user])
-                user (p/await (get-user {:name (:user/name context)}))]
-         (resolve* (assoc context
-                          :channel c
-                          :user/name (:favorite-fellow-user-name user))
-                   resolvers
-                   (:children ast)))
-       c))})
+     (p/alet [get-user (get-in context [:apis :get-user])
+              user (p/await (get-user {:name (:user/name context)}))]
+       (resolve* (assoc context
+                        :channel (chan)
+                        :user/name (:favorite-fellow-user-name user))
+                 resolvers
+                 (:children ast))))})

 (deftest new-thing-works
   (async done


Backfill tests for new hint option

Backfill tests for new hint option

--- test/cljc/snippets/rendering.cljc
+++ test/cljc/snippets/rendering.cljc
@@ -6,7 +6,9 @@
      (:use-macros [quil.snippet :only [defsnippet]])))

 (defsnippet hint {:renderer :p3d}
-  (let [hints [:enable-depth-test
+  (let [hints [:enable-async-saveframe
+               :disable-async-saveframe
+               :enable-depth-test
                :disable-depth-test
                :enable-depth-sort
                :disable-depth-sort


docstrings

docstrings

--- src/euler/helper.clj
+++ src/euler/helper.clj
@@ -1,12 +1,12 @@
 (ns euler.helper)

 (defn factor?
-  "*Int, Int -> Bool*
+  "**factor? :: Int, Int -> Bool**:
   Predicate that tests whether the divisor evenly divides the dividend."
   [dividend divisor] (zero? (mod dividend divisor)))

 (defn factor-any
-  "*[Int] -> Int -> Bool*
+  "**factor-any :: [Int] -> (Int -> Bool)**:
   Returns a predicate that tests whether its argument
   can be evenly divided by any of the divisors."
   [& divisors]
@@ -14,12 +14,12 @@
     (boolean (some #(factor? argument %) divisors))))

 (defn divisors
-  "*Int -> [Int]*
+  "**divisors :: Int -> [Int]**:
   The divisors of n (excluding n)"
   [n] (filter factor? (range 1 n)))

 (defn factors
-  "*Int -> [Int]*
+  "**factors :: Int -> [Int]**
   Returns all numbers that evenly divide n."
   ([n] (factors n 1))
   ([n start]
@@ -41,28 +41,30 @@
            ;; by (fac(n))^2
            (Math/pow (factorial n) 2))))

-(defn triangle
-  "*Int -> Int*
+(defn triangle [n]
+  "**triangle :: Int -> Int**
   Computes the nth triangle number.
   A triangle number is generated by adding the natural numbers up to n.
   Shortcut using Gauss technique."
-  [n] (/ (* n (inc n)) 2))
-
-(defn proper-divisors
-  "Returns the list of proper divisors of n, excluding n."
-  [n] (take-while #(not= n %) (factors n)))
+  (/ (* n (inc n)) 2))
+
+(defn proper-divisors [n]
+  "**proper-divisors :: Int -> [Int]**
+  Returns the list of proper divisors of n, excluding n."
+  (take-while #(not= n %) (factors n)))

 (def fibs
-  "*(Int)*
+  "**fibs :: (Int)**
   Lazy sequence of all Fibonacci numbers. Using BigIntegers."
   (lazy-cat [0N 1N] (map + (rest fibs) fibs)))

-(defn next-collatz
-  [n] (if (even? n) (bit-shift-right n 1) (inc (* 3 n))))
-
-(defn collatz
+(defn next-collatz [n]
+  "computes the next number of the collatz sequence."
+  (if (even? n) (bit-shift-right n 1) (inc (* 3 n))))
+
+(defn collatz [n]
   "Lazy seq of Collatz sequence of n."
-  [n] (cons n
+  (cons n
         (if (= n 1) '()
             (collatz (next-collatz n)))))

@@ -72,10 +74,9 @@
               (inc (memo-collatz c (next-collatz n))))
             n)))

-(defn parse-grid
-  "*String -> [[Int]]*
+(defn parse-grid [grid-str dimension]
+  "**parse-grid :: String -> [[Int]]**
   Converts a string into a dimension x dimension vector of integers."
-  [grid-str dimension]
   (vec (map vec (partition dimension (map #(Integer. %) (.split grid-str "\\s+"))))))

 (defn product
@@ -97,7 +98,7 @@
                       (reduce nth grid yx))))))

 (def primes
-  "*[Int]*
+  "**primes :: [Int]**
   Lazy stream of prime numbers, generated by the sieve of Eratosthenes algorithm.
   Internally stores in a hastable the next composite number corresponding to the prime number.
   Taken from http://voidmainargs.blogspot.de/2010/12/lazy-sieve-eratosthenes-in-scala-and.html"
@@ -118,10 +119,9 @@
                        (next-prime (+ x 2) (assoc sieve (* x x) (* x 2))))))))]
     (cons 2 (lazy-seq (next-prime 3 {})))))

-(defn prime?
-  "*Int -> Bool*
+(defn prime? [n]
+  "**prime? :: Int -> Bool**
 	Checks whether a given number n is a prime number."
-  [n]
   (and (< 1 n)
     (not-any? factor?
       (take-while #(<= (* % %) n) primes))))
@@ -139,10 +139,9 @@
       ;; no match - next iteration
      :else (get-primes n (rest ps) acc))))

-(defn max-prime
-  "*Int, [Int] -> Int*
+(defn max-prime [n ps]
+  "**max-prime :: Int, [Int] -> Int**
   Given a number n and a list of prime numbers ps, returns the largest prime factor of n."
-  [n ps]
   ;; local variable - head of prime list
   (let [div (first ps)]
     (cond
@@ -153,7 +152,7 @@
       :else (max-prime n (rest ps)))))

 (defn prime-factors
-  "*Int -> [Int]*
+  "** prime-factors :: Int -> [Int]**
 Given a number, returns the list of prime factors of n.
 Example: (prime-factors 12) => (2 2 3)"
   ([n] (prime-factors n [] primes))
@@ -163,16 +162,15 @@
      (factor? num (first ps)) (prime-factors (/ num (first ps)) (conj factors (first ps)) ps)
      :else (prime-factors num factors (rest ps)))))

-(defn palindrome?
-  "*Int -> Bool*
+(defn palindrome? [n]
+  "**palindrome? :: Int -> Bool**
 	Checks whether the given number n is a palindrome.
 	Uses reversed string comparison"
-  [n] (= (str n) (clojure.string/reverse (str n))))
-
-(defn least-common-multiple
-  "*[Int] -> Int*
-	Computes the smallest number divisible by all of the given input numbers."
-  [input]
+  (= (str n) (clojure.string/reverse (str n))))
+
+(defn least-common-multiple [input]
+  "**least-common-multiple :: [Int] -> Int**
+  Computes the smallest number divisible by all of the given input numbers."
   (->> input
        (map #(frequencies (get-primes %)))
        (apply merge-with max)
@@ -180,29 +178,28 @@
        (reduce *)
        (int)))

-(defn sum-of-factors
+(defn sum-of-factors [n]
   "The sum of all proper divisors, excluding  n."
-  [n] (reduce + 1 (factors n 2))) ; include 1, but ignore n
-
-(defn amicable?
-  [a]
+  (reduce + 1 (factors n 2))) ; include 1, but ignore n
+
+(defn amicable? [a]
   (let [b (sum-of-factors a)]
     (if (and (not= a b) (= a (sum-of-factors b)))
       [a b] ())))

-(defn abundant?
-  "*Int -> Bool*
+(defn abundant? [n]
+  "**abundant? :: Int -> Bool**
   Checks whether the sum of the factors of n is greater than n."
-  [n] (< n (reduce + (divisors n))))
-
-(defn sum-of-abundants?
-  "Int, Set[Number] -> Boolean - are there two elements in abundants which sum is i?"
-  [i abundants] (some (fn [a] (abundants (- i a))) abundants))
-
-(defn truncate
-  "*Int, Int -> Int*
+  (< n (reduce + (divisors n))))
+
+(defn sum-of-abundants? [i abundants]
+  "**su-of-abundants? :: Int, Set[Number] -> Boolean**
+  Are there two elements in abundants which sum is i?"
+  (some (fn [a] (abundants (- i a))) abundants))
+
+(defn truncate [number digits]
+  "**truncate :: Int, Int -> Int**
   Truncates the given number up to the first n digits."
-  [number digits]
   (->> digits
     (inc)
     (- (count (str number)))
@@ -214,14 +211,14 @@
   "The Golden Ratio - (1+sqrt5)/2."
   (/ (inc (Math/sqrt 5)) 2))

-(defn digits
-  "Converts a number n into a list of its digits."
-  [n] (map #(Character/digit % 10) (str n)))
-
-(defn narcissistic?
+(defn digits [n]
+  "**digits :: Int -> [Int]**
+  Converts a number n into a list of its digits."
+  (map #(Character/digit % 10) (str n)))
+
+(defn narcissistic? [n exp]
   "A number written as the sum of its nth powers.
   Exp.: 1634 = 1^4 + 6^4 + 3^4 + 4^4."
-  [n exp]
   (->> (digits n)
        (map #(Math/pow % exp))
        (reduce +)
@@ -235,10 +232,9 @@

 (def tens ["twenty" "thirty" "forty" "fifty" "sixty" "seventy" "eighty" "ninety"])

-(defn to-words
+(defn to-words [n]
   "Converts a number (up to 1000) into its string representation, omitting spaces.
   Example: (to-words 115) => 'onehundredandfifteen'."
-  [n]
   (cond
     (< n 20) (nth singles (dec n))
     (< n 100) (if (factor? n 10)


added add-to-set

added add-to-set

--- src/karras/sugar.clj
+++ src/karras/sugar.clj
@@ -88,6 +88,10 @@
 ;; mongo 1.6
 (defn slice         "" [field val]         {field {:$slice val}})
 (defn ||          "or" [& clauses]         {:$or clauses})
+(defn add-to-set    "" [field value & values]
+  (if values
+    {:$addToSet {field {:$each (cons value values)}}}
+    {:$addToSet {field value}}))

 (defn sort-by-keys [keys maps]
   (sort (fn [x y]


remove dead code and clean up in new with-git step

--- src/lambdacd/git.clj
+++ src/lambdacd/git.clj
@@ -72,15 +72,6 @@
       (persist-last-seen-revision ctx repo-uri branch current-revision)
       wait-for-result)))

-(defn- checkout [repo-uri revision]
-  (let [cwd (util/create-temp-dir)
-        sh-result (util/bash cwd
-                             (str "git clone " repo-uri )
-                             "cd $(ls)"
-                             (str "git checkout " revision))
-        content (first (.list (File. cwd)))]
-    (assoc sh-result :cwd (str cwd "/" content))))
-
 (defn append-to [result-ch key value]
   (let [additional-value-channel (async/chan 1)
         merged-channels (async/merge [result-ch additional-value-channel])]
@@ -88,17 +79,18 @@
       (async/>!! additional-value-channel [key value])
       merged-channels)))

-(defn- checkout-async [repo-uri revision & _]
-  (let [cwd (util/create-temp-dir)
-        sh-result (shell/bash cwd
-                             (str "git clone " repo-uri )
-                             "cd $(ls)"
-                             (str "git checkout " revision))]
-    (append-to sh-result :cwd cwd)))
+(defn- checkout-step [repo-uri revision]
+  (fn [& _ ]
+    (let [cwd (util/create-temp-dir)
+          sh-result (shell/bash cwd
+                               (str "git clone " repo-uri )
+                               "cd $(ls)"
+                               (str "git checkout " revision))]
+      (append-to sh-result :cwd cwd))))

 (defn- async-checkout [ctx repo-uri revision]
   (let [step-id (:step-id ctx)
-        step (partial checkout-async repo-uri revision)
+        step (checkout-step repo-uri revision)
         execute-step-output (execution/execute-step step {} ctx)
         output (get (:outputs execute-step-output) step-id)
         git-tmp-dir (:cwd output)


Realize the lazy seq

Realize the lazy seq

--- test/lcmap/aardvark/tile_test.clj
+++ test/lcmap/aardvark/tile_test.clj
@@ -60,8 +60,8 @@

 (deftest find
   (with-system
-    (map #(tile-spec/process % tile-spec-opts) [L5 L7])
-    (map #(tile/process %) [L5 L7])
+    (doall (map #(tile-spec/process % tile-spec-opts) [L5 L7]))
+    (doall (map #(tile/process %) [L5 L7]))
     (testing "Test a single ubid"
       (is (= 1 (count (tile/find (merge space-time one-ubid))))))
     (testing "Test two ubids"


Omit tests running in node

Omit tests running in node

--- test/reagenttest/testreagent.cljs
+++ test/reagenttest/testreagent.cljs
@@ -567,38 +567,40 @@
     (is (= (rstr [c2]) "
foo
"))))

 (deftest basic-with-let
-  (let [n1 (atom 0)
-        n2 (atom 0)
-        n3 (atom 0)
-        val (r/atom 0)
-        c (fn []
-            (r/with-let [v (swap! n1 inc)]
-              (swap! n2 inc)
-              [:div @val]
-              (finally
-                (swap! n3 inc))))]
-    (with-mounted-component [c]
-      (fn [_ div]
-        (is (= [1 1 0] [@n1 @n2 @n3]))
-        (swap! val inc)
-        (is (= [1 1 0] [@n1 @n2 @n3]))
-        (r/flush)
-        (is (= [1 2 0] [@n1 @n2 @n3]))))
-    (is (= [1 2 1] [@n1 @n2 @n3]))))
+  (when isClient
+    (let [n1 (atom 0)
+          n2 (atom 0)
+          n3 (atom 0)
+          val (r/atom 0)
+          c (fn []
+              (r/with-let [v (swap! n1 inc)]
+                (swap! n2 inc)
+                [:div @val]
+                (finally
+                  (swap! n3 inc))))]
+      (with-mounted-component [c]
+        (fn [_ div]
+          (is (= [1 1 0] [@n1 @n2 @n3]))
+          (swap! val inc)
+          (is (= [1 1 0] [@n1 @n2 @n3]))
+          (r/flush)
+          (is (= [1 2 0] [@n1 @n2 @n3]))))
+      (is (= [1 2 1] [@n1 @n2 @n3])))))

 (deftest with-let-destroy-only
-  (let [n1 (atom 0)
-        n2 (atom 0)
-        c (fn []
-            (r/with-let []
-              (swap! n1 inc)
-              [:div]
-              (finally
-                (swap! n2 inc))))]
-    (with-mounted-component [c]
-      (fn [_ div]
-        (is (= [1 0] [@n1 @n2]))))
-    (is (= [1 1] [@n1 @n2]))))
+  (when isClient
+    (let [n1 (atom 0)
+          n2 (atom 0)
+          c (fn []
+              (r/with-let []
+                (swap! n1 inc)
+                [:div]
+                (finally
+                  (swap! n2 inc))))]
+      (with-mounted-component [c]
+        (fn [_ div]
+          (is (= [1 0] [@n1 @n2]))))
+      (is (= [1 1] [@n1 @n2])))))

 (deftest with-let-non-reactive
   (let [n1 (atom 0)


Add filesystem handle helpers

Add filesystem handle helpers

--- src/grimoire/api.clj
+++ src/grimoire/api.clj
@@ -71,3 +71,54 @@
        (map :name)
        (interpose "/")
        (apply str)))
+
+(defn ensure-thing [maybe-thing]
+  (cond (string? maybe-thing)
+        ,,(thing->path maybe-thing)
+
+        (map? maybe-thing)
+        ,,maybe-thing
+
+        :else
+        ,,(throw (Exception.
+                  (str "Unsupported ensure-thing value "
+                       (pr-str maybe-thing))))))
+
+;; Interacting with the datastore
+;;--------------------------------------------------------------------
+(defn- thing->handle
+  "Helper for grabbing handles for reading/writing.
+
+  :docs     -> .json file
+  :notes    -> .md file
+  :examples -> dir"
+
+  [{store :datastore} which thing]
+  (let [d (get store which)
+        p (io/file (str d "/" (thing->path (:parent thing))))
+        e (case which
+            (:docs)     ".json"
+            (:examples) nil
+            (:notes)    ".md")
+        n (if (= :def (:type thing))
+            (util/munge (:name thing))
+            (name (:type thing)))
+        h (io/file p (str n e))]
+    (assert (.mkdirs p))
+    (when (= :examples which)
+      (assert (.mkdir h)))
+    h))
+
+(defn- thing->notes-handle
+  "Helper for grabbing the handle of a notes file "
+
+  [c thing]
+  (let [h (thing->handle c :notes thing)]
+    (io/file h "notes.md")))
+
+(defn- thing->example-handle
+  "Helper for getting a file handle for reading and writing a named example."
+
+  [c thing name]
+  (let [h (thing->handle c :examples thing)]
+    (io/file h (str name ".clj")))


Add a note about the API's assumptions

Add a note about the API's assumptions

--- src/grimoire/api.clj
+++ src/grimoire/api.clj
@@ -3,7 +3,12 @@
   up examples, symbols, namespaces and artifacts as values without
   regard to the implementation of the datastore. Ports of Grimoire to
   different datastores should only need to extend the multimethods in
-  this namespace.")
+  this namespace.
+
+  API Contract assumptions:
+
+  - Everything has metadata, even if it's nil. If metadata for a Thing
+    cannot be found, then the Thing itself is not in the datastore.")

 (defn dispatch [config & more]
   (-> config :datastore :mode))


Whitespace

Whitespace

--- src/grimoire/doc.clj
+++ src/grimoire/doc.clj
@@ -245,7 +245,7 @@
     ("src" :src "source" :source)
     ,,(let [[doc] args
             _ (assert doc "Doc target dir missing!")
-
+
             config  {:groupid    p-groupid
                      :artifactid p-artifactid
                      :version    p-version


Fixed caffeinate on Mac

Fixed caffeinate on Mac

--- src/video_server/util.clj
+++ src/video_server/util.clj
@@ -147,7 +147,7 @@
   "Attempts to prevent the computer from sleeping while executing
   the shell command via exec."
   [& cmd]
-  (apply exec (if caffeine? (concat ["caffeinate" "-s"] cmd) cmd)))
+  (apply exec (if @caffeine? (concat ["caffeinate" "-s"] cmd) cmd)))

 (defn periodically
   "Peridoically calls a function. Returns a stopping function."


write the results to a file

write the results to a file

--- src/k_means/core.clj
+++ src/k_means/core.clj
@@ -103,4 +103,6 @@
 (defn -main
   "Main function for k-means"
   [& args]
-  (let [c (k-means (make-vector-rand 5000) 5 100)] (println c)))
+  (let [c (k-means (make-vector-rand 5000) 5 100)]
+    (println c)
+    (spit "k-means.txt" c)))


Redis publush support

Redis publush support

--- src/kiries/redis.clj
+++ src/kiries/redis.clj
@@ -4,20 +4,28 @@
             [clj-json.core :as json]))

 (defn publish
+  "Returns a function which publishes a single event as JSON, to the
+  spcified redis server and key."
+  [conn key]
+  (let [f (spublish conn key)]
+    (fn [e]
+      (f [e]))))
+
+(defn spublish
   "Returns a function which takes a sequence of events or other
-   values, and publishes them as JSON, to the specific redis server
-   and key.  Suitable for using in a riemann stream."
+   values, and publishes them as JSON, to the specified redis server
+   and key.  Suitable for using inside of rollup."
   [conn key]
   (fn [events]
     (let [jevents
-          (doall (remove nil?
-                         (map
-                          (fn [e]
-                            (try (json/generate-string e)
-                                 (catch Exception err
-                                   (error "Could not coerce event to json (" e "):" err)
-                                   nil)))
-                          events)))]
+          (remove nil?
+                  (map
+                   (fn [e]
+                     (try (json/generate-string e)
+                          (catch Exception err
+                            (error "Could not coerce event to json (" e "):" err)
+                            nil)))
+                   events))]
       (doseq [je jevents]
         (try
           (car/wcar conn


not generating the environment

not generating the environment

--- src/ophion/kafka.clj
+++ src/ophion/kafka.clj
@@ -110,7 +110,7 @@
     (dir->streams spout path)))

 (def default-config
-  {:host (or (System/genenv "KAFKA_HOST") "localhost:9092")
+  {:host (or (System/getenv "KAFKA_HOST") "localhost:9092")
    :consumer
    {:group-id (uuid)}})


Fix a typo in the manifest doctype

Fix a typo in the manifest doctype

--- src/mdr2/dtb/xml.clj
+++ src/mdr2/dtb/xml.clj
@@ -9,7 +9,7 @@
 (def ^:private manifest-doctype
   (str
    "<!DOCTYPE html PUBLIC "
-   "\"-//W3C//DTD) XHTML 1.0 Transitional//EN\" "
+   "\"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
    "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"))

 (def ^:private smil-doctype


Use particle-count var instead of counting each time

--- src/physim/core.cljs
+++ src/physim/core.cljs
@@ -134,27 +134,30 @@

 (defn handle-collisions!
   []
-  (let [n (count @particles)]
-    (doseq [a (range n)
-            b (range n)]
-      (let [pa (nth @particles a)
-            pb (nth @particles b)]
-        (when (and (not= a b) (collided? pa pb))
-          (let [dir (direction-from (:pos pb) (:pos pa))
-                dist (distance (:pos pa) (:pos pb))
-                bounce (direction dir (- particle-diameter dist))]
-            (reset! particles
-                    (assoc @particles
-                      a (assoc pa
-                          :pos (map + (:pos pa) bounce)
-                          :vel (map + (:vel pa) (direction dir (magnitude (:vel pa)))))
-                      b (assoc pb
-                          :pos (map - (:pos pb) bounce)
-                          :vel (map - (:vel pb) (direction dir (magnitude (:vel pb)))))))))))))
+  (doseq [a (range particle-count)
+          b (range particle-count)]
+    (let [pa (nth @particles a)
+          pb (nth @particles b)]
+      (when (and (not= a b) (collided? pa pb))
+        (let [dir (direction-from (:pos pb) (:pos pa))
+              dist (distance (:pos pa) (:pos pb))
+              bounce (direction dir (- particle-diameter dist))]
+          (reset! particles
+                  (assoc @particles
+                    a (assoc pa
+                        :pos (map + (:pos pa) bounce)
+                        :vel (map +
+                                  (:vel pa)
+                                  (direction dir (magnitude (:vel pa)))))
+                    b (assoc pb
+                        :pos (map - (:pos pb) bounce)
+                        :vel (map -
+                                  (:vel pb)
+                                  (direction dir (magnitude (:vel pb))))))))))))

 (defn motion-tick!
   []
-  (doseq [i (range (count @particles))]
+  (doseq [i (range particle-count)]
     (let [p (nth @particles i)
           [p v a] (move (:pos p) (:vel p) @particles)]
       (reset! particles
@@ -167,7 +170,7 @@
   (motion-tick!)
   (handle-collisions!)

-  (doseq [i (range (count @particles))]
+  (doseq [i (range particle-count)]
     (let [p (nth @particles i)
           m (nth @particle-meshes i)]
       ;; static rotation for blinginess


Minor

Minor

--- src/demo/web.clj
+++ src/demo/web.clj
@@ -31,7 +31,7 @@
 (defn counter [{session :session}]
   (let [count (:count session 0)
         session (assoc session :count (inc count))]
-    (-> (ring-util/response (str "You accessed this page " count " times."))
+    (-> (ring-util/response (str "You accessed this page " count " times\n"))
         (assoc :session session))))
 ;;; Use Immutant's session store for automatic replication
 (web/start "/counter"


serializing values

serializing values

--- src/ophion/query.clj
+++ src/ophion/query.clj
@@ -318,13 +318,15 @@
   [^GraphTraversal g {:keys [head tail]}]
   (.cap g head (into-array tail)))

-;; (defn serialize
-;;   [val]
-;;   (if))
+(defn serialize
+  [val]
+  (if (coll? val)
+    (json/generate-string val)
+    val))

 (defn set-property!
   [element key val]
-  (.property element (name key) val))
+  (.property element (name key) (serialize val)))

 (defn set-properties!
   [element properties]


Ensuring capped profile collection

Ensuring capped profile collection

--- src/polismath/db.clj
+++ src/polismath/db.clj
@@ -192,6 +192,10 @@
         (doseq [c ["bidtopid" "main" "cache"]]
           (let [c (mongo-collection-name c)]
             (mc/ensure-index db c (array-map :zid 1) {:name (str c "_zid_index") :unique true})))
+        ; set up rolling limit on profile data
+        (let [prof-coll (mongo-collection-name "profile")]
+          (if (exists? db prof-coll)
+            (mc/create db (mongo-collection-name "profile") {:capped true :max 200000})))
         ; make sure to return db
         db))))


Remove the temporary error test.

Remove the temporary error test.

--- src/posthere/app.clj
+++ src/posthere/app.clj
@@ -40,9 +40,6 @@

   ; Resource requests (in development only, otherwise handled by nginx)
   (route/resources "/")
-
-  ;; Force an error for testing Sentry error reporting
-  (GET "/_/force_error" [] (/ 42 0))

   ;; Home page for development, handled by nginx in production
   (GET "/" [] (slurp "./resources/public/index"))


added :paredit-open-square command

added :paredit-open-square command

--- src/paredit/core.clj
+++ src/paredit/core.clj
@@ -235,6 +235,17 @@
 	                 "(defun f (x)\n  |)"
 	                "; (Foo.|"
 	                 "; (Foo.)|"}]
+	    ["["         :paredit-open-square
+                 {"(a b |c d)"  "(a b [|] c d)"
+                  "(foo \"bar |baz\" quux)" "(foo \"bar [|baz\" quux)"}
+                  {"(a b|c d)" "(a b [|] c d)"
+                   "(|)" "([|])"
+                   "|" "[|]"
+                   "a|" "a [|]"
+                   "(a |,b)" "(a [|],b)"
+                   "(a,| b)" "(a, [|] b)"
+                   "(a,|b)" "(a, [|] b)"
+                   "(a,|)" "(a, [|])"}]
     ]
   ])

@@ -292,20 +303,32 @@

 (defmulti paredit (fn [k & args] k))

-(defmethod paredit
-  :paredit-open-round
-  [cmd {:keys [text offset length] :as t}]
+(defn open-balanced
+  [[o c] {:keys [text offset length] :as t}]
   #_(prn "t:" t)
   (if (in-code? text offset)
     (let [add-pre-space? (not (contains? (into *real-spaces* *open-brackets*) (previous-char t)))
           add-post-space? (not (contains? (into *extended-spaces* *close-brackets*) (next-char t)))
           ins-str (str (if add-pre-space? " " "")
-                       "()"
+                       (str o c)
                        (if add-post-space? " " ""))
           offset-shift (if add-post-space? -2 -1)]
       #_(prn "ins-str:" ins-str)
       (-> t (insert ins-str) (shift-offset offset-shift)))
-    (-> t (insert "("))))
+    (-> t (insert (str o)))))
+
+
+(defmethod paredit
+  :paredit-open-round
+  [cmd {:keys [text offset length] :as t}]
+  #_(prn "t:" t)
+  (open-balanced [\( \)] t))
+
+(defmethod paredit
+  :paredit-open-square
+  [cmd {:keys [text offset length] :as t}]
+  #_(prn "t:" t)
+  (open-balanced [\[ \]] t))

 (defn test-command [title-prefix command]
   (testing (str title-prefix " " (second command) " (\"" (first command) "\")")