Simplify filter logic

Simplify filter logic

--- src-cljs/frontend/components/add_projects.cljs
+++ src-cljs/frontend/components/add_projects.cljs
@@ -216,14 +216,10 @@
                 [:ul.proj-list
                  (let [filtered-repos (sort-by sort-order (filter (fn [repo]
                                                                     (and
-                                                                     (if show-forks
-                                                                       true
-                                                                       (not (:fork repo)))
-                                                                     (-> repo
-                                                                         :name
-                                                                         (.toLowerCase)
-                                                                         (.indexOf (.toLowerCase repo-filter-string))
-                                                                         (not= -1))))
+                                                                     (or show-forks (not (:fork repo)))
+                                                                     (gstring/caseInsensitiveContains
+                                                                       (:name repo)
+                                                                       repo-filter-string)))
                                                                   repos))]
                    (map (fn [repo] (om/build repo-item {:repo repo
                                                         :settings settings}))


workaround missing start/end in errors

workaround missing start/end in errors

--- src-cljs/frontend/components/build_config.cljs
+++ src-cljs/frontend/components/build_config.cljs
@@ -9,12 +9,21 @@
             [om.core :as om :include-macros true])
     (:require-macros [frontend.utils :refer [html]]))

+(defn- maybe-add-start-end
+  "Workaround around missing start/end data from backend"
+  [error]
+  (if (:start error)
+    error
+    (assoc error
+           :start {:line 0 :index 0 :column 0}
+           :end {:line 0 :index 0 :column 0})))
+
 (defn diagnostics [config owner]
   (reify
     om/IInitState
     (init-state [_]
       ;; TODO convert CI.inner.Diagnostics to clojurescript
-      {:configDiagnostics (js/CI.inner.Diagnostics. (:string config) (clj->js (:errors config)))})
+      {:configDiagnostics (js/CI.inner.Diagnostics. (:string config) (->> config :errors (map maybe-add-start-end) clj->js))})
     om/IRenderState
     (render-state [_ {:keys [configDiagnostics]}]
       (html


Add suggestion to before-task-start doc.

--- src/onyx/information_model.cljc
+++ src/onyx/information_model.cljc
@@ -1063,7 +1063,7 @@
                                     :optional? true
                                     :added "0.8.0"}

-            :lifecycle/before-task-start {:doc "A function that takes two arguments - an event map, and the matching lifecycle map. Must return a map that is merged back into the original event map. This function is called after processes in the task are launched, but before the peer listens for incoming segments from other peers."
+            :lifecycle/before-task-start {:doc "A function that takes two arguments - an event map, and the matching lifecycle map. This lifecycle is especially useful for injecting non-serializable resources like connections into your `:onyx/fn` params. Must return a map that is merged back into the original event map. This function is called after processes in the task are launched, but before the peer listens for incoming segments from other peers."
                                           :type :function
                                           :optional? true
                                           :added "0.8.0"}


Bring pomegranate back to lein profile

Bring pomegranate back to lein profile

And bump test-refresh version

--- lein/profiles.clj
+++ lein/profiles.clj
@@ -1,6 +1,8 @@
 {:user {:aliases {"slamhound" ["run" "-m" "slam.hound"]}  ; Q: Will I ever find occasion to actually use this?
         :dependencies [;; Q: what's this really for? A: modifying CLASSPATH at runtime
                        [alembic "0.3.2" :exclusions [org.tcrawley/dynapath]]
+                       [com.cemerick/pomegranate "0.3.1" :exclusions [org.apache.maven.wagon/wagon-http
+                                                                      org.tcrawley/dynapath]]
                        [commons-logging "1.2"]
                        ;; TODO: Replace this with whatever replaced it
                        ;; Careful: 0.3.4 was working OK
@@ -26,8 +28,6 @@
                                                                                potemkin
                                                                                slingshot]]
                        ;; Q: How many of any of the rest of these do I actually use?
-                       ;; This one's gone
-                       #_[nrepl-inspect "0.4.1"]
                        [org.apache.maven.wagon/wagon-provider-api "2.10"]
                        [org.codehaus.plexus/plexus-utils "3.0.24"]
                        ;; I use this everywhere. But it doesn't belong in here
@@ -70,7 +70,7 @@
                      (require 'pjstadig.humane-test-output)
                      (pjstadig.humane-test-output/activate!)]
         ;;:local-repo "repo"
-        :plugins [[com.jakemccrary/lein-test-refresh "0.16.0"]
+        :plugins [[com.jakemccrary/lein-test-refresh "0.17.0"]
                   [jonase/eastwood "0.2.3" :exclusions [org.clojure/clojure]]
                   ;; Check for out-dated plugins in here using `lein ancient check-profiles`
                   [lein-ancient "0.6.10" :exclusions [cheshire


Previous checkin had some version conflicts

--- lein/profiles.clj
+++ lein/profiles.clj
@@ -27,10 +27,12 @@
                                                                                org.apache.maven.wagon/wagon-http
                                                                                org.apache.maven.wagon/wagon-http-shared4
                                                                                org.apache.maven.wagon/wagon-provider-api
+                                                                                org.clojure/clojure
                                                                                org.clojure/tools.cli
-                                                                                org.clojure/tools.reader
+                                                                                #_org.clojure/tools.reader
                                                                                org.jsoup/jsoup
-                                                                                potemkin]]
+                                                                                potemkin
+                                                                                slingshot]]
                        ;; Q: How many of any of the rest of these do I actually use?
                        ;; This one's gone
                        #_[nrepl-inspect "0.3.0"]
@@ -80,13 +82,13 @@
                                                      common-codec
                                                      commons-codec
                                                      org.clojure/clojure
-                                                     org.clojure/tools.reader
+                                                     #_org.clojure/tools.reader
                                                      slingshot]]
                   ;; This next one's super useful, but its dependencies are out of date
                   ;; TODO: Update!
-                  [lein-kibit "0.1.2"]
+                  [lein-kibit "0.1.2" :exclusions [org.clojure/clojure]]
                   [lein-pprint "1.1.1"]
-                  [mvxcvi/whidbey "1.3.0"]]
+                  [mvxcvi/whidbey "1.3.0" :exclusions [org.clojure/clojure]]]
         :repl-options {:nrepl-middleware
                        [inspector.middleware/wrap-inspect
                         ;;ritz.nrepl.middleware.apropos/wrap-apropos
@@ -99,4 +101,4 @@
                   :print-meta true
                   :color-scheme {}
                   :print-color true}}
-  :repl {:plugins [[cider/cider-nrepl "0.10.1" :exclusions [org.clojure/java.classpath]]]}}
+  :repl {:plugins [[cider/cider-nrepl "0.11.0" :exclusions [org.clojure/java.classpath]]]}}


Add explicit refers in ssh command

Add explicit refers in ssh command

--- src/yetibot/core/commands/ssh.clj
+++ src/yetibot/core/commands/ssh.clj
@@ -3,7 +3,7 @@
     [schema.core :as sch]
     [clojure.string :as s]
     [taoensso.timbre :refer [info warn error]]
-    [clj-ssh.ssh :refer :all]
+    [clj-ssh.ssh :refer [ssh ssh-agent add-identity session with-connection]]
     [yetibot.core.hooks :refer [cmd-hook]]
     [yetibot.core.config :refer [get-config]]))


added past-participle been

added past-participle been

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -127,7 +127,8 @@
                                        :3sing "was"
                                        :1plur "were"
                                        :2plur "were"
-                                       :3plur "were"}}}]
+                                       :3plur "were"}
+                                :past-participle {been}}}]
           [;; intransitive
            (unify common
                   {:sense 1


+believe<noun[human],CP>

+believe<noun[human],CP>

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -300,8 +300,18 @@
             :english {:past "began"
                       :participle "beginning"}}

-   "believe" {:synsem {:cat :verb
-                       :sem {:pred :believe}}}
+   "believe" (let [common {:synsem {:cat :verb
+                                    :subcat {:1 {:cat :noun
+                                                 :sem {:human true}}}}}]
+               [(unify common
+                       {:synsem {:sem {:pred :believe}
+                                 :subcat {:2 '()}}}) ;; intransitive
+
+                (unify common
+                       {:synsem {:sem {:pred :believe}
+                                 :subcat {:2 {:cat :comp ;; "that"
+                                              :subcat '()}
+                                          :3 '()}}})])

    "bicycle" {:synsem {:cat :noun
                        :sem {:pred :bicycle


Cosmetics

Cosmetics

--- test/clojurewerkz/cassaforte/multi/cql_test.clj
+++ test/clojurewerkz/cassaforte/multi/cql_test.clj
@@ -244,16 +244,16 @@
              (where :name "user1"))

      (is (= #{"str2"} (get-in (select th/session :users_set)
-                             [0 :test_set])))))
+                              [0 :test_set])))))

   (drop-table th/session :users_set))

 (deftest select-where-test
   (th/test-combinations
    (doto th/session
-       (insert :users {:name "Alex"   :city "Munich"        :age (int 19)})
-       (insert :users {:name "Robert" :city "Berlin"        :age (int 25)})
-       (insert :users {:name "Sam"    :city "San Francisco" :age (int 21)}))
+     (insert :users {:name "Alex"   :city "Munich"        :age (int 19)})
+     (insert :users {:name "Robert" :city "Berlin"        :age (int 25)})
+     (insert :users {:name "Sam"    :city "San Francisco" :age (int 21)}))

    (is (= "Munich" (get-in (select th/session :users
                                    (where :name "Alex"))
@@ -262,9 +262,9 @@
 (deftest select-in-test
   (th/test-combinations
    (doto th/session
-       (insert :users {:name "Alex"   :city "Munich"        :age (int 19)})
-       (insert :users {:name "Robert" :city "Berlin"        :age (int 25)})
-       (insert :users {:name "Sam"    :city "San Francisco" :age (int 21)}))
+     (insert :users {:name "Alex"   :city "Munich"        :age (int 19)})
+     (insert :users {:name "Robert" :city "Berlin"        :age (int 25)})
+     (insert :users {:name "Sam"    :city "San Francisco" :age (int 21)}))

    (let [users (select th/session :users
                        (where :name [:in ["Alex" "Robert"]]))]
@@ -280,17 +280,17 @@
            {:post_id "post1"}
            {:post_id "post2"}]
           (select th/session :user_posts
-           (columns :post_id)
-           (where :username "Alex")
-           (order-by [:post_id]))))
+                  (columns :post_id)
+                  (where :username "Alex")
+                  (order-by [:post_id]))))

    (is (= [{:post_id "post2"}
            {:post_id "post1"}
            {:post_id "post0"}]
           (select th/session :user_posts
-           (columns :post_id)
-           (where :username "Alex")
-           (order-by [:post_id :desc]))))))
+                  (columns :post_id)
+                  (where :username "Alex")
+                  (order-by [:post_id :desc]))))))

 (deftest select-range-query-test
   (create-table th/session :tv_series


Better input params, default to dry run if no explicit parameter passed, better logs.

--- src/oc/storage/resources/maintenance.clj
+++ src/oc/storage/resources/maintenance.clj
@@ -7,15 +7,16 @@
             [oc.storage.resources.org :as org-res]
             [oc.storage.resources.common :as common]))

