More consistent process named arg order

More consistent process named arg order

--- src/semantic_csv/core.clj
+++ src/semantic_csv/core.clj
@@ -268,7 +268,7 @@
     * `:comment-char` - specify a comment character to use for filtering out comments; overrides comment-re.
     * `:cast-fns` - optional map of `colname | index -> cast-fn`; row maps will have the values as output by the
        assigned `cast-fn`."
-    ([{:keys [remove-comments comment-re comment-char mappify header structs cast-fns]
+    ([{:keys [mappify header remove-comments comment-re comment-char structs cast-fns]
        :or   {remove-comments true
               comment-re   #"^\#"
               mappify      true}


Making sure correct defaults get passed through to mappify; also adding cast-with control to process

--- src/semantic_csv/core.clj
+++ src/semantic_csv/core.clj
@@ -258,6 +258,7 @@
   controlled by an `opts` hash with opinionated defaults:

   * `:mappify` - bool; transform rows from vectors into maps using `mappify`.
+  * `:keyify` - bool; specify whether header/column names should be turned into keywords (default: `true`).
   * `:header` - specify header to be used in mappify; as per `mappify`, first row will not be consumed as header
   * `:structs` - bool; use structs instead of array-maps or hash-maps in mappify.
   * `:remove-comments` - bool; remove comment lines, as specified by `:comment-re` or `:comment-char`. Also
@@ -265,17 +266,21 @@
   * `:comment-re` - specify a regular expression to use for commenting out lines.
   * `:comment-char` - specify a comment character to use for filtering out comments; overrides comment-re.
   * `:cast-fns` - optional map of `colname | index -> cast-fn`; row maps will have the values as output by the
-     assigned `cast-fn`."
-  ([{:keys [mappify header remove-comments comment-re comment-char structs cast-fns]
+     assigned `cast-fn`.
+  * `:cast-exception-handler` - If cast-fn raises an exception, this function will be called with args
+    `colname, value`, and the result used as the parse value.
+  * `:cast-only` - Only cast the specified column(s); can be either a single column name, or a vector of them."
+  ([{:keys [mappify keify header remove-comments comment-re comment-char structs cast-fns cast-exception-handler cast-only]
      :or   {mappify         true
+            keify           true
             remove-comments true
             comment-re      #"^\#"}
      :as opts}
     rows]
    (->> rows
         (?>> remove-comments (semantic-csv.core/remove-comments {:comment-re comment-re :comment-char comment-char}))
-        (?>> mappify (semantic-csv.core/mappify {:header header :structs structs}))
-        (?>> cast-fns (cast-with cast-fns))))
+        (?>> mappify (semantic-csv.core/mappify {:keify keify :header header :structs structs}))
+        (?>> cast-fns (cast-with cast-fns {:exception-handler cast-exception-handler :only cast-only}))))
   ; Use all defaults
   ([rows]
    (process {} rows)))


refactor pig latin menu system to handle errors clojure

--- tech-int/src/tech_int/core.clj
+++ tech-int/src/tech_int/core.clj
@@ -52,24 +52,6 @@
     )
 )

-; (defn printPhrase
-;     [v w]
-;     (def i (atom 0))
-;     (while (< @i (count v))
-;         (do
-;             (if (<= @i (count v))
-;                 (if (<= (count (v @i)) w)
-;                     (do
-;                         (println (apply str "* " (v @i) (apply str (repeat (- w (count (v @i))) " ")) " *"))
-;                     )
-;                     (println (apply str "* " (v @i) " *"))
-;                 )
-;             )
-;         )
-;         (swap! i inc)
-;     )
-; )
-
 (defn -sqPhrase []
     (println "Enter a phrase:")
     (def inputPhrase (read-line))
@@ -113,36 +95,37 @@
     (println "1. English to pig latin")
     (println "2. Pig latin to english")
     (def choice (read-line))
-    (println "Enter a phrase:")
-    (def inputPhrase (read-line))
-    (println "--")
-    (def inputArray (split inputPhrase #"\s+"))
-    (if (< (Integer. choice) 3)
-        (if (= choice 1)
+    (try
+        (if (and (Integer. choice) (< (Integer. choice) 3))
             (do
-                (def pigLatinArray (mapv toPigLatin inputArray))
-                (println (capitalize (join " " pigLatinArray)))
-            )
-            (do
-                (if (checkIfPigLatin inputArray)
+                (println "Enter a phrase:")
+                (def inputPhrase (read-line))
+                (println "--")
+                (def inputArray (split inputPhrase #"\s+"))
+                (if (= (Integer. choice) 1)
                     (do
-                        (def englishArray (mapv toEnglish inputArray))
-                        (println (capitalize (join " " englishArray)))
+                        (def pigLatinArray (mapv toPigLatin inputArray))
+                        (println (capitalize (join " " pigLatinArray)))
                     )
                     (do
-                        (println "Phrase is not pig latin, please correct and try again.")
-                        (-pigLatin)
+                        (if (checkIfPigLatin inputArray)
+                            (do
+                                (def englishArray (mapv toEnglish inputArray))
+                                (println (capitalize (join " " englishArray)))
+                            )
+                            (do
+                                (println "Phrase is not pig latin, please correct and try again.")
+                                (-pigLatin)
+                            )
+                        )
                     )
                 )
+                (println "--")
             )
+            (println "Sorry, invalid choice.")
         )
-        (do
-            (println "Sorry, invalid choice")
-            (-pigLatin)
-        )
+        (catch Exception e (println "Sorry, invalid choice."))
     )
-
-    (println "--")
 )


--- src/sicp/chapter1/1_8.clj
+++ src/sicp/chapter1/1_8.clj
@@ -1,5 +1,30 @@
-(ns sicp.chapter1.1-8)
+(ns sicp.chapter1.1-8
+  (:require [sicp.chapter1.1-4 :refer [square]]
+            [sicp.chapter1.1-6 :refer [abs]]
+            [sicp.chapter1.1-7 :refer [average]]))

 ;;;; 1.1  The Elements of Programming

 ;;; 1.1.8  Procedures as Black-Box Abstractions
+
+(defn sqrt [x]
+  (letfn [(good-enough? [guess x]
+            (< (abs (- (square guess) x)) 0.001))
+          (improve [guess x]
+            (average guess (/ x guess)))
+          (sqrt-iter [guess x]
+            (if (good-enough? guess x)
+              guess
+              (recur (improve guess x) x)))]
+    (sqrt-iter 1.0 x)))
+
+(defn sqrt' [x]
+  (letfn [(good-enough? [guess]
+            (< (abs (- (square guess) x)) 0.001))
+          (improve [guess]
+            (average guess (/ x guess)))
+          (sqrt-iter [guess]
+            (if (good-enough? guess)
+              guess
+              (recur (improve guess))))]
+    (sqrt-iter 1.0)))


Update dependencies

Update dependencies

--- build.boot
+++ build.boot
@@ -4,19 +4,19 @@
  :source-paths #{"src/"}
  :dependencies
  '[[org.clojure/clojure "1.8.0"]
-   [clj-jgit "0.8.9"]
-   [clj-http "3.3.0"]
-   [cheshire "5.6.3"]
+   [clj-jgit "0.8.10"]
+   [clj-http "3.8.0"]
+   [cheshire "5.8.0"]
    [throttler "1.0.0"]
-   [org.slf4j/slf4j-nop "1.7.21"]
+   [org.slf4j/slf4j-nop "1.7.25"]
    [grimradical/clj-semver "0.3.0" :exclusions [org.clojure/clojure]]
    [org.clojure/tools.cli "0.3.5"]
    ; testing
-   [degree9/boot-semver "1.3.6" :scope "test"]
+   [degree9/boot-semver "1.4.3" :scope "test"]
    [org.clojure/test.check "0.9.0" :scope "test"]
-   [clj-http-fake "1.0.2" :scope "test"]
-   [adzerk/boot-test "1.1.2" :scope "test"]
-   [tolitius/boot-check "0.1.3" :scope "test"]])
+   [clj-http-fake "1.0.3" :scope "test"]
+   [adzerk/boot-test "1.2.0" :scope "test"]
+   [tolitius/boot-check "0.1.9" :scope "test"]])

 (require
  '[adzerk.boot-test :as boot-test]


Simplify setting alt-test :fail flag

Simplify setting alt-test :fail flag

--- build.boot
+++ build.boot
@@ -84,15 +84,15 @@
     (if speak (boot.task.built-in/speak) identity)))

 (deftask run-tests
-  [c ci bool "If process should exit after test failure"]
+  [a autotest bool "If no exception should be thrown when tests fail"]
   (comp
-    (alt-test :fail (if (nil? ci) true ci))
+    (alt-test :fail (not autotest))
     (test-cljs :namespaces #{"frontend.core-test"})))

 (deftask autotest []
   (comp
     (watch)
-    (run-tests :ci false)))
+    (run-tests :autotest true)))

 (deftask package
   "Build the package"


Fixed bug where, if fetching of a new revision failed, the last seen revision would be replaced by nil, so the pipeline would always trigger after a failed revision fetch

--- src/lambdacd_git/core.clj
+++ src/lambdacd_git/core.clj
@@ -87,7 +87,7 @@
                              (do
                                (report-waiting-status ctx)
                                (wait-for-next-poll poll-notifications ms-between-polls kill-channel)
-                               (recur current-revisions))))))]
+                               (recur last-seen-revisions))))))]
     (clean-up-kill-switch->ch (:is-killed ctx))
     result))


Redo dev to not wipe target after doing Figwheel

