CMR-3091: Adding more formats to the collection metadata cache.

--- search-app/src/cmr/search/data/metadata_retrieval/metadata_cache.clj
+++ search-app/src/cmr/search/data/metadata_retrieval/metadata_cache.clj
@@ -1,8 +1,13 @@
 (ns cmr.search.data.metadata-retrieval.metadata-cache
-  "TODO
-
-   TODO include this in individual doc functions
-   ACLS are not applied by any fetching function"
+  "Defines a cache for catalog item metadata. It currently only stores collections.
+
+  The metadata cache contains data like the following:
+
+  concept-id -> revision-format-map
+                 * concept-id
+                 * revision-id
+                 * native-format - A key or map of format and version identifying the native format
+                 * various format keys each mapped to a gzip bytes of compressed metadata."
   (require [cmr.common.util :as u]
            [cmr.common.cache :as c]
            [cmr.common.jobs :refer [defjob]]
@@ -18,7 +23,6 @@
            [cmr.metadata-db.services.concept-service :as metadata-db]
            [cmr.umm-spec.core :as umm-spec]))

-;; TODO add ability to get sizes in bytes of this cache
 ;; TODO test by downloading all the metadata as native from ops and then see how much memory caching
 ;; all of it actually takes

@@ -31,6 +35,9 @@
    could make this a config (though need to make it a set)
    cached umm-json is the latest version"
   #{:echo10