-(defn- update-entry [conn entry original-entry]
+(defn- update-entry [conn entry original-entry dry-run]
   (schema/validate common/Entry entry)
   (timbre/info "--> Updating entry from" (count (:shared original-entry)) "to" (count (:shared entry)))
-  (db-common/update-resource conn common/entry-table-name :uuid original-entry entry (db-common/current-timestamp)))
+  (when-not dry-run
+    (db-common/update-resource conn common/entry-table-name :uuid original-entry entry (db-common/current-timestamp))))

 (schema/defn ^:always-validate shared-limit-for-entry!
   "Given a RethinkDB connection, an entry map and a limit to apply to share cut the list of
    shared to the passed value keeping only the newest"
-  [conn :- lib-schema/Conn entry :- common/Entry limit]
+  [conn :- lib-schema/Conn entry :- common/Entry limit dry-run]
   (let [old-shared (:shared entry)
         grouped-shared (group-by :shared-at old-shared)
         unique-shared (vec (map first (vals grouped-shared)))
@@ -24,7 +25,7 @@
     (timbre/info "      Old shared" (count old-shared))
     (timbre/info "      Unique shared" (count unique-shared))
     (timbre/info "      Limited shared" (count limited-shared))
-    (update-entry conn (assoc entry :shared limited-shared) entry)
+    (update-entry conn (assoc entry :shared limited-shared) entry dry-run)
     (timbre/info "      Cut!")))

 (schema/defn ^:always-validate list-all-entries-by-org!
@@ -34,24 +35,35 @@
 (schema/defn ^:always-validate shared-limit-for-org!
   "Give a RethinkDB connection and an org-uuid, load all the published entries of the org
    and call the shared-limit-for-entry on all that are exceeding the shared limit."
-  [conn :- lib-schema/Conn org-uuid :- lib-schema/UniqueID limit]
-  (timbre/info "  Cut for org" org-uuid)
+  [conn :- lib-schema/Conn org-uuid :- lib-schema/UniqueID limit dry-run]
   (let [entries (list-all-entries-by-org! conn org-uuid)]
     (timbre/info "  Entries count:" (count entries))
     (for [entry entries]
       (do
         (timbre/info "    Checking entry" (:uuid entry) "shared:" (count (:shared entry)))
         (when (> (count (:shared entry)) limit)
-          (shared-limit-for-entry! conn entry limit))))))
+          (shared-limit-for-entry! conn entry limit dry-run))))))

 (defn shared-limit!
   "List all the present orgs, for each load all the entries that have more then 20 shared entries
    and cut them to the 20 more recent values."
-  [conn batch-length batch-offset & [limit]]
-  (let [limit (or limit 50)]
+  [conn {:keys [batch-length batch-offset limit dry-run]}]
+  (let [batch-length (or batch-length 20)
+        batch-offset (or batch-offset 0)
+        dry-run (if (nil? dry-run)
+                  true
+                  dry-run)
+        limit (or limit 50)]
     (timbre/info "Cut :shared lists for all entries to:" limit "(orgs from " (* batch-length batch-offset) "to" (* batch-length (inc batch-offset)) ")")
+    (when dry-run
+      (timbre/info "---- Dry-run not updating ----"))
     (let [orgs (org-res/list-orgs conn)
-          batches (vec (partition batch-length orgs))
-          batch (vec (get batches batch-offset))]
+          partition-length (min batch-length (count orgs))
+          batches (into [] (partition partition-length orgs))
+          batch (into [] (get batches batch-offset))]
+      (timbre/info "Total orgs:" (count orgs) " batch: " (inc batch-offset) "/" (count batches))
+      (timbre/info "Current batch size:" (count batch))
       (for [org batch]
-        (shared-limit-for-org! conn (:uuid org) limit)))))+        (do
+          (timbre/info "Checking:" (:slug org))
+          (shared-limit-for-org! conn (:uuid org) limit dry-run))))))


fix webserver-url prep for email request