--- build.boot
+++ build.boot
@@ -161,7 +161,7 @@
 (deftask dev []
   (comp
    (fix)
-   (make-solver)
+   (build)
    (environ :env {:http-port "3000"})
    (figwheel)
    (run-figwheel)
@@ -175,7 +175,7 @@
    (sift :move {#"herder/sass/(.*)" "resources/public/css/$1"})
    (target :no-clean true)
    (system :sys #'dev-system :auto true :files ["lobos.clj" "handler.clj" "solver.clj" "systems.clj" "run.clj" "rules.drl"])
-   (make-solver)
+   (build)
    (testing)
    (test)
    (kill-pods)))


adding more properties for pom task

adding more properties for pom task

--- build.boot
+++ build.boot
@@ -5,9 +5,17 @@
                   [org.clojure/tools.logging "0.3.1"]
                   [adzerk/bootlaces "0.1.13"]])

+(def +version+ "0.0.3")
+
+(require '[adzerk.bootlaces :refer :all])
+(bootlaces! +version+)
+
 (task-options!
-  pom {:project 'clj-sql-builder
-       :version "0.0.2"})
+  pom {:project     'clj-sql-builder
+       :version     +version+
+       :description "A very simple SQL statement builder based on jsqlparser"
+       :url         "https://github.com/hsunsmile/clj-sql-builder"
+       :scm         {:url "https://github.com/hsunsmile/clj-sql-builder"}
+       :license     {"MIT" "https://opensource.org/licenses/MIT"}})

 (require '[sql.parser :refer :all])
-(require '[adzerk.bootlaces :refer :all])


missing bootlaces

missing bootlaces

--- build.boot
+++ build.boot
@@ -1,6 +1,7 @@
 (set-env!
  :dependencies  '[[org.clojure/clojure       "1.7.0"]
                   [org.clojure/clojurescript "1.7.48"]
+                  [adzerk/bootlaces          "0.1.13" :scope "test"]
                   [adzerk/boot-cljs          "1.7.48-6"]
                   [adzerk/boot-cljs-repl     "0.1.10-SNAPSHOT"]
                   [adzerk/boot-reload        "0.3.3-SNAPSHOT"]
@@ -25,6 +26,7 @@
  :asset-paths #{"resources/assets"})

 (require
+  '[adzerk.bootlaces :refer :all]
   '[adzerk.boot-cljs :refer :all]
   '[adzerk.boot-cljs-repl :refer :all]
   '[adzerk.boot-reload :refer :all]


Fix check if current user is admin for header

The problem was the user-id being passed to :user-is-group-admin?
subscription wasn't being deref'd, but this sub is a little more
declarative

--- src/braid/client/ui/views/header.cljs
+++ src/braid/client/ui/views/header.cljs
@@ -76,7 +76,7 @@
 (defn admin-header-view []
   (let [user-id (subscribe [:user-id])
         open-group-id (subscribe [:open-group-id])
-        admin? (subscribe [:user-is-group-admin? user-id] [open-group-id])]
+        admin? (subscribe [:current-user-is-group-admin?] [open-group-id])]
     (fn []
       (when @admin?
         [:div.admin-header


Differentiate between no compilable namespaces and no stale namespaces.

--- src/leiningen/compile.clj
+++ src/leiningen/compile.clj
@@ -9,22 +9,31 @@
            java.lang.management.ManagementFactory
            (org.apache.tools.ant.types Environment$Variable Path)))

-(defn namespaces-to-compile
-  "Returns a seq of the namespaces which need compiling."
+(defn compilable-namespaces
+  "Retrns a seq of the namespaces that are compilable, regardless of whether
+  their class files are present and up-to-date."
   [project]
   ;; TODO: Compile :main ns if needed
-  (for [n (cond (coll? (:namespaces project))
-                (:namespaces project)
-                (= :all (:namespaces project))
-                (find-namespaces-in-dir (file (:source-path project))))
-        :let [ns-file (str (-> (name n)
-                               (.replaceAll "\\." "/")
-                               (.replaceAll "-" "_")))]
-        :when (> (.lastModified (file (:source-path project)
-                                      (str ns-file ".clj")))
-                 (.lastModified (file (:compile-path project)
-                                      (str ns-file "__init.class"))))]
-    n))
+  (cond
+    (coll? (:namespaces project))
+      (:namespaces project)
+    (= :all (:namespaces project))
+      (find-namespaces-in-dir (file (:source-path project)))))
+
+(defn stale-namespaces
+  "Given a seq of namespaces that are both compilable and that hav missing or
+  out-of-date class files."
+  [project]
+  (filter
+    (fn [n]
+      (let [ns-file (str (-> (name n)
+                           (.replaceAll "\\." "/")
+                           (.replaceAll "-" "_")))]
+        (> (.lastModified (file (:source-path project)
+                                (str ns-file ".clj")))
+           (.lastModified (file (:compile-path project)
+                                (str ns-file "__init.class"))))))
+    (compilable-namespaces project)))

 (defn find-lib-jars
   "Returns a seq of Files for all the jars in the project's library directory."
@@ -130,18 +139,18 @@

 (defn compile
   "Ahead-of-time compile the project. Looks for all namespaces under src/
-unless a list of :namespaces is provided in project.clj."
+  unless a list of :namespaces is provided in project.clj."
   [project]
   ;; dependencies should be resolved by explicit "lein deps",
   ;; otherwise it will be done only if :library-path is empty
   (when (empty? (find-lib-jars project))
     (deps project :skip-dev))
   (.mkdir (file (:compile-path project)))
-  (let [namespaces (namespaces-to-compile project)]
-    (if (seq namespaces)
+  (if (compilable-namespaces project)
+    (if-let [namespaces (seq (stale-namespaces project))]
       (eval-in-project project
-                       `(doseq [namespace# '~namespaces]
-                          (println "Compiling" namespace#)
-                          (clojure.core/compile namespace#)))
-      (println "No :namespaces listed for compilation in project.clj."))))
-
+        `(doseq [namespace# '~namespaces]
+           (println "Compiling" namespace#)
+           (clojure.core/compile namespace#)))
+      (println "All :namespaces already compiled."))
+    (println "No :namespaces listed for compilation in project.clj.")))


badge only shows count of threads with new activity (not count of open threads)

--- src/chat/client/views/groups_nav.cljs
+++ src/chat/client/views/groups_nav.cljs
@@ -6,32 +6,44 @@
             [chat.client.views.helpers :refer [id->color]]
             [chat.client.routes :as routes]))

+(defn- unseen? [message thread]
+  (> (:created-at message)
+     (thread :last-open-at)))
+
 (defn groups-nav-view [data owner]
   (reify
     om/IRender
     (render [_]
       (dom/div #js {:className "groups-nav"}
-
-        (apply dom/div #js {:className "groups"}
-          (map (fn [group]
-                 (dom/a #js {:className (str "option group "
-                                             (when (= (@store/app-state :open-group-id)  (group :id)) "active"))
-                             :style #js {:backgroundColor (id->color (group :id))}
-                             :title (group :name)
-                             :href (routes/page-path {:group-id (group :id)
-                                                      :page-id "inbox"})}
-                   (string/join "" (take 2 (group :name)))
-                   (let [cnt (->>
-                               (select-keys (data :threads) (get-in data [:user :open-thread-ids]))
-                               vals
-                               (filter (fn [thread]
-                                         (contains? (set (->> (thread :tag-ids)
-                                                              (map  (fn [tag-id]
-                                                                      (get-in @store/app-state [:tags tag-id :group-id]))))) (group :id))))
-                               count)]
-                     (when (< 0 cnt)
-                       (dom/span #js {:className "badge"} cnt)))))
-               (vals (data :groups))))
+        (let [group-new-activity
+              (->>
+                (select-keys (data :threads) (get-in data [:user :open-thread-ids]))
+                vals
+                (filter (fn [thread]
+                          (unseen? (->> (thread :messages)
+                                        (sort-by :created-at)
+                                        last)
+                                   thread)))
+                (mapcat (fn [thread]
+                          (seq (flatten (concat (->> (thread :tag-ids)
+                                                     (map (fn [tag-id]
+                                                            (get-in @store/app-state [:tags tag-id :group-id]))))
+                                                (->> (thread :mentioned-ids)
+                                                     (map (fn [user-id]
+                                                            (get-in @store/app-state [:users user-id :group-ids])))))))))
+                frequencies)]
+          (apply dom/div #js {:className "groups"}
+            (map (fn [group]
+                   (dom/a #js {:className (str "option group "
+                                               (when (= (@store/app-state :open-group-id)  (group :id)) "active"))
+                               :style #js {:backgroundColor (id->color (group :id))}
+                               :title (group :name)
+                               :href (routes/page-path {:group-id (group :id)
+                                                        :page-id "inbox"})}
+                     (string/join "" (take 2 (group :name)))
+                     (when-let [cnt (group-new-activity (group :id))]
+                       (dom/span #js {:className "badge"} cnt))))
+                 (vals (data :groups)))))

         (dom/a #js {:className (str "option plus "
                                     (when (= (get-in @store/app-state [:page :type]) :group-explore) "active"))


Commit.

Commit.

--- src/clj/forma/hadoop/jobs/scatter.clj
+++ src/clj/forma/hadoop/jobs/scatter.clj
@@ -270,61 +270,14 @@
                       (?- (hfs-seqfile out-path)
                           (forma/forma-query est-map mid-src))))))))

-(defn populate-local [main-path timeseries-path]
-  (doto timeseries-path
-    (to-pail [[(schema/chunk-value
-                "ndvi" "16" nil
-                (schema/pixel-location "500" 8 6 0 0)
-                (schema/timeseries-value 693 (concat ndvi ndvi)))]])
-    (to-pail [[(schema/chunk-value
-                "reli" "16" nil
-                (schema/pixel-location "500" 8 6 0 0)
-                (schema/timeseries-value 693 (concat reli reli)))]])
-    (to-pail [[(schema/chunk-value
-                "precl" "32" nil
-                (schema/pixel-location "1000" 8 6 0 0)
-                (schema/timeseries-value 361 rain-raw))]]))
-  (doto main-path
-    (to-pail [[(schema/chunk-value "vcf" "00" nil
-                                   (schema/chunk-location "500" 8 6 0 24000)
-                                   (into [] (repeat 24000 30)))]])
-    (to-pail [(->> (schema/chunk-value "fire" "01" "2004-12-01"
-                                       (schema/pixel-location "500" 8 6 0 0)
-                                       (schema/fire-value 1 1 1 1))
-                   (repeat 10))])))
-
-(comment
-  (ultrarunner "/user/hadoop/checkpoint"
-               "s3n://pailbucket/master"
-               "s3n://formaresults/firetemp"
-               "s3n://formaresults/trendstemp"
-               "s3n://formaresults/finaloutput"))
-
 (def kryo-conf
   {"cascading.kryo.serializations"   "forma.schema.TimeSeriesValue,carbonite.PrintDupSerializer:forma.schema.FireValue,carbonite.PrintDupSerializer:forma.schema.FormaValue,carbonite.PrintDupSerializer:forma.schema.NeighborValue,carbonite.PrintDupSerializer"
    "fs.s3n.multipart.uploads.enabled" true})

 (defmain ultrarunner
-  [tmp-root pail-path fire-path trends-path out-path]
-  (let [{:keys [s-res t-res est-end] :as est-map} (forma-run-parameters "500-16")]
+  [tmp-root static-path final-path out-path]
+  (let [est-map (forma-run-parameters "500-16")]
     (workflow [tmp-root]
-              mid-forma
-              ([:tmp-dirs forma-mid-path]
-                 (with-job-conf kryo-conf
-                   (?- (hfs-seqfile forma-mid-path)
-                       (forma/forma-tap (hfs-seqfile trends-path)
-                                        (hfs-seqfile fire-path)))))
-
-              final-forma
-              ([:tmp-dirs final-path]
-                 (let [names
-                       ["?s-res" "?period" "?mod-h" "?mod-v" "?sample" "?line" "?forma-val"]
-                       mid-src (-> (hfs-seqfile forma-mid-path)
-                                   (name-vars names))]
-                   (with-job-conf kryo-conf
-                     (?- (hfs-seqfile final-path)
-                         (forma/forma-query est-map mid-src)))))
-
               bucketstatic
               ([:tmp-dirs static-path]
                  (?- (hfs-seqfile static-path)
@@ -343,3 +296,10 @@
                                             (hfs-seqfile beta-path)
                                             (hfs-seqfile final-path)
                                             (hfs-seqfile static-path)))))))
+
+(comment
+  "Run this:"
+  (ultrarunner "/user/hadoop/checkpoint"
+               "s3n://formaresults/staticbuckettemp"
+               "s3n://formaresults/finalbuckettemp"
+               "s3n://formaresults/finaloutput"))


Removed final reference to old trends processing queries

--- src/clj/forma/hadoop/jobs/scatter.clj
+++ src/clj/forma/hadoop/jobs/scatter.clj
@@ -197,7 +197,7 @@
                  (?- (hfs-seqfile trends-path)
                      (forma/analyze-trends
                       est-map
-                      (hfs-seqfile clean-series))))
+                      (hfs-seqfile adjusted-series-path))))

               fire-step
               ([:tmp-dirs fire-path]
@@ -222,7 +222,7 @@
                  trends + fires data"
                  (?- (hfs-seqfile forma-mid-path)
                      (forma/forma-tap est-map
-                                      (hfs-seqfile cleanup-path)
+                                      (hfs-seqfile trends-path)
                                       (hfs-seqfile adjusted-fire-path))))

               final-forma


Add missing alias for replace-first for cljs

--- src/superstring/core.cljs
+++ src/superstring/core.cljs
@@ -21,6 +21,7 @@
 (def upper-case str/upper-case)
 (def index-of str/index-of)
 (def last-index-of str/last-index-of)
+(def replace-first str/replace-first)

 (def substring clojure.core/subs)


add target o build.boot

add target o build.boot

--- build.boot
+++ build.boot
@@ -50,6 +50,7 @@
       :version "1.0.0"}
  jar {:main 'tango.core}
  aot {:all true}
+ target {:dir #{"target"}}
  )

 (deftask build "Create a standalone tango server jar." []
@@ -57,4 +58,5 @@
         (pom)
         (uber)
         (jar)
+	(target)
         ))


worked for blog.hashobject.com

worked for blog.hashobject.com

--- build.boot
+++ build.boot
@@ -55,6 +55,11 @@
         (notify)))

+(deftask install-locally
+  "Install locally"
+  []
+  (comp (pom) (jar) (install)))
+
 (deftask release-snapshot
   "Release snapshot"
   []


make build.boot executable

make build.boot executable

--- build.boot
+++ build.boot
@@ -1,3 +1,5 @@
+#!/usr/bin/env boot
+
 (set-env!
  :source-paths #{"src" "test"}
  :dependencies '[[org.clojure/clojure "1.6.0"]
@@ -48,3 +50,6 @@
                fileset)
              (repl :server true :port 4005))))
     (wait)))
+
+(defn -main [& args]
+  (println "to do"))


DNS routes using central value for domain

--- src/terraboot/cluster.clj
+++ src/terraboot/cluster.clj
@@ -359,7 +359,7 @@
                                        :internal-lb-dns (cluster-output-of "aws_elb" "internal-lb" "dns_name")
                                        :fallback-dns (vpc/fallback-dns vpc/vpc-cidr-block)
                                        :number-of-masters min-number-of-masters
-                                       :influxdb-dns (str "influxdb." (vpc-unique "kixi") ".mesos")
+                                       :influxdb-dns (str "influxdb." (vpc/vpc-dns-zone vpc-name))
                                        :mesos-dns "127.0.0.1"
                                        :alerts-server (str "alerts." (vpc/vpc-dns-zone vpc-name))}
                                 :lifecycle { :create_before_destroy true }
@@ -434,9 +434,9 @@
                                        :internal-lb-dns (cluster-output-of "aws_elb" "internal-lb" "dns_name")
                                        :fallback-dns (vpc/fallback-dns vpc/vpc-cidr-block)
                                        :number-of-masters min-number-of-masters
-                                       :influxdb-dns (str "influxdb." (vpc-unique "kixi") ".mesos")
+                                       :influxdb-dns (str "influxdb." (vpc/vpc-dns-zone vpc-name))
                                        :mesos-dns (cluster-output-of "aws_elb" "internal-lb" "dns_name")
-                                       :alerts-server (str "alerts." (vpc-unique "kixi.mesos"))}
+                                       :alerts-server (str "alerts." (vpc/vpc-dns-zone vpc-name)) }
                                 :lifecycle { :create_before_destroy true }})

              (vpc/private_route53_record (str cluster-name "-masters") vpc-name
@@ -502,9 +502,10 @@
                                        :internal-lb-dns (cluster-output-of "aws_elb" "internal-lb" "dns_name")
                                        :fallback-dns (vpc/fallback-dns vpc/vpc-cidr-block)
                                        :number-of-masters min-number-of-masters
-                                       :influxdb-dns (str "influxdb." (vpc-unique "kixi") ".mesos")
+                                       :influxdb-dns (str "influxdb." (vpc/vpc-dns-zone vpc-name))
                                        :mesos-dns (cluster-output-of "aws_elb" "internal-lb" "dns_name")
-                                       :alerts-server (str "alerts." (vpc-unique "kixi.mesos"))}
+                                       :alerts-server (str "alerts." (vpc/vpc-dns-zone vpc-name))
+                                       }
                                 :lifecycle { :create_before_destroy true }

                                 })