+    :iso19115
+    :dif
+    :dif10
     ;; TODO should we add other formats here?
     ;; Note that when upgrading umm version we should also cache the previous version of UMM.
     {:format :umm-json
@@ -183,7 +190,8 @@
           (cache-size (c/context->cache context cache-key)))))

 (defn- transform-and-cache
-  "TODO"
+  "Takes existing revision format maps missing the target format, generates the format XML, and returns
+   concepts with the requested format. Updates the cache with the generated XML."
   [context revision-format-maps target-format]
   (let [[t1 updated-revision-format-maps] (u/time-execution
                                            (u/fast-map #(rfm/add-additional-format context target-format %)
@@ -198,8 +206,8 @@
     concepts))

 (defn- fetch-and-cache-metadata
-  "TODO
-   use this if we want to provide easy caching"
+  "Fetches metadata from Metadata DB for the given concept tuples and converts them into the format
+   requested. The original native format and the requested format are both stored in the cache."
   [context concept-tuples target-format]
   (let [mdb-context (context->metadata-db-context context)

@@ -229,7 +237,8 @@

 (defn- fetch-metadata
-  "TODO"
+  "Fetches metadata from Metadata DB for the given concept tuples and converts them into the format
+   requested."
   [context concept-tuples target-format]
   (let [mdb-context (context->metadata-db-context context)
         ;; Get Concepts from Metadata db
@@ -310,6 +319,8 @@
     ;; Granule query. We don't cache those so just fetch from metadata db
     (fetch-metadata context concept-tuples target-format)))

+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Do the things below here make sense in this namespace?

 ;; TODO note that this isn't doing any caching and is really just a glorified faster search implementation.
 ;; It might make more sense for it to be implemented somewhere else. Or maybe the cache namespace here
@@ -381,57 +392,3 @@
            "metadata-transformer/transform-concepts time:" t4)
     concept))

-
-;; TODO throw this away
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; # Lookup logic
-;; This should be unit testable without having to do any mocking. It should also be easy to tweak later.
-;; Things skipping cache:
-;; - granules
-;; If in cache use that.
-;; If cache miss
-;; - specific revision is in cache but not format:
-;;   - parse the native metadata and convert to that.
-;;   - cache the requested format
-;; - specific collection is in cache but newer revision:
-;;   - Fetch revision from metadata db
-;;   - convert to requested format.
-;;   - cache requested format and native format. (others will be built as needed. The new revision
-;;      will also be handled during a cache refresh.
-;;   - Store the updated revision and remove the older revision.
-;; - specific collection is in cache but older revision:
-;;   - fetch revision from metadata db.
-;;   - Convert to requested format
-;;   - Do not cache this data (We don't want to cache every revision of collections because that
-;;     could be a lot of metadata and I haven't checked sizing for this.
-
-
-
-;; I think we can ignore all this. Get latest formatted conepts shouldn't be called for collections
-;; We'll leave it in the transformer still working for collections but it won't be called that way.
-; (defn get-latest-formatted-concepts
-;   "Get latest version of concepts with given concept-ids in a given format."
-;   [context concept-ids target-format skip-acls?]
-;   (if (= :collection concept-type)
-;     (let [condition (q/string-conditions :concept-id concept-ids)
-;           concept-rev-tuples (fetch-collections-from-elastic
-;                               context condition skip-acls?)])))
-    ;; TODO granules
-;
-; ;; lookup logic here should be similar to above with exceptions:
-; ;; - We will not know if there's a newer revision than what we have cached.
-
-
-;; Current problem - how do we implement get-latest-formatted-concepts? Several options
-;; granules direct fetch like in transformer
-;; collections
-;; - Get it from elasticsearch <-----
-;; this seems like it's wrong to do here but
-;; - Assume latest is in cache
-;; -
-;; -
-
-
-;; ACLS are another monkey wrench
-;; We could enforce acls during the search in elastic for collections.
-;; For granules we implement basically exactly as it is right now.


(SERVER-876) Move message into exception constructor for wrap-with-code-id

--- src/clj/puppetlabs/services/request_handler/request_handler_core.clj
+++ src/clj/puppetlabs/services/request_handler/request_handler_core.clj
@@ -337,7 +337,7 @@
   (fn [req]
     (let [wrapped-request (wrap-params-for-jruby req)
           env (get-environment-from-request wrapped-request)]
-      (when-not env (throw (IllegalStateException.) "Environment is required in a catalog request."))
+      (when-not env (throw (IllegalStateException. "Environment is required in a catalog request.")))
       (handler (assoc-in wrapped-request [:params "code_id"] (get-code-id-fn env))))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Extract a function for printing ignored tests

--- src/radicalzephyr/boot_junit.clj
+++ src/radicalzephyr/boot_junit.clj
@@ -48,6 +48,14 @@
        (mapcat find-tests-in-package)
        set))

+(defn- print-ignored-tests [ignored-tests]
+  (when (seq ignored-tests)
+    (println "Ignored:")
+    (println)
+    (doseq [ignored ignored-tests]
+      (println (style (.getDisplayName ignored) :yellow))
+      (println))))
+
 (defn- run-listener [packages]
   (let [running-tests (atom #{})
         ignored-tests (atom #{})]
@@ -59,12 +67,7 @@

       (testRunFinished [result]
         (println "\n")
-        (when @ignored-tests
-          (println "Ignored:")
-          (println)
-          (doseq [ignored @ignored-tests]
-            (println (style (.getDisplayName ignored) :yellow))
-            (println)))
+        (print-ignored-tests @ignored-tests)

         (when (> (.getFailureCount result) 0)
           (println (result->map result))))


Add specs for dispatcher + jetty-async-adapter

--- spec/rook/dispatcher_spec.clj
+++ spec/rook/dispatcher_spec.clj
@@ -6,6 +6,8 @@
             [io.aviso.rook.utils :as utils]
             [io.aviso.rook.async :as rook-async]
             [io.aviso.rook :as rook]
+            [io.aviso.rook.jetty-async-adapter :as jetty]
+            [clj-http.client :as http]
             [ring.mock.request :as mock]
             [clojure.core.async :as async]
             ring.middleware.params
@@ -476,4 +478,52 @@
           :port 8080
           :remote-addr "127.0.0.1"
           :scheme :http
-          :headers {}})))))
+          :headers {}}))))
+
+  (describe "running inside jetty-async-adapter"
+
+    (with-all server
+      (let [middleware (fn [handler]
+                         (-> handler
+                           rook/wrap-with-function-arg-resolvers
+                           rook-async/wrap-with-schema-validation))
+            handler (->
+                      (dispatcher/compile-dispatch-table
+                        {:build-handler-fn dispatcher/build-map-traversal-handler
+                         :apply-middleware-fn dispatcher/apply-middleware-async}
+                        (-> (dispatcher/namespace-dispatch-table
+                              ["fred"] 'fred middleware)
+                          (into
+                            (dispatcher/namespace-dispatch-table
+                              ["barney"] 'barney middleware))
+                          (into
+                            (dispatcher/namespace-dispatch-table
+                              ["slow"] 'slow middleware))
+                          (into
+                            (dispatcher/namespace-dispatch-table
+                              ["sessions"] 'sessions middleware))
+                          (into
+                            (dispatcher/namespace-dispatch-table
+                              ["creator"] 'creator middleware))
+                          (into
+                            (dispatcher/namespace-dispatch-table
+                              ["creator-loopback"] 'creator-loopback middleware))))
+                      rook-async/wrap-with-loopback
+                      rook-async/wrap-session
+                      rook-async/wrap-with-standard-middleware)]
+        (jetty/run-async-jetty handler
+          {:host "localhost" :port 9988 :join? false :async-timeout 100})))
+
+    (it "initializes the server successfully"
+      (should-not-be-nil @server))
+
+    (it "can process requests and return responses"
+      (let [response (http/get "http://localhost:9988/fred" {:accept :json})]
+        (should= HttpServletResponse/SC_OK
+          (:status response))
+        (should= "application/json; charset=utf-8"
+          (-> response :headers (get "Content-Type")))
+        (should= "{\"message\":\":barney says `ribs!'\"}" (:body response))))
+
+    (after-all
+      (.stop @server))))


Minor cleanup of sample data

Minor cleanup of sample data

--- frontend/src/faceboard/data/sample_board.cljs
+++ frontend/src/faceboard/data/sample_board.cljs
@@ -48,50 +48,40 @@
            :country "us"}
     :tags ["design"]}])

-(def hackerparadise-places
-  [{:name        "An's"
-    :description "Great coffee"}
-   {:name        "Tam's"
-    :description "Best burgers in the town"}])
-
 (def sample-board
   (schema/upgrade-schema-if-needed
-  {:version 2
-   :board {:name "hacker paradise"}
-   :tabs  [{:id      "people"
-            :label   "People"
-            :kind    "people"
-            :content hackerparadise-people}
-           #_{:id      "places"
-            :label   "Places"
-            :kind    "places"
-            :content hackerparadise-places}
-           #_{:id "sample-generic"
-            :label "Generic"
-            :content "hello world
this is a generic HTML content"}
-           {:id      "docs"
-            :label   "Docs"
-            :kind    "iframe"
-            :content {:url "https://drive.google.com/embeddedfolderview?id=0B008sEIaoPmvfjd6T3RxeUR4My0zOGtVbVNOeG9YcGhWRHl3Qmlia1VLOFdPOGwwQXJIYmc#grid"}}
-           {:id      "calendar"
-            :label   "Calendar"
-            :kind    "iframe"
-            :content {:url "https://www.google.com/calendar/embed?mode=AGENDA&showTitle=0&showPrint=0&showTabs=0&showTz=0&height=750&wkst=2&bgcolor=%23eee&src=uomn8jge32pvacda11fsrqgqqs%40group.calendar.google.com&ctz=Asia/Saigon"}}
-           {:id "sample-gist"
-            :label "Gist"
-            :kind "gist"
-            :content {:gist-id "e04bd2ed2da938a2ff48"}}
-           {:id "styled-tab"
-            :label "Styled"
-            :style { :background-color "darkred" }
-            :selected-style { :background-color "yellow" }
-            :kind "gist"
-            :content {:gist-id "e04bd2ed2da938a2ff48"}}
-           {:id "sample-inkpad"
-            :label "Inkpad"
-            :kind "inkpad"
-            :content {:inkpad-id "aqBdkShhea"}}
-           {:id      "more"
-            :label   "More"
-            :kind    "webget"
-            :content {:url "https://www.dropbox.com/"}}]}))+    {:version 2
+     :board   {:name "hacker paradise"}
+     :tabs    [{:id      "people"
+                :label   "People"
+                :kind    "people"
+                :content hackerparadise-people}
+               {:id      "sample-generic"
+                :label   "Generic"
+                :content "hello world
this is a generic HTML content"}
+               {:id      "docs"
+                :label   "Docs"
+                :kind    "iframe"
+                :content {:url "https://drive.google.com/embeddedfolderview?id=0B008sEIaoPmvfjd6T3RxeUR4My0zOGtVbVNOeG9YcGhWRHl3Qmlia1VLOFdPOGwwQXJIYmc#grid"}}
+               {:id      "calendar"
+                :label   "Calendar"
+                :kind    "iframe"
+                :content {:url "https://www.google.com/calendar/embed?mode=AGENDA&showTitle=0&showPrint=0&showTabs=0&showTz=0&height=750&wkst=2&bgcolor=%23eee&src=uomn8jge32pvacda11fsrqgqqs%40group.calendar.google.com&ctz=Asia/Saigon"}}
+               {:id      "sample-gist"
+                :label   "Gist"
+                :kind    "gist"
+                :content {:gist-id "e04bd2ed2da938a2ff48"}}
+               {:id             "styled-tab"
+                :label          "Styled"
+                :style          {:background-color "darkred"}
+                :selected-style {:background-color "yellow"}
+                :kind           "gist"
+                :content        {:gist-id "e04bd2ed2da938a2ff48"}}
+               {:id      "sample-inkpad"
+                :label   "Inkpad"
+                :kind    "inkpad"
+                :content {:inkpad-id "aqBdkShhea"}}
+               {:id      "more"
+                :label   "More"
+                :kind    "webget"
+                :content {:url "https://www.dropbox.com/"}}]}))


More on `pmap`

More on `pmap`

--- test/com/nomistech/clojure_the_language/c_400_state_and_concurrency/s_050_pmap_etc.clj
+++ test/com/nomistech/clojure_the_language/c_400_state_and_concurrency/s_050_pmap_etc.clj
@@ -22,7 +22,7 @@

 ;;;; ___________________________________________________________________________

-(defn demo-pmap-fun [my-pmap my-range]
+(defn demo-pmap-like-fun [my-pmap my-range]
   (doseq [i (map (partial * 2) (range 18))]
     (print i
            "Expected time ~="
@@ -38,8 +38,8 @@
 ;;;; `pmap` works as expected on unchunked sequences.

 #_
-(demo-pmap-fun pmap
-               (comp u/unchunk range))
+(demo-pmap-like-fun pmap
+                    (comp u/unchunk range))

 ;;; Time increases in accordance with the number of processors, as expected:
 ;;;
@@ -68,8 +68,8 @@
 ;;;;  See https://dev.clojure.org/jira/browse/CLJ-862

 #_
-(demo-pmap-fun pmap
-               range)
+(demo-pmap-like-fun pmap
+                    range)

 ;;; Time increases when we have more than 32 things, which is the chunk size
 ;;; in Clojure.
@@ -95,11 +95,11 @@
 ;;; 34 Expected time ~= 30.0  "Elapsed time: 12.483698 msecs"

 ;;;; ___________________________________________________________________________
-;;;; Let's try Claypoole
+;;;; Claypoole's `pmap` works as expected on a chunked sequences.

 #_
-(demo-pmap-fun (partial cp/pmap 6)
-               range)
+(demo-pmap-like-fun (partial cp/pmap 6)
+                    range)

 ;;; Time increases in accordance with the number of threads, as expected:
 ;;;
@@ -121,3 +121,9 @@
 ;;; 30 Expected time ~= 25.0  "Elapsed time: 30.773396 msecs"
 ;;; 32 Expected time ~= 30.0  "Elapsed time: 33.618415 msecs"
 ;;; 34 Expected time ~= 30.0  "Elapsed time: 32.72781 msecs"
+
+;;;; ___________________________________________________________________________
+;;;; For parallel HTTP requests, use either Claypoole or http-kit.
+
+;;;; Use http-kit if you don't want one thread per connection.
+;;;; See https://stackoverflow.com/questions/21448884/clojure-executing-a-bunch-of-http-requests-in-parallel-pmap


Generalize how the items tree is traversed

There is now a much more generalized approach that is less bound to the
format - genre - subgenre hierarchy. This should hopefully help with
different renderings of the items data for example for single format
output such as Neu in Grossdruck

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -1,8 +1,10 @@
 (ns catalog.layout.fop
   (:require [catalog.layout.common :as layout]
+            [clojure
+             [set :as set]
+             [string :as string]]
             [clojure.data.xml :as xml]
-            [clojure.java.io :as io]
-            [clojure.string :as string])
+            [clojure.java.io :as io])
   (:import java.io.StringReader
            javax.xml.transform.sax.SAXResult
            javax.xml.transform.stream.StreamSource
@@ -63,41 +65,49 @@
   [:fo:block {:keep-with-next "always"}
    [:fo:marker {:marker-class-name running-header-class-name} title]])

-(defn toc-entry [items fmt]
-  (when (fmt items)
-    [:fo:block {:text-align-last "justify"}
-     [:fo:basic-link {:internal-destination (hash [fmt])}
-      (str (layout/translations fmt) " ")
-      [:fo:leader {:leader-pattern "dots"}]
-      [:fo:page-number-citation {:ref-id (hash [fmt])}]]]))
-
-(defn toc [items formats]
+(defn- order
+  "Return `items` ordered. Checks first if `items` are either a subset
+  of `layout/formats`, `layout/braille-genres` or `layout/subgenres`
+  and consequently orders accordingly. Return nil if `items` are not a
+  subset of either."
+  [items]
+  (let [items (set (remove nil? items))]
+    (cond
+      (set/subset? items (set layout/formats))
+      (keep items layout/formats)
+      (set/subset? items (set layout/braille-genres))
+      (keep items layout/braille-genres)
+      (set/subset? items (set layout/subgenres))
+      (keep items layout/subgenres))))
+
+(defn- toc-entry [items path]
+  [:fo:block (if (<= (count path) 2)
+               {:text-align-last "justify"}
+               {:text-align-last "justify" :start-indent "1em"})
+   [:fo:basic-link {:internal-destination (hash path)}
+    (str (layout/translations (last path)) " ")
+    [:fo:leader {:leader-pattern "dots"}]
+    [:fo:page-number-citation {:ref-id (hash path)}]]])
+
+(defn toc [items]
   [:fo:block {:line-height "150%"}
    (h1 :inhalt)
-   (keep #(toc-entry items %) formats)])
-
-(defn- sub-sub-toc-entry [items fmt genre subgenre]
-  (when-let [items (subgenre items)]
-    [:fo:block {:text-align-last "justify" :start-indent "1em"}
-     [:fo:basic-link {:internal-destination (hash [fmt genre subgenre])}
-      (str (layout/translations subgenre) " ")
-      [:fo:leader {:leader-pattern "dots"}]
-      [:fo:page-number-citation {:ref-id (hash [fmt genre subgenre])}]]]))
-
-(defn- sub-toc-entry [items fmt genre]
-  (when-let [items (genre items)]
-    [:fo:block
-     [:fo:block {:text-align-last "justify"}
-      [:fo:basic-link {:internal-destination (hash [fmt genre])}
-       (str (layout/translations genre) " ")
-       [:fo:leader {:leader-pattern "dots"}]
-       [:fo:page-number-citation {:ref-id (hash [fmt genre])}]]]
-     (keep #(sub-sub-toc-entry items fmt genre %) layout/subgenres)]))
-
-(defn sub-toc [items fmt]
-  [:fo:block {:line-height "150%"}
-   (keep #(sub-toc-entry items fmt %)
-         (if (= fmt :braille) layout/braille-genres layout/genres))])
+   (keep #(toc-entry items [%]) (order (keys items)))])
+
+(defn- sub-toc-entry [items path]
+  [:fo:block
+   [:fo:block {:text-align-last "justify"}
+    [:fo:basic-link {:internal-destination (hash path)}
+     (str (layout/translations (last path)) " ")
+     [:fo:leader {:leader-pattern "dots"}]
+     [:fo:page-number-citation {:ref-id (hash path)}]]]
+   (when (map? items)
+     (keep #(toc-entry items (conj path %)) (order (keys items))))])
+
+(defn sub-toc [items path]
+  (when (map? items)
+    [:fo:block {:line-height "150%"}
+     (keep #(sub-toc-entry (% items) (conj path %)) (order (keys items)))]))

 (def wrap (layout/wrapper ""))

@@ -277,7 +287,7 @@
      (entries-sexp items)]))

 (defn subgenres-sexp [items fmt genre]
-  (mapcat #(subgenre-sexp items fmt genre %) layout/subgenres))
+  (mapcat #(subgenre-sexp items fmt genre %) (order (keys items))))

 (defn genre-sexp [items fmt genre]
   (when-let [items (genre items)]
@@ -291,12 +301,11 @@
 (defn format-sexp [items fmt]
   (when-let [items (fmt items)]
     [(h1 fmt)
-     (sub-toc items fmt)
+     (sub-toc items [fmt])
      (set-marker (layout/translations fmt))
      (case fmt
        (:hörfilm :ludo) (entries-sexp items)
-       (mapcat #(genre-sexp items fmt %)
-               (if (= fmt :braille) layout/braille-genres layout/genres)))]))
+       (mapcat #(genre-sexp items fmt %) (order (keys items))))]))

 (defn- page-number []
   [:fo:inline
@@ -360,8 +369,8 @@
     (header :verso)

     [:fo:flow {:flow-name "xsl-region-body"}
-     (toc items layout/formats)
-     (mapcat #(format-sexp items %) layout/formats)]]])
+     (toc items)
+     (mapcat #(format-sexp items %) (order (keys items)))]]])

 (defn document [items & args]
   (-> items


fix tag extraction fn

fix tag extraction fn

--- src/chat/client/parse.cljs
+++ src/chat/client/parse.cljs
@@ -16,5 +16,5 @@
                   (map second)
                   (filter avail-tags))
         tagless-text (string/replace text tag-pattern
-                                     (fn [m] (if (avail-tags (subs m 1)) "" m)))]
+                                     (fn [m] (if (avail-tags (subs (string/trim m) 1)) "" m)))]
     [tags tagless-text]))


display threads in a consistent order (oldest first)

--- src/chat/client/views.cljs
+++ src/chat/client/views.cljs
@@ -167,7 +167,11 @@
               (dom/div #js {:className "logout"
                             :onClick (fn [_] (dispatch! :logout nil))} "Log Out")))
           (apply dom/div #js {:className "threads"}
-            (concat (om/build-all thread-view (vals (data :threads)) {:key :id})
+            (concat (om/build-all thread-view
+                                  (->> (vals (data :threads))
+                                       (sort-by (fn [t]
+                                                  (apply min (map :created-at (t :messages))))))
+                                  {:key :id})
                     [(om/build thread-view
                                {:id (uuid/make-random-squuid)
                                 :new? true


fix path for client js digest

fix path for client js digest

--- src/chat/server/routes.clj
+++ src/chat/server/routes.clj
@@ -26,7 +26,7 @@
   (clostache/render-resource
     (str "public/" client ".html")
     {:algo "sha256"
-     :js (str (digest/from-file (str "/js/" client "/out/braid.js")))
+     :js (str (digest/from-file (str "public/js/" client "/out/braid.js")))
      :api_domain (or (:api-domain env) (str "localhost:" @api-port))}))

 (defroutes desktop-client-routes


implement Upayoga

implement Upayoga

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -927,6 +927,12 @@
                                     (trash state side card))
                                 (lose state :runner :credit 1)))}]}

+   "Upayoga"
+   {:abilities [(do-psi {:label "Make the Runner lose 2 [Credits]"
+                         :msg "make the Runner lose 2 [Credits]"
+                         :effect (effect (lose :runner :credit 2))})
+                {:msg "resolve a subroutine on a piece of rezzed psi ICE"}]}
+
    "Uroboros"
    {:abilities [(trace-ability 4 {:label "Prevent the Runner from making another run"
                                   :msg "prevent the Runner from making another run"


Don't overwrite existing players

Don't overwrite existing players

--- src/clj/ji/domain/game.clj
+++ src/clj/ji/domain/game.clj
@@ -59,7 +59,9 @@
   (get-in game [:players player-id]))

 (defn add-player [game player-id]
-  (update-in game [:players] assoc player-id {:sets []}))
+  (if (get-in game [:players player-id])
+    game
+    (update-in game [:players] assoc player-id {:sets []})))

 (defn remove-player [game player-id]
   (update-in game [:players] dissoc player-id))


(Possibly?) Fixed multimethod setup in munch.

--- src/clj/minijava/munch.clj
+++ src/clj/minijava/munch.clj
@@ -1,5 +1,5 @@
 (ns minijava.munch
-  (:use (minijava ir gas)))
+  (:use (minijava exp ir gas)))

 ;;helper method to do instanceof
@@ -23,12 +23,12 @@
 ;;ir is the root of the ir tree to munch; args is an (optional) list of the 'children' of the root node, for pattern matching purposes.
 ;;its ok to omit args.
 ;;Munch rules for statements return nil, munch rules for expressions return Temps
-(defmulti munchMap (fn [ir args] (vec (map type (cons ir args)))))
+(defmulti munchMap (fn [ir & args] (vec (map type (cons ir args)))))

 (defn munch
 	[x] ;;note: vec forces evaluation of the lazy sequence produced by vars into a vector, required by multimethod dispatching
-	(munchMap x  (vals x)));;if a call is made to munch with just the ir root argument, call back munchStm with the ir root followed by its children (for easier pattern matching).
+	(apply munchMap (conj  (vals x) x)));;if a call is made to munch with just the ir root argument, call back munchStm with the ir root followed by its children (for easier pattern matching).

 ;;Entry function to maximal munch.
 (defn select [irtree]
@@ -41,6 +41,7 @@
 ;;This method contains a bunch of special cases, organized by preference (size), of x86 statements that can
 ;;do a Move on a Mem and then (any) expression.
 ;;Similar methods can be defined for a Move and any combination of its arguments, all the way up to Move (Expression Expression)
+
 (defmethod munchMap [:minijava.ir/Move :minijava.exp/expression :minijava.ir/Mem]
   [x src dst]
   (cond


Add start-listening-on-user! fn

Add start-listening-on-user! fn

--- src/clj/skytwit/server.clj
+++ src/clj/skytwit/server.clj
@@ -133,19 +133,26 @@
       ((:cancel (meta s)))
       (reset! end? true))))

+(defn start-listening-on-user!
+  [creds screen-name at]
+  (let [ch (async/chan)
+        stop-old (put-old-tweets-on-channel creds screen-name ch)
+        stop-new (put-new-tweets-on-channel creds screen-name ch)]
+    (go-loop []
+             (when-let [tweets (<! ch)]
+               (swap! at update :tweets concat tweets)))
+    (fn []
+      (stop-old)
+      (stop-new))))
+
 (comment
   (def creds (get-credentials-from-env))
   (def a (atom []))

-  (let [ch (async/chan)]
-    #_(put-old-tweets-on-channel creds "_toch" ch)
-    (put-new-tweets-on-channel creds "InternetRadio" ch)
-    (go-loop []
-             (when-let [v (<! ch)]
-               (swap! a concat v)
-               (recur))))
+  (def stop-fn (start-listening-on-user! creds "_toch" a))
+  (stop-fn)

-  (-> a deref count)
+  (-> a deref)
   )

 (defroutes routes


New example: test-line-charts

New example: test-line-charts

--- src/clj_flotr/examples.clj
+++ src/clj_flotr/examples.clj
@@ -70,6 +70,58 @@

 ;
+; This function creates HTML page named "test-line-charts.html".
+; That page will contain various line-charts that shows how
+; the function (generator/line-chart) could be used.
+;
+(defn test-line-charts
+    "Creates HTML page with various types of line-charts."
+    []
+    (let [data [{:values [[1 1] [2 2] [3 3]] :label "foo"}
+                {:values [[1 0] [2 5] [3 0]]  :label "bar"}
+                {:values [[1 4] [2 2] [3 4]]  :label "baz"}]]
+        (spit "test-line-charts.html" (page/xhtml
+            [:head
+                [:title "Test Line Charts"]
+                [:meta {:name "Generator" :content "Clojure"}]
+                [:meta {:http-equiv "Content-type" :content "text/html; charset=utf-8"}]
+                ; we need to include all Flotr JavaScript libraries.
+                (generator/flotr-scripts nil nil nil)
+            ]
+            [:body
+                [:h1 "Test Line Charts"]
+                [:table
+                    [:tr
+                        [:td (generator/line-chart "chart1" "300px" "300px" data)]
+                        [:td (generator/line-chart "chart2" "300px" "300px" data
+                                :vertical-lines true)]
+                        [:td (generator/line-chart "chart3" "300px" "300px" data
+                                :horizontal-lines true)]
+                        [:td (generator/line-chart "chart4" "300px" "300px" data
+                                :horizontal-lines true
+                                :vertical-lines true)]
+                    ] ; </tr>
+                    [:tr
+                        [:td (generator/line-chart "chart5" "300px" "300px" data
+                                 :show-legend true)]
+                        [:td (generator/line-chart "chart6" "300px" "300px" data
+                                 :show-legend true
+                                 :legend-position "sw")]
+                        [:td (generator/line-chart "chart7" "300px" "300px" data
+                                 :show-legend true
+                                 :legend-position "ne"
+                                 :legend-background "#D2E8FF")]
+                        [:td (generator/line-chart "chart8" "300px" "300px" data
+                                 :show-legend true
+                                 :legend-position "sw"
+                                 :legend-background "#FFFFFF")]
+                    ] ; </tr>
+                ] ; </table>
+                [:h1 "done"]]))))
+
+
+
+;
 ; This function creates HTML page named "test-stacked-bars.html".
 ; That page will contain various pie-charts that shows how
 ; the function (generator/stacked-bars) could be used.
@@ -125,5 +177,6 @@

 ; You can call example function by using following two lines:
 ;(test-pie-charts)
+;(test-line-charts)
 ;(test-stacked-bars)


add support for UUID coercion

add support for UUID coercion

--- src/clj_money/coercion.clj
+++ src/clj_money/coercion.clj
@@ -1,7 +1,8 @@
 (ns clj-money.coercion
   (:require [clojure.pprint :refer [pprint]]
             [clojure.tools.logging :as log]
-            [clj-money.util :refer [parse-local-date]]))
+            [clj-money.util :refer [parse-local-date]])
+  (:import java.util.UUID))

 (def ^:private fns (atom {}))

@@ -56,6 +57,7 @@
 (register-coerce-fn :keyword    #(if (keyword? %) % (keyword %)))
 (register-coerce-fn :local-date #(if (string? %) (or (parse-local-date %) %) %))
 (register-coerce-fn :integer-collection parse-integer-collection)
+(register-coerce-fn :uuid #(if (instance? UUID %) % (UUID/fromString %)))

 (defn coerce
   "Given a model and a list of coercion rules, applies the rules to the model"


Add, remove, and edit labels

Add, remove, and edit labels

--- src/cljs/zetawar/data.cljs
+++ src/cljs/zetawar/data.cljs
@@ -62,12 +62,13 @@
          "here</a>.")

     ;; Status information
-    :terrain-label "Terrain"
+    :tile-coordinates-label "X,Y (Tile Coordinates)"
+    :terrain-effects-label "Movement Cost, Attack Bonus, Armor Bonus"
     :movement-cost-label "Movement Cost"
     :attack-bonus-label "Attack Bonus"
     :armor-bonus-label "Armor Bonus"
-    :selected-label "Selected"
-    :targeted-label "Targeted"
+    :selected-label "Selected: "
+    :targeted-label "Targeted: "

     ;; Ending turn
     :end-turn-alert "Are you sure you want to end your turn? You still have available moves."


Use more idiomatically Clojure commenting-out style

--- src/cljs/zetawar/data.cljs
+++ src/cljs/zetawar/data.cljs
@@ -573,8 +573,7 @@
       :terrain-type :deep-water}
      {:q 1
       :r 4
-      :terrain-type :seaport
-      ;:terrain-type :mountains
+      :terrain-type :seaport #_:mountains
       }
      {:q 2
       :r 4


Better name

Better name

--- src/cljs_workers/core.cljs
+++ src/cljs_workers/core.cljs
@@ -8,7 +8,7 @@
       undefined?
       not))

-(defn create-worker
+(defn create-one
   [script]
   (js/Worker. script))

@@ -23,5 +23,5 @@
    (let [workers (chan count)]
      (go
        (dotimes [_ count]
-         (>! workers (create-worker script))))
+         (>! workers (create-one script))))
      workers)))


translate all italian expressions into english

--- src/babel/english/writer.clj
+++ src/babel/english/writer.clj
@@ -3,9 +3,30 @@

 (require '[babel.english.grammar :refer [small small-plus-vp-pronoun]])
 (require '[babel.english.lexicon :refer [lexicon]])
+(require '[babel.reader :refer [read-all]])
 (require '[babel.writer :refer [delete-from-expressions process write-lexicon]])
 (require '[clojure.tools.logging :as log])
 (require '[dag-unify.core :refer (fail? get-in strip-refs unify)])
+
+(defn italian []
+  "generate English translations of all available Italian expressions."
+  (let [italian-expressions (read-all :top "it")]
+    (.size (map (fn [italian-expression]
+                  (do (log/info (str "Italian expression: " (:surface italian-expression)))
+                      (log/debug (str "Italian semantics: " (get-in (:structure italian-expression) [:synsem :sem])))
+                      (let [spec {:synsem {:sem (strip-refs (get-in (:structure italian-expression) [:synsem :sem]))}}]
+                        (log/debug (str "generating from spec: " spec))
+                        (try
+                          (process [{:fill-one-language
+                                     {:count 1
+                                      :spec spec
+                                      :model small
+                                      }}]
+                                   "it")
+                          (catch Exception e
+                           true
+                           (throw e))))))
+                italian-expressions))))

 (defn all [ & [count]]
   (let [count (if count (Integer. count) 10)


Bugfix: Palette drop zone was calculated incorrectly

--- src/alder/ui/interaction.cljs
+++ src/alder/ui/interaction.cljs
@@ -65,6 +65,7 @@

       (loop [node node]
         (let [{:keys [phase mouse-pos]} (<! read-chan)
+              abs-mouse-pos mouse-pos
               mouse-pos (math/mult-point (-> app :graph-xform :inv) mouse-pos)
               last-pos (geometry/rectangle-origin (:frame node))
               new-node-pos (geometry/point-sub mouse-pos offset)
@@ -76,7 +77,7 @@
             (recur node))

           (when (and (= phase :end)
-                     (< (first mouse-pos)
+                     (< (first abs-mouse-pos)
                         (- (.-innerWidth js/window) palette-width)))
             (>! reply-chan [:commit node]))))


pred imparare to learn

pred imparare to learn

--- src/babel/english/lexicon.clj
+++ src/babel/english/lexicon.clj
@@ -751,7 +751,7 @@
                     :sem {:pred :kill}}}

    "learn" {:synsem {:cat :verb
-                     :sem {:pred :imparare}}}
+                     :sem {:pred :learn}}}

    "leave" {:english {:past "left"}
             :synsem {:cat :verb


add a sanity check for the tika resources

tika reads the 'META-INF/services/org.apache.tika.parser.Parser'
resource and uses that to initialize the available parsers.

org.gagravarr/vorbis-java-tika is a dependency of tika and ships with
it's own version of the above file, but it does only list 3
vorbis-java-tika parsers.

lein uberjar chooses to use the resource file from vorbis-java-tika

we must make sure that we do not use the file shipped by
vorbis-java-tika, since then parsing only works for ogg files

--- src/brainbot/nozzle/main.clj
+++ src/brainbot/nozzle/main.clj
@@ -84,8 +84,34 @@
       (nrepl-server/start-server :port (Integer. port)))))

+(defn sanity-check-tika-resources
+  "this function checks that the right tika resources are being used.
+
+tika reads the 'META-INF/services/org.apache.tika.parser.Parser' resource
+and uses that to initialize the available parsers.
+
+org.gagravarr/vorbis-java-tika is a dependency of tika and ships with
+it's own version of the above file, but it does only list 3
+vorbis-java-tika parsers.
+
+lein uberjar chooses to use the resource file from vorbis-java-tika
+
+we must make sure that we do not use the file shipped by
+vorbis-java-tika, since then parsing only works for ogg files
+"
+  []
+  (let [path "META-INF/services/org.apache.tika.parser.Parser"
+        content (slurp (clojure.java.io/resource path))
+        line-count (count (clojure.string/split content #"\n"))]
+    (when (> 20 line-count)
+      (throw (ex-info "internal error: broken tika resources"
+                      {:line-count line-count
+                       :content content
+                       :path path})))))
+
 (defn -main [& args]
   (ensure-java-version)
+  (sanity-check-tika-resources)
   (maybe-start-repl-server)
   (let [{:keys [iniconfig sections]} (parse-command-line-options args)]
     (misc/setup-logging!)


Just some testing junk

Just some testing junk

--- src/borderless/osc_server.clj
+++ src/borderless/osc_server.clj
@@ -78,14 +78,16 @@
     (osc/osc-handle server "/TSPS/personWillLeave"
               (fn [msg]
                 (let [ id (nth (:args msg) 0)]
-                  (sound/end-sound! id)))))
+                  (sound/end-sound! id)
+                  (println "Someone left. these people are still here: " (deref borderless.sound/person-sound))))))

 (defn person-enter
   []
     (osc/osc-handle server "/TSPS/personEntered"
               (fn [msg]
                 (let [ id (nth (:args msg) 0)]
-                  (sound/start-sound! id)))))
+                  (sound/start-sound! id)
+                  (println "Someone Came in! Full list: " (deref borderless.sound/person-sound))))))

 (defn person []
   (sound/controller :timbre (nth  '(409 0 20 0.07673444 0.86617285 0.0 0.0 0.0 0.015625 0.73125 0.128125 0.25625 -0.0015625 0.0020833334 0.0 0.0 0.0 0.0 0.0 0.0) 2) 1)


CLJS-1111: browser REPL should have no side effects until -setup

refactor bREPL so all side-effecting setup logic is in -setup.

remove useless loaded library tracking logic

--- src/clj/cljs/repl/browser.clj
+++ src/clj/cljs/repl/browser.clj
@@ -22,10 +22,6 @@
 (defonce browser-state
   (atom {:return-value-fn nil
          :client-js nil}))
-
-(def loaded-libs (atom #{}))
-
-(def preloaded-libs (atom #{}))

 (defn- set-return-value-fn
   "Save the return value function which will be called when the next
@@ -123,7 +119,6 @@
 (def ordering (agent {:expecting nil :fns {}}))

 (defmethod handle-post :ready [_ conn _]
-  (reset! loaded-libs @preloaded-libs)
   (send ordering (fn [_] {:expecting nil :fns {}}))
   (send-for-eval conn
     (cljsc/-compile
@@ -187,13 +182,7 @@
   if any of the namespaces have not already been loaded from the
   ClojureScript REPL."
   [repl-env provides url]
-  (let [missing (remove #(contains? @loaded-libs %) provides)]
-    (when (seq missing)
-      (browser-eval (slurp url))
-      (swap! loaded-libs (partial apply conj) missing))))
-
-(defn setup [repl-env opts]
-  (server/start repl-env))
+  (browser-eval (slurp url)))

 ;; =============================================================================
 ;; Stracktrace parsing
@@ -473,6 +462,36 @@
 ;; =============================================================================
 ;; BrowserEnv

+(defn compile-client-js [opts]
+  (cljsc/build
+    '[(ns clojure.browser.repl.client
+        (:require [goog.events :as event]
+                  [clojure.browser.repl :as repl]))
+      (defn start [url]
+        (event/listen js/window
+          "load"
+          (fn []
+            (repl/start-evaluator url))))]
+    {:optimizations (:optimizations opts)
+     :output-dir (:working-dir opts)}))
+
+(defn create-client-js-file [opts file-path]
+  (let [file (io/file file-path)]
+    (when (not (.exists file))
+      (spit file (compile-client-js opts)))
+    file))
+
+(defn setup [{:keys [working-dir] :as repl-env} opts]
+  (println "Compiling client js ...")
+  (swap! browser-state
+    (fn [old]
+      (assoc old :client-js
+        (create-client-js-file
+          repl-env (io/file working-dir "client.js")))))
+  (println "Waiting for browser to connect ...")
+  opts
+  (server/start repl-env))
+
 (defrecord BrowserEnv []
   repl/IJavaScriptEnv
   (-setup [this opts]
@@ -497,88 +516,18 @@
     (reset! server/state {})
     (reset! browser-state {})))

-(defn compile-client-js [opts]
-  (cljsc/build
-    '[(ns clojure.browser.repl.client
-        (:require [goog.events :as event]
-                  [clojure.browser.repl :as repl]))
-      (defn start [url]
-        (event/listen js/window
-          "load"
-          (fn []
-            (repl/start-evaluator url))))]
-    {:optimizations (:optimizations opts)
-     :output-dir (:working-dir opts)}))
-
-(defn create-client-js-file [opts file-path]
-  (let [file (io/file file-path)]
-    (when (not (.exists file))
-      (spit file (compile-client-js opts)))
-    file))
-
-(defn- provides-and-requires
-  "Return a flat list of all provided and required namespaces from a
-  sequence of IJavaScripts."
-  [deps]
-  (flatten (mapcat (juxt :provides :requires) deps)))
-
-;; TODO: the following is questionable as it triggers compilation
-;; this code should other means to determine the dependencies for a
-;; namespace - David
-
-(defn- always-preload
-  "Return a list of all namespaces which are always loaded into the browser
-  when using a browser-connected REPL.
-
-  Uses the working-dir (see repl-env) to output intermediate compilation."
-  [& [{:keys [working-dir]}]]
-  (let [opts (if working-dir {:output-dir working-dir}
-                 {})
-        cljs (provides-and-requires
-              (cljsc/cljs-dependencies opts ["clojure.browser.repl"]))
-        goog (provides-and-requires
-               (cljsc/js-dependencies opts cljs))]
-    (disj (set (concat cljs goog)) nil)))
-
-;; NOTE: REPL evaluation environment designers do not replicate the behavior
-;; of the browser REPL. The design is outdated, refer to the Node.js, Rhino or
-;; Nashorn REPLs.
-
-(defn repl-env* [opts]
-  (let [ups-deps (cljsc/get-upstream-deps)
-        opts (assoc opts
-               :ups-libs (:libs ups-deps)
-               :ups-foreign-libs (:foreign-libs ups-deps))
-        compiler-env (cljs.env/default-compiler-env opts)
-        opts (merge (BrowserEnv.)
-               {:port           9000
-                :optimizations  :simple
-                :working-dir    (or (:output-dir opts)
-                                  (->> [".repl" (util/clojurescript-version)]
-                                    (remove empty?) (string/join "-")))
-                :serve-static   true
-                :static-dir     (cond-> ["." "out/"]
-                                  (:output-dir opts) (conj (:output-dir opts)))
-                :preloaded-libs []
-                :src            "src/"
-                ::env/compiler  compiler-env
-                :source-map     false}
-               opts)]
-    (cljs.env/with-compiler-env compiler-env
-      (reset! preloaded-libs
-        (set (concat
-               (always-preload opts)
-               (map str (:preloaded-libs opts)))))
-      (reset! loaded-libs @preloaded-libs)
-      (println "Compiling client js ...")
-      (swap! browser-state
-        (fn [old]
-          (assoc old :client-js
-                     (create-client-js-file
-                       opts
-                       (io/file (:working-dir opts) "client.js")))))
-      (println "Waiting for browser to connect ...")
-      opts)))
+(defn repl-env*
+  [{:keys [output-dir] :as opts}]
+  (merge (BrowserEnv.)
+    {:port 9000
+     :working-dir (->> [".repl" (util/clojurescript-version)]
+                       (remove empty?) (string/join "-"))
+     :serve-static true
+     :static-dir (cond-> ["." "out/"] output-dir (conj output-dir))
+     :preloaded-libs []
+     :optimizations :simple
+     :src "src/"}
+    opts))

 (defn repl-env
   "Create a browser-connected REPL environment.
@@ -593,9 +542,6 @@
                   Defaults to true.
   static-dir:     List of directories to search for static content. Defaults to
                   [\".\" \"out/\"].
-  preloaded-libs: List of namespaces that should not be sent from the REPL server
-                  to the browser. This may be required if the browser is already
-                  loading code and reloading it would cause a problem.
   optimizations:  The level of optimization to use when compiling the client
                   end of the REPL. Defaults to :simple.
   src:            The source directory containing user-defined cljs files. Used to


Only draw npcs that are visible

Only draw npcs that are visible

--- src/cljc/robinson/render.cljc
+++ src/cljc/robinson/render.cljc
@@ -890,18 +890,12 @@
                           y       (-> npc :pos :y)
                           vx      (- x (-> state :world :viewport :pos :x))
                           vy      (- y (-> state :world :viewport :pos :y))
-                          visible
-                                  (and (not (farther-than?
+                          t       (rw/get-time state)
+                          visible (and (not (farther-than?
                                               pos
                                               {:x x :y y}
-                                              5))
-                                       true
-                                       #_(visible? get-cell
-                                                 cell-blocking?
-                                                 (pos :x)
-                                                 (pos :y)
-                                                 x
-                                                 y))]
+                                              8))
+                                       (= (get (rw/get-cell state x y) :discovered) t))]
                       ;(log/debug "npc@" x y "visible?" visible)
                       (when visible
                         (apply put-string screen


factor out model layout

factor out model layout

--- src/clojure/defgraph/core.clj
+++ src/clojure/defgraph/core.clj
@@ -18,6 +18,19 @@
         complete-edges (reduce conj {} (map #(rootpath %) (keys filtered-edges)))]
     {:v (into #{} (concat (keys complete-edges) (vals complete-edges)))
      :e complete-edges}))
+
+(defn layout-graph [mx model root]
+  (.beginUpdate model)
+  (let [layout (mxOrganicLayout. mx)]
+    (doto layout
+      (.setFineTuning false)
+      (.setBorderLineCostFactor 10)
+      (.setEdgeLengthCostFactor 0.001)
+      (.setEdgeDistanceCostFactor 6000)
+      (.setEdgeCrossingCostFactor 6000)
+      (.setMaxIterations 1000)
+      (.execute root)))
+    (.endUpdate model))

 (defn -main [& args]
   (if (> (count args) 1)
@@ -44,17 +57,7 @@
           (doseq [e (:e g)]
             (.insertEdge mx root nil "" (vmap (key e)) (vmap (val e)))))
         (.endUpdate model))
-      (do
-        (.beginUpdate model)
-        (let [layout (mxOrganicLayout. mx)]
-          (doto layout
-            (.setBorderLineCostFactor 10)
-            (.setEdgeLengthCostFactor 0.001)
-            (.setEdgeDistanceCostFactor 1500)
-            (.setEdgeCrossingCostFactor 24000)
-            (.setMaxIterations 5000)
-            (.execute root)))
-        (.endUpdate model))
+      (layout-graph mx model root)
       (let [gc (mxGraphComponent. mx)
             bounds (.getGraphBounds mx)
             view (.getView mx)]
@@ -65,7 +68,7 @@
               actual-width (.getWidth bounds)
               scale-factor (* 0.9 (min (/ width actual-width) (/ height actual-height)))]
           (.setScale view scale-factor))
-        (doto (JFrame. (str "defgraph" (if prefix (str " - " prefix) "")))
+        (doto (JFrame. (str "defgraph" (if prefix (str " (" prefix ")") "")))
           (.add gc)
           (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
           (.setSize width height)


Added xml-handler.

Added xml-handler.

--- src/cmr/http/kit/response.clj
+++ src/cmr/http/kit/response.clj
@@ -33,8 +33,11 @@

 (defn parse-xml-body
   [body]
-  (let [str-data (if (string? body) body (slurp body))]
-    (xml/parse-str str-data)))
+  (let [str-data (if (string? body) body (slurp body))
+        zml-data (xml/parse-str str-data)]
+    (log/trace "str-data:" str-data)
+    (log/trace "xml-data:" xml-data)
+    xml-data))

 (defn xml-errors
   [body]
@@ -140,3 +143,4 @@
               parse-fn))))

 (def json-handler #(client-handler % error-handler parse-json-body))
+(def xml-handler #(client-handler % error-handler parse-xml-body))


CMR-595: Allow specifying concept retrieval format using URL extension.

--- src/cmr/search/api/routes.clj
+++ src/cmr/search/api/routes.clj
@@ -7,18 +7,13 @@
             [ring.middleware.json :as ring-json]
             [cmr.common.log :refer (debug info warn error)]
             [cmr.common.api.errors :as errors]
+            [cmr.common.services.errors :as svc-errors]
             [cmr.common.mime-types :as mt]
             [cmr.search.services.query-service :as query-svc]
             [cmr.system-trace.http :as http-trace]
             [cmr.search.api.search-results :as sr]
             [cmr.search.services.parameters.legacy-parameters :as lp]))

-(defn- get-search-results-format
-  "Returns the requested search results format parsed from headers"
-  [headers]
-  (let [mime-type (get headers "accept")]
-    (mt/validate-request-mime-type mime-type sr/supported-mime-types)
-    (mt/mime-type->format mime-type)))

 (defn- measure-query-time
   "Executes the query function measuring how long it takes. Adds a :took key to the results map
@@ -30,10 +25,45 @@
         took (- stop start)]
     (assoc result :took took)))

-(defn- find-references
+(def extension->mime-type
+  "A map of URL file extensions to the mime type they represent."
+  {"json" "application/json"
+   "xml" "application/xml"
+   "echo10" "application/echo10+xml"
+   "iso_prototype" "application/iso_prototype+xml"
+   "smap_iso" "application/iso:smap+xml"
+   "iso19115" "application/iso19115+xml"
+   "dif" "application/dif+xml"
+   "csv" "text/csv"})
+
+(defn- parse-concept-type-w-extension
+  "Parses the concept type and extension (\"granules.echo10\") into a pair of concept type keyword
+  and mime type"
+  [concept-type-w-extension]
+  (let [[_ concept-type extension]
+        (filter
+          identity
+          (re-matches #"^(.+)s(?:\.(.+))?$" concept-type-w-extension))
+        mime-type (extension->mime-type extension)]
+    (when (and (nil? mime-type) (some? extension))
+      (svc-errors/throw-service-error
+        :bad-request (format "The URL extension [%s] is not supported." extension)))
+    [(keyword concept-type)
+     mime-type]))
+
+(defn- get-search-results-format
+  "Returns the requested search results format parsed from headers or from the URL extension"
+  [ext-mime-type headers]
+  (let [mime-type (or ext-mime-type (get headers "accept"))]
+    (mt/validate-request-mime-type mime-type sr/supported-mime-types)
+    (mt/mime-type->format mime-type)))
+
+(defn- find-concepts
   "Invokes query service to find references and returns the response"
-  [context concept-type params headers query-string]
-  (let [result-format (get-search-results-format headers)
+  [context concept-type-w-extension params headers query-string]
+  (let [[concept-type ext-mime-type] (parse-concept-type-w-extension concept-type-w-extension)
+        params (dissoc params :concept-type-w-extension)
+        result-format (get-search-results-format ext-mime-type headers)
         params (assoc params :result-format result-format)
         pretty? (= (get params :pretty) "true")
         _ (info (format "Searching for %ss in format %s with params %s." (name concept-type) result-format (pr-str params)))
@@ -55,22 +85,26 @@
      :headers {"Content-Type" "application/xml; charset=utf-8"}
      :body (:metadata concept)}))

+(def concept-type-w-extension-regex
+  "A regular expression that matches URLs including the concept type (pluralized) along with a file
+  extension."
+  #"(?:granules)|(?:collections)(?:\..+)?")
+
 (defn- build-routes [system]
   (routes
     (context (get-in system [:search-public-conf :relative-root-url]) []
-      (context "/collections" []
-        (GET "/" {params :params headers :headers context :request-context query-string :query-string}
-          (find-references context :collection params headers query-string))
-        (POST "/" {params :params headers :headers context :request-context body :body-copy}
-          (find-references context :collection params headers body)))
-      (context "/granules" []
-        (GET "/" {params :params headers :headers context :request-context query-string :query-string}
-          (find-references context :granule params headers query-string))
-        (POST "/" {params :params headers :headers context :request-context body :body-copy}
-          (find-references context :granule params headers body)))
+
+      ;; Retrieve by cmr concept id
       (context "/concepts/:cmr-concept-id" [cmr-concept-id]
         (GET "/" {headers :headers context :request-context}
           (find-concept-by-cmr-concept-id context cmr-concept-id headers)))
+
+      ;; Find concepts
+      (context ["/:concept-type-w-extension" :concept-type-w-extension concept-type-w-extension-regex] [concept-type-w-extension]
+        (GET "/" {params :params headers :headers context :request-context query-string :query-string}
+          (find-concepts context concept-type-w-extension params headers query-string))
+        (POST "/" {params :params headers :headers context :request-context body :body-copy}
+          (find-concepts context concept-type-w-extension params headers body)))

       ;; reset operation available just for development purposes
       ;; clear the cache for search app


var renaming to avoid confusion.

var renaming to avoid confusion.

--- src/fcms/models/common.clj
+++ src/fcms/models/common.clj
@@ -46,11 +46,11 @@
   (clutch/with-db (db)
     (clutch/get-document id)))

-(defn delete [item]
+(defn delete [resource]
   (clutch/with-db (db)
-    (clutch/delete-document item)))
+    (clutch/delete-document resource)))

 (defn delete-by-id [id]
-  (let [item (retrieve id)]
-    (if-not (nil? item)
-      (delete item))))+  (let [resource (retrieve id)]
+    (if-not (nil? resource)
+      (delete resource))))


Formatting

Formatting

--- src/cljs/decktouch/core.cljs
+++ src/cljs/decktouch/core.cljs
@@ -1,12 +1,12 @@
 (ns decktouch.core
-    (:require [reagent.core :as reagent :refer [atom]]
-              [reagent.session :as session]
-              [secretary.core :as secretary :include-macros true]
-              [goog.events :as events]
-              [goog.history.EventType :as EventType]
-              [decktouch.card-data :as card-data]
-              [decktouch.card-input :as card-input])
-    (:import goog.History))
+  (:require [reagent.core :as reagent :refer [atom]]
+            [reagent.session :as session]
+            [secretary.core :as secretary :include-macros true]
+            [goog.events :as events]
+            [goog.history.EventType :as EventType]
+            [decktouch.card-data :as card-data]
+            [decktouch.card-input :as card-input])
+  (:import goog.History))

 (def the-cards (atom card-data/cards))


Aha! Immediate validation

Aha! Immediate validation

--- src/cljs/geoforms/forms.cljs
+++ src/cljs/geoforms/forms.cljs
@@ -232,8 +232,10 @@
        [bind-fields
         form-template
         doc
-        (fn [document])
-        (fn [document])]
+        (fn [k v _]
+          (let [after (assoc-in @doc k v)
+                errors (validate-user after)]
+            (assoc after :errors errors)))]

        [:button.btn.btn-default
         {:on-click #(when (validate-user! doc)


s/defonce/def/ for app-state

s/defonce/def/ for app-state

--- src/cljs/yadnd5ecs/core.cljs
+++ src/cljs/yadnd5ecs/core.cljs
@@ -5,7 +5,7 @@

 (enable-console-print!)

-(defonce app-state (atom {:text "Hello Chestnut!"}))
+(def app-state (atom {:text "Hello Chestnut!"}))

 (defn main []
   (om/root


Fix raw-buffer range

Fix raw-buffer range

--- src/cljs_bach/synthesis.cljs
+++ src/cljs_bach/synthesis.cljs
@@ -151,7 +151,7 @@
         frame-count (* sample-rate duration)
         buffer (.createBuffer context 1 frame-count sample-rate)
         data (.getChannelData buffer 0)]
-    (doseq [i (range sample-rate)]
+    (doseq [i (range frame-count)]
       (aset data i (generate-bit! i)))
     buffer))


Applied with-swing-error-msg

Applied with-swing-error-msg

where an JOptionPane has been used directly.

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

--- src/conexp/graphics/draw.clj
+++ src/conexp/graphics/draw.clj
@@ -44,9 +44,8 @@
 						      set-node-radius!)]
 	clojure.contrib.swing-utils)
   (:import [javax.swing JFrame JPanel JButton JTextField JLabel
-	                JOptionPane JSeparator SwingConstants
-	                BoxLayout Box JScrollBar JComboBox JScrollPane
-	                JFileChooser]
+	                JSeparator SwingConstants BoxLayout Box
+	                JScrollBar JComboBox JScrollPane JFileChooser]
 	   [javax.swing.filechooser FileNameExtensionFilter]
 	   [java.awt Canvas Color Dimension BorderLayout GridLayout Component Graphics]
 	   [java.awt.event ActionListener]
@@ -273,14 +272,8 @@
 			   (let [retVal (.showSaveDialog fc frame)]
 			     (when (= retVal JFileChooser/APPROVE_OPTION)
 			       (let [#^File file (.getSelectedFile fc)]
-				 (try
-				  (save-image scn file (get-file-extension file))
-				  (catch Exception e
-				    (JOptionPane/showMessageDialog
-				     frame
-				     (get-root-cause e)
-				     "Error while saving"
-				     JOptionPane/ERROR_MESSAGE)))))))))
+				 (with-swing-error-msg frame "Error while saving"
+				   (save-image scn file (get-file-extension file)))))))))
   nil)

 ;; save changes


Fix panel resizing

Fix panel resizing

--- src/day8/re_frame/trace.cljs
+++ src/day8/re_frame/trace.cljs
@@ -243,54 +243,56 @@
 (defn devtools []
   ;; Add clear button
   ;; Filter out different trace types
-  (let [position       (r/atom :right)
-        size           (r/atom 0.35)
-        showing?       (r/atom false)
-        dragging?      (r/atom false)
-        pin-to-bottom? (r/atom true)
-        selected-tab   (r/atom :traces)
-        handle-keys    (fn [e]
-                         (let [combo-key?      (or (.-ctrlKey e) (.-metaKey e) (.-altKey e))
-                               tag-name        (.-tagName (.-target e))
-                               key             (.-key e)
-                               entering-input? (contains? #{"INPUT" "SELECT" "TEXTAREA"} tag-name)]
-                           (when (and (not entering-input?) combo-key?)
-                             (cond
-                               (and (= key "h") (.-ctrlKey e))
-                               (do (swap! showing? not)
-                                   (if @showing?
-                                     (enable-tracing!)
-                                     (disable-tracing!))
-                                   (.preventDefault e))))))]
+  (let [position          (r/atom :right)
+        panel-width-ratio (r/atom 0.35)
+        showing?          (r/atom false)
+        dragging?         (r/atom false)
+        pin-to-bottom?    (r/atom true)
+        selected-tab      (r/atom :traces)
+        window-width      js/window.innerWidth
+        handle-keys       (fn [e]
+                           (let [combo-key?      (or (.-ctrlKey e) (.-metaKey e) (.-altKey e))
+                                 tag-name        (.-tagName (.-target e))
+                                 key             (.-key e)
+                                 entering-input? (contains? #{"INPUT" "SELECT" "TEXTAREA"} tag-name)]
+                             (when (and (not entering-input?) combo-key?)
+                               (cond
+                                 (and (= key "h") (.-ctrlKey e))
+                                 (do (swap! showing? not)
+                                     (if @showing?
+                                       (enable-tracing!)
+                                       (disable-tracing!))
+                                     (.preventDefault e))))))
+        handle-mousemove  (fn [e]
+                           (when @dragging?
+                             (let [x (.-clientX e)
+                                   y (.-clientY e)]
+                               (.preventDefault e)
+                               (reset! panel-width-ratio (/ (- window-width x) window-width)))))]
     (r/create-class
-      {:component-will-mount   #(js/window.addEventListener "keydown" handle-keys)
-       :component-will-unmount #(js/window.removeEventListener "keydown" handle-keys)
+      {:component-will-mount   (fn []
+                                 (js/window.addEventListener "keydown" handle-keys)
+                                 (js/window.addEventListener "mousemove" handle-mousemove))
+       :component-will-unmount (fn []
+                                 (js/window.removeEventListener "keydown" handle-keys)
+                                 (js/window.removeEventListener "mousemove" handle-mousemove))
        :display-name           "devtools outer"
        :reagent-render         (fn []
                                  (let [draggable-area 10
-                                       full-width     js/window.innerWidth
-                                       full-height    js/window.innerHeight
-                                       left           (if @showing? (str (* 100 (- 1 @size)) "%")
-                                                                    (str full-width "px"))
-                                       transition     (if @showing?
-                                                        ease-transition
-                                                        (str ease-transition ", opacity 0.01s linear 0.2s"))]
+                                       left           (if @showing? (str (* 100 (- 1 @panel-width-ratio)) "%")
+                                                                    (str window-width "px"))
+                                       transition     (if @dragging?
+                                                        ""
+                                                        ease-transition)]
                                    [:div.panel-wrapper
                                     {:style {:position "fixed" :width "0px" :height "0px" :top "0px" :left "0px" :z-index 99999999}}
                                     [:div.panel
-                                      {:style {:position   "fixed" :z-index 1 :box-shadow "rgba(0, 0, 0, 0.298039) 0px 0px 4px" :background "white"
-                                               :left       left :top "0px" :width (str (* 100 @size) "%") :height "100%"
+                                      {:style {:position   "fixed" :z-index 1 :box-shadow "rgba(0, 0, 0, 0.3) 0px 0px 4px" :background "white"
+                                               :left       left :top "0px" :width (str (inc (int (* 100 @panel-width-ratio))) "%") :height "100%"
                                                :transition transition}}
                                       [:div.panel-resizer {:style         (resizer-style draggable-area)
                                                            :on-mouse-down #(reset! dragging? true)
-                                                           :on-mouse-up   #(reset! dragging? false)
-                                                           :on-mouse-move (fn [e]
-                                                                           (when @dragging?
-                                                                             (let [x (.-clientX e)
-                                                                                y (.-clientY e)]
-                                                                               (.preventDefault e)
-                                                                               (reset! size (/ (- full-width x)
-                                                                                full-width)))))}]
+                                                           :on-mouse-up   #(reset! dragging? false)}]
                                       [:div.panel-content
                                         {:style {:width "100%" :height "100%" :display "flex" :flex-direction "column"}}
                                         [:div.panel-content-top


Add commercial audio books to stats

Add commercial audio books to stats

at least the ones that are ready and archived

--- src/mdr2/abacus/import.clj
+++ src/mdr2/abacus/import.clj
@@ -99,7 +99,8 @@
                     :producedDate :produced_date
                     :sourceDate :source_date
                     :revisionDate :revision_date
-                    :sourcePublisher :source_publisher})))
+                    :sourcePublisher :source_publisher
+                    :process_status :state})))

 (defn cleanup-commercial-production
   [m]
@@ -117,7 +118,7 @@
         (assoc :total_time total_time)
         (assoc :library_signature (get production-id-to-library-signature-map (:id m)))
         (select-keys [:id :creator :date :depth :language :library_number :library_signature
-                        :narrator :process_status :produced_date :production_type
+                        :narrator :state :produced_date :production_type
                         :revision_date :source :source_date :source_publisher
                         :subject :title :total_time :volumes]))))

@@ -142,24 +143,26 @@
   [{id :id}]
   (get all-files-by-id id))

-(def ready-productions
+(defn ready-productions
   "All productions with state \"ready\""
-  (filter #(= (:state %) "ready") all-productions))
+  [productions]
+  (filter #(= (:state %) "ready") productions))

 (defn create-ready-productions!
   "Create all productions with state \"ready\""
   []
-  (doseq [p ready-productions]
+  (doseq [p (ready-productions all-productions)]
     (-> p prod/create!)))

-(def archived-productions
+(defn archived-productions
   "All productions with state \"archived\""
-  (filter #(= (:state %) "archived") all-productions))
+  [productions]
+  (filter #(= (:state %) "archived") productions))

 (defn create-archived-productions!
   "Create all productions with state \"archived\""
   []
-  (->> archived-productions
+  (->> (archived-productions all-productions)
        (map #(assoc % :state "archived"))
        (map prod/add-default-meta-data)
        (apply jdbc/insert! db :production)))
@@ -234,10 +237,10 @@
   (println)
   (println "Importing from ABACUS")
   (println)
-  (println "Ready: " (count ready-productions))
-  (println (string/join ", " (map :id ready-productions)))
-  (println)
-  (println "Archived: " (count archived-productions))
+  (println "Ready: " (count (ready-productions all-productions)))
+  (println (string/join ", " (map :id (ready-productions all-productions))))
+  (println)
+  (println "Archived: " (count (archived-productions all-productions)))
   (println)
   (println "Recording with no wav and a struct.html: " (count recording-productions-with-struct))
   (println (string/join ", " (map :id recording-productions-with-struct)))
@@ -259,4 +262,9 @@
   (println )
   (println "Importing commercial audio books")
   (println)
+  (println "Ready: " (count (ready-productions all-commercial-productions)))
+  (println (string/join ", " (map :id (ready-productions all-commercial-productions))))
+  (println)
+  (println "Archived: " (count (archived-productions all-commercial-productions)))
+  (println)
 )


Config options handling in the core module

--- src/emender_jenkins/core.clj
+++ src/emender_jenkins/core.clj
@@ -3,13 +3,16 @@
 (require '[ring.adapter.jetty      :as jetty])
 (require '[ring.middleware.params  :as http-params])
 (require '[ring.middleware.cookies :as cookies])
+
 (require '[clojure.tools.cli       :as cli])
-
+
+(require '[emender-jenkins.server       :as server])
 (require '[emender-jenkins.config       :as config])
-(require '[emender-jenkins.server       :as server])
+(require '[emender-jenkins.middleware   :as middleware])
 (require '[emender-jenkins.process-info :as process-info])

 (def cli-options
+    "Definitions of all command line options that are  currenty supported."
     ;; an option with a required argument
     [["-h"   "--help"                       "show help"                                                    :id :help]
      ["-p"   "--port   PORT"                "port number on which Stage Dashboard should accepts requests" :id :port]
@@ -17,6 +20,9 @@
      ["-t"   "--test-jobs-suffix suffix"    "test jobs suffix, for example 'test'"                         :id :test-jobs-suffix]
      ["-f"   "--fetch-only"                 "just start job fetcher once, then stop processing"            :id :fetch-only]
      ["-c"   "--config"                     "just show the actual configuration"                           :id :show-config]])
+
+; we need to load the configuration in advance so the 'app' could use it
+(def configuration (config/load-configuration-from-ini "config.ini"))

 (def access-control-allow-origins
     "Only following domains will be properly handled by HTTP access control."
@@ -63,10 +69,11 @@
                    response))))

 (def app
-    "Ring application."
-    (-> server/handler
-        cookies/wrap-cookies
-        http-params/wrap-params
+    "Definition of a Ring-based application behaviour."
+    (-> server/handler            ; handle all events
+        (middleware/inject-configuration configuration) ; inject configuration structure into the parameter
+        cookies/wrap-cookies      ; we need to work with cookies
+        http-params/wrap-params   ; and to process request parameters, of course
         all-cors))
         ;cors-handler))

@@ -126,7 +133,6 @@

 (defn fetch-jobs-only
     [options]
-    ;(config/load-all-configuration-options-if-necessary)
     (println "Generating data2.edn")
     ;(job-data-fetcher/try-to-fetch-and-export-data)
     (println "Done"))
@@ -138,6 +144,8 @@
           test-jobs-suffix    (options :test-jobs-suffix)
           openshift-ip        (System/getenv "OPENSHIFT_CLOJURE_HTTP_IP")
           openshift-port      (System/getenv "OPENSHIFT_CLOJURE_HTTP_PORT")]
+        (print-environment-configuration)
+        ;(config/override-options-by-cli jenkins-url test-jobs-suffix)
         (println "Finished")))

 (defn run-app
@@ -155,7 +163,7 @@
         (start-server (get-port port) openshift-port openshift-ip)))

 (defn -main
-    "Entry point to the titan server."
+    "Entry point to the Emender service server."
     [& args]
     (let [all-options         (cli/parse-opts args cli-options)
           options             (all-options :options)
@@ -164,9 +172,10 @@
           show-config?        (options :show-config)]
           (System/setProperty "javax.net.ssl.keyStore",   "keystore")
           (System/setProperty "javax.net.ssl.trustStore", "keystore")
-          (print-environment-configuration)
           (cond show-help?   (show-help (:summary all-options))
                 fetch-only?  (fetch-jobs-only options)
                 show-config? (show-config options)
                 :else        (run-app options))))

+; finito
+


Problem added - Longest Increasing Sub-Seq

--- src/foreclojure/data_set.clj
+++ src/foreclojure/data_set.clj
@@ -527,11 +527,15 @@
             :times-solved 0
             :description "Let bindings and function parameter lists support destructuring."
             :tags ["easy" "destructuring"]
-            :tests ["(= [2 4] (let [[a b c d e f g] (range)] __))"]})))
-
-
-(doseq [{id :_id :keys [test secrets]}
-        (fetch :problems)]
-  (update! :problems
-           {:_id id}
-           {:$set {:test (concat test secrets) :secrets []}}))+            :tests ["(= [2 4] (let [[a b c d e f g] (range)] __))"]})
+
+      (insert! :problems
+           {:_id 53
+            :title "Longest Increasing Sub-Seq"
+            :times-solved 0
+            :description "Given a vector of integers, find the longest consecutive sub-sequence of increasing numbers. If two sub-sequences have the same length, use the one that occurs first."
+            :tags ["medium" "seqs"]
+            :tests ["(= (__ [1 0 1 2 3 0 4 5]) [0 1 2 3])"
+		    "(= (__ [5 6 1 2 6 7]) [5 6])"
+		    "(= (__ [2 3 3 4 5]) [3 4 5])"
+		    "(= (__ [7 6 5 4]) [])"]})))


Make problem numbers appear in links

Make problem numbers appear in links

--- src/foreclojure/problems.clj
+++ src/foreclojure/problems.clj
@@ -90,7 +90,7 @@
    (let [solved (get-solved (session/session-get :user))
          problems (get-problem-list)]
      (map-indexed
-      (fn [x {:keys [title times-solved tags], id :id}]
+      (fn [x {:keys [title times-solved tags], id :_id}]
         [:tr (row-class x)
          [:td {:class "title-link"}
           [:a {:href (str "/problem/" id)}


Read user forms before deciding whether input is empty

--- src/foreclojure/problems.clj
+++ src/foreclojure/problems.clj
@@ -135,10 +135,10 @@
         {:keys [tests restricted]} (get-problem id)
         sb-tester (get-tester restricted)]
     (session/flash-put! :code code)
-    (if (empty? code)
-      (flash-msg "Empty input is not allowed" *url*)
-      (try
-        (let [user-forms (s/join " " (map pr-str (read-string-safely code)))]
+    (try
+      (let [user-forms (s/join " " (map pr-str (read-string-safely code)))]
+        (if (empty? user-forms)
+          (flash-msg "Empty input is not allowed" *url*)
           (loop [[test & more] tests
                  i 0]
             (session/flash-put! :failing-test i)
@@ -147,9 +147,9 @@
               (let [testcase (s/replace test "__" user-forms)]
                 (if (sb sb-tester (first (read-string-safely testcase)))
                   (recur more (inc i))
-                  (flash-msg "You failed the unit tests." *url*))))))
-        (catch Exception e
-          (flash-msg (.getMessage e) *url*))))))
+                  (flash-msg "You failed the unit tests." *url*)))))))
+      (catch Exception e
+        (flash-msg (.getMessage e) *url*)))))

 (defn render-test-cases [tests]
   [:table {:class "testcases"}


Added 4clj tagline to footer, making it now official.

--- src/foreclojure/template.clj
+++ src/foreclojure/template.clj
@@ -69,7 +69,7 @@
              [:span (link-to "/problems/submit" "Submit a Problem")])])
         [:div#content_body (:content attrs)]
         [:div#footer
-         "The content on 4clojure.com is available under the EPL v 1.0 license."
+         "#(-> % discover learn master). The content on 4clojure.com is available under the EPL v 1.0 license."
          (let [email "team@4clojure.com"]
            [:span
             [:a#contact {:href (str "mailto:" email)} "Contact us"]


Run init on load

Run init on load

--- src/golden_kestrel/core.cljs
+++ src/golden_kestrel/core.cljs
@@ -128,3 +128,5 @@
           (run-altmetric-embeds)
           (om/component (embed app)))
         embed-element))))
+
+(init)


add linear model to params object that goes to R

--- server-cached/src/patavi/server/server_cached.clj
+++ server-cached/src/patavi/server/server_cached.clj
@@ -34,7 +34,7 @@
   (let [method (:method data)
         linearModel (:linearModel data)
         problem (json/parse-string (:problem data))
-        from-patavi (fn [] (cache-result (:id data) (handlers/service-run-rpc method [problem linearModel])))
+        from-patavi (fn [] (cache-result (:id data) (handlers/service-run-rpc method (assoc problem :linearModel linearModel))))
         from-cache (fn [] (json/parse-string (:result data)))
         run (if (nil? (:result data)) from-patavi from-cache)]
     (wamp/with-channel-validation request channel handlers/origin-re


refactor: try catch is not necessary

refactor: try catch is not necessary

--- src/leiningen/namespaces.clj
+++ src/leiningen/namespaces.clj
@@ -74,11 +74,10 @@
     (map #(str % "/" ns-path) folders)))

 (defn update-files! [from-file to-file]
-  (try
-    (io/make-parents (io/file to-file))
-    (spit (io/file to-file) (slurp (io/file from-file)))
-    (catch FileNotFoundException e
-      (m/info "* Could not update" to-file "because: " (.getMessage e)))))
+  (io/make-parents (io/file to-file))
+  (spit
+   (io/file to-file)
+   (slurp (io/file from-file))))

 (defn should-update? [entry-definition entry target-project]
   (-> target-project
@@ -141,7 +140,7 @@
       (<= 1 (count existing-source-paths))
       (ask-for-localtion-and-update! name target-project existing-source-paths target-paths)
       ;default: do nothing
-      :else (m/info "WARNING: Could not find strategy to update" name "on project" target-project
+      :else (m/info "* WARNING: Could not find strategy to update" name "on project" target-project
                     "\n    ==>" name "may not exist on the source project"))))

 (defn update-name-space! [name-space target-project source-project-desc]


waiting for start and preventing start on a running machine conflict

--- src/openstack/provider.clj
+++ src/openstack/provider.clj
@@ -66,6 +66,14 @@
     {:type ::openstack:status-failed :timeout timeout}
       "Timed out on waiting for ip to be available"))

+(defn running? [this] (= (.status this) "running"))
+
+(defn wait-for-start [this timeout]
+  "Wait for an ip to be avilable"
+  (wait-for {:timeout timeout} #(running? this)
+    {:type ::openstack:status-failed :timeout timeout}
+      "Timed out on waiting for ip to be available"))
+
 (defn system-val
   "grabbing instance id of spec"
    [spec ks]
@@ -83,6 +91,7 @@
   "update instance id"
   (when (s/system-exists? (spec :system-id))
      (s/partial-system (spec :system-id) {:openstack {:instance-id id}})))
+

 (defconstrainedrecord Instance [tenant spec user]
   "An Openstack compute instance"
@@ -106,10 +115,12 @@

   (start [this]
      (with-instance-id
-       (debug "starting" instance-id )
-       (.action (servers tenant) instance-id Action/START)
-       (wait-for-ssh
-         (system-val spec [:machine :ip]) (get-in spec [:machine :user]) [5 :minute])))
+       (when-not (running? this)
+         (debug "starting" instance-id )
+         (.action (servers tenant) instance-id Action/START)
+         (wait-for-start this [5 :minute])
+         (wait-for-ssh
+           (system-val spec [:machine :ip]) (get-in spec [:machine :user]) [5 :minute]))))

   (delete [this]
      (with-instance-id


tidy up docstrings

tidy up docstrings

--- src/overtone/gui/scope.clj
+++ src/overtone/gui/scope.clj
@@ -34,9 +34,9 @@
                                 (satisfy-deps :scope-group-created)))

 (defn- ensure-internal-server!
-  "Throws an exception if the server isn't internal - scope relies on fast
-  access to shared buffers with the server which is currently only available
-  with the internal server. Also ensures server is connected."
+  "Throws an exception if the server isn't internal - scope relies on
+  fast access to shared buffers with the server which is currently only
+  available with the internal server. Also ensures server is connected."
   []
   (when (server-disconnected?)
     (throw (Exception. "Cannot use scopes until a server has been booted or connected")))
@@ -45,10 +45,11 @@

 (defn- update-scope-data
   "Updates the scope by reading the current status of the buffer and repainting.
-  Currently only updates bus scope as there's a bug in scsynth-jna which crashes
-  the server after too many calls to buffer-data for a large buffer. As buffers
-  tend to be large, updating the scope frequently will cause the crash to happen
-  sooner. Need to remove this limitation when scsynth-jna is fixed."
+  Currently only updates bus scope as there's a bug in scsynth-jna which
+  crashes the server after too many calls to buffer-data for a large
+  buffer. As buffers tend to be large, updating the scope frequently
+  will cause the crash to happen sooner. Need to remove this limitation
+  when scsynth-jna is fixed."
   [s]
   (let [{:keys [buf size width height panel y-arrays x-array panel]} s
         frames    (if @(:update? s) (buffer-data buf) @(:frames s))
@@ -99,7 +100,8 @@
     panel))

 (defn- scope-frame
-  "Display scope window. If you specify keep-on-top to be true, the window will stay on top of the other windows in your environment."
+  "Display scope window. If you specify keep-on-top to be true, the
+  window will stay on top of the other windows in your environment."
   ([panel slider title keep-on-top width height]
      (let [f (JFrame. title)
            cp (.getContentPane f)
@@ -115,8 +117,8 @@
          (.setAlwaysOnTop keep-on-top)))))

 (defn scopes-start
-  "Schedule the scope to be updated every (/ 1000 FPS) ms (unless the scopes are
-  already running in which case it does nothing."
+  "Schedule the scope to be updated every (/ 1000 FPS) ms (unless the
+  scopes are already running in which case it does nothing."
   []
   (ensure-internal-server!)
   (dosync
@@ -173,8 +175,8 @@
       :buf  info)))

 (defn scope-close
-  "Close a given scope. Copes with the case where the server has crashed by
-  handling timeout errors when killing the scope's bus-synth."
+  "Close a given scope. Copes with the case where the server has crashed
+  by handling timeout errors when killing the scope's bus-synth."
   [s]
   (log/info (str "Closing scope: \n" s))
   (let [{:keys [id bus-synth buf]} s]
@@ -265,7 +267,8 @@
        (scopes-start))))

 (defn pscope
-  "Creates a 'perminent' scope, i.e. one where the window is always kept on top of other OS windows. See scope."
+  "Creates a 'perminent' scope, i.e. one where the window is always kept
+  on top of other OS windows. See scope."
   ([& args]
      (ensure-internal-server!)
      (apply scope (concat args [:keep-on-top true]))))


Bump serverless-cljs template version

Bump serverless-cljs template version

--- templates/serverless/project.clj
+++ templates/serverless/project.clj
@@ -1,4 +1,4 @@
-(defproject serverless-cljs/lein-template "0.1.4"
+(defproject serverless-cljs/lein-template "0.1.5"
   :description "Clojurescript on AWS Lambda via Serverless"
   :url         "https://github.com/nervous-systems/cljs-lambda"
   :license     {:name "Unlicense" :url "http://unlicense.org/UNLICENSE"}


Make the regex testing more concise

Make the regex testing more concise

--- test/comic_reader/sites_test.clj
+++ test/comic_reader/sites_test.clj
@@ -72,20 +72,23 @@
     (html/html-resource image-resource)))

 (defn num-groups [regex]
-  (-> regex
-      (.matcher "")
-      (.groupCount)))
+  (some-> regex
+          (.matcher "")
+          (.groupCount)))
+
+(defmacro has-x-groups [x pattern-fn]
+  `(and
+    (tu/ensure-dependencies-defined ~pattern-fn)
+    (is (= ~x (num-groups (~pattern-fn)))
+        ~(str "There should be exactly " x " matching groups in the `"
+              pattern-fn "' regular expression."))))

 (defn test-regexes []
   (and
-   (is (= 1 (num-groups (manga-pattern)))
-       "There should be exactly 1 matching group in the `manga-pattern' regex.")
-   (is (= 1 (num-groups (chapter-number-match-pattern)))
-       "There should be exactly 1 matching group in the `chapter-number-match-pattern' regex.")
-   (is (= 0 (num-groups (page-normalize-pattern)))
-       "There should not be any matching groups in the `page-normalize-pattern' regex.")
-   (is (= 0 (num-groups (chapter-number-pattern)))
-       "There should not be any matching groups in the `page-normalize-pattern' regex.")))
+   (has-x-groups 1 manga-pattern)
+   (has-x-groups 1 chapter-number-match-pattern)
+   (has-x-groups 0 page-normalize-pattern)
+   (has-x-groups 0 chapter-number-pattern)))

 (defn valid-selector? [selector]
   (and


Removed redundant local

Removed redundant local

--- src/leiningen/amp/package.clj
+++ src/leiningen/amp/package.clj
@@ -76,8 +76,7 @@
   * :java-source-paths (Java source files)
   * :resource-paths    (resource source files)"
   [tgt-amp-file project]
-  (let [project-home   (io/file (:root project))
-        src-amp        (get-amp-src        project)
+  (let [src-amp        (get-amp-src        project)
         srcs-clojure   (map io/file (:source-paths      project))
         srcs-java      (map io/file (:java-source-paths project))
         srcs-resources (map io/file (:resource-paths    project))]


Reflection warnings.

Reflection warnings.

--- src/onyx/messaging/aeron.clj
+++ src/onyx/messaging/aeron.clj
@@ -197,15 +197,15 @@
         (let [t (System/currentTimeMillis)
               snapshot @publications
               to-remove (map first
-                             (filter (fn [[k v]] (>= (- t @(:last-used v)) idle))
+                             (filter (fn [[k v]] (>= (- ^long t ^long @(:last-used v)) idle))
                                      snapshot))]
           (doseq [k to-remove]
             (let [pub (:publication (snapshot k))
                   conn (@connections k)]
               (swap! publications dissoc k)
               (swap! connections dissoc k)
-              (.close pub)
-              (.close conn))))
+              (.close ^Publication pub)
+              (.close ^Aeron conn))))
         (catch InterruptedException e
           (throw e))
         (catch Throwable e
@@ -267,7 +267,7 @@
     (doseq [conn (vals @connections)]
       (.close ^Aeron conn))
     (when media-driver (.close ^MediaDriver media-driver))
-    (when media-driver-context (.deleteAeronDirectory media-driver-context))
+    (when media-driver-context (.deleteAeronDirectory ^MediaDriver$Context media-driver-context))
     (assoc component
            :pub-gc-thread nil
            :media-driver nil :publications nil :virtual-peers nil


Made definst set the instrument metadata and accept a docstring.

--- src/overtone/studio/core.clj
+++ src/overtone/studio/core.clj
@@ -1,5 +1,6 @@
 (ns overtone.studio.core
   (:use
+    [clojure.contrib [def :only [name-with-attributes]]]
     [overtone util event time-utils deps]
     [overtone.sc.ugen.defaults]
     [overtone.sc core synth ugen envelope node synthdef bus]
@@ -209,10 +210,12 @@
        (= ::instrument (:type o))))

 (defmacro definst [i-name & inst-form]
-  (let [[md params ugen-form] (synth-form i-name inst-form)
+  (let [[i-name inst-form] (name-with-attributes i-name inst-form)
+        [md params ugen-form] (synth-form i-name inst-form)
         md (assoc md :type ::instrument)]
-    (list 'def i-name ;(with-meta i-name md)
-       `(inst ~i-name ~params ~ugen-form))))
+    `(do
+       (def ~i-name (inst ~i-name ~params ~ugen-form))
+       (.setMeta #'~i-name (merge (.meta #'~i-name) ~md)))))

 (defmethod overtone.sc.node/kill :overtone.studio.core/instrument
   [& args]


Fix :note-off handler in 'midi-poly-player. #'overtone.sc.node/node-control* requires a seq of key value pairs and doesn't work with a map. Also using when-let instead of let to short circuit evaluation.

--- src/overtone/studio/midi.clj
+++ src/overtone/studio/midi.clj
@@ -71,14 +71,19 @@
   (let [notes*  (atom {})
         on-key  (keyword (gensym 'note-on))
         off-key (keyword (gensym 'note-off))]
+
     (on-event [:midi :note-on] (fn [{note :note velocity :velocity}]
                                  (swap! notes* assoc note (play-fn note velocity)))
-    on-key)
+              on-key)
+
     (on-event [:midi :note-off] (fn [{note :note velocity :velocity}]
-                                  (let [n (get @notes* note)]
-                                    (node-control n {:gate 0}))
-                                  (swap! notes* dissoc note))
+                                  (when-let [n (get @notes* note)]
+                                    (node-control n [:gate 0])
+                                    (swap! notes* dissoc note)))
               off-key)
+
+    ;; TODO listen for '/n_end' event for nodes that free themselves
+    ;; before recieving a note-off message.
     {:notes* notes*
      :on-key on-key
      :off-key off-key


CMR-1699 Accommodates new virtual product matchers.

Virtual product bootstrapping now uses the virtual product service
functions for determining if a source granule should result in virtual
granules being created based on the granule UMM and the predicate
functions in the virtual product configuration itself.

--- system-int-test/test/cmr/system_int_test/bootstrap/virtual_products_test.clj
+++ system-int-test/test/cmr/system_int_test/bootstrap/virtual_products_test.clj
@@ -70,8 +70,9 @@
         source-granules (doall (for [source-coll source-collections
                                      :let [{:keys [provider-id entry-title]} source-coll]
                                      granule-ur (vp-config/sample-source-granule-urs
-                                                 [provider-id entry-title])]
-                                 (d/ingest provider-id (dg/granule source-coll {:granule-ur granule-ur}))))
+                                                  [provider-id entry-title])]
+                                 (vp/ingest-source-granule provider-id
+                                                          (dg/granule source-coll {:granule-ur granule-ur}))))
         all-expected-granule-urs (concat (mapcat vp/source-granule->virtual-granule-urs source-granules)
                                          (map :granule-ur source-granules))]
     (index/wait-until-indexed)
@@ -109,9 +110,10 @@
         vp-colls   (vp/ingest-virtual-collections [ast-coll])
         s-granules (doall
                     (for [n (range 10)]
-                      (d/ingest "LPDAAC_ECS"
-                                (dg/granule ast-coll {:granule-ur (format "SC:AST_L1A.003:%d" n)
-                                                      :revision-id 5}))))
+                      (vp/ingest-source-granule
+                       "LPDAAC_ECS"
+                       (dg/granule ast-coll {:granule-ur (format "SC:AST_L1A.003:%d" n)
+                                             :revision-id 5}))))
         _          (bootstrap-and-index)
         v-granules (mapcat #(:refs
                              (search/find-refs :granule


produce unique package names for riemann

--- tasks/leiningen/fatdeb.clj
+++ tasks/leiningen/fatdeb.clj
@@ -1,8 +1,10 @@
 (ns leiningen.fatdeb
   (:use [clojure.java.shell :only [sh]]
         [clojure.java.io :only [file delete-file writer copy]]
-        [clojure.string :only [join capitalize trim-newline]]
-        [leiningen.uberjar :only [uberjar]]))
+        [clojure.string :only [join capitalize trim-newline replace]]
+        [leiningen.uberjar :only [uberjar]])
+  (:import java.text.SimpleDateFormat
+           java.util.Date))

 (defn delete-file-recursively
     "Delete file f. If it's a directory, recursively delete all its contents.
@@ -31,13 +33,18 @@
   (cleanup project)
   (sh "rm" (str (:root project) "/target/*.deb")))

+(defn get-version
+  [project]
+  (let [df   (SimpleDateFormat. "yyyyMMdd-HHmmss")]
+    (replace (:version project) #"SNAPSHOT" (.format df (Date.)))))
+
 (defn control
   "Control file"
   [project]
   (join "\n"
         (map (fn [[k v]] (str (capitalize (name k)) ": " v))
              {:package (:name project)
-              :version (:version project)
+              :version (get-version project)
               :section "base"
               :priority "optional"
               :architecture "all"
@@ -76,7 +83,7 @@
     ; Jar
     (.mkdirs (file dir "usr" "lib" "riemann"))
     (copy (file (:root project) "target"
-                (str "riemann-" (:version project) "-standalone.jar"))
+                (str "riemann-" (get-version project) "-standalone.jar"))
           (file dir "usr" "lib" "riemann" "riemann.jar"))

     ; Binary
@@ -99,7 +106,7 @@
                    (str deb-dir)
                    (str (file (:root project) "target")))))
   (let [deb-file (file (:root project) "target" (str (:name project) "_"
-                                                     (:version project) "_"
+                                                     (get-version project) "_"
                                                      "all" ".deb"))]
     (write (str deb-file ".md5")
            (:out (sh "md5sum" (str deb-file))))))


make shadow.test.env/register-test return the test var

just in case someone uses (deftest ...) in the REPL

--- src/main/shadow/test/env.cljs
+++ src/main/shadow/test/env.cljs
@@ -22,7 +22,8 @@

 (defn register-test [test-ns test-name test-var]
   ;; register by name so reloading replaces the old test
-  (swap! tests-ref assoc-in [:namespaces test-ns :vars test-name] test-var))
+  (swap! tests-ref assoc-in [:namespaces test-ns :vars test-name] test-var)
+  test-var)

 (defn register-fixtures [test-ns type fix]
   (swap! tests-ref assoc-in [:namespaces test-ns :fixtures type] fix))


key-name and floating-ip validation

key-name and floating-ip validation

--- src/openstack/validations.clj
+++ src/openstack/validations.clj
@@ -28,8 +28,9 @@
 (def openstack-common
   {:openstack
    {:flavor #{:required :String} :tenant #{:required :String}
-    :security-groups #{:Vector :group*} :networks #{:Vector :network*}}}
-  )
+    :security-groups #{:Vector :group*} :networks #{:Vector :network*}
+    :key-name #{:required :String} :floating-ip #{:ip :String}
+    }})

 (defn validate-entity
   "openstack based systems entity validation "


fix arity bug

fix arity bug

--- kafka-clj/src/kafka_clj/consumer/consumer.clj
+++ kafka-clj/src/kafka_clj/consumer/consumer.clj
@@ -124,7 +124,7 @@
   (if-let [res (try                                         ;this command throws a SocketTimeoutException if the queue does not exist
                  (car/wcar redis-conn                       ;we check for this condition and continue to block
                            (car/brpoplpush queue working-queue 1000))
-                 (catch java.net.SocketTimeoutException e (do (safe-sleep) (debug "Timeout on queue " queue " retry ") nil)))]
+                 (catch java.net.SocketTimeoutException e (do (safe-sleep 1000) (debug "Timeout on queue " queue " retry ") nil)))]
     res
     (recur redis-conn queue working-queue)))


up default consumer threads to 8

up default consumer threads to 8

--- kafka-clj/src/kafka_clj/consumer/consumer.clj
+++ kafka-clj/src/kafka_clj/consumer/consumer.clj
@@ -302,7 +302,7 @@
                        (>!! msg-ch resp-data))
                      (assoc state :status :ok))
         {:keys [load-pool] :as ret-state} (merge state (consumer-start state) {:restart 0})
-        consumer-threads (get conf :consumer-threads 2)
+        consumer-threads (get conf :consumer-threads 8)
         publish-pool (start-publish-pool-thread ret-state)]
     ;add threads that will consume from the load-pool and run f-delegate, that will in turn put data on the msg-ch
     (dotimes [i consumer-threads]


Pass result-type through doc command

Pass result-type through doc command

--- lein-light-nrepl/src/lighttable/nrepl/doc.clj
+++ lein-light-nrepl/src/lighttable/nrepl/doc.clj
@@ -74,15 +74,15 @@
                        (clean-meta)
                        (format-cljs-result))))

-(defmethod core/handle "editor.clj.doc" [{:keys [ns sym loc session path] :as msg}]
+(defmethod core/handle "editor.clj.doc" [{:keys [ns sym loc session path result-type] :as msg}]
   (let [ns (eval/normalize-ns ns path)
         _ (eval/require|create-ns (symbol ns))
         res (get-doc ns sym)
-        res (when res (assoc res :loc loc))]
+        res (when res (assoc res :loc loc :result-type result-type))]
     (core/respond msg "editor.clj.doc" res))
   @session)

-(defmethod core/handle "editor.cljs.doc" [{:keys [ns sym loc session path] :as msg}]
+(defmethod core/handle "editor.cljs.doc" [{:keys [ns sym loc session path result-type] :as msg}]
   (env/with-compiler-env cljs/compiler-env
                          (let [ns (eval/normalize-ns ns path)]
                            (eval/require|create-ns (symbol ns))
@@ -91,7 +91,7 @@
                                  res (if (:macro clj)
                                        clj
                                        (get-cljs-doc ns sym))
-                                 res (when res (assoc res :loc loc))]
+                                 res (when res (assoc res :loc loc :result-type result-type))]
                              (core/respond msg "editor.cljs.doc" res))))
   @session)


cond-> typo

cond-> typo


Fixed the pull parser tests to call the pull parser lazy-parse

--- modules/xml.pull-parser/src/test/clojure/clojure/data/xml/test_pull_parser.clj
+++ modules/xml.pull-parser/src/test/clojure/clojure/data/xml/test_pull_parser.clj
@@ -13,11 +13,16 @@
         [clojure.data.xml :as xml :only [element]]
         [clojure.data.xml.pull-parser :as pp :only []]))

+(defn test-stream [x]
+  (java.io.ByteArrayInputStream. (.getBytes x)))
+
+(def lazy-parse* (comp pp/lazy-parse test-stream))
+
 (deftest simple
   (let [input "This is bold test"
         expected (element :html {} (element :body {:bg "red"}
                    "This is " (element :b {} "bold") " test"))]
-    (with-in-str input (is (= expected (xml/lazy-parse *in*))))))
+    (is (= expected (lazy-parse* input)))))

 (deftest deep
   (let [input (str ""
@@ -35,4 +40,4 @@
                    "  t7" (element :e {:l "5" :m "6"}
                    "    t8" (element :f {} "t10") "t11")
                    "  t12" (element :g {} "t13") "t14")]
-    (with-in-str input (is (= expected (xml/lazy-parse *in*))))))
+    (is (= expected (lazy-parse* input)))))