--- src/polismath/darwin/server.clj
+++ src/polismath/darwin/server.clj
@@ -123,7 +123,7 @@
     (let [darwin-config (-> darwin :config)
           response
           ;; The next three lines should probably be extracted
-          (client/post (:webserver-url darwin-config) "/sendEmailExportReady"
+          (client/post (str (:webserver-url darwin-config) "/sendEmailExportReady")
                        {:form-params {:webserver_username (:webserver-username darwin-config)
                                       :webserver_pass (:webserver-pass darwin-config)
                                       :email email


Document nit for wrap-render function

Document nit for wrap-render function

--- src/reagent/impl/component.cljs
+++ src/reagent/impl/component.cljs
@@ -87,10 +87,12 @@
 ;;; Rendering

 (defn wrap-render
-  "Calls the render function of the component. If the result of render function is
-  1) Vector (type one component) - Create a react element of the result and returned
-  2) Function (type two component) - Recursively execute the function until we get a vector, and then create a react element of the result and returned
-  3) else - result of render is returned"
+  "Calls the render function of the component `c`.  If result `res` evaluates to a:
+     1) Vector (form-1 component) - Treats the vector as hiccup and returns
+        a react element with a render function based on that hiccup
+     2) Function (form-2 component) - updates the render function to `res` i.e. the internal function
+        and calls wrap-render again (`recur`), until the render result doesn't evaluate to a function.
+     3) Anything else - Returns the result of evaluating `c`"
   [c]
   (let [f ($ c :reagentRender)
         _ (assert-callable f)


updated to adjust with new data.

updated to adjust with new data.

--- src/clinvar_submitter/form.clj
+++ src/clinvar_submitter/form.clj
@@ -265,8 +265,9 @@
   (defn evidence-pmid-citations
     "Returns the list of critieron pmid citations for the evidence provided"
     [t e]
-    (let [info-sources (ld-> t e "evidenceLine" "evidenceItem" "evidenceLine" "evidenceItem" "source")
-          pmids (re-extract info-sources #"https\:\/\/www\.ncbi\.nlm\.nih\.gov\/pubmed\/(\p{Digit}*)" 1)]
+    ;(let [info-sources (ld-> t e "information" "evidence" "information" "source")
+    (let [info-sources (ld-> t e "evidenceItem" "evidenceLine" "evidenceItem" "source")
+          pmids (re-extract info-sources #"https\:\/\/www\.ncbi\.nlm\.nih\.gov\/pubmed\/(\p{Digit}*)" 1)]
       (if (nil? pmids) (str "**W-551" ":" (rand-int 200))
       (csv-colval (clojure.string/join ", " (map #(str "PMID:" %) pmids))))))

@@ -274,7 +275,8 @@
    "Returns a collated map of all 'met' evidence records needed for the
     clinvar 'variant' submission sheet."
    [t i]
-   (let [e (ld-> t i "evidenceLine"  (prop= t "met" "evidenceItem" "outcome" "label"))]
+   ;(let [e (ld-> t i "evidence"  (prop= t "met" "information" "outcome" "code"))]
+   (let [e (ld-> t i "evidenceLine" (prop= t "http://clinicalgenome.org/datamodel/criterion-assertion-outcome/met" "evidenceItem" "outcome" "label"))]
      (if (nil? e) "*W-551"
      {:summary (evidence-summary t e),
       :rules (evidence-rules t e),


specs for ns

specs for ns

Signed-off-by: Rich Hickey <2f3b32171da334ad5d7d0db393d0928eef4308ab@gmail.com>

--- src/clj/clojure/core/specs.clj
+++ src/clj/clojure/core/specs.clj
@@ -96,3 +96,106 @@
                :bs (s/alt :arity-1 ::args+body
                           :arity-n (s/+ (s/spec ::args+body))))
   :ret any?)
+
+;;;; ns
+
+(s/def ::exclude (s/coll-of simple-symbol?))
+(s/def ::only (s/coll-of simple-symbol?))
+(s/def ::rename (s/map-of simple-symbol? simple-symbol?))
+
+(s/def ::ns-refer-clojure
+  (s/spec (s/cat :clause #{:refer-clojure}
+            :filters (s/keys* :opt-un [::exclude ::only ::rename]))))
+
+(s/def ::refer (s/or :all #{:all}
+                 :syms  (s/coll-of simple-symbol?)))
+
+(s/def ::prefix-list
+  (s/spec
+    (s/cat :prefix simple-symbol?
+      :suffix (s/* (s/alt :lib simple-symbol? :prefix-list ::prefix-list))
+      :refer (s/keys* :opt-un [::as ::refer]))))
+
+(s/def ::ns-require
+  (s/spec (s/cat :clause #{:require}
+            :libs (s/* (s/alt :lib simple-symbol?
+                         :prefix-list ::prefix-list
+                         :flag #{:reload :reload-all :verbose})))))
+
+(s/def ::package-list
+  (s/spec
+    (s/cat :package simple-symbol?
+      :classes (s/* simple-symbol?))))
+
+(s/def ::ns-import
+  (s/spec
+    (s/cat :clause #{:import}
+      :classes (s/* (s/alt :class simple-symbol?
+                      :package-list ::package-list)))))
+
+(s/def ::ns-refer
+  (s/spec (s/cat :clause #{:refer}
+            :lib simple-symbol?
+            :filters (s/keys* :opt-un [::exclude ::only ::rename]))))
+
+(s/def ::use-prefix-list
+  (s/spec
+    (s/cat :prefix simple-symbol?
+      :suffix (s/* (s/alt :lib simple-symbol? :prefix-list ::use-prefix-list))
+      :filters (s/keys* :opt-un [::exclude ::only ::rename]))))
+
+(s/def ::ns-use
+  (s/spec (s/cat :clause #{:use}
+            :libs (s/* (s/alt :lib simple-symbol?
+                         :prefix-list ::use-prefix-list
+                         :flag #{:reload :reload-all :verbose})))))
+
+(s/def ::ns-load
+  (s/spec (s/cat :clause #{:load}
+            :libs (s/* string?))))
+
+(s/def ::name simple-symbol?)
+(s/def ::extends simple-symbol?)
+(s/def ::implements (s/coll-of simple-symbol? :kind vector?))
+(s/def ::init symbol?)
+(s/def ::signature (s/coll-of simple-symbol? :kind vector?))
+(s/def ::constructors (s/map-of ::signature ::signature))
+(s/def ::post-init symbol?)
+(s/def ::method (s/and vector?
+                  (s/cat :name simple-symbol?
+                    :param-types ::signature
+                    :return-type simple-symbol?)))
+(s/def ::methods (s/coll-of ::method :kind vector?))
+(s/def ::main boolean?)
+(s/def ::factory simple-symbol?)
+(s/def ::state simple-symbol?)
+(s/def ::get simple-symbol?)
+(s/def ::set simple-symbol?)
+(s/def ::expose (s/keys :opt-un [::get ::set]))
+(s/def ::exposes (s/map-of simple-symbol? ::expose))
+(s/def ::prefix string?)
+(s/def ::impl-ns simple-symbol?)
+(s/def ::load-impl-ns boolean?)
+
+(s/def ::ns-gen-class
+  (s/spec (s/cat :clause #{:gen-class}
+            :options (s/keys* :opt-un [::name ::extends ::implements
+                                       ::init ::constructors ::post-init
+                                       ::methods ::main ::factory ::state
+                                       ::exposes ::prefix ::impl-ns ::load-impl-ns]))))
+
+(s/def ::ns-clauses
+  (s/* (s/alt :refer-clojure ::ns-refer-clojure
+         :require ::ns-require
+         :import ::ns-import
+         :use ::ns-use
+         :refer ::ns-refer
+         :load ::ns-load
+         :gen-class ::ns-gen-class)))
+
+(s/fdef clojure.core/ns
+  :args (s/cat :name simple-symbol?
+          :docstring (s/? string?)
+          :attr-map (s/? map?)
+          :clauses ::ns-clauses)
+  :ret any?)


calendar fix

calendar fix

--- src/cljs/re_form/calendar.cljs
+++ src/cljs/re_form/calendar.cljs
@@ -41,7 +41,9 @@
         curr-month (get-days-of-month date true)

         first-week (concat prev-month-week (first curr-month))
-        last-week (concat (last curr-month) next-month-week)]
+        last-week (if (< (count (last curr-month)) 7)
+                    (concat (last curr-month) next-month-week)
+                    (last curr-month))]
     (concat [first-week]
             (drop-last (rest curr-month))
             [last-week])))


style

style

--- src/cljs/schafkopfen/core.cljs
+++ src/cljs/schafkopfen/core.cljs
@@ -59,12 +59,12 @@

 (defn main []
   (om/root
-    (fn [app owner]
-      (reify
-        om/IRender
-        (render [_]
-                (dom/div nil
-                         (dom/h1 nil (:header app))
-                         (om/build players-view app)))))
-    app-state
-    {:target (. js/document (getElementById "app"))}))
+   (fn [app owner]
+     (reify
+       om/IRender
+       (render [_]
+         (dom/div nil
+                  (dom/h1 nil (:header app))
+                  (om/build players-view app)))))
+   app-state
+   {:target (. js/document (getElementById "app"))}))


And fix stage.

And fix stage.

--- src/cljx/geschichte/stage.cljx
+++ src/cljx/geschichte/stage.cljx
@@ -141,10 +141,11 @@
           (sub p :binary-fetch bfch)
           (go-loop>? ferr-ch []
                 (let [to-fetch (:id (<? bfch))]
-                  (>! out {:topic :binary-fetched
-                           :value (get new-values to-fetch)
-                           :peer id})
-                  (recur)))
+                  (when to-fetch
+                    (>! out {:topic :binary-fetched
+                             :value (get new-values to-fetch)
+                             :peer id})
+                    (recur))))
           (when-not (empty? pubs)
             (>! out (with-meta {:topic :meta-pub :metas pubs :peer id}
                       {:host ::stage})))


fix #68 except the shortcut to maximize the editor pane

--- src/clojure/nightcode/core.clj
+++ src/clojure/nightcode/core.clj
@@ -95,18 +95,22 @@
   []
   (let [process (atom nil)
         console (ui/create-console)
-        console-io (atom nil)]
-    (s/left-right-split
-      (s/top-bottom-split (get-project-pane console console-io)
-                          (get-repl-pane process console console-io)
-                          :divider-location 0.8
-                          :resize-weight 0.5)
-      (s/top-bottom-split (get-editor-pane)
-                          (get-builder-pane)
-                          :divider-location 0.8
-                          :resize-weight 0.5)
-      :divider-location 0.4
-      :resize-weight 0)))
+        console-io (atom nil)
+        one-touch! #(doto % (.setOneTouchExpandable true))]
+    (one-touch!
+      (s/left-right-split
+        (one-touch!
+          (s/top-bottom-split (get-project-pane console console-io)
+                              (get-repl-pane process console console-io)
+                              :divider-location 0.8
+                              :resize-weight 0.5))
+        (one-touch!
+          (s/top-bottom-split (get-editor-pane)
+                              (get-builder-pane)
+                              :divider-location 0.8
+                              :resize-weight 0.5))
+        :divider-location 0.4
+        :resize-weight 0))))

 (defn confirm-exit-app!
   []


CMR-813: Removed commented code.

CMR-813: Removed commented code.

--- src/cmr/indexer/api/routes.clj
+++ src/cmr/indexer/api/routes.clj
@@ -35,8 +35,6 @@
       (let [{:keys [concept-id revision-id]} (walk/keywordize-keys body)
             ignore-conflict (ignore-conflict? params)
             context (acl/add-authentication-to-context context params headers)]
-        ;; TODO commenting out for now due to performance issue CMR-813
-        ; (acl/verify-ingest-management-permission context :update)
         (r/created (index-svc/index-concept context concept-id revision-id ignore-conflict))))

     ;; reset operation available just for development purposes
@@ -74,8 +72,6 @@
       (DELETE "/" {context :request-context params :params headers :headers}
         (let [ignore-conflict (ignore-conflict? params)
               context (acl/add-authentication-to-context context params headers)]
-          ;; TODO commenting out for now due to performance issue CMR-813
-          ; (acl/verify-ingest-management-permission context :update)
           (index-svc/delete-concept context concept-id revision-id ignore-conflict)
           (r/response nil))))


add short summaries

add short summaries

--- gorilla/analysis-ws.clj
+++ gorilla/analysis-ws.clj
@@ -10,16 +10,17 @@
   (:require [gorilla-plot.core :refer :all]
             [ceres.collector :refer :all]
             [ceres.curator :refer [random-tree build-tree-from-source compute-summary]]
+            [ceres.analyzer :refer [reaction-tree summary hashtags-of-the-day]]
             [monger.collection :as mc]
+            [clojure.walk :as walk]
+            [clojure.zip :as zip]
             [clj-time.core :as t]
             [clj-time.periodic :as p]
+            [incanter.stats :refer [mean median quantile variance]]
             [monger.operators :refer :all]
             [monger.query :refer :all])
   (:import org.bson.types.ObjectId))
 ;; @@
-;; =>
-;;; {"type":"html","content":"nil","value":"nil"}
-;; <=

 ;; **
 ;;; Follwing news distributors are watched
@@ -373,7 +374,7 @@

 ;; @@
 (def source-tweet-counts (->> (mc/find-maps @db "users" {:screen_name {$in news-accounts}})
-     			    	 (pmap (fn [{:keys [screen_name _id]}] [screen_name (mc/count @db "published" {:user _id})]))
+     			    	 (pmap (fn [{:keys [screen_name _id]}] [screen_name (mc/count @db "publications" {:user _id})]))
                          (into {})))
 ;; @@
 ;; =>
@@ -397,16 +398,116 @@
   (bar-chart (keys source-url-counts) (vals source-url-counts)))
 ;; @@
 ;; =>
-;;; {"type":"vega","content":{"width":1000,"height":618.0469970703125,"padding":{"bottom":20,"top":10,"right":10,"left":50},"scales":[{"name":"x","type":"ordinal","range":"width","domain":{"data":"cdab57da-9f48-45e3-b073-985d18645933","field":"data.x"}},{"name":"y","range":"height","nice":true,"domain":{"data":"cdab57da-9f48-45e3-b073-985d18645933","field":"data.y"}}],"axes":[{"scale":"x","type":"x"},{"scale":"y","type":"y"}],"data":[{"name":"cdab57da-9f48-45e3-b073-985d18645933","values":[{"x":"dpa","y":520},{"x":"tazgezwitscher","y":700},{"x":"BILD","y":1327},{"x":"ZDFheute","y":949},{"x":"FAZ_NET","y":2919},{"x":"focusonline","y":271},{"x":"welt","y":1990},{"x":"N24_de","y":1962},{"x":"DerWesten","y":947},{"x":"SPIEGELONLINE","y":1763},{"x":"ntvde","y":1816},{"x":"tagesschau","y":1736},{"x":"SZ","y":1615},{"x":"sternde","y":982}]},{"name":"e0e1d1d2-4b30-4339-b9f3-d04295f8898f","values":[{"x":"dpa","y":445},{"x":"tazgezwitscher","y":639},{"x":"BILD","y":983},{"x":"ZDFheute","y":530},{"x":"FAZ_NET","y":2187},{"x":"focusonline","y":266},{"x":"welt","y":1798},{"x":"N24_de","y":1940},{"x":"DerWesten","y":854},{"x":"SPIEGELONLINE","y":1642},{"x":"ntvde","y":1793},{"x":"tagesschau","y":1282},{"x":"SZ","y":1523},{"x":"sternde","y":895}]}],"marks":[{"type":"rect","from":{"data":"cdab57da-9f48-45e3-b073-985d18645933"},"properties":{"enter":{"y":{"scale":"y","field":"data.y"},"width":{"offset":-1,"scale":"x","band":true},"x":{"scale":"x","field":"data.x"},"y2":{"scale":"y","value":0}},"update":{"fill":{"value":"red"},"opacity":{"value":1}},"hover":{"fill":{"value":"#FF29D2"}}}},{"type":"rect","from":{"data":"e0e1d1d2-4b30-4339-b9f3-d04295f8898f"},"properties":{"enter":{"y":{"scale":"y","field":"data.y"},"width":{"offset":-1,"scale":"x","band":true},"x":{"scale":"x","field":"data.x"},"y2":{"scale":"y","value":0}},"update":{"fill":{"value":"steelblue"},"opacity":{"value":1}},"hover":{"fill":{"value":"#FF29D2"}}}}]},"value":"#gorilla_repl.vega.VegaView{:content {:width 1000, :height 618.047, :padding {:bottom 20, :top 10, :right 10, :left 50}, :scales [{:name \"x\", :type \"ordinal\", :range \"width\", :domain {:data \"cdab57da-9f48-45e3-b073-985d18645933\", :field \"data.x\"}} {:name \"y\", :range \"height\", :nice true, :domain {:data \"cdab57da-9f48-45e3-b073-985d18645933\", :field \"data.y\"}}], :axes [{:scale \"x\", :type \"x\"} {:scale \"y\", :type \"y\"}], :data ({:name \"cdab57da-9f48-45e3-b073-985d18645933\", :values ({:x \"dpa\", :y 520} {:x \"tazgezwitscher\", :y 700} {:x \"BILD\", :y 1327} {:x \"ZDFheute\", :y 949} {:x \"FAZ_NET\", :y 2919} {:x \"focusonline\", :y 271} {:x \"welt\", :y 1990} {:x \"N24_de\", :y 1962} {:x \"DerWesten\", :y 947} {:x \"SPIEGELONLINE\", :y 1763} {:x \"ntvde\", :y 1816} {:x \"tagesschau\", :y 1736} {:x \"SZ\", :y 1615} {:x \"sternde\", :y 982})} {:name \"e0e1d1d2-4b30-4339-b9f3-d04295f8898f\", :values ({:x \"dpa\", :y 445} {:x \"tazgezwitscher\", :y 639} {:x \"BILD\", :y 983} {:x \"ZDFheute\", :y 530} {:x \"FAZ_NET\", :y 2187} {:x \"focusonline\", :y 266} {:x \"welt\", :y 1798} {:x \"N24_de\", :y 1940} {:x \"DerWesten\", :y 854} {:x \"SPIEGELONLINE\", :y 1642} {:x \"ntvde\", :y 1793} {:x \"tagesschau\", :y 1282} {:x \"SZ\", :y 1523} {:x \"sternde\", :y 895})}), :marks ({:type \"rect\", :from {:data \"cdab57da-9f48-45e3-b073-985d18645933\"}, :properties {:enter {:y {:scale \"y\", :field \"data.y\"}, :width {:offset -1, :scale \"x\", :band true}, :x {:scale \"x\", :field \"data.x\"}, :y2 {:scale \"y\", :value 0}}, :update {:fill {:value \"red\"}, :opacity {:value 1}}, :hover {:fill {:value \"#FF29D2\"}}}} {:type \"rect\", :from {:data \"e0e1d1d2-4b30-4339-b9f3-d04295f8898f\"}, :properties {:enter {:y {:scale \"y\", :field \"data.y\"}, :width {:offset -1, :scale \"x\", :band true}, :x {:scale \"x\", :field \"data.x\"}, :y2 {:scale \"y\", :value 0}}, :update {:fill {:value \"steelblue\"}, :opacity {:value 1}}, :hover {:fill {:value \"#FF29D2\"}}}})}}"}
-;; <=
-
-;; @@
-
-;; @@
-;; =>
-;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":""dpa"","value":"\"dpa\""},{"type":"html","content":"75","value":"75"}],"value":"[\"dpa\" 75]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":""tazgezwitscher"","value":"\"tazgezwitscher\""},{"type":"html","content":"61","value":"61"}],"value":"[\"tazgezwitscher\" 61]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":""BILD"","value":"\"BILD\""},{"type":"html","content":"344","value":"344"}],"value":"[\"BILD\" 344]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":""ZDFheute"","value":"\"ZDFheute\""},{"type":"html","content":"419","value":"419"}],"value":"[\"ZDFheute\" 419]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":""FAZ_NET"","value":"\"FAZ_NET\""},{"type":"html","content":"732","value":"732"}],"value":"[\"FAZ_NET\" 732]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":""focusonline"","value":"\"focusonline\""},{"type":"html","content":"5","value":"5"}],"value":"[\"focusonline\" 5]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":""welt"","value":"\"welt\""},{"type":"html","content":"192","value":"192"}],"value":"[\"welt\" 192]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":""N24_de"","value":"\"N24_de\""},{"type":"html","content":"22","value":"22"}],"value":"[\"N24_de\" 22]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":""DerWesten"","value":"\"DerWesten\""},{"type":"html","content":"93","value":"93"}],"value":"[\"DerWesten\" 93]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":""SPIEGELONLINE"","value":"\"SPIEGELONLINE\""},{"type":"html","content":"121","value":"121"}],"value":"[\"SPIEGELONLINE\" 121]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":""ntvde"","value":"\"ntvde\""},{"type":"html","content":"23","value":"23"}],"value":"[\"ntvde\" 23]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":""tagesschau"","value":"\"tagesschau\""},{"type":"html","content":"454","value":"454"}],"value":"[\"tagesschau\" 454]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":""SZ"","value":"\"SZ\""},{"type":"html","content":"92","value":"92"}],"value":"[\"SZ\" 92]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":""sternde"","value":"\"sternde\""},{"type":"html","content":"87","value":"87"}],"value":"[\"sternde\" 87]"}],"value":"{\"dpa\" 75, \"tazgezwitscher\" 61, \"BILD\" 344, \"ZDFheute\" 419, \"FAZ_NET\" 732, \"focusonline\" 5, \"welt\" 192, \"N24_de\" 22, \"DerWesten\" 93, \"SPIEGELONLINE\" 121, \"ntvde\" 23, \"tagesschau\" 454, \"SZ\" 92, \"sternde\" 87}"}
-;; <=
-
-;; @@
-
-;; @@
+;;; {"type":"vega","content":{"width":1000,"height":618.0469970703125,"padding":{"bottom":20,"top":10,"right":10,"left":50},"scales":[{"name":"x","type":"ordinal","range":"width","domain":{"data":"5a7033d4-82fe-4d01-a6ff-6b4f30745d2f","field":"data.x"}},{"name":"y","range":"height","nice":true,"domain":{"data":"5a7033d4-82fe-4d01-a6ff-6b4f30745d2f","field":"data.y"}}],"axes":[{"scale":"x","type":"x"},{"scale":"y","type":"y"}],"data":[{"name":"5a7033d4-82fe-4d01-a6ff-6b4f30745d2f","values":[{"x":"dpa","y":520},{"x":"tazgezwitscher","y":700},{"x":"BILD","y":1327},{"x":"ZDFheute","y":949},{"x":"FAZ_NET","y":2919},{"x":"focusonline","y":271},{"x":"welt","y":1990},{"x":"N24_de","y":1962},{"x":"DerWesten","y":947},{"x":"SPIEGELONLINE","y":1763},{"x":"ntvde","y":1816},{"x":"tagesschau","y":1736},{"x":"SZ","y":1615},{"x":"sternde","y":982}]},{"name":"f42733d3-7271-4aa2-a87e-c3412e9b856c","values":[{"x":"dpa","y":445},{"x":"tazgezwitscher","y":639},{"x":"BILD","y":983},{"x":"ZDFheute","y":530},{"x":"FAZ_NET","y":2187},{"x":"focusonline","y":266},{"x":"welt","y":1798},{"x":"N24_de","y":1940},{"x":"DerWesten","y":854},{"x":"SPIEGELONLINE","y":1642},{"x":"ntvde","y":1793},{"x":"tagesschau","y":1282},{"x":"SZ","y":1523},{"x":"sternde","y":895}]}],"marks":[{"type":"rect","from":{"data":"5a7033d4-82fe-4d01-a6ff-6b4f30745d2f"},"properties":{"enter":{"y":{"scale":"y","field":"data.y"},"width":{"offset":-1,"scale":"x","band":true},"x":{"scale":"x","field":"data.x"},"y2":{"scale":"y","value":0}},"update":{"fill":{"value":"red"},"opacity":{"value":1}},"hover":{"fill":{"value":"#FF29D2"}}}},{"type":"rect","from":{"data":"f42733d3-7271-4aa2-a87e-c3412e9b856c"},"properties":{"enter":{"y":{"scale":"y","field":"data.y"},"width":{"offset":-1,"scale":"x","band":true},"x":{"scale":"x","field":"data.x"},"y2":{"scale":"y","value":0}},"update":{"fill":{"value":"steelblue"},"opacity":{"value":1}},"hover":{"fill":{"value":"#FF29D2"}}}}]},"value":"#gorilla_repl.vega.VegaView{:content {:width 1000, :height 618.047, :padding {:bottom 20, :top 10, :right 10, :left 50}, :scales [{:name \"x\", :type \"ordinal\", :range \"width\", :domain {:data \"5a7033d4-82fe-4d01-a6ff-6b4f30745d2f\", :field \"data.x\"}} {:name \"y\", :range \"height\", :nice true, :domain {:data \"5a7033d4-82fe-4d01-a6ff-6b4f30745d2f\", :field \"data.y\"}}], :axes [{:scale \"x\", :type \"x\"} {:scale \"y\", :type \"y\"}], :data ({:name \"5a7033d4-82fe-4d01-a6ff-6b4f30745d2f\", :values ({:x \"dpa\", :y 520} {:x \"tazgezwitscher\", :y 700} {:x \"BILD\", :y 1327} {:x \"ZDFheute\", :y 949} {:x \"FAZ_NET\", :y 2919} {:x \"focusonline\", :y 271} {:x \"welt\", :y 1990} {:x \"N24_de\", :y 1962} {:x \"DerWesten\", :y 947} {:x \"SPIEGELONLINE\", :y 1763} {:x \"ntvde\", :y 1816} {:x \"tagesschau\", :y 1736} {:x \"SZ\", :y 1615} {:x \"sternde\", :y 982})} {:name \"f42733d3-7271-4aa2-a87e-c3412e9b856c\", :values ({:x \"dpa\", :y 445} {:x \"tazgezwitscher\", :y 639} {:x \"BILD\", :y 983} {:x \"ZDFheute\", :y 530} {:x \"FAZ_NET\", :y 2187} {:x \"focusonline\", :y 266} {:x \"welt\", :y 1798} {:x \"N24_de\", :y 1940} {:x \"DerWesten\", :y 854} {:x \"SPIEGELONLINE\", :y 1642} {:x \"ntvde\", :y 1793} {:x \"tagesschau\", :y 1282} {:x \"SZ\", :y 1523} {:x \"sternde\", :y 895})}), :marks ({:type \"rect\", :from {:data \"5a7033d4-82fe-4d01-a6ff-6b4f30745d2f\"}, :properties {:enter {:y {:scale \"y\", :field \"data.y\"}, :width {:offset -1, :scale \"x\", :band true}, :x {:scale \"x\", :field \"data.x\"}, :y2 {:scale \"y\", :value 0}}, :update {:fill {:value \"red\"}, :opacity {:value 1}}, :hover {:fill {:value \"#FF29D2\"}}}} {:type \"rect\", :from {:data \"f42733d3-7271-4aa2-a87e-c3412e9b856c\"}, :properties {:enter {:y {:scale \"y\", :field \"data.y\"}, :width {:offset -1, :scale \"x\", :band true}, :x {:scale \"x\", :field \"data.x\"}, :y2 {:scale \"y\", :value 0}}, :update {:fill {:value \"steelblue\"}, :opacity {:value 1}}, :hover {:fill {:value \"#FF29D2\"}}}})}}"}
+;; <=
+
+;; **
+;;; # Overall Statistics
+;; **
+
+;; **
+;;; ## Tree Size
+;; **
+
+;; @@
+(def short-summary
+  (let [users (map :_id (mc/find-maps @db "users" {:screen_name {$in news-accounts}}))
+        reaction-forest (pmap #(reaction-tree (:_id %)) (mc/find-maps @db "publications" {:user {$in users}}))]
+         (pmap summary reaction-forest)))
+;; @@
+;; =>
+;;; {"type":"html","content":"#'unsightly-reserve/short-summary","value":"#'unsightly-reserve/short-summary"}
+;; <=
+
+;; @@
+(defn short-metrics [coll]
+  {:mean (mean coll)
+   :variance (variance coll)
+   :quantiles (quantile coll)})
+;; @@
+;; =>
+;;; {"type":"html","content":"#'unsightly-reserve/short-metrics","value":"#'unsightly-reserve/short-metrics"}
+;; <=
+
+;; @@
+(short-metrics (map :size short-summary))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":mean","value":":mean"},{"type":"html","content":"6.257219059342463","value":"6.257219059342463"}],"value":"[:mean 6.257219059342463]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":variance","value":":variance"},{"type":"html","content":"86.42137086670392","value":"86.42137086670392"}],"value":"[:variance 86.42137086670392]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":quantiles","value":":quantiles"},{"type":"html","content":"(1.0 1.0 3.0 8.0 207.0)","value":"(1.0 1.0 3.0 8.0 207.0)"}],"value":"[:quantiles (1.0 1.0 3.0 8.0 207.0)]"}],"value":"{:mean 6.257219059342463, :variance 86.42137086670392, :quantiles (1.0 1.0 3.0 8.0 207.0)}"}
+;; <=
+
+;; @@
+(short-metrics (map :height short-summary))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":mean","value":":mean"},{"type":"html","content":"0.9200389803559522","value":"0.9200389803559522"}],"value":"[:mean 0.9200389803559522]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":variance","value":":variance"},{"type":"html","content":"1.499094212678211","value":"1.499094212678211"}],"value":"[:variance 1.499094212678211]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":quantiles","value":":quantiles"},{"type":"html","content":"(0.0 0.0 1.0 1.0 48.0)","value":"(0.0 0.0 1.0 1.0 48.0)"}],"value":"[:quantiles (0.0 0.0 1.0 1.0 48.0)]"}],"value":"{:mean 0.9200389803559522, :variance 1.499094212678211, :quantiles (0.0 0.0 1.0 1.0 48.0)}"}
+;; <=
+
+;; **
+;;; ## User Posts
+;; **
+
+;; @@
+(def user-post-frequencies
+  (->> (mc/find-maps @db "publications")
+       (map :user)
+       frequencies))
+;; @@
+;; =>
+;;; {"type":"html","content":"#'unsightly-reserve/user-post-frequencies","value":"#'unsightly-reserve/user-post-frequencies"}
+;; <=
+
+;; @@
+(short-metrics (vals user-post-frequencies))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":mean","value":":mean"},{"type":"html","content":"4.354942375886525","value":"4.354942375886525"}],"value":"[:mean 4.354942375886525]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":variance","value":":variance"},{"type":"html","content":"915.8972380673573","value":"915.8972380673573"}],"value":"[:variance 915.8972380673573]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":quantiles","value":":quantiles"},{"type":"html","content":"(1.0 1.0 1.0 2.0 2919.0)","value":"(1.0 1.0 1.0 2.0 2919.0)"}],"value":"[:quantiles (1.0 1.0 1.0 2.0 2919.0)]"}],"value":"{:mean 4.354942375886525, :variance 915.8972380673573, :quantiles (1.0 1.0 1.0 2.0 2919.0)}"}
+;; <=
+
+;; **
+;;; ## User Mentions
+;; **
+
+;; @@
+(def user-mention-frequencies
+  (->> (mc/find-maps @db "mentions")
+       (map :user)
+       frequencies))
+;; @@
+;; =>
+;;; {"type":"html","content":"#'unsightly-reserve/user-mention-frequencies","value":"#'unsightly-reserve/user-mention-frequencies"}
+;; <=
+
+;; @@
+(short-metrics (vals user-mention-frequencies))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":mean","value":":mean"},{"type":"html","content":"35.81539447190188","value":"35.81539447190188"}],"value":"[:mean 35.81539447190188]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":variance","value":":variance"},{"type":"html","content":"705749.0909520709","value":"705749.0909520709"}],"value":"[:variance 705749.0909520709]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":quantiles","value":":quantiles"},{"type":"html","content":"(1.0 1.0 2.0 6.0 52035.0)","value":"(1.0 1.0 2.0 6.0 52035.0)"}],"value":"[:quantiles (1.0 1.0 2.0 6.0 52035.0)]"}],"value":"{:mean 35.81539447190188, :variance 705749.0909520709, :quantiles (1.0 1.0 2.0 6.0 52035.0)}"}
+;; <=
+
+;; **
+;;; ## Hashtags
+;; **
+
+;; @@
+(def hashtag-frequencies
+  (->> (mc/find-maps @db "publications")
+       (map :hashtags)
+       (remove nil?)
+       flatten
+       frequencies))
+;; @@
+;; =>
+;;; {"type":"html","content":"#'unsightly-reserve/hashtag-frequencies","value":"#'unsightly-reserve/hashtag-frequencies"}
+;; <=
+
+;; @@
+(short-metrics (vals hashtag-frequencies))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":mean","value":":mean"},{"type":"html","content":"10.725150555659031","value":"10.725150555659031"}],"value":"[:mean 10.725150555659031]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":variance","value":":variance"},{"type":"html","content":"10728.604261859029","value":"10728.604261859029"}],"value":"[:variance 10728.604261859029]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":quantiles","value":":quantiles"},{"type":"html","content":"(1.0 1.0 2.0 4.0 6491.0)","value":"(1.0 1.0 2.0 4.0 6491.0)"}],"value":"[:quantiles (1.0 1.0 2.0 4.0 6491.0)]"}],"value":"{:mean 10.725150555659031, :variance 10728.604261859029, :quantiles (1.0 1.0 2.0 4.0 6491.0)}"}
+;; <=
+
+;; @@
+
+;; @@


added kanji repeat mark

added kanji repeat mark

--- src/corpus_utils/wikipedia.clj
+++ src/corpus_utils/wikipedia.clj
@@ -40,7 +40,8 @@
   (let [code-point (.codePointAt ch 0)]
     (cond
      (and (>= code-point 0x3041) (<= code-point 0x309f)) :hiragana
-     (and (>= code-point 0x4e00) (<= code-point 0x9fff)) :kanji
+     (or (and (>= code-point 0x4e00) (<= code-point 0x9fff))
+         (= code-point 0x3005)) :kanji ;; 0x3005 -> kanji repeat mark
      (and (>= code-point 0x30a0) (<= code-point 0x30ff)) :katakana
      (or (and (>= code-point 65)    (<= code-point 122))    ; half-width alphabet (A-Za-z)
          (and (>= code-point 65313) (<= code-point 65370))  ; full-width alphabet (Ａ-Ｚａ-ｚ)


Nicer var name

Nicer var name

--- src/doctopus/doctopus/head.clj
+++ src/doctopus/doctopus/head.clj
@@ -18,8 +18,8 @@

 (defn split
-  [string]
-  (str/split string #" "))
+  [s]
+  (str/split s #" "))

 (defn injest-shell-strings
   "Takes a vector of shell commands, like:


handle self-join case

handle self-join case

--- pigpen-cascading/src/main/clojure/pigpen/cascading.clj
+++ pigpen-cascading/src/main/clojure/pigpen/cascading.clj
@@ -81,7 +81,12 @@
     (if-not (nil? cogroup-opts)
       (if (= udf :algebraic)
         (let [key-fields (cfields (first (:keys cogroup-opts)))
-              ; TODO: this is a hack to emulate multiple streams with a single stream by using a sentinel value to fill absent fields.
+              ; This is a hack to emulate multiple streams with a single stream by using a sentinel value to fill absent fields.
+              ; For example, if we have generate1 -> [1 1 2 3], generate2 => [1 2 2 3], the resulting merged stream will be:
+              ; [[1 1 s] [1 1 s] [2 2 s] [3 3 s] [1 s 1] [2 s 2] [2 s 2] [3 s 3]], where each tuple contains [key, value1, value2],
+              ; and s represents the sentinel value.
+              ; Another twist is that in case of a self join, a single pipe must be used because otherwise cascading will
+              ; do each operation twice.
               agg-fields (->> field-projections
                               (filter #(= :projection-func (:type %)))
                               (map :alias)
@@ -104,7 +109,12 @@
                                                                 (if (= index i)
                                                                   nil {:field v :shared-source (= (.getName pipe) (str (field-to-source (nth agg-fields i))))}))
                                                               agg-fields))))
-                         ;(#(vector (first %)))
+                         (reduce (fn [pipes pipe]
+                                   (let [pipe-names (into #{} (map #(.getName %) pipes))]
+                                     (if (pipe-names (.getName pipe))
+                                       pipes
+                                       (conj pipes pipe))))
+                                 [])
                          (into-array))]
           (add-val flowdef [:pipes] pipe (let [p (PigPenAggregateBy/buildAssembly (str pipe) pipes key-fields agg-fields inits funcs)]
                                            (if (:group-all cogroup-opts)


Add placeholders for all spec macros in clojure.spec

--- src/spec_tools/json_schema.cljc
+++ src/spec_tools/json_schema.cljc
@@ -113,21 +113,7 @@
     ;; (s/every (s/tuple key-spec value-spec) :into {} ...)
     (and (= pred #?(:clj 'clojure.spec/tuple :cljs 'cljs.spec/tuple)) (= (get kwargs :into)) {})))

-(defmethod accept-spec 'clojure.spec/every [dispatch spec children]
-  ;; Special case handling of s/map-of, which expands to s/every
-  (if (is-map-of? spec)
-    {:type "object" :additionalProperties (get-in (unwrap children) [:items 1])}
-    {:type "array" :items (unwrap children)}))
-
-(defmethod accept-spec 'clojure.spec/tuple [dispatch spec children]
-  {:type "array" :items children :minItems (count children)})
-
-(defmethod accept-spec 'clojure.spec/* [dispatch spec children]
-  {:type "array" :items (unwrap children)})
-
-(defmethod accept-spec 'clojure.spec/+ [dispatch spec children]
-  {:type "array" :items (unwrap children) :minItems 1})
-
+; keys
 (defmethod accept-spec 'clojure.spec/keys [dispatch spec children]
   (let [[_ & {:keys [req req-un opt opt-un]}] (s/form spec)
         names (map name (concat req req-un opt opt-un))
@@ -136,15 +122,52 @@
      :properties (zipmap names children)
      :required required}))

+; or
 (defmethod accept-spec 'clojure.spec/or [dispatch spec children]
   {:anyOf children})

+; and
 (defmethod accept-spec 'clojure.spec/and [dispatch spec children]
   (simplify-all-of {:allOf children}))
+
+; merge
+
+; every
+(defmethod accept-spec 'clojure.spec/every [dispatch spec children]
+  ;; Special case handling of s/map-of, which expands to s/every
+  (if (is-map-of? spec)
+    {:type "object" :additionalProperties (get-in (unwrap children) [:items 1])}
+    {:type "array" :items (unwrap children)}))
+
+; every-ks
+; coll-of
+; map-of
+
+; *
+(defmethod accept-spec 'clojure.spec/* [dispatch spec children]
+  {:type "array" :items (unwrap children)})
+
+; +
+(defmethod accept-spec 'clojure.spec/+ [dispatch spec children]
+  {:type "array" :items (unwrap children) :minItems 1})
+
+; ?
+; alt
+; cat
+; &
+
+; tuple
+(defmethod accept-spec 'clojure.spec/tuple [dispatch spec children]
+  {:type "array" :items children :minItems (count children)})
+
+; keys*
+
+; nilable

 (defmethod accept-spec 'clojure.spec/nilable [dispatch spec children]
   {:oneOf [(unwrap children) {:type "null"}]})

+;; this is just a function in clojure.spec?
 (defmethod accept-spec 'clojure.spec/int-in-range? [dispatch spec children]
   (let [[_ minimum maximum _] (visitor/strip-fn-if-needed spec)]
     {:minimum minimum :maximum maximum}))


Move and document load-config.

Move and document load-config.

--- src/fhofherr/simple/engine.clj
+++ src/fhofherr/simple/engine.clj
@@ -2,14 +2,6 @@
   "FIXME: Add documentation.")

 (def config-ns-name 'fhofherr.simple.projectdef)
-
-(defn load-config
-  [path]
-  (when (find-ns config-ns-name)
-    (remove-ns config-ns-name))
-  (binding [*ns* (find-ns 'fhofherr.simple.dsl)]
-    (load-file path))
-  (find-ns config-ns-name))

 (defn initial-context
   "Initial context of a job execution."
@@ -69,6 +61,17 @@
                  (apply-step after true)))]
     (with-meta job {:ci-job? true})))

+
+(defn load-config
+  "Load the Simple CI configuration file located under the given `path`.
+  Returns the namespace into which the configration was loaded."
+  [path]
+  (when (find-ns config-ns-name)
+    (remove-ns config-ns-name))
+  (binding [*ns* (find-ns 'fhofherr.simple.dsl)]
+    (load-file path))
+  (find-ns config-ns-name))
+
 (defn find-ci-jobs
   "Find Simple CI jobs in the `cidef-ns` namespace. All mappings with
   a truthy value for the key `:ci-job?` in their meta data are treated as


Cleanup

Cleanup

--- test/clojure/clojurewerkz/cassaforte/async_cql_test.clj
+++ test/clojure/clojurewerkz/cassaforte/async_cql_test.clj
@@ -1,105 +0,0 @@
-(ns clojurewerkz.cassaforte.async-cql-test
-  (:refer-clojure :exclude [update])
-  (:import [java.util.concurrent CountDownLatch Executors])
-  )
-
-
-;;   (use-fixtures :each (fn [f]
-;;                         (th/with-temporary-keyspace f)))
-
-;; (let [s (th/make-test-session)]
-;;   (deftest test-insert
-;;     (let [r {:name "Alex" :city "Munich" :age (int 19)}]
-;;       (deref (client/async
-;;               (insert s :users r)))
-;;       (is (= r (first @(select-async s :users))))
-;;       (truncate s :users)))
-
-;;   (deftest test-insert-time-unit
-;;     (let [r {:name "Alex" :city "Munich" :age (int 19)}]
-;;       @(insert-async s :users r)
-;;       (is (= r (first (deref (select-async s :users) 1000 nil))))
-;;       (truncate s :users)))
-
-;;   (deftest test-insert-callback
-;;     (let [r     {:name "Alex" :city "Munich" :age (int 19)}
-;;           latch (CountDownLatch. 1)]
-;;       @(insert-async s :users r)
-;;       (let [result-future (select-async s :users)]
-;;         (client/add-listener result-future
-;;                              (fn [] (.countDown latch))
-;;                              (Executors/newFixedThreadPool 1))
-;;         (is (= r (first @result-future)))
-;;         (.await latch)
-;;         (is (= 0 (.getCount latch))))
-
-;;       (truncate s :users)))
-
-;;   (deftest test-insert-batch-with-ttl
-;;     (let [input [[{:name "Alex" :city "Munich" :age (int 19)} (using :ttl (int 350))]
-;;                  [{:name "Alex" :city "Munich" :age (int 19)} (using :ttl (int 350))]]]
-;;       @(insert-batch-async s :users input)
-
-;;       @(insert-batch-async s :users input)
-;;       (is (= (first (first input)) (first @(select-async s :users))))
-;;       (truncate s :users)))
-
-;;   (deftest test-insert-batch-plain
-;;     (let [input [{:name "Alex" :city "Munich" :age (int 19)}
-;;                  {:name "Alex" :city "Munich" :age (int 19)}]]
-;;       @(insert-batch-async s :users input)
-;;       (is (= (first input) (first @(select-async s :users))))
-;;       (truncate s :users)))
-
-;;   (deftest test-update
-;;     (testing "Simple updates"
-;;       (let [r {:name "Alex" :city "Munich" :age (int 19)}]
-;;         @(insert-async s :users r)
-;;         (is (= r (first @(select-async s :users))))
-;;         (update s :users
-;;                 {:age (int 25)}
-;;                 (where {:name "Alex"}))
-;;         (is (= {:name "Alex" :city "Munich" :age (int 25)}
-;;                (first @(select-async s :users))))))
-
-;;     (testing "One of many update"
-;;       (dotimes [i 3]
-;;         @(insert-async s :user_posts {:username "user1"
-;;                                       :post_id (str "post" i)
-;;                                       :body (str "body" i)}))
-;;       @(update-async s :user_posts
-;;                      {:body "bodynew"}
-;;                      (where {:username "user1"
-;;                              :post_id "post1"}))
-;;       (is (= "bodynew"
-;;              (get-in @(select-async s :user_posts
-;;                                     (where {:username "user1"
-;;                                             :post_id "post1"}))
-;;                      [0 :body])))))
-
-;;   (deftest test-delete
-;;     (->> (range 0 3)
-;;          (map #(insert-async s :users {:name (str "name" %) :age (int %)}))
-;;          (map deref)
-;;          doall) ;; Better deref before couting, otherwise there's a good chance it's not even inserted yet
-
-
-;;     (is (= 3 (perform-count s :users)))
-;;     @(delete-async s :users
-;;                    (where {:name "name1"}))
-;;     (is (= 2 (perform-count s :users)))
-;;     (truncate s :users)
-
-;;     @(insert-async s :users {:name "name1" :age (int 19)})
-;;     @(delete-async s :users
-;;                    (columns :age)
-;;                    (where {:name "name1"}))
-;;     (is (nil? (:age @(select-async s :users))))
-;;     (truncate s :users))
-
-;;   (deftest test-insert-with-timestamp
-;;     (let [r {:name "Alex" :city "Munich" :age (int 19)}]
-;;       @(insert-async s :users r
-;;                      (using :timestamp (.getTime (java.util.Date.))))
-;;       (is (= r (first @(select-async s :users))))
-;;       (truncate s :users))))


Move function to fix 'undefined fn' error

--- src/ecregister/core.clj
+++ src/ecregister/core.clj
@@ -27,6 +27,21 @@
                   }))
 (defn update-state [& args]
   (apply swap! state assoc args))
+
+(defn update-stamped-image [form]
+  "Gets an image from state, [re]stamps it according to state config,
+saves newly stamped to state updates widgets"
+  (when-let [image-orig (:image-orig @state)]
+    (update-state :image-stamped
+                  (av/stamped image-orig
+                              (get-in @state [:stamp-path (:stamp-type @state)])
+                              (:image-ext @state)))
+    (config! (select form [:#stamped-ava]) :icon (:image-stamped @state))
+    (let [filename (str (:username @state) "." (:image-ext @state))]
+      (config! (select form [:#save-label-orig])
+               :text (str (:save-dir-orig @state) filename))
+      (config! (select form [:#save-label-new])
+               :text (str (:save-dir-new @state) filename)))))

 ;;(require '[clojure.core.async :refer [chan >!! <!! <! >! alts!! alts! timeout thread put! go go-loop close!]])
 (defn prepare-avatars [username lb-log form]
@@ -46,21 +61,6 @@
            (update-stamped-image form)
            ))
        ))))
-
-(defn update-stamped-image [form]
-  "Gets an image from state, [re]stamps it according to state config,
-saves newly stamped to state updates widgets"
-  (when-let [image-orig (:image-orig @state)]
-    (update-state :image-stamped
-                  (av/stamped image-orig
-                              (get-in @state [:stamp-path (:stamp-type @state)])
-                              (:image-ext @state)))
-    (config! (select form [:#stamped-ava]) :icon (:image-stamped @state))
-    (let [filename (str (:username @state) "." (:image-ext @state))]
-      (config! (select form [:#save-label-orig])
-               :text (str (:save-dir-orig @state) filename))
-      (config! (select form [:#save-label-new])
-               :text (str (:save-dir-new @state) filename)))))

 (defn build-avatars-tab []
   (let [bg-stamp-pos (button-group)


Better way of handling regular ws connections

- We create the connection stream periodically and close it after a specific time
- Removes use of atom
- We publish events to bus regularly in the process
- Since Subscribers are subscribed to the bus the updation doesn't effect them

--- src/in/co/sdslabs/slack_lens/lib/slack_rtm.clj
+++ src/in/co/sdslabs/slack_lens/lib/slack_rtm.clj
@@ -4,7 +4,8 @@
             [cheshire.core :as json]
             [manifold.stream :as s]
             [manifold.time :as t]
-            [manifold.bus :as bus]))
+            [manifold.bus :as bus]
+            [clojure.core.async :refer [timeout <! go]]))

 (def event-bus (bus/event-bus))

@@ -42,19 +43,20 @@
   (-> (get-rtm-ws-url url token)
        get-rtm-ws-connection))

-(defn- reset-conn
-  [options]
-  (reset! rtm-conn (connect (:url options) (:token options))))

 (defn subscribe
   [type func]
   (let [message-stream (bus/subscribe event-bus type)]
     (future (s/consume func message-stream))))

+(defn- reset-conn
+  [options]
+  (let [conn (connect (:url options) (:token options))]
+    (s/consume publish-events (->> conn (s/buffer 100)))
+    (go
+      (<! (timeout conn-reset-delay))
+      (s/close! conn))))
+
 (defn start
   [options]
-  (let [conn (connect (:url options) (:token options))
-        _ (reset! rtm-conn conn)]
-    (t/every conn-reset-delay #(reset-conn options))
-    (future (s/consume publish-events (->> @rtm-conn (s/buffer 100))))
-    @rtm-conn))
+  (t/every conn-reset-delay #(reset-conn options)))


new: parallel graph index generation

new: parallel graph index generation

--- src/hangman/triples.clj
+++ src/hangman/triples.clj
@@ -88,6 +88,29 @@
                     triple)))))
     {} triples))

+
+;;;;
+;;; The following index implementation exploits clojure reducers
+;;; concurrency.  It is included for reference and is not
+;;; currently in use because in practice it provides no gains
+;;; in performance
+;;;;
+
+;; (defn make-index [triples key1 key2 key3]
+;;   (r/fold util/rmerge (fn
+;;                         ([] {})
+;;                         ([i0 triple]
+;;                            (let [i0 (or i0 {})
+;;                                  i1 (or (i0 (key1 triple)) {})
+;;                                  i2 (or (i1 (key2 triple)) {})]
+;;                              (assoc i0
+;;                                (key1 triple)
+;;                                (assoc i1
+;;                                  (key2 triple)
+;;                                  (assoc i2
+;;                                    (key3 triple)
+;;                                    triple))))))
+;;     triples))

 ;;;;
 ;;; The following index implementation creates a set for the innermost


Update docstring for new lazy impl

Update docstring for new lazy impl

--- src/useful.clj
+++ src/useful.clj
@@ -48,8 +48,8 @@
     [item (concat head tail)]))

 (defn separate
-  "Split coll into two sequences, one that matches pred and one that doesn't. Unlike, the
-  version in clojure.contrib.seq-utils, this is not lazy, but pred is only called once per item."
+  "Split coll into two sequences, one that matches pred and one that doesn't. Unlike the
+  version in clojure.contrib.seq-utils, pred is only called once per item."
   [pred coll]
   (let [coll (map (fn [x]
                     [x (pred x)])


Spacing

Spacing

--- src/wireframes/shape_loader.clj
+++ src/wireframes/shape_loader.clj
@@ -60,8 +60,8 @@
 (defn load-shape [file divisions]
   (let [raw-data    (vec (str/split-lines (slurp file)))
         num-patches (Integer/parseInt (raw-data 0))
-	patches     (create-patches (subvec raw-data 1 (inc num-patches)))
-	vertices    (create-vertices (subvec raw-data (+ num-patches 2)))]
+        patches     (create-patches (subvec raw-data 1 (inc num-patches)))
+        vertices    (create-vertices (subvec raw-data (+ num-patches 2)))]
       (->>
 	;(take 2 (drop 5 patches))
 	patches


start work on rhs deletion

start work on rhs deletion

--- dada2-core/src/test/clojure/org/dada2/test_join_model.clj
+++ dada2-core/src/test/clojure/org/dada2/test_join_model.clj
@@ -384,6 +384,15 @@
 	   }
 	   (data joined-model)))

+    ;; join - delete rhs - c2
+    (on-delete cs c2)
+    (is (= [[{:b {:a1 a1v1}}{:c {:a1 a1v1}}]
+	    {:b {:b1 b1v1 :b2 nil}} {:c {:c1 c1v1 :c2 nil}}] (data join)))
+    (is (= {
+	   [:a1 :b1 :c1] (->ABC [:a1 :b1 :c1] [1 1 1] "b1v1-data" "c1v1-data")
+	   }
+	   (data joined-model)))
+
     ;; TODO:
     ;;  amend in/out
     ;;  delete


don't try across recur

don't try across recur

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@8050 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- plugins/DataBrowser/src/org/micromanager/browser/core.clj
+++ plugins/DataBrowser/src/org/micromanager/browser/core.clj
@@ -304,23 +304,24 @@

 (defn start-reading-thread []
   (doto (Thread.
-            (fn []
+          (fn []
+            (try
               (dorun
                 (loop []
                   (Thread/sleep 5)
-                  (try
-                    (let [data-set (.take pending-data-sets)]
-                      ;(println @current-locations (second data-set) (contains? @current-locations (second data-set)))
-                      (if (= data-set pending-data-sets) ;; poison
-                        (update-browser-status)
-                        (let [loc (second data-set)]
-                          (when (or (= loc "") (contains? @current-locations loc))
-                            (let [m (apply get-summary-map data-set)]
-                              (add-browser-table-row (map #(get m %) tags))
-                              (remove-sibling-positions m)
-                              (awt-event (update-browser-status))))
-                          (recur))))
-                    (catch Exception e (.printStackTrace e))))))
+                  (let [data-set (.take pending-data-sets)]
+                    ;(println @current-locations (second data-set) (contains? @current-locations (second data-set)))
+                    (if (= data-set pending-data-sets) ;; poison
+                      (update-browser-status)
+                      (let [loc (second data-set)]
+                        (when (or (= loc "") (contains? @current-locations loc))
+                          (let [m (apply get-summary-map data-set)]
+                            (add-browser-table-row (map #(get m %) tags))
+                            (remove-sibling-positions m)
+                            (awt-event (update-browser-status))))
+                        (recur))))))
+              (catch Exception e (.printStackTrace e))
+              ))
           "data browser reading thread") .start))

 (defn scan-location [location]


More charset tests

More charset tests

--- test/yada/representation_test.clj
+++ test/yada/representation_test.clj
@@ -107,6 +107,24 @@
             {:charset (charset/to-charset-map "utf-8")})
            [(float 1.0) (float 1.0)])))

+  (testing "Basic match with wildcard"
+    (is (= (get-highest-charset-quality
+            {:headers {"accept-charset" "*"}}
+            {:charset (charset/to-charset-map "utf-8")})
+           [(float 1.0) (float 1.0)])))
+
+  (testing "Basic match with wildcard, multiple choices"
+    (is (= (get-highest-charset-quality
+            {:headers {"accept-charset" "*;q=0.9,utf-8"}}
+            {:charset (charset/to-charset-map "utf-8")})
+           [(float 1.0) (float 1.0)])))
+
+  (testing "Basic match with wildcard, multiple choices, matches wildcard"
+    (is (= (get-highest-charset-quality
+            {:headers {"accept-charset" "*;q=0.9,utf-8"}}
+            {:charset (charset/to-charset-map "us-ascii")})
+           [(float 0.9) (float 1.0)])))
+
   (testing "Quality values"
     (is (= (get-highest-charset-quality
             {:headers {"accept-charset" "utf-8;q=0.8"}}


Fixed bug in explore-model

Fixed bug in explore-model

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

--- src/conexp/contrib/dl/languages/EL_gfp_exploration.clj
+++ src/conexp/contrib/dl/languages/EL_gfp_exploration.clj
@@ -108,7 +108,10 @@
 		   next-Pi_k  (conj Pi_k P_k),

 		   implications (if (= K next-K)
-                                  implications
+                                  (let [new-impl (make-implication P_k (context-attribute-closure next-K P_k))]
+                                    (if (not (empty? (conclusion new-impl)))
+                                      (conj implications new-impl)
+                                      implications))
                                   (set-of impl [P_l next-Pi_k
                                                 :let [impl (make-implication P_l (context-attribute-closure next-K P_l))]
                                                 :when (not (empty? (conclusion impl)))])),


Include data used to access state store in ex-info

--- src/onyx/http_query.clj
+++ src/onyx/http_query.clj
@@ -212,27 +212,29 @@
                start-time (get-param request "start-time" :long)
                end-time (get-param request "end-time" :long)
                store (get @(:state state-store-group) [job-id task slot-id allocation-version])
-               _ (when-not store (throw (ex-info "Peer state store not found." {})))
+               _ (when-not store (throw (ex-info "Peer state store not found."
+                                                 {:job-id job-id :task task
+                                                  :slot-id slot-id :allocation-version allocation-version})))
                {:keys [db state-indices grouped? idx->window]} store
                idx (get state-indices window)
                group (get-in request [:query-params "group"])
                groups (if group
                         [(clojure.edn/read-string group)]
                         (db/groups db))]
-           {:result {:grouped? grouped?
+           {:result {:grouped? grouped?
                      :window (get idx->window idx)
                      :contents (->> groups
                                     (reduce (fn [m group]
-                                              (let [group-id (db/group-id db group)]
+                                              (let [group-id (db/group-id db group)]
                                                 (assoc m group (db/get-state-entries db idx group-id start-time end-time))))
                                             {})
                                     (unwrap-grouped-contents grouped?))}}))}

    {:uri "/state"
     :request-method :get}
-   {:doc "Retrieve a task's window state for a particular job. Must supply the :allocation-version for the job.
+   {:doc "Retrieve a task's window state for a particular job. Must supply the :allocation-version for the job.
           The allocation version can be looked up via the /replica/allocation-version, or by subscribing to the log and looking up the [:allocation-version job-id]."
-    :query-params-schema {"job-id" String
+    :query-params-schema {"job-id" String
                           "task-id" String
                           "slot-id" Long
                           "group" String
@@ -252,17 +254,19 @@
                groups (if group
                         [(clojure.edn/read-string group)]
                         (db/groups db))
-               _ (when-not store (throw (ex-info "Peer state store not found." {})))
+               _ (when-not store (throw (ex-info "Peer state store not found."
+                                                 {:job-id job-id :task task
+                                                  :slot-id slot-id :allocation-version allocation-version})))
                idx (get state-indices window)]
-           {:result {:grouped? grouped?
+           {:result {:grouped? grouped?
                      :window (get idx->window idx)
                      :contents (->> groups
                                     (reduce (fn [m group]
-                                              (let [group-id (db/group-id db group)]
+                                              (let [group-id (db/group-id db group)]
                                                 (reduce (fn [m extent]
-                                                          (update m
-                                                                  group
-                                                                  (fn [m]
+                                                          (update m
+                                                                  group
+                                                                  (fn [m]
                                                                     (conj (or m [])
                                                                           [extent (db/get-extent db idx group-id extent)]))))
                                                         m


Add input.

Add input.

--- src/onyx/plugin/sql.clj
+++ src/onyx/plugin/sql.clj
@@ -74,6 +74,7 @@
                           (let [result (first (alts!! [read-ch timeout-ch] :priority true))]
                             (if (= :done result)
                               {:id (java.util.UUID/randomUUID)
+                               :input :datomic
                                :message :done}
                               {:id (java.util.UUID/randomUUID)
                                :input :sql


adding setup for web tests

adding setup for web tests

--- resources/leiningen/new/closp/integtest/clj/web/setup.clj
+++ resources/leiningen/new/closp/integtest/clj/web/setup.clj
@@ -46,7 +46,7 @@
   (w/quit))

 (defn start-server []
-  (reloaded.repl/set-init! prod-system)
+  (reloaded.repl/set-init! test-system)
   (go))

 (defn stop-server []


Added test mode to cli

Added test mode to cli

--- src/plan_schema/cli.clj
+++ src/plan_schema/cli.clj
@@ -94,6 +94,10 @@
              "Actions:"])
     (string/join \newline)))

+(def test-mode false)
+(defn set-test-mode [value]
+  (def test-mode value))
+
 (defn repl?
   "Helper function returns true if on the REPL (for development)"
   {:added "0.2.0"}
@@ -109,8 +113,8 @@
       (println (string/join \newline msgs))
       (pschema/log-error \newline (string/join \newline msgs))))
   (flush) ;; ensure all pending output has been flushed
-  (if (repl?)
-    (pschema/log-warn "exit" status "In DEV MODE. Not exiting")
+  (if (or (repl?) test-mode)
+    (pschema/log-warn "exit" status "plan-schema in DEV MODE. Not exiting ->" "repl?" (repl?) "test-mode" test-mode)
     (do (shutdown-agents)
         (System/exit status)))
   true)
@@ -143,6 +147,7 @@
     (when (and verbose? (not exit?))
       (when (> verbose 1)
         (println "repl?:" (repl?))
+        (println "test-mode:" test-mode)
         (println "cwd:" cwd)
         (println "version:" (:plan-schema-version env)))
       (println "verbosity level:" verbose)


Fixed up prep-for-uploading-to-client: whitelist and various cleanup

--- src/polismath/utils.clj
+++ src/polismath/utils.clj
@@ -76,6 +76,16 @@
   (apply (apply partial f (butlast args)) (apply concat (last args))))

+(defn hash-map-subset
+    "Create a new map which is given by subsetting to the given keys (ks)"
+    [m ks]
+    (let [ks (set ks)]
+      (into {}
+        (filter
+          (fn [[k v]] (ks k))
+          m))))
+
+
 (defn use-debuggers
   "Handy debugging utility for loading in debugging namespaces - doesn't really always work. XXX - maybe
   use Vinyasa?"
@@ -97,31 +107,45 @@
   {"bidToPid" (:bid-to-pid results)})

+
+(defn- assoc-in-bc
+  "Helper function to clean up the prep-for-uploading fn"
+  [conv k v & kvs]
+  (let [this-part (assoc-in conv [:base-clusters k] v)]
+    (if (empty? kvs)
+      this-part
+      (apply assoc-in-bc this-part kvs))))
+
+
 (defn prep-for-uploading-to-client [results]
   ; XXX - this should really be in conversations I think; not really a util function
-  (let [base-clusters (:base-clusters results)
-        repness (:base-clusters results)]
+  (let [base-clusters (:base-clusters results)]
     (-> results
-      ; remove things we don't want to publish
-      (dissoc :mat :rating-mat :opts' :bucket-dists :base-clusters-proj)
-
-      ; REFORMAT PROJECTION
-      ; remove original projection - we'll provide buckets/base-clusters instead
-      (dissoc :proj)
-
       ; REFORMAT BASE CLUSTERS
       (dissoc :base-clusters)
-      (dissoc :bid-to-pid)
-      ; XXX - This should actually be based on the base-clusters-proj, since the work has already be done
-      ; here, but before it gets dissoc'd
-      (assoc-in [:base-clusters "x"] (map #(first (:center %)) base-clusters))
-      (assoc-in [:base-clusters "y"] (map #(second (:center %)) base-clusters))
-      (assoc-in [:base-clusters "id"] (map :id base-clusters))
-      (assoc-in [:base-clusters "members"] (map :members base-clusters))
-      (assoc-in [:base-clusters "count"] (map #(count (:members %)) base-clusters))
+      (assoc-in-bc
+        "x"       (map #(first (:center %)) base-clusters)
+        "y"       (map #(second (:center %)) base-clusters)
+        "id"      (map :id base-clusters)
+        "members" (map :members base-clusters)
+        "count"   (map #(count (:members %)) base-clusters))

       ; REFORMAT REPNESS
       ; make the array position of each cluster imply the cluster id
-      (assoc :repness (map :repness (sort-by :id repness))))))
+      (assoc :repness (map :repness (sort-by :id base-clusters)))
+
+      ; Whitelist of keys to be included in sent data; removes intermediates
+      (hash-map-subset #{
+        :base-clusters
+        :group-clusters
+        :in-conv
+        :lastVoteTimestamp
+        :n
+        :n-cmts
+        :pca
+        :repness
+        :sid
+        :user-vote-counts
+        :votes-base}))))


Make trace delivery reschedule time be 25ms instead of 10ms

Half of 50, makes it less likely to cause issues with only a slight
increase in overhead (more likely to make several setTimeout calls).

--- src/re_frame/trace.cljc
+++ src/re_frame/trace.cljc
@@ -84,8 +84,8 @@
   ;; to avoid constant setting and cancelling
   ;; timeouts.

-  ;; If we are within 10 ms of next delivery
-  (when (< (- @next-delivery 10) now)
+  ;; If we are within 25 ms of next delivery
+  (when (< (- @next-delivery 25) now)
     (schedule-debounce)
     ;; The next-delivery time is not perfectly accurate
     ;; as scheduling the debounce takes some time, but


Increment seqv on ago-world events.

Increment seqv on ago-world events.

--- src/rewindable/ago.cljs
+++ src/rewindable/ago.cljs
@@ -29,7 +29,7 @@
 (defn make-ago-world []
   (let [last-id (atom 0)]
     (atom {:gen-id #(swap! last-id inc)
-           :seq [0]     ; Extended when a snapshot is revived (branching).
+           :seqv [0]    ; Sequence numbers, grown when snapshot revived/branched.
            :bufs {}     ; Keyed by buf-id.
            :smas {}     ; Keyed by buf-id, value is state-machine array.
            :smas-new {} ; Same as :smas, but for new, not yet run goroutines.
@@ -40,12 +40,12 @@
                           sma-map)))

 (defn ago-snapshot [ago-world-now]
-  (-> ago-world-now
+  (-> ago-world-now ; The mutable sma's need explicit cloning.
       (assoc :smas (copy-sma-map (:smas ago-world-now)))
       (assoc :smas-new (copy-sma-map (:smas-new ago-world-now)))))

-(defn ago-world-inc-seq [ago-world]
-  (swap! ago-world #(update-in % [:seq (dec (count (:seq @ago-world)))] inc)))
+(defn seqv+ [ago-world-now]
+  (update-in ago-world-now [:seqv (dec (count (:seqv ago-world-now)))] inc))

 ; --------------------------------------------------------

@@ -58,13 +58,13 @@
   (pop [_]
     ; Assumes nil is not a valid buffer item.
     (when-let [x (last (get-in @ago-world [:bufs buf-id]))]
-      (swap! ago-world #(update-in % [:bufs buf-id] drop-last))
+      (swap! ago-world #(seqv+ (update-in % [:bufs buf-id] drop-last)))
       (when (empty? (get-in @ago-world [:bufs buf-id]))
-        (swap! ago-world #(dissoc-in % [:bufs buf-id])))
+        (swap! ago-world #(seqv+ (dissoc-in % [:bufs buf-id]))))
       x))

   (unshift [_ x]
-    (swap! ago-world #(update-in % [:bufs buf-id] conj x))
+    (swap! ago-world #(seqv+ (update-in % [:bufs buf-id] conj x)))
     nil)

   (unbounded-unshift [this x] ; From RingBuffer 'interface'.
@@ -73,7 +73,8 @@
   (resize [_] nil) ; From RingBuffer 'interface'.

   (cleanup [_ keep?]
-    (swap! ago-world #(update-in % [:bufs buf-id] (fn [xs] (filter keep? xs)))))
+    (swap! ago-world #(seqv+ (update-in % [:bufs buf-id]
+                                        (fn [xs] (filter keep? xs))))))

   protocols/Buffer
   (full? [this]
@@ -117,17 +118,19 @@
 ; --------------------------------------------------------

 (defn ago-reg-state-machine [ago-world state-machine-arr buf]
-  (swap! ago-world #(assoc-in % [:smas-new (.-buf-id buf)] state-machine-arr)))
+  (swap! ago-world #(seqv+ (assoc-in % [:smas-new (.-buf-id buf)] state-machine-arr))))

 (defn ago-run-state-machine [ago-world state-machine-arr buf]
   (swap! ago-world #(-> %
                         (dissoc-in [:smas-new (.-buf-id buf)])
-                        (assoc-in [:smas (.-buf-id buf)] state-machine-arr))))
+                        (assoc-in [:smas (.-buf-id buf)] state-machine-arr)
+                        (seqv+))))

 (defn ago-dereg-state-machine [ago-world buf]
   (swap! ago-world #(-> %
                         (dissoc-in [:smas-new (.-buf-id buf)])
-                        (dissoc-in [:smas (.-buf-id buf)]))))
+                        (dissoc-in [:smas (.-buf-id buf)])
+                        (seqv+))))

 (defn ago-revive-state-machine [ago-world old-sma buf]
   (let [ch (rewindable.ago/ago-chan-buf ago-world buf)


Replace refs in moving-time-window by an atom (#811)

--- src/riemann/streams.clj
+++ src/riemann/streams.clj
@@ -298,25 +298,30 @@

   Events without times accrue in the current window."
   [n & children]
-  (let [cutoff (ref 0)
-        buffer (ref [])]
+  (let [state (atom {:cutoff 0
+                     :buffer []
+                     :send? true})]
     (fn stream [event]
-      (let [events (dosync
-                     ; Compute minimum allowed time
-                     (let [cutoff (alter cutoff max (- (get event :time 0) n))]
-                       (when (or (nil? (:time event))
-                                 (< cutoff (:time event)))
-                         ; This event belongs in the buffer, and our cutoff may
-                         ; have changed.
-                         (alter buffer conj event)
-                         (alter buffer
-                                (fn alter [events]
-                                  (vec (filter
-                                         (fn [e] (or (nil? (:time e))
-                                                     (< cutoff (:time e))))
-                                         events)))))))]
-        (when events
-          (call-rescue events children))))))
+      (let [result (swap!
+                    state
+                    (fn [{:keys [cutoff buffer]}]
+                      ; Compute minimum allowed time
+                      (let [cutoff (max cutoff (- (get event :time 0) n))
+                            send? (or (nil? (:time event))
+                                      (< cutoff (:time event)))
+                            buffer (if send?
+                                        ; This event belongs in the buffer,
+                                        ; and our cutoff may have changed.
+                                     (vec (filter
+                                           (fn [e] (or (nil? (:time e))
+                                                       (< cutoff (:time e))))
+                                           (conj buffer event)))
+                                     buffer)]
+                        {:cutoff cutoff
+                         :buffer buffer
+                         :send? send?})))]
+        (when (:send? result)
+          (call-rescue (:buffer result) children))))))

 (defn- fixed-time-window-fn
   "A fixed window over the event stream in time. Emits vectors of events, such


make prepl return :val as string

make prepl return :val as string

mistakenly assumed it was supposed to return the val

--- src/main/shadow/cljs/devtools/server/prepl.clj
+++ src/main/shadow/cljs/devtools/server/prepl.clj
@@ -143,11 +143,11 @@
                  (let [{:keys [session-ns]} loop-state
                        {::m/keys [printed-result form eval-ms]} msg]
                    ;; worst hack in history to prevent having to read-string the result
-                   (send! identity (str "{:tag :ret :ns " session-ns
-                                        " :form " (pr-str form)
-                                        " :ms " (or eval-ms 0)
-                                        " :val " printed-result
-                                        "}"))
+                   (send! {:tag :ret
+                           :ns session-ns
+                           :form form
+                           :ms (or eval-ms 0)
+                           :val printed-result})
                    (recur loop-state))

                  ::m/session-out


braveclojure: more on concurrency + started the type-identifier function

--- src/clojure_learning/chap-10-mutation-and-concurrency.clj
+++ src/clojure_learning/chap-10-mutation-and-concurrency.clj
@@ -299,3 +299,136 @@
 ;; but this function can leave the data in an inconsistent state. because it does not uses a retrial mechanism
 ;; it takes the outside-curr-state only once, and then commits it.

+;;;;;;
+;; vars
+;;;;;;
+;; vars are associations/mappings from symbols to objects. New vars can be created with [def]
+
+;; this example is just to debate with what the author from the braveclojure says about constant vars binding:
+;; "Unlike regular vars, however, you can temporarily change the value of dynamic vars by using binding"
+(def my-job "clojure-programmer")
+(do
+  (println my-job)
+  (let [my-job "js-programmer"]
+    (println my-job)))
+;; prints both: clojure-programmer from outside scope, and also js-programmer as a rebinding of the inner local scope.
+
+;; clojure also has dynamic-vars, that simulate the use of static-bindings defined by [let] and add several
+;; things on top.
+;; a dynamic var is in the form of:
+(def ^:dynamic *some-job* "clojure-programmer")
+(binding [*some-job* "js-programmer"]
+  *some-job*)
+;; js-programmer
+
+;; the lisp notion of: earmuffers when it comes to declare the name of a dynamic binding: *name*
+;; we can also nest bindings in other bindings, and the scope is kept consistent.
+
+(def ^:dynamic *to-mail* "claudiu.cosar@gmail.com")
+(defn send-mail [message]
+  (str "TO: " *to-mail* ", message: " message))
+
+(send-mail "aloha") ;; "TO: claudiu.cosar@gmail.com, message: aloha"
+;; in our tests we may want to mock and don't spam claudiu with all emails, so we need a re-binding
+(binding [*to-mail* "test@gmail.com"]
+  (send-mail "test case sending mail to test recipients..."))
+;; "TO: test@gmail.com, message: test case sending mail to test recipients..."
+
+
+;; let's try it with a static-binding-let:
+(def somebody "cclaudiu@gmail.com")
+(defn send-mail [message]
+  (format "TO: %1s, message: %2s" somebody message))
+
+(send-mail "clojure real name") ;; wysiwyg
+
+;; attempt to re-bind using local-let
+(let [somebody "test@gmail.com"]
+  (send-mail "mocking through core [let] a test-recipient"))
+;; "TO: cclaudiu@gmail.com, message: mocking through core [let] a test-recipient"
+
+;; hence --> therefore same behavior for [let] and [binding] of "static-binding" vs "dynamic-binding"
+
+;; most common dynamic vars are used to name a shared-common resource, like a built in dynamic resource:
+;; *out*, or *print-length* and so on...
+;; because they are dynamic we can control their visibility, and can "override" some of them to make
+;; them approapriate in our context:
+(binding [*print-length* 1]
+  (print ["cclaudiu" "cosar"])) ;; prints: [cclaudiu ...]
+
+;; well this is a behavior we cannot approach using well-known let-bindings. This sort of use is defined
+;; in terms of configurations, hence dynamic-bindings are often used in configurations...
+
+;; because dynamic-binding allows to mutate the state of some vars, using the [set!] function
+;; and because i don't quite use mutation in clojure, i m gonna skip this part of side-effecting world.
+
+;;;;;;;;
+;; binding dynamically per thread of execution
+;;;;;;;;
+;; as we know by now there are dynamic vars bound to some values depdnedending on their execution context.
+;; REPL binds the dynamic *out* to its REPL console, and so on.
+;; when we create manually a new thread, every dynamic-binding var rollsback to its initial value.
+(.write *out* "printed on the REPL as REPL bound this dynamic out-var to its REPL console")
+(.start (Thread. #(.write *out* "printed on the STDOUT")))
+(println "repl console")
+
+;; to overcome this, we can use an intermediary var that captures the current *out* value(as "that" in js)
+;; and then rebinding the *out* from within the local thread to the saved value
+(let [repl-out *out*]
+  (.start
+     (Thread. #(binding [*out* repl-out]
+                 (.write *out* "repl console in action")))))
+
+
+;; Also note that any dynamic binding needs to be declared FIRST, prior using it and [binding]
+(binding [*c* "that"])  ;; unable to resolve symbol var: c
+
+;; declared:
+(def ^:dynamic *c* "initial root value")
+;; used:
+(binding [*c* "that"]
+  *c*)   ;; that
+;; so using dynamic binding requires a 2-step approach
+
+;; Clojure provides the option to alter a var's root value. using the function: [alter-var-root] we can
+;; mutate the value of a var. I'm not interested in mutation when it comes to Clojure but we have to know
+;; that we CAN if we want :)
+
+;;;;;;;;;;;;;;;
+;; Clojure parallelism with: pmap (divide and conquer)
+;;;;;;;;;;;;;;;
+
+
+(ns for-clojure)
+(declare struct-type?)
+(map struct-type? [#{} {} [] '()])  ;; (:set :map :vector :list)
+(defn struct-type?
+  [ds]
+  (let [seqable? (fn [xs ys]
+                   (and (= (inc (count xs)) (count ys)) (nil? (get ys xs))))
+        new-ds (conj ds ds)]
+    (if (seqable? ds new-ds)
+      (if (identical? (last new-ds) ds)
+        :vector
+        (if (identical? (first new-ds) ds)
+          :list))
+      (if (= new-ds ds)
+        :map
+        :set
+       ))))
+
+(struct-type? [1 2])
+(struct-type? [])
+(struct-type? {})
+(struct-type? #{})
+(conj [] [])
+(conj [1 2] [1 2])
+(conj [:a :b] [:a :b])
+(def ab (conj [:a :b] [:a :b]))
+(get ab [:a :b])
+
+(def ab (conj {:a :b} {:a :b}))
+(get ab {:a :b})
+(count [[]])
+(def lol (conj '() '()))
+(first lol)


fixing

fixing

--- src/name_bazaar/ui/pages/register_name_page.cljs
+++ src/name_bazaar/ui/pages/register_name_page.cljs
@@ -479,7 +479,7 @@
                  "Create Offering"])
               (when (contains? #{:registrar.entry.state/loading
                                  :registrar.entry.state/empty-name
-                                 "registrar.entry.state/open"
+                                 :registrar.entry.state/open
                                  :registrar.entry.state/auction-no-user-made-bid
                                  ::invalid-length
                                  ::subname


Update lein profile to include flycheck-clojoure deps.

--- lein/.lein/profiles.clj
+++ lein/.lein/profiles.clj
@@ -1,5 +1,12 @@
 {:user {
-        :plugins [[cider/cider-nrepl "0.11.0-SNAPSHOT"]]
-        :dependencies [[com.datomic/datomic-free "0.9.5350"]
-                       [me.raynes/fs "1.4.6"]]
+        :plugins [[cider/cider-nrepl "0.11.0-SNAPSHOT"]
+                  [jonase/eastwood "0.2.3"]
+                  [lein-kibit "0.1.2"]
+                  [lein-typed "0.3.5"]
+                  ]
+        :dependencies [[org.clojure/clojure "1.8.0"]
+                       [com.datomic/datomic-free "0.9.5350"]
+                       [me.raynes/fs "1.4.6"]
+                       ;; Consider using typed? [org.clojure/core.typed "0.3.22"]
+                       ]
         }}


Generator idiomatically replaces underscores in NS

eg: `lein joplin create dev sql-dev add_cool_stuff`
will generate the ns `migrators.sql.20150310063918-add-cool-stuff`
instead of `migrators.sql.20150310063918-add_cool_stuff`

--- joplin.core/src/joplin/core.clj
+++ joplin.core/src/joplin/core.clj
@@ -184,6 +184,7 @@
   [target id ns]
   (when (:migrator target)
     (let [migration-id (get-full-migrator-id id)
+          ns-name (string/replace migration-id "_" "-")
           path (str (:migrator target) "/"
                     (string/replace migration-id "-" "_")
                     ".clj")]
@@ -202,7 +203,7 @@
 " (apply str (interpose "."
                         (concat
                          (-> (:migrator target) (string/split #"/") rest)
-                         [migration-id]))) ns))
+                         [ns-name]))) ns))
         (catch Exception e
           (println "Error creating file" path))))))


(PDB-4934-2) Add unit test for migration pool.

--- test/puppetlabs/puppetdb/cli/services_test.clj
+++ test/puppetlabs/puppetdb/cli/services_test.clj
@@ -546,3 +546,26 @@
                         (set (get-temporal-partitions "reports"))))
                  (is (= (->> event-parts (sort-by :table) (drop 1) set)
                         (set (get-temporal-partitions "resource_events")))))))))))))
+
+(deftest initialize-db
+  (testing "use connection user for database connections"
+    (let [con-mig-user "conn-migration-user-value"
+          mig-pass     "migrator-password-value"
+          user         "user-value"
+          pass         "password-value"
+          validation-fn (fn [config metrics-registry]
+                          (is (= con-mig-user (:connection-migrator-username config)))
+                          (is (= con-mig-user (:user config)))
+                          (is (= mig-pass (:migrator-password config)))
+                          (is (= mig-pass (:password config)))
+                          ; We throw exception in order to interrupt execution in `init-with-db` function.
+                          (throw (Exception.
+                                   "everything ok exception")))]
+      (with-redefs [jdbc/make-connection-pool validation-fn]
+        (testing "should use connection user"
+          (is (thrown-with-msg?
+                Exception #"everything ok exception"
+                (init-with-db "test-db" {:connection-migrator-username con-mig-user
+                                         :migrator-password            mig-pass
+                                         :user                         user
+                                         :password                     pass}))))))))


publish tools

publish tools

--- src/leech/io.clj
+++ src/leech/io.clj
@@ -1,6 +1,8 @@
 (ns leech.io
   (:require [leech.util :as util])
   (:require [leech.queue :as queue])
+  (:require [clj-json.core :as json])
+  (:require [clj-redis.client :as redis])
   (:import (clojure.lang LineNumberingPushbackReader))
   (:import (java.io InputStreamReader BufferedReader PrintWriter))
   (:import (java.net Socket ConnectException)))
@@ -37,3 +39,16 @@
         (bleeder aorta-url (fn [line]
           (queue/offer apply-queue [aorta-host line]))))))))

+(defn init-publishers [publish-queue redis-url chan workers]
+  (let [redis (redis/init {:url redis-url})]
+    (log "init_publishers chan=%s" chan)
+    (dotimes [i workers]
+      (log "init_publisher chan=%s index=%d" chan i)
+      (util/spawn-loop (fn []
+        (let [data (queue/take publish-queue)
+              data-str (try
+                         (json/generate-string data)
+                         (catch Exception e
+                           (log "publish event=error data=%s" (pr-str data))
+                           (throw e)))]
+          (redis/publish redis chan data-str)))))))