tweaks to build.boot to accomodate building on Windows

--- build.boot
+++ build.boot
@@ -48,6 +48,9 @@
     (speak)
     (test :exit? false)))

+(def windows?
+  (.startsWith (.toLowerCase (System/getProperty "os.name")) "windows"))
+
 (deftask check-node-modules []
   (with-pass-thru _
     (let [nm (io/file "node_modules")]
@@ -85,7 +88,7 @@
         (-> fileset (add-resource tmp) commit!)))))

 (deftask write-core-analysis-caches []
-  (let [core-caches-re #"^cljs\/core(\$macros)?\.(cljs\.cache\.aot|cljc\.cache)\.json$"
+  (let [core-caches-re #"^cljs[\\\/]core(\$macros)?\.(cljs\.cache\.aot|cljc\.cache)\.json$"
         tmp (tmp-dir!)]
     (comp
       (with-pre-wrap fileset
@@ -105,13 +108,13 @@
 (deftask sift-cljs-resources []
   (comp
     (sift :add-jar
-      {'org.clojure/clojure #"^clojure/template\.clj"
+      {'org.clojure/clojure #"^clojure[\\\/]template\.clj"
        'org.clojure/clojurescript
-       #"^cljs/(test\.cljc|core\.cljs\.cache\.aot\.edn|spec(\.cljc|/test\.clj[sc]|/impl/gen\.cljc))$"}
-      :move {#"^main.out/((cljs|clojure|cognitect|lumo|lazy_map).*)" "$1"})
+       #"^cljs/(test\.cljc|core\.cljs\.cache\.aot\.edn|spec(\.cljc|[\\\/]test\.clj[sc]|[\\\/]impl[\\\/]gen\.cljc))$"}
+      :move {#"^main.out[\\\/]((cljs|clojure|cognitect|lumo|lazy_map).*)" "$1"})
     (sift :include #{#"^main.js" #"^bundle.js" #"^cljs(?!\.js)"
-                     #"^clojure" #"^cognitect" #"^lumo/" #"^lazy_map/"})
-    (sift :include #{#"^cljs\/core\.cljs\.cache\.json$"} :invert true)))
+                     #"^clojure" #"^cognitect" #"^lumo[\\\/]" #"^lazy_map[\\\/]"})
+    (sift :include #{#"^cljs[\\\/]core\.cljs\.cache\.json$"} :invert true)))

 (deftask compile-cljs []
   (cljs :compiler-options {:hashbang false
@@ -152,7 +155,9 @@
    without having to recompile CLJS"
   []
   (with-pass-thru _
-    (dosh "cp" "-R" "target" "resources_bak")))
+    (if windows?
+      (dosh "xcopy" "target" "resources_bak" "/s" "/e" "/y")
+      (dosh "cp" "-R" "target" "resources_bak"))))

 (deftask aot-macros []
   (with-pass-thru _


sends_gelf sg added to all mesos instances

--- src/terraboot/cluster.clj
+++ src/terraboot/cluster.clj
@@ -182,6 +182,7 @@
            max-number-of-public-slaves]}]
   (let [public-subnets (mapv #(id-of "aws_subnet" (stringify  vpc-name "-public-" %)) azs)
         private-subnets (mapv #(id-of "aws_subnet" (stringify vpc-name "-private-" %)) azs)
+        vpc-unique (fn [name] (str vpc-name "-" name))
         cluster-identifier (str vpc-name "-" cluster-name)
         cluster-unique (fn [name] (str cluster-identifier "-" name))
         cluster-resource (partial resource cluster-unique)
@@ -317,7 +318,8 @@
                   cluster-unique
                   {:image_id current-coreos-ami
                    :instance_type "m4.large"
-                   :sgs (mapv cluster-unique ["master-security-group" "admin-security-group"])
+                   :sgs (concat (mapv cluster-unique ["master-security-group" "admin-security-group"])
+                                [(vpc-unique "sends_gelf")])
                    :role (cluster-unique "master-role")
                    :public_ip true
                    :tags {:Key "role"
@@ -377,7 +379,8 @@
                   cluster-unique
                   {:image_id current-coreos-ami
                    :instance_type "m4.large"
-                   :sgs (mapv cluster-unique ["public-slave-security-group"])
+                   :sgs [(cluster-unique "public-slave-security-group")
+                         (vpc-unique "sends_gelf")]
                    :role (cluster-unique "slave-role")
                    :public_ip true
                    :tags {:Key "role"
@@ -428,7 +431,8 @@
                   cluster-unique
                   {:image_id current-coreos-ami
                    :instance_type "m4.large"
-                   :sgs (mapv cluster-unique ["slave-security-group"])
+                   :sgs [(cluster-unique "slave-security-group")
+                         (vpc-unique "sends_gelf")]
                    :role (cluster-unique "slave-role")
                    :tags {:Key "role"
                           :PropagateAtLaunch "true"


Bump version

Bump version

--- build.boot
+++ build.boot
@@ -1,5 +1,5 @@
 (def project 'hangul-utils)
-(def version "0.1.0-SNAPSHOT")
+(def version "0.1.1-SNAPSHOT")

 (set-env! :resource-paths #{"resources" "src"}
           :source-paths #{"test"}


Add the tests to source-paths

Add the tests to source-paths

--- build.boot
+++ build.boot
@@ -1,6 +1,5 @@
 (set-env!
- :source-paths #{"src/main/java"}
- :test-paths #{"src/test/java"}
+ :source-paths #{"src/main/java" "src/test/java"}
  :dependencies '[[junit "4.12" :scope "test"]])

 (def +version+ "0.1.0")
@@ -18,7 +17,6 @@
 (deftask junit
   "Run the jUnit test runner."
   []
-  (set-env! :source-paths #(clojure.set/union % (get-env :test-paths)))
   (with-pre-wrap fileset
     fileset))


bump some deps

bump some deps

--- build.boot
+++ build.boot
@@ -11,7 +11,7 @@
                  [cljsjs/react-with-addons    "15.3.1-0"       :scope "test"]
                  [cljsjs/react-dom            "15.3.1-0"       :scope "test"
                   :exclusions [cljsjs/react]]
-                 [com.cognitect/transit-clj   "0.8.293"        :scope "test"]
+                 [com.cognitect/transit-clj   "0.8.297"        :scope "test"]
                  [org.clojure/core.async      "0.2.395"        :scope "test"]
                  [devcards                    "0.2.2"          :scope "test"
                   :exclusions [cljsjs/react cljsjs/react-dom]]
@@ -20,13 +20,13 @@
                  [adzerk/boot-cljs            "1.7.228-2"      :scope "test"]
                  [adzerk/boot-cljs-repl       "0.3.3"          :scope "test"]
                  [adzerk/boot-test            "1.1.2"          :scope "test"]
-                 [crisptrutski/boot-cljs-test "0.2.2-SNAPSHOT" :scope "test"]
+                 [crisptrutski/boot-cljs-test "0.3.0" :scope "test"]
                  [adzerk/boot-reload          "0.4.13"         :scope "test"]
                  [adzerk/bootlaces            "0.1.13"         :scope "test"]
                  [org.clojure/tools.nrepl     "0.2.12"         :scope "test"]
                  [org.clojure/tools.namespace "0.3.0-alpha3"   :scope "test"]
                  [weasel                      "0.7.0"          :scope "test"]
-                 [boot-codox                  "0.10.1"         :scope "test"]])
+                 [boot-codox                  "0.10.2"         :scope "test"]])

 (require
  '[adzerk.boot-cljs      :refer [cljs]]


Fix bug relating to ambiguous "name" column for the "in" operator

This work is intended to fix the test failure that we have right
now for fact subqueries that use the `in` operator and try to
join on the `name` field.  The problem is that "name" was ambiguous;
it could have been referring to either `certname_facts.name`, or
to `certnames.name` (which we were `JOIN`ing in to the query).

We decided that using a subselect in our `WHERE` clause (instead of
that `JOIN`) was cleaner, since the only reason we were `JOIN`ing
in the `certnames` table was to check the `deactivated` field (i.e.,
we weren't actually selecting any fields from that table).  This
commit switches the logic for checking the `active` status to use
that approach.

As a side effect, it turned out that our entire infrastructure for
supporting `JOIN` clauses as a generic part of the query compilation
was no longer being used by any of the other code, so I discussed
with Nick and we decided to go ahead and remove it for now.

--- src/com/puppetlabs/puppetdb/query.clj
+++ src/com/puppetlabs/puppetdb/query.clj
@@ -6,8 +6,8 @@
 ;; the "compiled" form of the query, and then to turn that into a complete SQL
 ;; query.
 ;;
-;; The compiled form of a query consists of a map with three keys: `where`,
-;; `joins`, and `params`. The `where` key contains SQL for querying that
+;; The compiled form of a query consists of a map with two keys: `where`
+;; and `params`. The `where` key contains SQL for querying that
 ;; particular predicate, written in such a way as to be suitable for placement
 ;; after a `WHERE` clause in the database. `params` contains, naturally, the
 ;; parameters associated with that SQL expression. For instance, a resource
@@ -16,15 +16,7 @@
 ;;     {:where "certname_catalogs.certname = ?"
 ;;      :params ["foo.example.com"]}
 ;;
-;; The `joins` key contains a list of additional tables that need to be
-;; included in the query in order for the `where` clause to work properly. Note
-;; that for resources, the `certname_catalogs` and `catalog_resources` tables
-;; are always included, and for facts the `certname_facts` table is always
-;; included.
-;;
-;; The tables referenced in the `joins` key of the final compiled query are
-;; turned into proper `JOIN` clauses by the `build-join-expr` function. The
-;; `joins` and `where` keys are then inserted into a template query to return
+;; The `where` key is then inserted into a template query to return
 ;; the final result as a string of SQL code.
 ;;
 ;; The compiled query components can be combined by operators such as `AND` or
@@ -98,13 +90,11 @@
   (when (empty? terms)
     (throw (IllegalArgumentException. (str op " requires at least one term"))))
   (let [compiled-terms (map #(compile-term ops %) terms)
-        joins  (distinct (mapcat :joins compiled-terms))
         params (mapcat :params compiled-terms)
         query  (->> (map :where compiled-terms)
                     (map #(format "(%s)" %))
                     (string/join (format " %s " (string/upper-case op))))]
-    {:joins  joins
-     :where  query
+    {:where  query
      :params params}))

 (def compile-and
@@ -190,40 +180,13 @@
   (let [{:keys [where] :as compiled-subquery} (compile-term ops subquery)]
     (assoc compiled-subquery :where (format "%s IN (%s)" field where))))

-(defn join-tables
-  "Constructs the appropriate join statement to `table` for a query of the
-  specified `kind`."
-  [kind table]
-  {:pre [(keyword? kind)
-         (keyword? table)]
-   :post [(string? %)]}
-  (condp = [kind table]
-        [:fact :certnames]
-        "INNER JOIN certnames ON certname_facts.certname = certnames.name"
-
-        [:resource :certnames]
-        "INNER JOIN certnames ON certname_catalogs.certname = certnames.name"))
-
-(defn build-join-expr
-  "Constructs the entire join statement from `lhs` to each table specified in
-  `joins`."
-  [lhs joins]
-  {:pre [(keyword? lhs)
-         (or (nil? joins)
-             (sequential? joins))]
-   :post [(string? %)]}
-  (->> joins
-       (map #(join-tables lhs %))
-       (string/join " ")))
-
 (defn resource-query->sql
   "Compile a resource query, returning a vector containing the SQL and
   parameters for the query. All resource columns are selected, and no order is applied."
   [ops query]
   {:post [valid-jdbc-query? %]}
-  (let [{:keys [where joins params]} (compile-term ops query)
-        join-stmt (build-join-expr :resource joins)
-        sql (format "SELECT %s FROM catalog_resources JOIN certname_catalogs USING(catalog) %s WHERE %s" (string/join ", " resource-columns) join-stmt where)]
+  (let [{:keys [where params]} (compile-term ops query)
+        sql (format "SELECT %s FROM catalog_resources JOIN certname_catalogs USING(catalog) WHERE %s" (string/join ", " resource-columns) where)]
     (apply vector sql params)))

 (defn fact-query->sql
@@ -231,9 +194,8 @@
   for the query. All fact columns are selected, and no order is applied."
   [ops query]
   {:post [valid-jdbc-query? %]}
-  (let [{:keys [where joins params]} (compile-term ops query)
-        join-stmt (build-join-expr :fact joins)
-        sql (format "SELECT %s FROM certname_facts %s WHERE %s" (string/join ", " (map #(str "certname_facts." %) fact-columns)) join-stmt where)]
+  (let [{:keys [where params]} (compile-term ops query)
+        sql (format "SELECT %s FROM certname_facts WHERE %s" (string/join ", " (map #(str "certname_facts." %) fact-columns)) where)]
     (apply vector sql params)))

 (defn node-query->sql
@@ -267,8 +229,8 @@

          ;; {in,}active nodes.
          [["node" "active"]]
-         {:joins [:certnames]
-          :where (format "certnames.deactivated IS %s" (if value "NULL" "NOT NULL"))}
+         {
+           :where (format "certname_catalogs.certname IN (SELECT name FROM certnames WHERE deactivated IS %s)" (if value "NULL" "NOT NULL"))}

          ;; param joins.
          [["parameter" (name :when string?)]]
@@ -348,9 +310,8 @@
           :params [value]}

          [["node" "active"]]
-         {:joins [:certnames]
-          :where (format "certnames.deactivated IS %s" (if value "NULL" "NOT NULL"))}
-
+         {
+          :where (format "certname_facts.certname IN (SELECT name FROM certnames WHERE deactivated IS %s)" (if value "NULL" "NOT NULL"))}
          :else
          (throw (IllegalArgumentException. (str path " is not a queryable object for facts")))))


removing some useless TODO

removing some useless TODO

--- src/thehex/notube/cli.clj
+++ src/thehex/notube/cli.clj
@@ -25,7 +25,6 @@
    ;; A boolean option defaulting to nil
    ["-h" "--help"]])

-;; TODO: doesnt need to be the main app, could be a fn that core.clj calls
 (defn -main [& args]
   (let [clargs (parse-opts args cli-options)
         opts (:options clargs)]


Address comments

Address comments

--- storm-core/src/clj/backtype/storm/daemon/logviewer.clj
+++ storm-core/src/clj/backtype/storm/daemon/logviewer.clj
@@ -190,7 +190,7 @@
       logs)))

 (defn per-workerdir-cleanup
-  "Delete the oldest files in overloaded worker log dir"
+  "Delete the oldest files in each overloaded worker log dir"
   [^File root-dir size]
   (dofor [worker-dir (get-all-worker-dirs root-dir)]
     (let [filtered-logs (filter #(not (is-active-log %)) (.listFiles worker-dir))
@@ -367,6 +367,9 @@
 (defn- daemon-download-link [fname]
   [[:p (link-to (url-format "/daemondownload/%s" fname) "Download Full File")]])

+(defn- is-txt-file [fname]
+  (re-find #"\.(log.*|txt|yaml|pid)$" fname))
+
 (def default-bytes-per-page 51200)

 (defn log-page [fname start length grep user root-dir]
@@ -390,9 +393,8 @@
                length (if length
                        (min 10485760 length)
                        default-bytes-per-page)
-              is-txt-file (re-find #"\.(log.*|txt|yaml|pid)$" fname)
               log-string (escape-html
-                           (if is-txt-file
+                           (if (is-txt-file fname)
                              (if start
                                (page-file path start length)
                                (page-file path length))
@@ -405,7 +407,7 @@
                           (filter #(.contains % grep))
                           (string/join "\n"))
                      log-string)])
-            (let [pager-data (if is-txt-file (pager-links fname start length file-length) nil)]
+            (let [pager-data (if (is-txt-file fname) (pager-links fname start length file-length) nil)]
               (html (concat (log-file-selection-form reordered-files-str "log") ; list all files for this topology
                             pager-data
                             (download-link fname)
@@ -420,7 +422,7 @@

 (defn daemonlog-page [fname start length grep user root-dir]
   (if (or (blank? (*STORM-CONF* UI-FILTER))
-        (authorized-log-user? user fname *STORM-CONF*)) ;; how to deal with this???????????
+        (authorized-log-user? user fname *STORM-CONF*))
     (let [file (.getCanonicalFile (File. root-dir fname))
           file-length (.length file)
           path (.getCanonicalPath file)
@@ -436,9 +438,8 @@
               files-str (for [file log-files]
                           (.getName file))
               reordered-files-str (conj (filter #(not= fname %) files-str) fname)
-              is-txt-file (re-find #"\.(log.*|txt|yaml|pid)$" fname)
               log-string (escape-html
-                           (if is-txt-file
+                           (if (is-txt-file fname)
                              (if start
                                (page-file path start length)
                                (page-file path length))
@@ -451,7 +452,7 @@
                        (filter #(.contains % grep))
                        (string/join "\n"))
                      log-string)])
-            (let [pager-data (if is-txt-file (pager-links fname start length file-length) nil)]
+            (let [pager-data (if (is-txt-file fname) (pager-links fname start length file-length) nil)]
               (html (concat (log-file-selection-form reordered-files-str "daemonlog") ; list all daemon logs
                       pager-data
                       (daemon-download-link fname)
@@ -561,9 +562,6 @@
         (log-error ex)
         (ring-response-from-exception ex))))
   (GET "/download/:file" [:as {:keys [servlet-request servlet-response log-root]} file & m]
-    ;; We do not use servlet-response here, but do not remove it from the
-    ;; :keys list, or this rule could stop working when an authentication
-    ;; filter is configured.
     (try
       (let [user (.getUserName http-creds-handler servlet-request)]
         (download-log-file file servlet-request servlet-response user log-root))
@@ -571,9 +569,6 @@
         (log-error ex)
         (ring-response-from-exception ex))))
   (GET "/daemondownload/:file" [:as {:keys [servlet-request servlet-response daemonlog-root]} file & m]
-    ;; We do not use servlet-response here, but do not remove it from the
-    ;; :keys list, or this rule could stop working when an authentication
-    ;; filter is configured.
     (try
       (let [user (.getUserName http-creds-handler servlet-request)]
         (download-log-file file servlet-request servlet-response user daemonlog-root))


Added tests for per-topology classpath and per-topology environment-variables.

--- storm-core/test/clj/backtype/storm/supervisor_test.clj
+++ storm-core/test/clj/backtype/storm/supervisor_test.clj
@@ -246,8 +246,8 @@
     (let [mock-port "42"
           mock-storm-id "fake-storm-id"
           mock-worker-id "fake-worker-id"
-          mock-cp "mock-classpath"
-          exp-args-fn (fn [opts topo-opts]
+          mock-cp "/base:/stormjar.jar"
+          exp-args-fn (fn [opts topo-opts classpath]
                        (concat [(supervisor/java-cmd) "-server"]
                                opts
                                topo-opts
@@ -258,7 +258,7 @@
                                 (str "-Dstorm.id=" mock-storm-id)
                                 (str "-Dworker.id=" mock-worker-id)
                                 (str "-Dworker.port=" mock-port)
-                                "-cp" mock-cp
+                                "-cp" classpath
                                 "backtype.storm.daemon.worker"
                                 mock-storm-id
                                 mock-port
@@ -267,7 +267,8 @@
         (let [string-opts "-Dfoo=bar  -Xmx1024m"
               topo-string-opts "-Dkau=aux   -Xmx2048m"
               exp-args (exp-args-fn ["-Dfoo=bar" "-Xmx1024m"]
-                                    ["-Dkau=aux" "-Xmx2048m"])
+                                    ["-Dkau=aux" "-Xmx2048m"]
+                                    mock-cp)
               mock-supervisor {:conf {STORM-CLUSTER-MODE :distributed
                                       WORKER-CHILDOPTS string-opts}}]
           (stubbing [read-supervisor-storm-conf {TOPOLOGY-WORKER-CHILDOPTS
@@ -286,7 +287,7 @@
       (testing "testing *.worker.childopts as list of strings, with spaces in values"
         (let [list-opts '("-Dopt1='this has a space in it'" "-Xmx1024m")
               topo-list-opts '("-Dopt2='val with spaces'" "-Xmx2048m")
-              exp-args (exp-args-fn list-opts topo-list-opts)
+              exp-args (exp-args-fn list-opts topo-list-opts mock-cp)
               mock-supervisor {:conf {STORM-CLUSTER-MODE :distributed
                                       WORKER-CHILDOPTS list-opts}}]
           (stubbing [read-supervisor-storm-conf {TOPOLOGY-WORKER-CHILDOPTS
@@ -301,7 +302,39 @@
                                       mock-worker-id)
             (verify-first-call-args-for-indices launch-process
                                                 [0]
-                                                exp-args)))))))
+                                                exp-args))))
+      (testing "testing topology.classpath is added to classpath"
+        (let [topo-cp "/any/path"
+              exp-args (exp-args-fn [] [] (add-to-classpath mock-cp [topo-cp]))
+              mock-supervisor {:conf {STORM-CLUSTER-MODE :distributed}}]
+          (stubbing [read-supervisor-storm-conf {TOPOLOGY-CLASSPATH topo-cp}
+                     supervisor-stormdist-root nil
+                     supervisor/jlp nil
+                     launch-process nil
+                     current-classpath "/base"]
+                    (supervisor/launch-worker mock-supervisor
+                                              mock-storm-id
+                                              mock-port
+                                              mock-worker-id)
+                    (verify-first-call-args-for-indices launch-process
+                                                        [0]
+                                                        exp-args))))
+      (testing "testing topology.environment is added to environment for worker launch"
+        (let [topo-env {"THISVAR" "somevalue" "THATVAR" "someothervalue"}
+              exp-args (exp-args-fn [] [] mock-cp)
+              mock-supervisor {:conf {STORM-CLUSTER-MODE :distributed}}]
+          (stubbing [read-supervisor-storm-conf {TOPOLOGY-ENVIRONMENT topo-env}
+                     supervisor-stormdist-root nil
+                     supervisor/jlp nil
+                     launch-process nil
+                     current-classpath "/base"]
+                    (supervisor/launch-worker mock-supervisor
+                                              mock-storm-id
+                                              mock-port
+                                              mock-worker-id)
+                    (verify-first-call-args-for-indices launch-process
+                                                        [2]
+                                                        (merge topo-env {"LD_LIBRARY_PATH" nil}))))))))

 (deftest test-workers-go-bananas
   ;; test that multiple workers are started for a port, and test that


GET api/dash filters properly (handles `f=mine` or `f=all`)

--- src/metabase/api/dash.clj
+++ src/metabase/api/dash.clj
@@ -9,8 +9,10 @@
                              [dashboard :refer [Dashboard]]
                              [dashboard-card :refer [DashboardCard]])))

-(defendpoint GET "/" [org f] ; TODO - what to do with f ?
-  (-> (sel :many Dashboard :organization_id org)
+(defendpoint GET "/" [org f]
+  (-> (case (or (keyword f) :all) ; default value for f is `all`
+        :all (sel :many Dashboard :organization_id org)
+        :mine (sel :many Dashboard :organization_id org :creator_id *current-user-id*))
       (hydrate :creator :organization)))

 (defendpoint POST "/" [:as {:keys [body]}]


JC | #283 | Added logging for activity source file location

--- src/mooncake/activity.clj
+++ src/mooncake/activity.clj
@@ -14,12 +14,14 @@
            [org.jose4j.jws JsonWebSignature]))

 (defn load-activity-sources-from-resource [activity-resource-name]
+  (log/info (format "Loading activity sources from resource [%s]" activity-resource-name))
   (-> activity-resource-name
       io/resource
       slurp
       yaml/parse-string))

 (defn load-activity-sources-from-file [file-name]
+  (log/info (format "Loading activity sources from file [%s]" file-name))
   (-> file-name
       slurp
       yaml/parse-string))


add a new setting for `metabot-enabled` which defaults to true and only launch metabot when it's enabled.  also, remove printlns and tidy up logging a bit.

--- src/metabase/metabot.clj
+++ src/metabase/metabot.clj
@@ -13,10 +13,12 @@
             [metabase.api.common :refer [let-404]]
             [metabase.db :refer [sel]]
             [metabase.integrations.slack :as slack]
+            [metabase.models.setting :as setting]
             [metabase.task.send-pulses :as pulses]
             [metabase.util :as u]
             [metabase.util.urls :as urls]))

+(setting/defsetting metabot-enabled "Enable Metabot, which lets you search for and view your saved questions directly via Slack" "true")

 ;;; # ------------------------------------------------------------ Metabot Command Handlers ------------------------------------------------------------

@@ -37,7 +39,6 @@
                           {(if (true? dispatch-token)
                              (keyword symb)
                              dispatch-token) varr}))]
-    (println (u/format-color 'cyan verb) fn-map)
     (fn dispatch*
       ([]
        (keys-description (format "Here's what I can %s:" verb) fn-map))
@@ -147,23 +148,20 @@
     (when-let [tokens (seq (edn/read-string (str "(" (-> s
                                                          (str/replace "“" "\"") ; replace smart quotes
                                                          (str/replace "”" "\"")) ")")))]
-      (println (u/format-color 'magenta tokens))
       (apply apply-metabot-fn tokens))))

 ;;; # ------------------------------------------------------------ Metabot Input Handling ------------------------------------------------------------

 (defn- message->command-str [{:keys [text]}]
-  (u/prog1 (when (seq text)
-             (second (re-matches #"^mea?ta?boa?t\s+(.*)$" text)))
-    (println (u/format-color 'yellow <>))))
+  (when (seq text)
+    (second (re-matches #"^mea?ta?boa?t\s+(.*)$" text))))

 (defn- respond-to-message! [message response]
   (when response
     (let [response (if (coll? response) (str "```\n" (u/pprint-to-str response) "```")
                        (str response))]
       (when (seq response)
-        (println (u/format-color 'green response))
         (slack/post-chat-message! (:channel message) response)))))

 (defn- handle-slack-message [message]
@@ -181,14 +179,13 @@

 (defn- handle-slack-event [socket start-time event]
   (when-not (= socket @websocket)
-    (println "Go home websocket, you're drunk.")
+    (log/debug "Go home websocket, you're drunk.")
     (s/close! socket)
     (throw (Exception.)))

   (when-let [event (json/parse-string event keyword)]
     (when (and (human-message? event)
                (> (event-timestamp-ms event) start-time))
-      (println (u/pprint-to-str 'cyan event))
       (binding [*channel-id* (:channel event)]
         (do-async (handle-slack-message event))))))

@@ -197,10 +194,8 @@

 (defn- connect-websocket! []
   (when-let [websocket-url (slack/websocket-url)]
-    (log/info "Launching MetaBot... 🤖")
     (let [socket @(aleph/websocket-client websocket-url)]
       (reset! websocket socket)
-      (log/info "Connected to WebSocket.")
       (d/catch (s/consume (partial handle-slack-event socket (System/currentTimeMillis))
                           socket)
           (fn [error]
@@ -221,7 +216,6 @@
 (defn- start-websocket-monitor! []
   (future
     (reset! websocket-monitor-thread-id (.getId (Thread/currentThread)))
-    (log/debug "Monitor thread ID ->" (.getId (Thread/currentThread)))
     ;; Every 2 seconds check to see if websocket connection is [still] open, [re-]open it if not
     (loop []
       (Thread/sleep 500)
@@ -229,7 +223,7 @@
         (try
           (when (or (not  @websocket)
                     (s/closed? @websocket))
-            (log/info "MetaBot WebSocket is closed. < Thread" (.getId (Thread/currentThread)) ">")
+            (log/debug "MetaBot WebSocket is closed.  Reconnecting now.")
             (connect-websocket!))
           (catch Throwable e
             (log/error "Error connecting websocket:" (.getMessage e))))
@@ -240,7 +234,8 @@

    This will spin up a background thread that opens and maintains a Slack WebSocket connection."
   []
-  (when (slack/slack-token)
+  (when (and (setting/get :slack-token)
+             (= "true" (setting/get :metabot-enabled)))
     (log/info "Starting MetaBot WebSocket monitor thread...")
     (start-websocket-monitor!)))


(PE-4372) :dns-alt-names should be a required key in master settings

--- src/clj/puppetlabs/master/certificate_authority.clj
+++ src/clj/puppetlabs/master/certificate_authority.clj
@@ -22,8 +22,7 @@
    :localcacert      String
    :hostprivkey      String
    :hostpubkey       String
-   (schema/optional-key :dns-alt-names)
-                     (schema/maybe String)})
+   :dns-alt-names    (schema/maybe String)})

 (def CaSettings
   "Settings from Puppet that are necessary for CA initialization and request


Refactor collision system

Refactor collision system

--- src/particlebox/core.cljs
+++ src/particlebox/core.cljs
@@ -5,15 +5,14 @@
 (def particle-diameter (* 2 particle-radius))
 (def particle-count 10)
 (def gravitational-constant 200)
-(def speed-limit 5)
 (def initial-speed 0)
+(def bounciness 0.4)

 (def scene-width window/innerWidth)
 (def scene-height window/innerHeight)

 (def particles (atom []))
 (def particle-meshes (atom []))
-(def collided-particles (atom {}))

 (def nullv [0 0 0])

@@ -83,6 +82,10 @@
   [v]
   (Math/sqrt (apply + (map #(* % %) v))))

+(defn scale
+  [v s]
+  (map #(* % s) v))
+
 (defn direction
   "Given a vector, returns a unit vector in the same direction, optionally
 scaled."
@@ -92,6 +95,12 @@
        (if (zero? mag)
          nullv
          (map #(* (/ % mag) m) v)))))
+
+(defn project
+  "Calculates the vector projection of a in the direction of b."
+  [a b]
+  (let [scalar (apply + (map * a (direction b)))]
+    (direction b scalar)))

 (defn direction-from
   "Given two vectors, returns a unit vector representing the direction from the
@@ -126,16 +135,6 @@
   [p v all]
   (let [a (calc-accel p all)
         v (map + v a)
-
-        ;; added a speed limit here because gavitational sigularities were
-        ;; causing particles to become superaccelerated, which is kind of cool
-        ;; but generally doesn't make for a good simulation. This is needed only
-        ;; when there's no collision detection.
-        speed (magnitude v)
-        v (if (> speed speed-limit)
-            (direction v speed-limit)
-            v)
-
         p (map + p v)]
     [p v a]))

@@ -179,25 +178,28 @@
        particles

        ;; if there are collisions, calculate the appropriate adjustments to
-       ;; position and velocity, and assoc the updated particles back into the
-       ;; particles vector.
-       (apply
-        (partial assoc particles)
-        (flatten
-         (for [[a pa b pb] collisions
-               :let [dir (direction-from (:pos pa) (:pos pb))
-                     dist (distance (:pos pa) (:pos pb))
-                     bounce (direction dir (- particle-diameter dist))]]
-           [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)))))]))))))
+       ;; position and velocity.
+       (reduce
+        (fn [ps [a-idx a-key a-fn
+                 b-idx b-key b-fn]]
+          (-> ps
+              (update-in [a-idx a-key] a-fn)
+              (update-in [b-idx b-key] b-fn)))
+
+        particles
+
+        (for [[a pa b pb] collisions
+              :let [dir (direction-from (:pos pa) (:pos pb))
+                    dist (distance (:pos pa) (:pos pb))
+                    bounce (direction dir (/ (- particle-diameter dist) 2))]]
+          [a :pos #(map - % bounce)
+           a :vel #(map -
+                        %
+                        (scale (project % dir) bounciness))
+           b :pos #(map + % bounce)
+           b :vel #(map -
+                        %
+                        (scale (project % (direction dir -1)) bounciness))])))))

 (defn generate-particles
   "Creates the given number of particles, and arranges them in the universe


route for staging/production public directly

--- src/terraboot/cluster.clj
+++ src/terraboot/cluster.clj
@@ -430,6 +430,11 @@
                                       :zone_id (cluster-output-of "aws_elb" "public-slaves" "zone_id")
                                       :evaluate_target_health true}})

+             (route53_record cluster-identifier
+                             {:alias {:name (cluster-output-of "aws_elb" "public-slaves" "dns_name")
+                                      :zone_id (cluster-output-of "aws_elb" "public-slaves" "zone_id")
+                                      :evaluate_target_health true}})
+
              (cluster-resource "template_file" "slave-user-data"
                                {:template (mesos-slave-user-data)
                                 :vars {:aws-region region


Eliminated tmp file leak

Eliminated tmp file leak

--- library/src/doo/core.clj
+++ library/src/doo/core.clj
@@ -29,13 +29,12 @@

 (def base-dir "runners/")

-;; The runner keyword is not necessary
 (defn runner-path! [runner filename]
   "Creates a temp file for the given runner resource file"
   (let [full-path (str base-dir filename)
         runner-path (.getAbsolutePath
                      (doto (File/createTempFile (name runner) ".js")
-                       ;; (.deleteOnExit)
+                       (.deleteOnExit)
                        (#(io/copy (slurp (io/resource full-path)) %))))]
     runner-path))


Fix nested testing-ctx test in context-test.

--- test/fixturex/context_test.clj
+++ test/fixturex/context_test.clj
@@ -45,9 +45,9 @@
   (testing-ctx "hotter ryan" [:ryan 8]
     (is (= 6 pam))
     (is (= 8 ryan))
-    (testing-fx "equally hot pam" [:ryan 9
-                                   :pam ryan]
-      (is (= ryan pam 9)))))
+    (testing-ctx "equally hot pam" [:ryan 9
+                                    :pam ryan]
+      (is (= 9 ryan pam)))))

 (deftest-ctx test-lookup [:hey 1]
   (testing "sanity" (is (= hey 1)))


update misaki.html.core/footer to add css class

--- src/misaki/html/core.clj
+++ src/misaki/html/core.clj
@@ -263,7 +263,7 @@
   "Make default footer."
   [& p]
   [:footer {:class "footer"}
-   [:p {:class "right"} (link "Back to top" "#")]
+   [:p {:class "right back_to_top"} (link "Back to top" "#")]
    [:p p]])

 (defn post-list


adopted friboo to check for user.json and client.json

--- src/org/zalando/stups/friboo/system/credentials.clj
+++ src/org/zalando/stups/friboo/system/credentials.clj
@@ -17,35 +17,39 @@
 (extend File json/JSONWriter
   {:-write serialize-file})

-
 (defn- check-file
   "Checks a file if it has new credentials and updates the credentials atom."
-  [file credentials]
+  [type file credentials]
   (try
-    (let [content (slurp file)
-          data (json/read-str content)]
-      (when (and data (not (empty? data)) (not= data @credentials)
-        (reset! credentials data)
-        (log/info "New credentials found for %s." (select-keys data ["application_username" "client_id"])))))
+    (let [data (-> file slurp json/read-str)]
+      (when (and (not-empty data) (not= data (get @credentials type)))
+        (swap! credentials assoc type data)
+        (log/info "New credentials for %s in %s found." type file)))
     (catch Exception e
-      (log/warn "Cannot read credentials file %s because %s." file (str e)))))
+      (log/warn "Cannot read %s credentials file %s because %s." type file (.getMessage e)))))

-; configuration map has to contain :file key
+; configuration map has to contain :dir key
 ; credentials key will be set during initilization and holds atom with credentials
 (defrecord CredentialUpdater [configuration credentials]
   component/Lifecycle

   (start [this]
-    (let [^File file (io/file (require-config configuration :file))
-          credentials (atom nil)]
-      (log/info "Watching %s for credentials." file)
-      (check-file file credentials)
-      (start-watch [{:path        (.getParent file)
-                     :event-types [:create :modify]
-                     :callback    (fn [_ filename]
-                                    (when (= filename (str file))
-                                      (check-file file credentials)))}])
-      (assoc this :credentials credentials)))
+    (if-let [dir (:dir configuration)]
+      (let [credentials (atom {})
+            dir (.getAbsolutePath (io/file dir))]
+        (doseq [[type file] {:user   "user.json"
+                             :client "client.json"}]
+          (swap! credentials assoc type nil)
+          (let [source (io/file dir file)]
+            (log/info "Watching %s for %s credentials." source type)
+            (start-watch [{:path        (.getParent source)
+                           :event-types [:create :modify]
+                           :callback    (fn [_ filename]
+                                          (when (= filename (str source))
+                                            (check-file type source credentials)))}])
+            (check-file type source credentials)))
+        (assoc this :credentials credentials))
+      (log/warn "No credentials directory given, will not watch for any credentials.")))

   (stop [this]
     ; unfortunatly, start-watch does not provide stop-watch


whitespace.

whitespace.

--- namespaces/common/src/main/clojure/immutant/util.clj
+++ namespaces/common/src/main/clojure/immutant/util.clj
@@ -71,7 +71,7 @@
             .getAddress
             .getHostAddress))
       (catch Exception e
-        (log/warn (format "Unable to obtain %s interface address (%s)" iface, e) )))))
+        (log/warn (format "Unable to obtain %s interface address (%s)" iface, e))))))

 (def ^{:doc "Looks up the ip address for the AS management interface."}
   management-interface-address


checkpoint in refactoring

checkpoint in refactoring

--- src/structural_typing/mechanics/compiling_types.clj
+++ src/structural_typing/mechanics/compiling_types.clj
@@ -8,6 +8,9 @@
   (let [lifted (map lift preds)
         combined (apply juxt lifted)]
     (comp e/lefts combined)))
+
+(defn compile-path [path]
+  [(apply specter/comp-paths path) identity identity])

 ;; TODO: This code could be made tenser. It cries out for transients.

@@ -41,24 +44,22 @@
 (defn run-select [compiled-path object-to-check]
   (e/make-either (specter/compiled-select compiled-path object-to-check)))

-(defn compile-path-check [[path preds]]
-  (vector path
-          (apply specter/comp-paths path)
-          (compile-predicates preds)))
-
-(defn run-path-check [object-to-check [original-path compiled-path run-path-preds]]
-  (e/either [x (run-select compiled-path object-to-check)]
-               (oopsies-for-bad-path object-to-check original-path)
-               (oopsies-for-one-path object-to-check
-                                     x
-                                     original-path
-                                     run-path-preds)))
+(defn compile-path-check [[original-path preds]]
+  (let [[compiled-path leaf-selector path-describer] (compile-path original-path)
+        compiled-preds (compile-predicates preds)]
+    (fn [object-to-check]
+      (e/either [x (run-select compiled-path object-to-check)]
+                (oopsies-for-bad-path object-to-check original-path)
+                (oopsies-for-one-path object-to-check
+                                      (leaf-selector x)
+                                      original-path
+                                      compiled-preds)))))

 (defn compile-type [t]
   ;; Note that the path-checks are compiled once, returning a function to be run often.
   (let [compiled-path-checks (map compile-path-check t)]
     (fn [object-to-check]
       (reduce (fn [all-errors path-check]
-                (into all-errors (run-path-check object-to-check path-check)))
+                (into all-errors (path-check object-to-check)))
               []
               compiled-path-checks))))


Changed destroy! to use gl-lock instead of seperate ref.

--- src/zaffre/glterminal.clj
+++ src/zaffre/glterminal.clj
@@ -321,7 +321,7 @@
     [LWJGLUtil/PLATFORM_WINDOWS true]
       (System/setProperty "org.lwjgl.librarypath", (.getAbsolutePath (File. "natives/windows/x86_64"))))))

-(defn- init-display [title screen-width screen-height icon-paths gl-lock close-ref]
+(defn- init-display [title screen-width screen-height icon-paths gl-lock]
   (let [pixel-format       (PixelFormat.)
         context-attributes (ContextAttribs. 3 0)
         icon-array         (when icon-paths
@@ -359,7 +359,7 @@
                ; Process messages in the main thread rather than the input go-loop due to Windows only allowing
                ; input on the thread that created the window
                (Display/processMessages)
-               (or (Display/isCloseRequested) @close-ref))
+               (or (Display/isCloseRequested) (not @gl-lock)))
            (do
              (log/info "Destroying display")
              (with-gl-context gl-lock
@@ -521,8 +521,7 @@
                            cursor-xy
                            gl
                            key-chan
-                           gl-lock
-                           close]
+                           gl-lock]
   zat/ATerminal
   (get-size [_]
     [columns rows])
@@ -743,7 +742,7 @@
                            line))
                    cm))))
   (destroy! [_]
-    (ref-set close true)))
+    (reset! gl-lock false)))

 (defn make-terminal
@@ -792,8 +791,6 @@
                                                    (make-font else-font Font/PLAIN font-size)))
           ;; false if Display is destoyed
           gl-lock            (atom true)
-          ; Used to request Display destruction.
-          close-ref          (ref false)
           {:keys [screen-width
                   screen-height
                   character-width
@@ -802,7 +799,7 @@
                   font-texture-height
                   font-texture-image]} (get @font-textures (font-key @normal-font))
           _                  (log/info "screen size" screen-width "x" screen-height)
-          _                  (init-display title screen-width screen-height icon-paths gl-lock close-ref)
+          _                  (init-display title screen-width screen-height icon-paths gl-lock)

           font-texture       (with-gl-context gl-lock (texture-id font-texture-image))
           _                  (swap! font-textures update (font-key @normal-font) (fn [m] (assoc m :font-texture font-texture)))
@@ -895,8 +892,7 @@
                                    :fg-image-data fg-image-data
                                    :bg-image-data bg-image-data}}
                            key-chan
-                           gl-lock
-                           close-ref)]
+                           gl-lock)]
       ;; Access to terminal will be multi threaded. Release context so that other threads can access it)))
       (Display/releaseContext)
       ;; Start font file change listener thread


CMR-687: Added test for or option.

CMR-687: Added test for or option.

--- test/cmr/system_int_test/search/granule_search_test.clj
+++ test/cmr/system_int_test/search/granule_search_test.clj
@@ -443,4 +443,8 @@
     (testing "Search with wildcards in concept_id param not supported."
       (is (= {:status 400
               :errors [(msg/invalid-pattern-opt-setting-msg #{:concept-id :echo-collection-id :echo-granule-id})]}
-             (search/find-refs :granule {:concept_id "G*" "options[concept_id]" {:pattern true}}))))))
+             (search/find-refs :granule {:concept_id "G*" "options[concept_id]" {:pattern true}}))))
+    (testing "OR option is not supported for anything but attribute, science-keywords"
+      (is (= {:status 400
+              :errors [(msg/invalid-or-opt-setting-msg :concept-id)]}
+             (search/find-refs :granule {:concept-id "G" "options[concept_id]" {:or true}}))))))


whitespace

whitespace

--- sidecar/src/figwheel_sidecar/config_check/type_check.clj
+++ sidecar/src/figwheel_sidecar/config_check/type_check.clj
@@ -483,7 +483,8 @@
         count-uniq (float (count freqs))
         sum   (float (count l))
         average (/ count-uniq sum)]
-    (into {} (map (fn [[k v]] [k (- (/ v count-uniq) average)]) freqs))))
+    (into {} (map (fn [[k v]] [k (- (/ v count-uniq)
+                                   average)]) freqs))))

 (defn max-val [mp]
   (reduce (fn [[k v] [k1 v1]] (if (< v v1) [k1 v1] [k v])) ['_ 0] mp))


Moving render of build timings to correct om life cycle stage.

--- src-cljs/frontend/components/build_timings.cljs
+++ src-cljs/frontend/components/build_timings.cljs
@@ -198,8 +198,8 @@
 ;;;; Main component
 (defn build-timings [{:keys [build project plan]} owner]
   (reify
-    om/IDidMount
-    (did-mount [_]
+    om/IDidUpdate
+    (did-update [_ _ _]
       (if (project-model/show-build-timing? project plan)
         (draw-chart! build)
         (analytics/track-build-timing-upsell-impression {:org-name (:org_name plan)


Back out primary name change

Back out primary name change

--- src-cljs/frontend/components/pieces/button.cljs
+++ src-cljs/frontend/components/pieces/button.cljs
@@ -181,19 +181,19 @@
      [;; Primary buttons
       [(button {:kind :primary
                 :on-click #(js/alert "Clicked!")}
-               "Default")
+               "Primary")
        (button {:disabled? true
                 :kind :primary
                 :on-click #(js/alert "Clicked!")}
-               "Default Disabled")
+               "Primary Disabled")
        (button {:fixed? true
                 :kind :primary
                 :on-click #(js/alert "Clicked!")}
-               "Default Fixed")
+               "Primary Fixed")
        (button {:kind :primary
                 :size :small
                 :on-click #(js/alert "Clicked!")}
-               "Default Small")]
+               "Primary Small")]

       ;; Secondary buttons
       [(button {:on-click #(js/alert "Clicked!")}
@@ -281,11 +281,11 @@
      [;; Primary link buttons
       [(link {:kind :primary
               :href "#"}
-             "Default Link")
+             "Primary Link")
        (link {:fixed? true
               :kind :primary
               :href "#"}
-             "Default Link Fixed")
+             "Primary Link Fixed")
        (link {:kind :primary
               :href "#"
               :size :small}


Add href so the link can be focused

Add href so the link can be focused

--- src-cljs/frontend/components/pieces/button.cljs
+++ src-cljs/frontend/components/pieces/button.cljs
@@ -351,6 +351,7 @@
        (icon {:label "Bordered GitHub icon button"
               :bordered? true}
              (icon/github))
-       (icon-link {:label "Bordered Bitbucket icon link-button"
+       (icon-link {:href "#"
+                   :label "Bordered Bitbucket icon link-button"
                    :bordered? true}
                   (icon/bitbucket))]])))


Use stops-layer over stop-markers

Use stops-layer over stop-markers

--- src/cljs/gtfve/components/maps_canvas/google.cljs
+++ src/cljs/gtfve/components/maps_canvas/google.cljs
@@ -223,10 +223,8 @@
           (when (and gmap
                      (some #{:stops?} modes)
                      (<= 16 (.getZoom gmap)))
-            (om/build-all stop-marker
-                          (map second (:stops data))
-                          {:key :db/id
-                           :state {:gmap gmap}}))
+            (om/build stops-layer (:stops data)
+                      {:state {:gmap gmap}}))
           (when gmap
             (om/build-all search-stop-marker stops {:key :stop/name
                                                     :state {:gmap gmap


All timestamps are rewound by 1 hour so the 1am entry now represents 00.00 -> 01.00 on the heatmap. This fixes the start and end gap problems. Any excess data is now trimmed (although it's now unlikely the API will return >14 days)

--- src/cljs/kixi/hecuba/tabs/hierarchy/tapestry.cljs
+++ src/cljs/kixi/hecuba/tabs/hierarchy/tapestry.cljs
@@ -235,44 +235,52 @@
     (->> (t/plus d (t/weeks 2))
          (tf/unparse (tf/formatter "yyyy-MM-dd HH:mm:ss")))))

+(defn rewind-one-hour [date]
+  (let [d (tf/parse (tf/formatter "yyyy-MM-dd'T'HH:mm:ssZ") date)]
+    (->> (t/minus d (t/hours 1))
+         (tf/unparse (tf/formatter "yyyy-MM-dd HH:mm:ss")))))
+
 (defn process-data
   "This will currently only work for hourly data"
-  [data]
+  [start-date data]
   ;; step 1
-  (let [remove-times  (map #(-> %
+  (let [fmt (tf/formatter "yyyy-MM-dd")
+        start-date-ts (tf/parse fmt start-date)
+        dates (map (fn [d] (tf/unparse fmt d)) (map #(t/plus start-date-ts (t/days %)) (range 0 x-readings)))
+        ;;
+        rewind-time  (map #(assoc % :timestamp (rewind-one-hour (:timestamp %))) data) ;; rewind timestamps by an hour
+        remove-times (map #(-> %
                                 (assoc-in [:value] (js/parseFloat (:value %)))
                                 (assoc-in [:date] (.slice (:timestamp %) 0 10))
                                 (assoc-in [:time] (.slice (:timestamp %) 11 19))
                                 (dissoc :sensor_id)
-                                (dissoc :timestamp)) data)
-        grouped-data  (group-by :date remove-times)]
-    (if (not= (count grouped-data) x-readings) ;; ensure there are 2 weeks worth
-      ((throw (js/Error. (str "We don't have 14 days of data here (" (count grouped-data) " days)")))))
-
-    ;; step 2
-    (let [with-hours    (apply merge
-                               (map (fn [[k v]]
-                                      (hash-map k (map (fn [m] {:hour (js/parseInt (.slice (:time m) 0 2))
-                                                                :value (:value m)}) v))) grouped-data))
-          without-blank (apply merge
-                               (map (fn [[k v]]
-                                      (let [hours (->> v (map :hour) set)]
-                                        (hash-map k (apply merge v
-                                                           (remove nil? (map (fn [i]
-                                                                               (if-not (contains? hours i) {:hour i :value nil})) (range 0 y-readings))))))) with-hours))
-          sorted-groups (apply merge
-                               (map (fn [[k v]]
-                                      (hash-map k (sort-by :hour v))) without-blank))
-          sorted-top-map (into (sorted-map) sorted-groups)
-          flattened (reduce concat (map (fn [[k v]]
-                                          (map :value v)) sorted-top-map))
-          rotated (flatten (reverse (apply map list (matrix x-readings y-readings flattened))))]
-      rotated)))
-
-(defn load-heatmap-data [heatmap-data-chan tapestry-data resp]
+                                (dissoc :timestamp)) rewind-time)
+        grouped-data  (take x-readings (group-by :date remove-times))
+        grouped-data-map (into {} (map #(apply hash-map %) grouped-data))
+        grouped-data-patched (into {} (map (fn [date] (hash-map date (if (contains? grouped-data-map date) (get grouped-data-map date) []))) dates))
+        with-hours    (apply merge
+                            (map (fn [[k v]]
+                                   (hash-map k (map (fn [m] {:hour (js/parseInt (.slice (:time m) 0 2))
+                                                             :value (:value m)}) v))) grouped-data-patched))
+       without-blank (apply merge
+                            (map (fn [[k v]]
+                                   (let [hours (->> v (map :hour) set)]
+                                     (hash-map k (apply merge v
+                                                        (remove nil? (map (fn [i]
+                                                                            (if-not (contains? hours i) {:hour i :value nil})) (range 0 y-readings))))))) with-hours)) ;; add nil values for missing times
+       sorted-groups (apply merge
+                            (map (fn [[k v]]
+                                   (hash-map k (sort-by :hour v))) without-blank))
+       sorted-top-map (into (sorted-map) sorted-groups)
+       flattened (reduce concat (map (fn [[k v]]
+                                       (map :value v)) sorted-top-map))
+       rotated (flatten (reverse (apply map list (matrix x-readings y-readings flattened))))]
+    rotated))
+
+(defn load-heatmap-data [heatmap-data-chan tapestry-data start-date resp]
   (om/update! tapestry-data [:error] false)
   (try
-    (let [new-data (process-data (:measurements resp))
+    (let [new-data (process-data start-date (:measurements resp))
           new-dates (distinct (map (fn [{:keys [timestamp]}]
                                      (let [date-part (.substring timestamp 0
                                                                  (.indexOf timestamp "T"))
@@ -302,10 +310,11 @@
   (let [[type device_id] (str/split sensor #"~")
         start-ts (data/date->amon-timestamp start-date)
         end-ts   (calculate-end-date start-date)
-        url (data/url-str start-ts end-ts entity_id device_id type :hourly_rollups)]
+        url (data/url-str start-ts end-ts entity_id device_id type :hourly_rollups)
+        url "http://localhost:8000/foo1.json"]
     (om/update! tapestry-data :date start-date)
     (GET url
-         {:handler #(load-heatmap-data data-chan tapestry-data %)
+         {:handler #(load-heatmap-data data-chan tapestry-data start-date %)
           :error-handler (fn [{:keys [status status-text]}]
                            (log "There was an error. Status " status " Text " status-text))
           :headers {"Accept" "application/json"}


Fixed draw-open

Fixed draw-open

--- src/cljs/wombats_web_client/components/arena.cljs
+++ src/cljs/wombats_web_client/components/arena.cljs
@@ -73,6 +73,11 @@
   (draw-image canvas-element
               "images/poison/poison_vial.png"
               x y width height)
+  (draw-meta canvas-element contents meta x y width height))
+
+(defn- draw-open
+  "Draws whatever belongs on an open cell"
+  [canvas-element contents meta x y width height]
   (draw-meta canvas-element contents meta x y width height))

 (defn- draw-zakano
@@ -159,25 +164,6 @@

         (js/console.log type)))))

-(defn- draw-open
-  "Draws whatever belongs on an open cell"
-  [canvas-element contents meta x y width height]
-  (doseq [{type :type
-           orientation :orientation} meta]
-    (case type
-      :shot
-      (draw-image canvas-element
-                  (case orientation
-                    :n "images/fire_shot/fire_shot_up.png"
-                    :w "images/fire_shot/fire_shot_left.png"
-                    :e "images/fire_shot/fire_shot_right.png"
-                    :s "images/fire_shot/fire_shot_down.png")
-                  x
-                  y
-                  width
-                  height)
-      nil)))
-
 (defn- draw-cell
   "Draw an arena cell on the canvas"
   [cell x y width height canvas-element]


Simplify plot layout.

Simplify plot layout.

--- metlog-vault/src-client/metlog_client/metlog.cljs
+++ metlog-vault/src-client/metlog_client/metlog.cljs
@@ -51,7 +51,7 @@
     1024))

 (defn series-tsplot [ series ]
-  (let [ series-state (atom { :series-name (:name series)} ) ]
+  (let [ series-state (atom { }) ]
     (reagent/create-class
      {:display-name (str "series-tsplot-" (:name series))
       :component-did-update
@@ -64,7 +64,7 @@
         (tsplot-fetch-and-draw (reagent/dom-node this) (:name series) (dom-width (.-parentNode (reagent/dom-node this)))))

       :reagent-render
-      (fn [ width ]
+      (fn [ ]
         @window-width
         [:canvas { :width (dom-width (:dom-node @series-state)) :height 180}])})))


Decouple plot drawing from plot fetching.

--- metlog-vault/src-client/metlog_client/metlog.cljs
+++ metlog-vault/src-client/metlog_client/metlog.cljs
@@ -38,12 +38,14 @@
             (fn [ data ]
               (cb data))))

-(defn tsplot-fetch-and-draw [ canvas series-name width ]
+(defn tsplot-draw [ canvas width series-data ]
   (let [ ctx (.getContext canvas "2d")]
-    (go
-      (tsplot/draw ctx width 180  (<! (<<< fetch-series-data
-                                           series-name
-                                           @query-window-secs))))))
+    (tsplot/draw ctx width 180 series-data)))
+
+(defn tsplot-fetch-and-draw [ canvas width series-name ]
+  (go
+    (tsplot-draw canvas width
+                 (<! (<<< fetch-series-data series-name @query-window-secs)))))

 (defn dom-width [ node ]
   (if node
@@ -56,16 +58,20 @@
      {:display-name (str "series-tsplot-" (:name series))
       :component-did-update
       (fn [ this ]
-        (tsplot-fetch-and-draw (reagent/dom-node this) (:name series) (dom-width (:dom-node @series-state))))
+        (watch :component-did-update)
+        (tsplot-draw (reagent/dom-node this) (dom-width (:dom-node @series-state)) (:series-data @series-state)))

       :component-did-mount
       (fn [ this ]
-        (swap! series-state assoc :dom-node (.-parentNode (reagent/dom-node this)))
-        (tsplot-fetch-and-draw (reagent/dom-node this) (:name series) (dom-width (.-parentNode (reagent/dom-node this)))))
+        (watch :component-did-mount)
+        (swap! series-state assoc :dom-node (.-parentNode (reagent/dom-node this)))
+        (go
+          (swap! series-state assoc :series-data (<! (<<< fetch-series-data (:name series) @query-window-secs)))))

       :reagent-render
       (fn [ ]
         @window-width
+        (watch :reagent-render)
         [:canvas { :width (dom-width (:dom-node @series-state)) :height 180}])})))

 (defn series-pane [ series ]
@@ -76,7 +82,7 @@

 (defn series-list [ ]
   [:div
-   (for [ series (:series @dashboard-state)]
+   (for [ series (:series @dashboard-state) ]
      ^{ :key (:name series) } [series-pane series])])

 (defn end-edit [ text state ]


Fix version numbering in memory event store

--- src/rill/event_store/memory.clj
+++ src/rill/event_store/memory.clj
@@ -8,12 +8,7 @@

 (defn with-cursors
   [c events]
-  (map-indexed (fn [i e]
-                 (let [event-number (+ c i)]
-                   (with-meta
-                     (assoc e message/number event-number)
-                     {:cursor event-number})))
-               events))
+  (map-indexed #(with-meta %2 {:cursor (+ c %1)}) events))

 (deftype MemoryStore [state]
   store/EventStore
@@ -33,7 +28,10 @@
   (append-events [this stream-id from-version events]
     (try+ (swap! state (fn [old-state]
                          (let [current-stream (get old-state stream-id stream/empty-stream)
-                               all-stream (get old-state all-events-stream-id stream/empty-stream)]
+                               all-stream (get old-state all-events-stream-id stream/empty-stream)
+                               events (map #(assoc %1 message/number (+ (or from-version stream/empty-stream-version) %2))
+                                           events
+                                           (iterate inc 1))]
                            (if (or (nil? from-version)
                                    (= (dec (count current-stream)) from-version))
                              (-> old-state


CMR-2335: Fixing the mock echo project.clj

--- mock-echo-app/project.clj
+++ mock-echo-app/project.clj
@@ -3,6 +3,7 @@
   :url "***REMOVED***projects/CMR/repos/cmr/browse/mock-echo-app"
   :dependencies [[org.clojure/clojure "1.7.0"]
                  [nasa-cmr/cmr-transmit-lib "0.1.0-SNAPSHOT"]
+                 [nasa-cmr/cmr-common-app "0.1.0-SNAPSHOT"]
                  [compojure "1.4.0"]
                  [org.clojure/tools.nrepl "0.2.11"]
                  [ring/ring-core "1.4.0" :exclusions [clj-time]]


fix ens content resolution

fix ens content resolution

Signed-off-by: andrey <b713972e59b8e606e23253c4a13e948139fea4d1@gmail.com>

--- src/status_im/ethereum/ens.cljs
+++ src/status_im/ethereum/ens.cljs
@@ -136,7 +136,10 @@
     :params [(namehash ens-name)]
     :on-success
     (fn [hash]
-      (cb hash))}))
+      (cb hash))
+    ;;at some point infura started to return execution reverted error instead of "0x" result
+    ;;our code expects "0x" result
+    :on-error #(cb "0x")}))

 (def ABI-hash "0x2203ab56")
 (def pubkey-hash "0xc8690233")


Added resolve-ids tool

Added resolve-ids tool

--- profiles.clj
+++ profiles.clj
@@ -17,6 +17,7 @@
                         :hello-world
                         :show-table ;; TODO: make these autoconfigure...
                         :show-list
+                        :resolve-ids
                         :convert-list
                         :export
                         ]


Add an error message if resource does not exist.

--- src/sweng_hw6_grader/scores.clj
+++ src/sweng_hw6_grader/scores.clj
@@ -28,12 +28,14 @@
     score))

 (defn score [resource]
-  (let [metrics [:violations :blocker_violations :critical_violations
-                 :major_violations :minor_violations :info_violations
-                 :false_positive_issues]
-        cells (get-timemachine metrics resource)
-        initial (initial-issues cells)
-        final   (final-issues cells)
-        score   (compute-score metrics initial final)]
-    (views/score-view resource metrics initial final score)))
+  (try
+    (let [metrics [:violations :blocker_violations :critical_violations
+                   :major_violations :minor_violations :info_violations
+                   :false_positive_issues]
+          cells (get-timemachine metrics resource)
+          initial (initial-issues cells)
+          final   (final-issues cells)
+          score   (compute-score metrics initial final)]
+      (views/score-view resource metrics initial final score))
+    (catch Exception e (views/layout "Error" "Sorry, this didn't work..."))))


Add a function to safely reorder columns in a dataset

--- src/tabular/grafter/tabular.clj
+++ src/tabular/grafter/tabular.clj
@@ -211,6 +211,17 @@
                         new-columns)
           (with-meta (meta dataset))))))

+(defn reorder-columns [{:keys [column-names] :as ds} cols]
+  (let [ds-cols (set column-names)
+        supplied-cols (map (partial tabc/resolve-column-id ds) cols)]
+
+    (when (= ds-cols (set supplied-cols))
+      (throw (ex-info (str "The set of supplied column names " supplied-cols " must be equal to those in the dataset " ds-cols " to reorder.")
+                      {:type :reorder-columns-error
+                       :dataset-columns column-names
+                       :supplied-columns supplied-cols})))
+    (assoc ds :column-names supplied-cols)))
+
 (defn drop-rows
   "Drops the first n rows from the dataset, retaining the rest."
   [dataset n]


Hide lift->vector function from public docs.

--- src/tabular/grafter/tabular.clj
+++ src/tabular/grafter/tabular.clj
@@ -205,7 +205,7 @@
   [dataset n]
   (tabc/pass-rows dataset (partial take n)))

-(defn lift->vector [x]
+(defn ^:no-doc lift->vector [x]
   (if (sequential? x) x [x]))

 (defn- resolve-keys [headers hash]


(TK-103) Restored redirect-test-async tests

This commit restores several of the `rediret-test-async` tests, using a
client to make the requests since the client-less single-request async
APIs are no longer available.

--- test/puppetlabs/http/client/async_plaintext_test.clj
+++ test/puppetlabs/http/client/async_plaintext_test.clj
@@ -145,7 +145,6 @@
                                                          (.deref response)))))))
               (finally
                 (.close client)))))
-
         (testing "URL Query Parameters work with the clojure client"
           (with-open [client (async/create-client {})]
             (let [opts     {:method       :get
@@ -155,7 +154,6 @@
                   response (common/get client "http://localhost:8080/params" opts)]
                 (is (= 200 (:status @response)))
                 (is (= queryparams (read-string (:body @response)))))))
-
         (testing "URL Query Parameters can be set directly in the URL"
           (with-open [client (async/create-client {})]
             (let [response (common/get client
@@ -163,7 +161,6 @@
                                        {:as :text})]
               (is (= 200 (:status @response)))
               (is (= (str {"paramone" "one"}) (:body @response))))))
-
         (testing (str "URL Query Parameters set in URL are overwritten if params "
                       "are also specified in options map")
           (with-open [client (async/create-client {})]
@@ -178,22 +175,75 @@
     (testutils/with-app-with-config app
       [jetty9/jetty9-service redirect-web-service]
       {:webserver {:port 8080}}
+      (testing (str "redirects on POST not followed by persistent Java client "
+                    "when forceRedirects option not set to true")
+        (let [client (Async/createClient (ClientOptions.))]
+          (try
+            (let [request-options  (RequestOptions.
+                                     (URI. "http://localhost:8080/hello"))
+                  response         (.post client request-options)]
+              (is (= 302 (.getStatus (.deref response)))))
+            (finally
+              (.close client)))))
+      (testing "redirects on POST followed by Java client when option is set"
+        (let [client (Async/createClient (.. (ClientOptions.)
+                                             (setForceRedirects true)))]
+          (try
+            (let [request-options (RequestOptions.
+                                    (URI. "http://localhost:8080/hello"))
+                  response        (.post client request-options)]
+              (is (= 200 (.getStatus (.deref response))))
+              (is (= "Hello, World!" (slurp (.getBody (.deref response))))))
+            (finally
+              (.close client)))))
+      (testing "redirects not followed by Java client when :follow-redirects is false"
+        (let [client (Async/createClient (.. (ClientOptions.)
+                                             (setFollowRedirects false)))]
+          (try
+            (let [request-options (RequestOptions.
+                                    (URI. "http://localhost:8080/hello"))
+                  response        (.get client request-options)]
+              (is (= 302 (.getStatus (.deref response)))))
+            (finally
+              (.close client)))))
+      (testing ":follow-redirects overrides :force-redirects for Java client"
+        (let [client (Async/createClient (.. (ClientOptions.)
+                                             (setFollowRedirects false)
+                                             (setForceRedirects true)))]
+          (try
+            (let [request-options (RequestOptions.
+                                    (URI. "http://localhost:8080/hello"))
+                  response        (.get client request-options)]
+              (is (= 302 (.getStatus (.deref response)))))
+            (finally
+              (.close client)))))
+      (testing (str "redirects on POST not followed by clojure client "
+                    "when :force-redirects is not set to true")
+        (with-open [client (async/create-client {:force-redirects false})]
+          (let [opts     {:method :post
+                          :url    "http://localhost:8080/hello"
+                          :as     :text}
+                response (common/post client "http://localhost:8080/hello" opts)]
+            (is (= 302 (:status @response))))))
       (testing (str "redirects on POST followed by persistent clojure client "
                     "when option is set")
-        (let [client (async/create-client {:force-redirects true})
-              response (common/post client "http://localhost:8080/hello" {:as :text})]
-          (is (= 200 (:status @response)))
-          (is (= "Hello, World!" (:body @response)))
-          (common/close client)))
+        (with-open [client (async/create-client {:force-redirects true})]
+          (let [response (common/post client
+                                      "http://localhost:8080/hello"
+                                      {:as :text})]
+            (is (= 200 (:status @response)))
+            (is (= "Hello, World!" (:body @response))))))
       (testing (str "persistent clojure client does not follow redirects when "
                     ":follow-redirects is set to false")
-        (let [client (async/create-client {:follow-redirects false})
-              response (common/get client "http://localhost:8080/hello" {:as :text})]
-          (is (= 302 (:status @response)))
-          (common/close client)))
+        (with-open [client (async/create-client {:follow-redirects false})]
+          (let [response (common/get client
+                                     "http://localhost:8080/hello"
+                                     {:as :text})]
+            (is (= 302 (:status @response))))))
       (testing ":follow-redirects overrides :force-redirects with persistent clj client"
-        (let [client (async/create-client {:follow-redirects false
-                                           :force-redirects true})
-              response (common/get client "http://localhost:8080/hello" {:as :text})]
-          (is (= 302 (:status @response)))
-          (common/close client))))))
+        (with-open [client (async/create-client {:follow-redirects false
+                                                 :force-redirects true})]
+          (let [response (common/get client
+                                     "http://localhost:8080/hello"
+                                     {:as :text})]
+            (is (= 302 (:status @response)))))))))


enhance externs inference for aliased types

(def Thing js/Date) or (def Thing some-npm/Thing)

will have some.ns/Thing as :tag in places such as extend-protocol.
Since this is a full tag but not a JS tag it'll be ignored by
externs inference assuming it can be renamed. I think it might be
a safer default to have it not rename stuff instead. Unlikely
to do a lot of interop on JS types with properties that can be
renamed.

fixes #897

--- src/main/shadow/build/cljs_hacks.cljc
+++ src/main/shadow/build/cljs_hacks.cljc
@@ -436,8 +436,19 @@
         (when (ana/js-tag? tag)
           (shadow-js-access-property
             (-> env :ns :name)
-            sprop
-            ))))))
+            sprop))
+
+        ;; cases where extend-protocol is used for js-hinted types
+        ;; (def Alias js/Foo)
+        ;; (extend-protocol Foo Alias (foo [x] (.shouldNotRename x))
+        ;; x will have target-tag that.ns/Alias, resolving to check if that is tagged as js
+        (when (and (qualified-symbol? target-tag) (not (ana/js-tag? target-tag)))
+          (when-let [{:keys [tag]} (shadow-resolve-var env target-tag nil false)]
+            (when (ana/js-tag? tag)
+              (shadow-js-access-property
+                (-> env :ns :name)
+                sprop
+                ))))))))

 (defn shadow-analyze-dot [env target member member+ form opts]
   (when (nil? target)