fix that reference bug

fix that reference bug

--- src/ceres_collector/pipeline.clj
+++ src/ceres_collector/pipeline.clj
@@ -111,9 +111,9 @@
     (doall (map #(d/store-reference mid % "url") url-ids))
     (doall (map #(d/store-reference mid % "tag") hids))
     (case type
-      :reply (let [sid (mc/find-one-as-map @db "messages" {:tweet (:in_reply_to_status_id tweet)})]
+      :reply (let [sid (:_id (mc/find-one-as-map @db "messages" {:tweet (:in_reply_to_status_id tweet)}))]
                (d/store-reference mid sid "reply"))
-      :retweet (let [sid (mc/find-one-as-map @db "messages" {:tweet (get-in tweet [:retweeted_status :id])})]
+      :retweet (let [sid (:_id (mc/find-one-as-map @db "messages" {:tweet (get-in tweet [:retweeted_status :id])}))]
                  (d/store-reference mid sid "retweet"))
       :share (if news?
                nil


add some graph stuff

add some graph stuff

--- src/clj/ceres_analytics/core.clj
+++ src/clj/ceres_analytics/core.clj
@@ -79,4 +79,13 @@

   (stop-server)

+
+
+  (let [messages (mc/find-maps @db "messages" {:ts {$gt (t/date-time 2015 3 18 8)
+                                                    $lt (t/date-time 2015 3 18 8 10)}})
+        retweets (map  (fn [{:keys [_id text]}]
+                         [text (mc/find-maps @db "retweets" {:target _id})]) messages)]
+    )
+
+
   )


File deletion is ready

File deletion is ready

--- src/clj/fortress/ring/server.clj
+++ src/clj/fortress/ring/server.clj
@@ -2,14 +2,15 @@
   (:use fortress.util.clojure)
   (:require [clojure.tools.logging :as log]
             [fortress.ring.handler :as fhandler]
-            [fortress.ring.writers :as writers])
+            [fortress.ring.writers :as writers]
+            [clojure.java.io :as io])
   (:import [io.netty.bootstrap ServerBootstrap]
            [io.netty.channel ChannelOption]
            [io.netty.channel.nio NioEventLoopGroup]
            [io.netty.channel.socket.nio NioServerSocketChannel]
            [fortress.ring.handler FortressInitializer]
            [java.net InetSocketAddress]
-           [java.util.concurrent ThreadFactory]))
+           [java.util.concurrent ThreadFactory Executors TimeUnit]))

 (def default-options {:threads 0
                       :host "0.0.0.0"
@@ -27,6 +28,34 @@
   (proxy [ThreadFactory] []
     (newThread [thunk]
       (Thread. thunk (random-thread-name thread-name-prefix)))))
+
+(defonce deletion-executor
+  (Executors/newSingleThreadScheduledExecutor
+    (thread-factory "fortress-deleter")))
+
+(defn delete-files
+  "Delete files older than 15 minutes in temp path"
+  [path]
+  (fn []
+    (let [file (io/file path)
+          fs (file-seq file)]
+      (try
+        (doseq [f fs]
+          (if (and (.isFile f)
+                   (.startsWith (.getName f) "fortress")
+                   (> (- (System/currentTimeMillis)
+                         (.lastModified f))
+                      (* 15 60 1000)))
+            (io/delete-file f)))
+        (catch Exception e
+          (.printStackTrace e))))))
+
+(defn start-deleting [path]
+  (.scheduleAtFixedRate deletion-executor
+                        (delete-files path)
+                        15
+                        5
+                        TimeUnit/MINUTES))

 (defn secure-channel-clone [bootstrap handler temp-path {:keys [host ssl? ssl-port zero-copy? max-size ssl-context error-fn]}]
   (when (and ssl? ssl-port)
@@ -97,6 +126,7 @@
    (run-fortress handler {}))
   ([handler {:keys [debug-requests temp-path]
              :as options}]
+   (start-deleting temp-path)
    (let [options (merge default-options options)]
      (reset! fhandler/debug-request debug-requests)
      (if debug-requests


add test mini-game: HB glacier tactics, Caprice psi, Runner drip economy, positional ice strength

--- src/clj/test/games-scenarios.clj
+++ src/clj/test/games-scenarios.clj
@@ -41,3 +41,82 @@
           (card-ability state :runner fg 0) ; Trash Fall Guy to save the Apartment!
           (is (= (:title (get-in @state [:runner :rig :resource 0])) "Off-Campus Apartment") "Apartment still standing")
           (is (= (:title (last (:discard (get-runner)))) "Fall Guy") "Fall Guy trashed"))))))
+
+(deftest hb-glacier
+  "HB Glacier econ and server protection with upgrades - Ash, Caprice, Breaker Bay Grid, positional ice strength boost"
+  (do-game
+    (new-game (make-deck "Haas-Bioroid: Engineering the Future"
+                [(qty "Adonis Campaign" 1) (qty "Global Food Initiative" 1) (qty "Breaker Bay Grid" 1)
+                 (qty "Caprice Nisei" 1) (qty "Ash 2X3ZB9CY" 1) (qty "Turing" 1) (qty "Hedge Fund" 1)])
+              (default-runner [(qty "Desperado" 1) (qty "Dirty Laundry" 1) (qty "Emergency Shutdown" 1)
+                               (qty "Lamprey" 1) (qty "Data Folding" 1) (qty "Career Fair" 1)]))
+    (core/draw state :corp 1)
+    (core/gain state :corp :click 1)
+    (play-from-hand state :corp "Hedge Fund")
+    (play-from-hand state :corp "Adonis Campaign" "New remote")
+    (is (= 10 (:credit (get-corp))) "HB:EtF ability paid 1 credit")
+    (play-from-hand state :corp "Breaker Bay Grid" "Server 1")
+    (play-from-hand state :corp "Ash 2X3ZB9CY" "HQ")
+    (let [adon (get-in @state [:corp :servers :remote1 :content 0])
+          bbg (get-in @state [:corp :servers :remote1 :content 1])
+          ash (get-in @state [:corp :servers :hq :content 0])]
+      (core/rez state :corp bbg)
+      (core/rez state :corp adon)
+      (is (= 10 (:credit (get-corp))) "Breaker Bay Grid allowed rez of Adonis for free")
+      (take-credits state :corp)
+      (core/draw state :runner 1)
+      (play-from-hand state :runner "Career Fair")
+      (prompt-select :runner (find-card "Data Folding" (:hand (get-runner))))
+      (is (= 5 (:credit (get-runner))) "Data Folding installed for free by Career Fair")
+      (play-from-hand state :runner "Lamprey")
+      (play-from-hand state :runner "Desperado")
+      (is (= 1 (:credit (get-runner))))
+      (core/click-run state :runner {:server :hq})
+      (core/rez state :corp ash)
+      (card-ability state :corp ash 0)
+      (prompt-choice :corp 0)
+      (prompt-choice :runner 0)
+      (core/no-action state :corp nil)
+      (core/successful-run state :runner nil)
+      (is (and (= 2 (:credit (get-runner))) (= 7 (:credit (get-corp)))) "Desperado paid 1 to Runner, Lamprey took 1 from Corp")
+      (prompt-choice :runner "No") ; can't afford to trash Ash
+      (take-credits state :runner)
+      (play-from-hand state :corp "Caprice Nisei" "Server 1")
+      (is (= 11 (:credit (get-corp))) "Gained 3 from Adonis and 1 from HB:EtF")
+      (play-from-hand state :corp "Turing" "Server 1")
+      (take-credits state :corp 1)
+      (is (= 3 (:credit (get-runner))) "Gained 1 from Data Folding")
+      (core/gain state :runner :click 2)
+      (core/click-run state :runner {:server :hq})
+      (card-ability state :corp ash 0)
+      (prompt-choice :corp 0)
+      (prompt-choice :runner 0)
+      (core/no-action state :corp nil)
+      (core/successful-run state :runner nil)
+      (prompt-choice :runner "Yes") ; trash Ash
+      (is (and (= 1 (:credit (get-runner))) (= 11 (:credit (get-corp)))))
+      (core/gain state :runner :credit 1)
+      (play-from-hand state :runner "Dirty Laundry")
+      (prompt-choice :runner "HQ")
+      (core/no-action state :corp nil)
+      (core/successful-run state :runner nil)
+      (prompt-choice :runner "Steal")
+      (is (= 2 (:agenda-point (get-runner))) "Stole Global Food Initiative")
+      (is (and (= 6 (:credit (get-runner))) (= 10 (:credit (get-corp)))) "Desperado plus Dirty Laundry, Lamprey took 1 from Corp")
+      (core/click-run state :runner {:server "Server 1"})
+      (let [tur (get-in @state [:corp :servers :remote1 :ices 0])
+            cap (get-in @state [:corp :servers :remote1 :content 2])]
+        (core/rez state :corp tur)
+        (is (= 5 (:current-strength (refresh tur))) "Turing +3 strength protecting a remote")
+        (card-ability state :corp tur 0) ; end the run
+        (play-from-hand state :runner "Emergency Shutdown")
+        (prompt-select :runner tur)
+        (is (not (get-in (refresh tur) [:rezzed])) "Turing derezzed")
+        (core/click-run state :runner {:server "Server 1"}) ; letting Runner in this time to use Caprice
+        (core/rez state :corp cap)
+        (core/no-action state :corp nil)
+        (core/continue state :runner nil)
+        (card-ability state :corp cap 0) ; psi game
+        (prompt-choice :corp "1 [Credits]")
+        (prompt-choice :runner "2 [Credits]")
+        (is (not (:run @state)) "Corp won Caprice psi game and ended the run")))))


Fix LogCat launching

Fix LogCat launching

--- src/clojure/nightcode/logcat.clj
+++ src/clojure/nightcode/logcat.clj
@@ -18,8 +18,6 @@
   (->> (lein/start-process! process
                             nil
                             (-> (lein/read-project-clj path)
-                                :android
-                                :sdk-path
                                 (leiningen.droid.utils/sdk-binary :adb))
                             "logcat"
                             "*:I")


Add click sound

Add click sound

--- src/clojure/nightmod/screens.clj
+++ src/clojure/nightmod/screens.clj
@@ -237,7 +237,8 @@
       (update! screen
                :renderer (stage)
                :camera (orthographic)
-               :cursor-image (pixmap "glove.png"))
+               :cursor-image (pixmap "glove.png")
+               :click-sound (sound "click.ogg"))
       (let [ui-skin (skin "uiskin.json")
             font (skin! ui-skin :get-font "default-font")
             col-count (/ (count templates) 2)
@@ -297,6 +298,7 @@
   :on-ui-changed
   (fn [screen entities]
     (when-let [n (actor! (:actor screen) :get-name)]
+      (sound! (:click-sound screen) :play)
       (if (contains? (set templates) n)
         (new-project! n)
         (load-project! n)))


Increase font size of header labels

Increase font size of header labels

--- src/clojure/nightmod/screens.clj
+++ src/clojure/nightmod/screens.clj
@@ -24,7 +24,8 @@
 (declare nightmod main-screen blank-screen overlay-screen)

 (def ^:const text-height 40)
-(def ^:const pad-space 5.0)
+(def ^:const pad-small 5.0)
+(def ^:const pad-large 20.0)
 (def ^:const tile-size 250)

 (def templates ["arcade"
@@ -124,7 +125,7 @@
      wrap-label!)
    :width tile-size
    :height tile-size
-   :pad pad-space pad-space pad-space pad-space])
+   :pad pad-small pad-small pad-small pad-small])

 (defn set-visible!
   [entity show?]
@@ -261,14 +262,20 @@
                            (apply concat))]
         [(assoc (shape :filled) :id :background)
          (-> (concat (when (seq saved-games)
-                       [[(label (nc-utils/get-string :load) ui-skin)
-                         :colspan col-count]])
+                       [[(label (nc-utils/get-string :load) ui-skin
+                                :set-font-scale 1.5)
+                         :colspan col-count
+                         :pad-top pad-large
+                         :pad-bottom pad-large]])
                      saved-games
                      [:row
-                      [(label (nc-utils/get-string :new) ui-skin)
-                       :colspan col-count]]
+                      [(label (nc-utils/get-string :new) ui-skin
+                              :set-font-scale 1.5)
+                       :colspan col-count
+                       :pad-top pad-large
+                       :pad-bottom pad-large]]
                      new-games)
-             (table :align (align :center) :pad pad-space)
+             (table :align (align :center) :pad pad-small)
              (scroll-pane ui-skin
                           :set-fade-scroll-bars false
                           :set-fill-parent true))])))
@@ -347,29 +354,29 @@
                     :set-font-scale 0.8
                     :set-alignment (bit-or (align :left) (align :bottom)))
              (scroll-pane (style :scroll-pane nil nil nil nil nil))
-             (assoc :id :text :x pad-space :y (+ text-height (* 2 pad-space))))
+             (assoc :id :text :x pad-small :y (+ text-height (* 2 pad-small))))
          (-> [(check-box (nc-utils/get-string :stack-trace) ui-skin
                          :set-name "stack-trace")
               (text-button (nc-utils/get-string :copy) ui-skin
                            :set-name "copy")]
-             (horizontal :space (* 2 pad-space) :pack)
-             (assoc :id :error-buttons :x pad-space :y pad-space))
+             (horizontal :space (* 2 pad-small) :pack)
+             (assoc :id :error-buttons :x pad-small :y pad-small))
          (-> [(image-button home-style :set-name "home")
               (image-button restart-style :set-name "restart")
               (image-button screenshot-style :set-name "screenshot")
               (image-button files-style :set-name "files")
               (image-button docs-style :set-name "docs")
               (image-button repl-style :set-name "repl")]
-             (horizontal :space (* 2 pad-space) :pack)
-             (assoc :id :menu :x pad-space))
+             (horizontal :space (* 2 pad-small) :pack)
+             (assoc :id :menu :x pad-small))
          (-> [(image-button (texture-drawable "home_key.png"))
               (image-button (texture-drawable "restart_key.png"))
               (image-button (texture-drawable "screenshot_key.png"))
               (image-button (texture-drawable "files_key.png"))
               (image-button (texture-drawable "docs_key.png"))
               (image-button (texture-drawable "repl_key.png"))]
-             (horizontal :space (* 2 pad-space) :pack)
-             (assoc :id :menu-keys :x pad-space))
+             (horizontal :space (* 2 pad-small) :pack)
+             (assoc :id :menu-keys :x pad-small))
          (assoc (label " " ui-skin :set-visible false) :menu-label? true)])))

   :on-render
@@ -392,8 +399,8 @@
     (height! screen height)
     (for [e entities]
       (case (:id e)
-        :menu (assoc e :y (- height (vertical! e :get-height) pad-space))
-        :menu-keys (assoc e :y (- height (vertical! e :get-height) pad-space))
+        :menu (assoc e :y (- height (vertical! e :get-height) pad-small))
+        :menu-keys (assoc e :y (- height (vertical! e :get-height) pad-small))
         :text (assoc e :width width :height (- height (* 2 (:y e))))
         e)))


cleanup

cleanup

--- src/clojure_fabric/grpc_core.clj
+++ src/clojure_fabric/grpc_core.clj
@@ -36,10 +36,6 @@
            [org.hyperledger.fabric.protos.msp Identities$SerializedIdentity]
            [com.google.protobuf ByteString Timestamp]))

-;;;
-;;; Low level functions
-;;;
-
 (defn make-chaincode-id
   ([name]
    (make-chaincode-id name {}))
@@ -194,10 +190,6 @@
        (.setExtension extension)
        (.build))))

-;;;
-;;; User level functions
-;;;
-
 (defn make-proposal-payload [chaincode-id fcn args]
   (assert (vector? args))
   ;; FIXME: From Java comment


Fixed variable POST support.

Fixed variable POST support.

--- src/cmr/opendap/ous/variable.clj
+++ src/cmr/opendap/ous/variable.clj
@@ -215,27 +215,24 @@
   variables, if params does not contain any."
   [search-endpoint user-token {variable-ids :variables}]
   (if (seq variable-ids)
-    (let [url (str search-endpoint "/variables"
-              "?"
-              (build-query variable-ids))
-          ;payload (build-query variable-ids)
-          ]
-      ;(log/debug "Variables query to CMR:" payload)
-      (log/debug "Variables query to CMR:" url)
-      (request/async-get
+    (let [url (str search-endpoint "/variables")
+          payload (build-query variable-ids)]
+      (log/debug "Variables query CMR URL:" url)
+      (log/debug "Variables query CMR payload:" payload)
+      (request/async-post
        url
        (-> {}
            (request/add-token-header user-token)
            (request/add-accept "application/vnd.nasa.cmr.umm+json")
-           ;(request/add-payload payload)
-           )
+           (request/add-form-ct)
+           (request/add-payload payload))
        response/json-handler))
     (deliver (promise) [])))

 (defn extract-metadata
   [promise]
   (let [results @promise]
-    (log/warn "Got results from CMR variable search:" results)
+    (log/debug "Got results from CMR variable search:" results)
     ;; XXX Error handling is not fully centralized yet ... this
     ;;     will change when it has been:
     (if (errors/erred? results)


Add some helper functions to utils.clj

Add some helper functions to utils.clj

--- contrib/mr-kluj/src/main/clj/com/linkedin/mr_kluj/utils.clj
+++ contrib/mr-kluj/src/main/clj/com/linkedin/mr_kluj/utils.clj
@@ -29,4 +29,80 @@
               (let [[field-name default-value] field-spec]
                 (fn [in-map] [field-name (get in-map field-name default-value)]))))
           fields)]
-    (fn [in-map] (into {} (map #(% in-map) selection-fns)))))+    (fn [in-map] (into {} (map #(% in-map) selection-fns)))))
+
+(defn- aselect
+  "Selects indexes out of an array.
+
+   indexes is a sequence of indexes (0, 1, 2, etc.)
+   returns a vector of the indexes pulled out of the array"
+  [indexes]
+  (fn [arg]
+    (vec (map (fn [index] (when (< index (alength arg)) (aget arg index))) indexes))))
+
+(defn cut
+  "Creates a function that takes a String as input, splits the string according to the
+   delimiter and then selects the specified indexes.  Similar to the UNIX cut command,
+   except indexes start from 0:
+
+   cut -f 1,2 -> (cut [0 1])
+   cut -d ',' -f 6,8 -> (cut \",\" [5 7])
+
+   indexes is a list of integer indexes.
+   delimiter is the delimiter of the split (defaults to tab)"
+  ([indexes]
+     (cut "\t" indexes))
+  ([delimiter indexes]
+     (let [select-fn (aselect indexes)]
+       (fn [arg]
+	 (select-fn (.split #^java.lang.String arg delimiter))))))
+
+(defn assoc-fn
+  "Applies a function to multiple indices of a vector, replacing those indices with the
+   output of the function.
+
+   ((assoc-fn #(* % 2) 1) [0 5 10 15 20 25 30]) -> [0 10 10 15 20 25 30]
+   ((assoc-fn #(* % 2) [1 2 5]) [0 5 10 15 20 25 30]) -> [0 10 20 15 20 50 30]
+
+   the-fn is the function to apply
+   index is either a single index or a collection of indexes that specify what should be replaced"
+  [the-fn index]
+  (if (coll? index)
+    (apply comp (map (partial assoc-fn the-fn) index))
+    (fn [arg] (assoc arg index (the-fn (arg index))))))
+
+(defn uniq
+  "Returns the unique elements of a sequence.  The comparison is done based on the equality of the
+   return value of key-fn.  This operates very similarly to the UNIX uniq command in that for a true
+   unique set, it requires things be pre-sorted.
+
+   (uniq identity [1 1 1 1 2 2 2 2 1 2 2 3 3 3 3]) -> [1 2 1 2 3]
+
+   key-fn is a function that returns a key for testing equality
+   sequence is a sequence of things to produce the unique values of"
+  ([key-fn sequence] (let [first-val (first sequence)] (uniq (key-fn first-val) first-val key-fn (rest sequence))))
+  ([key value key-fn sequence]
+     (if (empty? sequence)
+       [key]
+       (let [first-val (first sequence)
+	     first-key (key-fn first-val)]
+	 (if (= first-key key)
+	   (recur key value key-fn (rest sequence))
+	   (lazy-seq (cons value (uniq first-key first-val key-fn (rest sequence)))))))))
+
+(defn with-count
+  "Wraps the sequence such that it will print out status text after each mod-operand elements
+   have been read.  This is basically useful when processing large files and you want status
+   messages to ensure that stuff is actually happening.  This is lazy, so it will not traverse
+   any elements on its own, a reduce/doseq/etc. call is required to make anything actually
+   happen."
+  ([mod-operand coll] (with-count mod-operand 0 (java.lang.System/currentTimeMillis) coll))
+  ([mod-operand count startMillis coll]
+     (if (empty? coll)
+       nil
+       (let [mod-eq-0 (= (mod count mod-operand) 0)
+	     workingMillis (if mod-eq-0 (java.lang.System/currentTimeMillis) startMillis)]
+	 (do (when mod-eq-0  (println (format "%s millis, %sth line" (- workingMillis startMillis) count)))
+	     (lazy-seq
+	      (cons (first coll)
+		    (with-count mod-operand (inc count) workingMillis (rest coll)))))))))


Include `text/event-stream` in list of gzip exclude mime types

--- src/puppetlabs/trapperkeeper/services/webserver/jetty9_core.clj
+++ src/puppetlabs/trapperkeeper/services/webserver/jetty9_core.clj
@@ -107,6 +107,7 @@
     (.setPort (options :port 80))
     (.setHost (options :host "localhost"))))

+;; TODO: make all of this gzip-mime-type stuff configurable
 (defn- gzip-excluded-mime-types
   "Build up a list of mime types that should not be candidates for
   gzip compression in responses."
@@ -120,7 +121,7 @@
                  (.startsWith % "audio/")
                  (.startsWith % "video/"))
             (MimeTypes/getKnownMimeTypes))
-    (conj "application/compress" "application/zip" "application/gzip")
+    (conj "application/compress" "application/zip" "application/gzip" "text/event-stream")
     (HashSet.)))

 (defn- gzip-handler


Update block/list docstrings to reflect sorting order.

--- src/blocks/core.clj
+++ src/blocks/core.clj
@@ -183,7 +183,8 @@
   (-list
     [store opts]
     "Lists the blocks contained in the store. Returns a lazy sequence of stat
-    metadata about each block. See `list` for the supported options.")
+    metadata about each block. The stats should be returned in order sorted by
+    multihash id. See `list` for the supported options.")

   (-get
     [store id]
@@ -209,9 +210,9 @@

 (defn list
-  "Enumerates the stored blocks, returning a lazy sequence of block stats.
-  Iterating over the list may result in additional operations to read from the
-  backing data store.
+  "Enumerates the stored blocks, returning a lazy sequence of block stats sorted
+  by id. Iterating over the list may result in additional operations to read
+  from the backing data store.

   - `:algorithm`  only return blocks using this hash algorithm
   - `:after`      list blocks whose id (in hex) lexically follows this string


Rotation + shift mode. Thanks to Jake Wisdom

--- src/brevis/core.clj
+++ src/brevis/core.clj
@@ -24,13 +24,18 @@
   [state]
   (app/title! "brevis")
   (app/vsync! true)
-  (app/key-repeat! false)
+  ;(app/key-repeat! true)
   (enable :blend)
   (enable :depth-test)
   (init-box-graphic)
   (enable :lighting)
   (enable :light0)
   (blend-func :src-alpha :one-minus-src-alpha))
+
+
+(def shift-key-down (atom false))
+(defn sin [n] (float (Math/sin n)))
+(defn cos [n] (float (Math/cos n)))

 (defn reshape
   "Reshape after the window is resized."
@@ -49,11 +54,11 @@
   "Display the world."
   [[dt time] state]
   (text/write-to-screen (str (int (/ 1 dt)) " fps") 0 0)
-  (text/write-to-screen (str (:simulation-time state) " time") 0 30)
-  (text/write-to-screen (str "Rotation [active " (:rotate-mode state) "]: ("
+  (text/write-to-screen (str (float (:simulation-time state)) " time") 0 30)
+  (text/write-to-screen (str "Rotation: ("
                              (:rot-x state) "," (:rot-y state) "," (:rot-z state) ")") 0 60)
-  (text/write-to-screen (str "Translation [active " (:translate-mode state) "]: ("
-                             (:shift-x state) "," (:shift-y state) "," (:shift-z state) ")") 0 90)
+  (text/write-to-screen (str "Translation: ("
+                             (int (:shift-x state)) "," (int (:shift-y state)) "," (int (:shift-z state)) ")") 0 90)
   (rotate (:rot-x state) 1 0 0)
   (rotate (:rot-y state) 0 1 0)
   (rotate (:rot-z state) 0 0 1)
@@ -73,9 +78,8 @@
 	file (File. filename)]
     (ImageIO/write capture img-type file)))

-;; ## Input handling
-
-(defn mouse-drag
+
+#_(defn mouse-drag
   "Perform the respective action given a mouse click and displacement."
   [[dx dy] _ button state]
   (let [displacement dx];(math/sqrt (+ (* dx dx) (* dy dy)))]
@@ -94,11 +98,105 @@
                (= (:translate-mode state) :x) {:shift-x (+ (:shift-x state) displacement)}
                (= (:translate-mode state) :y) {:shift-y (+ (:shift-y state) displacement)}
                (= (:translate-mode state) :z) {:shift-z (+ (:shift-z state) displacement)})))))
-
+
 (defn key-press
   "Update the state in response to a keypress."
   [key state]
   (cond
+    (= :lshift key) (reset! shift-key-down true)
+    (= "p" key) (do (app/pause!)
+                  state)
+    (= "o" key) (do (screenshot (str "brevis_screenshot_" (System/currentTimeMillis) ".png"))
+                  state)
+    (= :escape key)
+    (do (app/stop!)
+      (assoc state
+             :terminated? true)
+      ))
+  (println @shift-key-down))
+
+(defn key-release
+  "Update the state in response to the release of a key"
+  [key state]
+  (cond
+    (= :lshift key) (reset! shift-key-down false)))
+
+;; ## Input handling
+(defn mouse-drag
+  "Rotate the world."
+  [[dx dy] _ button state]
+  (def rads (/ (Math/PI) 180))
+  (def thetaY (*(:rot-y state) rads))
+  (def sY (sin thetaY))
+  (def cY (cos thetaY))
+  (def thetaX (* (:rot-x state) rads))
+  (def sX (sin thetaX))
+  (def cX (cos thetaX))
+
+  (if @shift-key-down
+    (cond
+      ; Rotate
+      (= :left button)
+      (assoc state
+             :rot-x (+ (:rot-x state) dy)
+             :rot-y (+ (:rot-y state) dx))
+      (= :center button)
+      (assoc state
+             :shift-x (+ (:shift-x state) (* dx cY))
+             :shift-y (- (:shift-y state) (* dy cX))
+             :shift-z (+ (:shift-z state) (* dx sY))
+             )
+      ; Zoom
+      (= :right button)
+      (assoc state
+             :shift-x (+ (:shift-x state) (* (/ dy 6) (* sY -1)))
+             :shift-y (+ (:shift-y state) (* (/ dy 6) sX))
+             :shift-z (+ (:shift-z state) (* (/ dy 6) cY))
+             ))))
+
+
+(defn mouse-wheel
+  "Respond to a mousewheel movement. dw is +/- depending on scroll-up or down."
+  [dw state]
+  (def rads (/ (Math/PI) 180))
+  (def thetaY (*(:rot-y state) rads))
+  (def sY (sin thetaY))
+  (def cY (cos thetaY))
+  (def thetaX (* (:rot-x state) rads))
+  (def sX (sin thetaX))
+  (def cX (cos thetaX))
+
+  (assoc state
+         :shift-z (+ (:shift-z state) (* (/ dw 6) cY))
+         :shift-x (+ (:shift-x state) (* (/ dw 6) (* sY -1)))
+         :shift-y (+ (:shift-y state) (* (/ dw 6) sX))
+         ))
+
+
+
+#_(defn turnAround
+  [rot-x ]
+  (if (or (= rot-x 90) (= rot-x -90))
+    ;z translation to be 0
+    )
+  (if (= rot-x 180)
+    ;z translation goes negative
+    )
+  (if (or (= rot-y 90) (= rot-y -90))
+    ;z translation to be 0
+    )
+  (if (= rot-x 180)
+    ;z translation goes negative
+    )
+  )
+
+
+
+#_(defn key-press
+  "Update the state in response to a keypress."
+  [key state]
+  (cond
+
    (= "q" key) (assoc state
                       :rotate-mode :x)
    (= "w" key) (assoc state
@@ -171,18 +269,14 @@
   #_(println button)
   state)

-(defn mouse-wheel
-  "Respond to a mousewheel movement. dw is +/- depending on scroll-up or down."
-  [dw state]
-  #_(println dw)
-  state)

 ;; ## Start a brevis instance

 (defn start-gui [initialize update]
   "Start the simulation with a GUI."
   (app/start
-   {:reshape reshape, :init init, :mouse-drag mouse-drag, :key-press key-press, :update update, :display display
+   {:reshape reshape, :init init, :mouse-drag mouse-drag, :key-press key-press :mouse-wheel mouse-wheel, :update update, :display display
+    :key-release key-release
     ;:mouse-move    (fn [[[dx dy] [x y]] state] (println )
     ;:mouse-up       (fn [[x y] button state] (println button) state)
     ;:mouse-click   (fn [[x y] button state] (println button) state)
@@ -196,6 +290,7 @@
            :dt 1 :last-report-time 0 :simulation-time 0}
           (initialize))))

+
 #_(defn start-nogui [iteration-step-size]
   (let [dt iteration-step-size
         max-t 25]


invoke

invoke

--- src/leiningen/new/re_frame_7theta/src/events.cljs
+++ src/leiningen/new/re_frame_7theta/src/events.cljs
@@ -18,7 +18,7 @@
 (reg-event-fx
  :application/login
  (fn [{:keys [db]} _]
-   {:via/dispatch
+   {:via/invoke
     {:event [:via.auth/id-password-login {:id "admin" :password "admin"}]
      :on-success [:application.login/succeeded]
      :on-failure [:application.login/failed]
@@ -27,7 +27,7 @@
 (reg-event-fx
  :application.login/succeeded
  (fn [{:keys [db]} [_ login-creds]]
-   {:db (assoc db :authenticated login-creds)}))
+   {:db (assoc db :authenticated (:body login-creds))}))

 (reg-event-db
  :application.login/failed


remove multimethod for text?

remove multimethod for text?

--- src/crison/core.clj
+++ src/crison/core.clj
@@ -55,8 +55,6 @@

 (defmethod decode :title [x] (title? (:title x)))

-(defmethod decode :text? [x] (text? x))
-
 (defmethod decode :default [x] (? x))

 (defn take-screenshot


Tweaked data formatting.

Tweaked data formatting.

--- src/dragon/util.clj
+++ src/dragon/util.clj
@@ -6,7 +6,8 @@
             [trifl.fs :as fs]))

 (def post-regex #"posts/(\d{4})-(\d{2})/(\d{2})-(\d{2})(\d{2})(\d{2})/.*")
-(def date-format ":year-:month-:day :hour::minute::second")
+(def timestamp-format ":year-:month-:day :hour::minute::second")
+(def datestamp-format ":year-:month-:day")

 (defn get-build
   []
@@ -38,12 +39,20 @@
     :all))

 (defn format-date
-  [date-map]
+  [date-map formater]
   (reduce
     (fn [acc [k v]]
       (string/replace acc (str k) v))
-    date-format
+    formater
     date-map))
+
+(defn format-timestamp
+  [date-map]
+  (format-date date-map timestamp-format))
+
+(defn format-datestamp
+  [date-map]
+  (format-date date-map datestamp-format))

 (defn sanitize-str
   [str]
@@ -84,3 +93,7 @@
   (-> month
       (month->name)
       (subs 0 3)))
+
+(defn dots->dashes
+  [str]
+  (string/replace str #"\." "-"))


Fixed sidebar/command.cljs warnings

Fixed sidebar/command.cljs warnings

--- src/lt/objs/sidebar/command.cljs
+++ src/lt/objs/sidebar/command.cljs
@@ -90,14 +90,6 @@
   (set-val this v)
   (object/raise this :change! v))

-(defn current-selected [this]
-  (let [cur (indexed-results @this)
-        cnt (count cur)
-        idx (:selected @this)
-        i (mod idx (if (> cnt (:size @this)) (:size @this) cnt))]
-    (when (> cnt 0)
-      (aget (aget cur i) 0))))
-
 (defn ensure-visible [this]
   (let [list (dom/$ "ul" (object/->content this))
         elem (dom/$ ".selected" list)]
@@ -107,6 +99,33 @@
         (+ (.-scrollTop list) (.-clientHeight list))) (set! (.-scrollTop list)
                                                             (- (+ (.-offsetTop elem) (.-offsetHeight elem) 15) (.-clientHeight list)))
      :else nil)))
+
+(defn fill-lis [{:keys [lis size search selected key transform] :as this} results]
+  (let [cnt (count results)
+        cur (mod selected (if (> cnt size)
+                            size
+                            cnt))
+        transform (if transform
+                    transform
+                    #(do %3))]
+    (if (= cnt 0)
+      (dom/add-class (:content this) :empty)
+      (dom/remove-class (:content this) :empty))
+    (doseq [[i li res] (map vector (range) lis results)
+            :when res]
+      (dom/html li (transform (aget res 1) (aget res 4) (if-not (empty? search)
+
+                                                          (js/wrapMatch (aget res 1) (aget res 4))
+                                                          (aget res 1))
+                              (aget res 0)))
+      (dom/css li {:display "block"})
+      (if (= i cur)
+        (dom/add-class li :selected)
+        (dom/remove-class li :selected)))
+    (doseq [li (drop cnt lis)]
+      (dom/css li {:display "none"}))))
+
+(declare sidebar-command indexed-results)

 (behavior ::move-selection
           :triggers #{:move-selection}
@@ -144,13 +163,13 @@
           :triggers #{:escape!}
           :reaction (fn [this]
                       (object/raise this :inactive)
-                      (exec! :close-sidebar)))
+                      (cmd/exec! :close-sidebar)))

 (behavior ::options-escape!
           :triggers #{:escape!}
           :reaction (fn [this]
                       (object/raise sidebar-command :cancel!)
-                      (exec! :close-sidebar)))
+                      (cmd/exec! :close-sidebar)))

 (behavior ::set-on-select
           :triggers #{:select}
@@ -240,7 +259,13 @@
         score2)
       (.. items (map #(array % (key %) nil nil))))))

-
+(defn current-selected [this]
+  (let [cur (indexed-results @this)
+        cnt (count cur)
+        idx (:selected @this)
+        i (mod idx (if (> cnt (:size @this)) (:size @this) cnt))]
+    (when (> cnt 0)
+      (aget (aget cur i) 0))))

 (defui item [this x]
   [:li {:index x}]
@@ -249,31 +274,6 @@
                (dom/stop-propagation e)
                (object/raise this :set-selection! x)
                (object/raise this :select! x)))
-
-(defn fill-lis [{:keys [lis size search selected key transform] :as this} results]
-  (let [cnt (count results)
-        cur (mod selected (if (> cnt size)
-                            size
-                            cnt))
-        transform (if transform
-                    transform
-                    #(do %3))]
-    (if (= cnt 0)
-      (dom/add-class (:content this) :empty)
-      (dom/remove-class (:content this) :empty))
-    (doseq [[i li res] (map vector (range) lis results)
-            :when res]
-      (dom/html li (transform (aget res 1) (aget res 4) (if-not (empty? search)
-
-                                                          (js/wrapMatch (aget res 1) (aget res 4))
-                                                          (aget res 1))
-                              (aget res 0)))
-      (dom/css li {:display "block"})
-      (if (= i cur)
-        (dom/add-class li :selected)
-        (dom/remove-class li :selected)))
-    (doseq [li (drop cnt lis)]
-      (dom/css li {:display "none"}))))

 (object/object* ::filter-list
                 :tags #{:filter-list}
@@ -305,7 +305,7 @@
 (behavior ::select-command
           :triggers #{:select}
           :reaction (fn [this sel]
-                      (when-let [cmd (by-id sel)]
+                      (when-let [cmd (cmd/by-id sel)]
                         (if (:options cmd)
                           (do
                             (object/merge! sidebar-command {:active cmd})
@@ -320,7 +320,7 @@
 (behavior ::select-hidden
           :triggers #{:select-unknown}
           :reaction (fn [this v]
-                      (when-let [cmd (by-id (keyword v))]
+                      (when-let [cmd (cmd/by-id (keyword v))]
                         (object/raise this :select cmd))))

 (behavior ::post-select-pop
@@ -334,11 +334,11 @@
 (behavior ::exec-command
           :triggers #{:exec!}
           :reaction (fn [this sel & args]
-                      (let [cmd (by-id sel)]
+                      (let [cmd (cmd/by-id sel)]
                         (cond
-                         (not (:options cmd)) (apply exec! cmd args)
+                         (not (:options cmd)) (apply cmd/exec! cmd args)
                          (and (:options cmd) (seq args)) (apply (:exec cmd) args)
-                         :else (do (exec! :show-commandbar-transient)
+                         :else (do (cmd/exec! :show-commandbar-transient)
                                  (object/raise (:selector @this) :select cmd))))))

 (behavior ::exec-active!
@@ -455,10 +455,6 @@
   (object/raise sidebar/rightbar :toggle sidebar-command (assoc opts :soft? true))
   (object/raise sidebar-command :soft-focus!))

-(def by-id cmd/by-id)
-
-(def exec! cmd/exec!)
-
 (defn exec-active! [& args]
   (object/raise sidebar-command :exec-active! args))


Move `quit' somewhere else

Move `quit' somewhere else

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

--- src/main/clojure/conexp/base.clj
+++ src/main/clojure/conexp/base.clj
@@ -56,14 +56,6 @@

 (immigrate 'clojure.set
            'clojure.math.numeric-tower)
-
-
-;;; Java stuff
-
-(defn quit
-  "Quits conexp-clj."
-  []
-  (System/exit 0))

 ;;; Version

@@ -170,6 +162,11 @@

 ;;; Technical Helpers
+
+(defn quit
+  "Quits conexp-clj."
+  []
+  (System/exit 0))

 (defmacro defmacro-                     ; from clojure.core.incubator
   "Same as defmacro but yields a private definition"


Change timeout to 250 ms

Change timeout to 250 ms

--- src/gol/client.cljs
+++ src/gol/client.cljs
@@ -52,7 +52,7 @@
     (reify
       om/IInitState
       (init-state [_]
-        {:timeout {:current 100}
+        {:timeout {:current 250}
          :board   {:width  50
                    :height 50}
          :stop    false})


Formatting

Formatting

--- src/icecap/rest.clj
+++ src/icecap/rest.clj
@@ -19,28 +19,28 @@

 (defroutes routes
   (context "/v0/caps" {store :store kdf :kdf scheme :scheme}
-           (POST "/" {plan :body-params :as request}
-                 (info request)
-                 (let [{cap :cap error :error}
-                       (spy (<!! (create-cap (spy plan)
-                                             :store store
-                                             :kdf kdf
-                                             :scheme scheme)))]
-                   {:body (if cap
-                            (cap-url request cap)
-                            (str error))}))
-           (context "/:encoded-cap" [encoded-cap]
-                    (GET "/" request
-                         (let [cap (spy (safebase64-decode encoded-cap))]
-                           (spy (<!! (execute-cap cap
-                                                  :store store
-                                                  :kdf kdf
-                                                  :scheme scheme)))))
-                    (DELETE "/" request
-                            (let [cap (spy (safebase64-decode encoded-cap))]
-                              (spy (<!! (revoke-cap cap
-                                                    :store store
-                                                    :kdf kdf))))))))
+    (POST "/" {plan :body-params :as request}
+      (info request)
+      (let [{cap :cap error :error}
+            (spy (<!! (create-cap (spy plan)
+                                  :store store
+                                  :kdf kdf
+                                  :scheme scheme)))]
+        {:body (if cap
+                 (cap-url request cap)
+                 (str error))}))
+    (context "/:encoded-cap" [encoded-cap]
+      (GET "/" request
+        (let [cap (spy (safebase64-decode encoded-cap))]
+          (spy (<!! (execute-cap cap
+                                 :store store
+                                 :kdf kdf
+                                 :scheme scheme)))))
+      (DELETE "/" request
+        (let [cap (spy (safebase64-decode encoded-cap))]
+          (spy (<!! (revoke-cap cap
+                                :store store
+                                :kdf kdf))))))))

 (defn ^:private wrap-components
   "Adds some components to each request map."


Rewrite and add docs to load-parses-and-layouts.

--- src/incise/core.clj
+++ src/incise/core.clj
@@ -10,14 +10,20 @@
   #{'incise.parsers.core
     'incise.layouts.core})

-(defn namespace-is-layout-or-parser [namespace-sym]
-  (and (not (contains? core-namespace-symbols namespace-sym))
-       (re-find #"incise\.(layouts|parsers)\..+" (str namespace-sym))))
+(defn namespace-is-layout-or-parser?
+  "Predicate to determine if the given symbol is a namespace for a layout or
+   parser. It would be a namespace under incise.layouts or incise.parsers."
+  [namespace-sym]
+  (re-find #"incise\.(layouts|parsers)\..+" (str namespace-sym)))

-(defn load-parsers-and-layouts []
-  (doseq [ns-sym (filter namespace-is-layout-or-parser
-                         (ns-tools/find-namespaces (classpath)))]
-    (require ns-sym)))
+(defn load-parsers-and-layouts
+  "Require with reload all namespaces under incise.layouts and incise.parsers."
+  []
+  (doseq [ns-sym (->> (classpath)
+                      (ns-tools/find-namespaces)
+                      (remove (partial contains? core-namespace-symbols))
+                      (filter namespace-is-layout-or-parser?)) ]
+    (require :reload ns-sym)))

 (load-parsers-and-layouts)


Fix failing clojure.spec test

Fix failing clojure.spec test

--- test/com/nomistech/clojure_the_language/c_200_clojure_basics/s_600_clojure_spec/ss_examples_from_clojure_org.clj
+++ test/com/nomistech/clojure_the_language/c_200_clojure_basics/s_600_clojure_spec/ss_examples_from_clojure_org.clj
@@ -131,89 +131,24 @@
       ::s/spec ::suit
       ::s/value 42})

-
-;;;; Temp notes on functions in Midje
-(fact [clojure.core/string?] => (just [(exactly clojure.core/string?)]))
-(fact {:a clojure.core/string?} => (just {:a (exactly clojure.core/string?)}))
-
-(fact {:a {:b clojure.core/string?}}
-  => (just {:a (just {:b (exactly clojure.core/string?)})}))
-
-;; (s/explain-data ::name-or-id :foo)
-;; =>
-;; #:clojure.spec.alpha{:problems [{:path [:name]
-;;                                  :pred clojure.core/string?
-;;                                  :val :foo
-;;                                  :via [::name-or-id]
-;;                                  :in []}
-;;                                 {:path [:id]
-;;                                  :pred clojure.core/int?
-;;                                  :val :foo
-;;                                  :via [::name-or-id]
-;;                                  :in []}]
-;;                      :spec ::name-or-id
-;;                      :value :foo}
-
-(fact (s/explain-data ::name-or-id :foo)
-  =>
-  (just
-   {::s/problems (just
-                  [(just
-                    {:path [:name]
-                     ;; FIXME What's wrong here? (See temp notes above.)
-                     ;; :pred (exactly string?)
-                     :pred anything
-                     :val :foo
-                     :via [::name-or-id]
-                     :in []})
-                   (just
-                    {:path [:id]
-                     ;; FIXME What's wrong here? (See temp notes above.)
-                     ;; :pred (exactly int?)
-                     :pred anything
-                     :val :foo
-                     :via [::name-or-id]
-                     :in []})])
-    ::s/spec ::name-or-id
-    ::s/value :foo}))
-
-(fact (case 3
-        1 (s/explain-data ::name-or-id :foo)
-        2 {::s/problems [{:path [:name]
-                          :pred string?
-                          :val :foo
-                          :via [::name-or-id]
-                          :in []}]
-           ::s/spec ::name-or-id
-           ::s/value :foo}
-        3 (just
-           #:clojure.spec.alpha{:problems
-                                [{:path [:name]
-                                  :pred clojure.core/string?
-                                  :val :foo
-                                  :via
-                                  [:com.nomistech.clojure-the-language.c-200-clojure-basics.s-600-clojure-spec.ss-examples-from-clojure-org/name-or-id]
-                                  :in []}
-                                 {:path [:id]
-                                  :pred clojure.core/int?
-                                  :val :foo
-                                  :via
-                                  [:com.nomistech.clojure-the-language.c-200-clojure-basics.s-600-clojure-spec.ss-examples-from-clojure-org/name-or-id]
-                                  :in []}]
-                                :spec
-                                :com.nomistech.clojure-the-language.c-200-clojure-basics.s-600-clojure-spec.ss-examples-from-clojure-org/name-or-id
-                                :value :foo}))
-  =>
-  (just
-   {::s/problems (just
-                  [(just
-                    {:path [:name]
-                     :pred (exactly string?)
-                     :val :foo
-                     :via [::name-or-id]
-                     :in []})])
-    ::s/spec ::name-or-id
-    ::s/value :foo}))
+(fact
+  (s/explain-data ::name-or-id :foo)
+  => (just
+      {::s/problems (just
+                     [(just
+                       {:path [:name]
+                        :pred 'clojure.core/string?
+                        :val :foo
+                        :via [::name-or-id]
+                        :in []})
+                      (just
+                       {:path [:id]
+                        :pred 'clojure.core/int?
+                        :val :foo
+                        :via [::name-or-id]
+                        :in []})])
+       ::s/spec ::name-or-id
+       ::s/value :foo}))

 ;;;; ___________________________________________________________________________
 ;;;; TODO When you have finished going through https://clojure.org/guides/spec


Is this call returning anything?

Is this call returning anything?

--- src/korhal/core.clj
+++ src/korhal/core.clj
@@ -54,6 +54,7 @@

   ;; spawn a drone
   (for [unit (.getMyUnits (:api @this))]
+    (println unit)
     (when (= (.getTypeID unit) (.getID jnibwapi.types.UnitType$UnitTypes/Zerg_Larva))
       (when (and (>= (.. (:api @this) getSelf getMinerals) 50) (not (:morphed-drone this)))
         (println "morphing a drone")


Fix js promises example in the book

Fix js promises example in the book

--- src-docs/com/wsscode/pathom/book/async/js_promises.cljs
+++ src-docs/com/wsscode/pathom/book/async/js_promises.cljs
@@ -1,8 +1,7 @@
 (ns com.wsscode.pathom.book.async.js-promises
   (:require [com.wsscode.common.async-cljs :refer [go-catch <!p]]
-            [goog.object :as gobj]
             [com.wsscode.pathom.core :as p]
-            [com.wsscode.pathom.profile :as pp]))
+            [goog.object :as gobj]))

 (def reader
   {:dog.ceo/random-dog-url
@@ -15,4 +14,4 @@
 (def parser
   (p/async-parser {::p/plugins [(p/env-plugin {::p/reader reader})
                                 p/error-handler-plugin
-                                pp/profile-plugin]}))
+                                p/trace-plugin]}))


Ingress queues will always be a map now.

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -270,7 +270,6 @@
           task (:task/name (:task payload))
           catalog (extensions/read-node sync (:node/catalog (:nodes payload)))
           ingress-queues (:task/ingress-queues (:task payload))
-          ingress-queues (if-not (coll? ingress-queues) (vector ingress-queues) ingress-queues)

           pipeline-data {:onyx.core/id id
                          :onyx.core/task task


equal lib passes

equal lib passes

--- src/latte/equal.clj
+++ src/latte/equal.clj
@@ -201,63 +201,16 @@
     (assume [H3 (Q (f y))]
       (have <c1> _ :by (eq-subst% T (lambda [z T] (Q (f z))) y x))
       (have <c> (Q (f x)) :by (<c1> <b> H3)))
-    (have <d> (<=> (Q (f x)) (Q (f y))) :by ((p/iff-intro <a>) <c>)))
+    (have <d> (<=> (Q (f x)) (Q (f y))) :by (p/iff-intro <a> <c>)))
   (qed <d>))

-(defspecial eq-cong%
-  "Congruence of `equal`, a special version of [[eq-cong]]."
-  [def-env ctx f eq-term]
-  (let [[status eq-ty] (ty/type-of-term def-env ctx eq-term)]
-    (when (= status :ko)
-      (throw (ex-info "Cannot type term." {:special 'latte.prop/eq-cong%
-                                           :term eq-term
-                                           :from eq-ty})))
-    (let [[status T x y] (decompose-equal-type def-env ctx eq-ty)]
-      (when (= status :ko)
-        (throw (ex-info "Cannot infer an `equal`-type." {:special 'latte.prop/eq-cong%
-                                                         :term eq-term
-                                                         :type eq-ty})))
-      (let [[status f-ty] (ty/type-of-term def-env ctx f)]
-        (when (= status :ko)
-          (throw (ex-info "Cannot type term." {:special 'latte.prop/eq-cong%
-                                               :term f
-                                               :from f-ty})))
-        (let [[status T' U] (p/decompose-impl-type def-env ctx f-ty)]
-          (when (= status :ko)
-            (throw (ex-info "Cannot infer an `==>`-type." {:special 'latte.prop/eq-cong%
-                                                           :term f
-                                                           :type f-ty})))
-          [(list #'eq-cong T U f x y) eq-term])))))
-
-(defthm eq-impl
-  [[T :type] [P (==> T :type)] [x T] [y T]]
-  (==> (equal T x y)
-       (P x)
-       (P y)))
-
-(proof eq-impl
-    :script
-  (assume [H1 (equal T x y)
-           H2 (P x)]
-    (have <a> (<=> (P x) (P y))
-          :by (H1 P))
-    (have <b> (==> (P x) (P y))
-          :by (p/and-elim-left% <a>))
-    (have <c> (P y) :by (<b> H2))
-    (qed <c>)))
-
-(defthm eq-impl-sym
-  [[T :type] [P (==> T :type)] [x T] [y T]]
-  (==> (equal T x y)
-       (P y)
-       (P x)))
-
-(proof eq-impl-sym
-    :script
-  (assume [H1 (equal T x y)
-           H2 (P y)]
-    (have <a> (equal T y x) :by (eq-sym% H1))
-    (have <b> (P x) :by ((eq-impl T P y x) <a> H2))
-    (qed <b>)))
-
-
+(defimplicit eq-cong
+  "Congruence of `equal`, an implicit version of [[eq-cong]]."
+  [def-env ctx [f f-ty] [eq-term eq-ty]]
+  (let [[T x y] (decompose-equal-type def-env ctx eq-ty)
+        [T' U] (p/decompose-impl-type def-env ctx f-ty)]
+    [(list #'eq-cong% T U f x y) eq-term]))
+
+
+
+


(SERVER-1630) Only append classpath:/ to default ruby-code-dir for 9k

Previously, the Ruby load path segment for the Puppet Server's Ruby code
was changed to include a prefix of "classpath:/" so that the code could
be found properly when run under JRuby 9k.  Under JRuby 1.7, however,
including the "classpath:/" prefix broke the puppetserver irb
subcommand.

With this commit, the "classpath:/" prefix is only appended when not
running under JRuby 1.x, compatible with the approach we've used
previously for JRuby 1.7 in Puppet Server while allowing code to load
properly under JRuby 9k.

--- src/clj/puppetlabs/services/jruby/jruby_puppet_core.clj
+++ src/clj/puppetlabs/services/jruby/jruby_puppet_core.clj
@@ -15,7 +15,8 @@
   (:import (com.puppetlabs.puppetserver PuppetProfiler JRubyPuppet)
            (clojure.lang IFn)
            (java.util HashMap)
-           (com.codahale.metrics MetricRegistry)))
+           (com.codahale.metrics MetricRegistry)
+           (org.jruby.runtime Constants)))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Constants
@@ -31,7 +32,19 @@
   classpath.

   See also:  http://jruby.org/apidocs/org/jruby/runtime/load/LoadService.html"
-  "classpath:/puppetserver-lib")
+  (let [jruby-version Constants/VERSION]
+    (if (< (count jruby-version) 2)
+      (throw (Exception. (str "Unexpected jruby-version format: " jruby-version)))
+      ;; Under JRuby 9k (and presumably later JRuby versions as well), JRuby
+      ;; will fail to find resources from the classpath unless they are prefixed
+      ;; with "classpath:/".  JRuby 1.x will generally find resources when
+      ;; prefixed with "classpath:/" as well, but an invocation of JRuby's irb
+      ;; will error out with "java.lang.NullPointerException: 'in' is null"
+      ;; when the "classpath:/" prefix is included.  The code below ensures
+      ;; that the "classpath:/" prefix is only omitted for JRuby 1.x.
+      (str (if (not= "1." (subs jruby-version 0 2))
+             "classpath:/")
+           "puppetserver-lib"))))

 (def default-http-connect-timeout
   "The default number of milliseconds that the client will wait for a connection


Hot Water Systems.

Hot Water Systems.

--- src-cljs/kixi/hecuba/tabs/profiles.cljs
+++ src-cljs/kixi/hecuba/tabs/profiles.cljs
@@ -416,7 +416,8 @@
                (for [c conservatories]
                  (bs/panel
                   "Conservtory"
-                  [(text-control c state owner :conservatory_type "Conservatory Type")
+                  [:div
+                   (text-control c state owner :conservatory_type "Conservatory Type")
                    (text-control c state owner :area "Area")
                    (text-control c state owner :double_glazed "Double Glazed")
                    (text-control c state owner :glazed_perimeter "Glazed Perimeter")
@@ -438,7 +439,8 @@
                (for [item extensions]
                  (bs/panel
                   "Extension"
-                  [(text-control item state owner :age ":age")
+                  [:div
+                   (text-control item state owner :age ":age")
                    (text-control item state owner :construction_date ":construction_date")]))]
               [:p "No extensions."]))])]))))

@@ -457,7 +459,8 @@
                (for [item heating-systems]
                  (bs/panel
                   "Heating System"
-                  [(text-control item state owner :heating_type "Heating Type")
+                  [:div
+                   (text-control item state owner :heating_type "Heating Type")
                    (text-control item state owner :heat_source "Heat Source")
                    (text-control item state owner :heat_transport "Heat Transport")
                    (text-control item state owner :heat_delivery "Heat Delivery")
@@ -493,6 +496,36 @@
                    (text-control item state owner :efficiency "Efficiency")]))]
               [:p "No heating systems."]))])]))))

+(defn hot-water-systems-row [profiles owner]
+  (reify
+    om/IRenderState
+    (render-state [_ state]
+      (html
+       [:div.col-md-12
+        (for [profile profiles]
+          [:div {:class (profile-column-width)}
+           (bs/panel
+            "Hot Water Systems"
+            (if-let [hot-water-systems (seq (:hot-water-systems profile))]
+              [:div {:class (profile-column-width)}
+               (for [item hot-water-systems]
+                 (bs/panel
+                  "Hot Water System"
+                  [:div
+                   (text-control item state owner :dhw_type "DHW Type")
+                   (text-control item state owner :fuel "Fuel")
+                   (text-control item state owner :fuel_other "Fuel Other")
+                   (text-control item state owner :immersion "Immersion")
+                   (text-control item state owner :cylinder_capacity "Cylinder Capacity")
+                   (text-control item state owner :cylinder_capacity_other "Cylinder Capacity Other")
+                   (text-control item state owner :cylinder_insulation_type "Cylinder Insulation Type")
+                   (text-control item state owner :cylinder_insulation_type_other "Cylinder Insulation Type Other")
+                   (text-control item state owner :cylinder_insulation_thickness "Cylinder Insulation Thickness")
+                   (text-control item state owner :cylinder_insulation_thickness_other "Cylinder Insulation Thickness Other")
+                   (text-control item state owner :cylinder_thermostat "Cylinder Thermostat")
+                   (text-control item state owner :controls_same_for_all_zones "Controls Same For All Zones")]))]
+              [:p "No hot water systems."]))])]))))
+
 (defn profile-rows [profiles owner]
   (reify
     om/IRenderState
@@ -525,7 +558,7 @@
          (om/build conservatories-row profiles)
          (om/build extensions-row profiles)
          (om/build heating-systems-row profiles)
-         ;; (om/build hot-water-systems profiles)
+         (om/build hot-water-systems-row profiles)
          ;; (om/build storeys profiles)
          ;; (om/build walls profiles)
          ;; (om/build roofs profiles)


Optimize parsing podnapisi

Optimize parsing podnapisi

--- src/subman/sources/podnapisi.clj
+++ src/subman/sources/podnapisi.clj
@@ -65,10 +65,10 @@
                     :content
                     first
                     clojure.string/trim)
-          :page-url (-> (download-element item)
-                        :attrs
-                        :href
-                        make-url)
+          :url (-> (download-element item)
+                   :attrs
+                   :href
+                   make-url)
           :season (season-episode-part item 1)
           :episode (season-episode-part item 2)
           :version (-> item
@@ -87,26 +87,17 @@
             ((fn [page] (map #(create-subtitle-map %)
                             page)))))

-(defn- get-download-url
-  "Get subtitle download url"
-  [page-url] (-> (helpers/fetch page-url)
-                 (html/select [:a.download])
-                 first
-                 :attrs
-                 :href
-                 make-url))
-
 (defn get-all-flat
   "Get all subtitles as flat list"
   [] (->> (pmap (fn [lang]
                  (->> (get-lang-letters lang)
-                      (pmap get-pages-urls)
+                      (pmap (helpers/make-safe get-pages-urls nil))
+                      (remove nil?)
                       flatten
-                      (pmap parse-list-page)
+                      (pmap (helpers/make-safe parse-list-page nil))
+                      (remove nil?)
                       flatten
-                      (pmap #(assoc % :lang (:lang lang)
-                          :url (get-download-url (:page-url %))
-                          :source const/type-podnapisi))
-                      (pmap #(dissoc % :page-url))))
+                      (map #(assoc % :lang (:lang lang)
+                          :source const/type-podnapisi))))
                (get-langs))
           flatten))


Remove unused code

Remove unused code

--- src/io/sarnowski/swagger1st/schemas/swagger_2_0.clj
+++ src/io/sarnowski/swagger1st/schemas/swagger_2_0.clj
@@ -13,12 +13,6 @@

 (defn ref? [x]
   (get x "$ref"))
-
-(def primitives
-  {"integer" s-long
-   "number" s-float
-   "string" s-string
-   "boolean" s-boolean})

 ;;; complex types


DRYd out the tests in controls_test a bit

--- test-cljs/frontend/controllers/controls_test.cljs
+++ test-cljs/frontend/controllers/controls_test.cljs
@@ -66,34 +66,35 @@

 (defn failed-event [] "failed")

+(defn check-button-ajax [{:keys [status success-count failed-count]}]
+  (async done
+         (go
+           (bond/with-spy [success-event failed-event]
+             (bond/with-stub [[ajax/ajax (fn [_ _ _ c _] (go (>! c  ["" status ""])))]]
+               (let [channel (chan)]
+                 (controls/button-ajax "a" "b" "c" channel
+                                       :fake "data"
+                                       :events {:success success-event
+                                                :failed failed-event})
+                 (<! channel)
+                 (is (= success-count (-> success-event bond/calls count)))
+                 (is (= failed-count (-> failed-event bond/calls count)))
+                 (done)))))))
+
 (deftest button-ajax-failed-event-works
   (testing "button-ajax correctly sends a failed event on failed"
-    (async done
-           (go
-             (bond/with-spy [success-event failed-event]
-               (bond/with-stub [[ajax/ajax (fn [_ _ _ c _] (go (>! c  ["" :failed ""])))]]
-                 (let [channel (chan)]
-                   (controls/button-ajax "a" "b" "c" channel
-                                         :fake "data"
-                                         :events {:success success-event
-                                                  :failed failed-event})
-                   (<! channel)
-                   (is (= 0 (-> success-event bond/calls count)))
-                   (is (= 1 (-> failed-event bond/calls count)))
-                   (done))))))))
+    (check-button-ajax {:status :success
+                        :success-count 1
+                        :failed-count 0})))

 (deftest button-ajax-success-event-works
   (testing "button-ajax correctly sends a success event on success"
-    (async done
-           (go
-             (bond/with-spy [success-event failed-event]
-               (bond/with-stub [[ajax/ajax (fn [_ _ _ c _] (go (>! c  ["" :success ""])))]]
-                 (let [channel (chan)]
-                   (controls/button-ajax "a" "b" "c" channel
-                                         :fake "data"
-                                         :events {:success success-event
-                                                  :failed failed-event})
-                   (<! channel)
-                   (is (= 1 (-> success-event bond/calls count)))
-                   (is (= 0 (-> failed-event bond/calls count)))
-                   (done))))))))
+    (check-button-ajax {:status :failed
+                        :success-count 0
+                        :failed-count 1})))
+
+(deftest button-ajax-random-status-no-event-fires
+  (testing "a non success or failed event fire no events"
+    (check-button-ajax {:status :foobar
+                        :success-count 0
+                        :failed-count 0})))


Bring pagination tests back

Bring pagination tests back

--- test/clojure/clojurewerkz/cassaforte/cql_test.clj
+++ test/clojure/clojurewerkz/cassaforte/cql_test.clj
@@ -1,6 +1,6 @@
 (ns clojurewerkz.cassaforte.cql-test
   (:refer-clojure :exclude [update])
-  (:require [clojurewerkz.cassaforte.test-helper :as th :refer [*session*]]
+  (:require [clojurewerkz.cassaforte.test-helper :as th :refer [*session* with-table]]
             [clojurewerkz.cassaforte.client      :as client]
             [clojurewerkz.cassaforte.policies    :as cp]
             [clojurewerkz.cassaforte.uuids       :as uuids]
@@ -308,46 +308,6 @@
                  (columns :post_id)
                  (where {:username "Alex"})
                  (order-by (new-query-api/desc :post_id))))))
-
-(deftest test-select-range-query
-  (create-table *session* :tv_series
-                (column-definitions {:series_title  :varchar
-                                     :episode_id    :int
-                                     :episode_title :text
-                                     :primary-key   [:series_title :episode_id]}))
-  (dotimes [i 20]
-    (insert *session* :tv_series
-            {:series_title  "Futurama"
-             :episode_id    i
-             :episode_title (str "Futurama Title " i)})
-    (insert *session* :tv_series
-            {:series_title  "Simpsons"
-             :episode_id    i
-             :episode_title (str "Simpsons Title " i)}))
-
-  (is (= (set (range 11 20))
-         (->> (select *session* :tv_series
-                      (where [[= :series_title "Futurama"]
-                              [> :episode_id 10]]))
-              (map :episode_id )
-              set)))
-
-  (is (= (set (range 11 16))
-         (->> (select *session* :tv_series
-                      (where [[=  :series_title "Futurama"]
-                              [>  :episode_id 10]
-                              [<= :episode_id 15]]))
-              (map :episode_id)
-              set)))
-
-  (is (= (set (range 0 15))
-         (->> (select *session* :tv_series
-                      (where [[= :series_title "Futurama"]
-                              [< :episode_id 15]]))
-              (map :episode_id)
-              set)))
-
-  (drop-table *session* :tv_series))

 (deftest test-timeuuid-now-and-unix-timestamp-of
   (let [dt (-> 2 seconds ago)
@@ -408,30 +368,72 @@
            (set (map :message xs))))))

-;; (deftest test-paginate
-;;   (create-table s :tv_series
-;;                 (column-definitions {:series_title  :varchar
-;;                                      :episode_id    :int
-;;                                      :episode_title :text
-;;                                      :primary-key [:series_title :episode_id]}))
-;;   (dotimes [i 20]
-;;     (insert s :tv_series {:series_title "Futurama" :episode_id i :episode_title (str "Futurama Title " i)})
-;;     (insert s :tv_series {:series_title "Simpsons" :episode_id i :episode_title (str "Simpsons Title " i)}))
-
-
-;;   (is (= (set (range 0 10))
-;;          (->> (select s :tv_series
-;;                       (paginate :key :episode_id :per-page 10 :where {:series_title "Futurama"}))
-;;               (map :episode_id)
-;;               set)))
-
-;;   (is (= (set (range 11 20))
-;;          (->> (select s :tv_series
-;;                       (paginate :key :episode_id :per-page 10 :last-key 10 :where { :series_title "Futurama"}))
-;;               (map :episode_id)
-;;               set)))
-
-;;   (drop-table s :tv_series))
+(deftest test-select-range-query
+  (create-table *session* :tv_series
+                (column-definitions {:series_title  :varchar
+                                     :episode_id    :int
+                                     :episode_title :text
+                                     :primary-key   [:series_title :episode_id]}))
+  (dotimes [i 20]
+    (insert *session* :tv_series
+            {:series_title  "Futurama"
+             :episode_id    i
+             :episode_title (str "Futurama Title " i)})
+    (insert *session* :tv_series
+            {:series_title  "Simpsons"
+             :episode_id    i
+             :episode_title (str "Simpsons Title " i)}))
+
+  (is (= (set (range 11 20))
+         (->> (select *session* :tv_series
+                      (where [[= :series_title "Futurama"]
+                              [> :episode_id 10]]))
+              (map :episode_id )
+              set)))
+
+  (is (= (set (range 11 16))
+         (->> (select *session* :tv_series
+                      (where [[=  :series_title "Futurama"]
+                              [>  :episode_id 10]
+                              [<= :episode_id 15]]))
+              (map :episode_id)
+              set)))
+
+  (is (= (set (range 0 15))
+         (->> (select *session* :tv_series
+                      (where [[= :series_title "Futurama"]
+                              [< :episode_id 15]]))
+              (map :episode_id)
+              set)))
+
+  (drop-table *session* :tv_series))
+
+(deftest test-paginate
+  (with-table :tv_series
+    (dotimes [i 20]
+      (insert *session* :tv_series
+              {:series_title  "Futurama"
+               :episode_id    i
+               :episode_title (str "Futurama Title " i)})
+      (insert *session* :tv_series
+              {:series_title  "Simpsons"
+               :episode_id    i
+               :episode_title (str "Simpsons Title " i)}))
+
+
+    (is (= (set (range 0 10))
+           (->> (select *session* :tv_series
+                        (paginate :key :episode_id :per-page 10
+                                  :where {:series_title "Futurama"}))
+                (map :episode_id)
+                set)))
+
+    (is (= (set (range 11 20))
+           (->> (select *session* :tv_series
+                        (paginate :key :episode_id :per-page 10 :last-key 10
+                                  :where {:series_title "Futurama"}))
+                (map :episode_id)
+                set)))))

 ;; (deftest test-insert-with-consistency-level
 ;;   (let [r {:name "Alex" :city "Munich" :age (int 19)}]


small fix

small fix

--- src/cljs/salava/metabadge/ui/modal.cljs
+++ src/cljs/salava/metabadge/ui/modal.cljs
@@ -52,17 +52,16 @@
            [:div {:dangerouslySetInnerHTML {:__html criteria}}]]]]]])))

 (defn declined-badge [badge]
-  (let [data-atom (atom {:id (-> badge :id)})]
+  (let [data-atom (atom {:id (-> badge :user_badge_id)})]
     (init-user-badge data-atom)
     (fn []
-      (let [{:keys [badge-info user_badge]} badge
-            {:keys [image name]} badge-info
+      (let [{:keys [image_file name]}badge
             {:keys [owner? user-logged-in?]} @data-atom]
         (if (and user-logged-in? owner?)
           [:div#metabadgegrid {:class "row flip-table"}
            [:div.col-md-3.badge-image
             [:div.image-container
-             [:img {:src image :title name}]]]
+             [:img {:src (str "/" image_file) :title name}]]]
            [:div.col-md-9
             [:div.col-md-12
              [:h1.uppercase-header name]


if claims invalid do not compute avatar hash, use default #186

--- src/cljs/swarmpit/component/header.cljs
+++ src/cljs/swarmpit/component/header.cljs
@@ -31,8 +31,10 @@

 (defn user-gravatar-hash [email]
   (let [md5 (Md5.)]
-    (.update md5 (string/trim email))
-    (crypt/byteArrayToHex (.digest md5))))
+    (when (some? email)
+      (do
+        (.update md5 (string/trim email))
+        (crypt/byteArrayToHex (.digest md5))))))

 (defn- user-avatar []
   (comp/avatar
@@ -76,8 +78,7 @@
 (rum/defc appbar < rum/static [title]
   (comp/mui
     (comp/app-bar
-      {
-       :title              title
+      {:title              title
        :titleStyle         appbar-title-style
        :style              appbar-style
        :iconElementRight   (userbar)


Use new IMac abstraction on poly1305 ns.

--- src/clojure/buddy/core/mac/poly1305.clj
+++ src/clojure/buddy/core/mac/poly1305.clj
@@ -42,6 +42,9 @@
            clojure.lang.Keyword
            buddy.Arrays))

+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Low level hmac engine.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (def ^{:doc "Default engine factories."
        :dynamic true}
@@ -49,7 +52,7 @@
                        :serpent #(SerpentEngine.)
                        :twofish #(TwofishEngine.)})

-(defn resolve-engine
+(defn- resolve-engine
   "Given dynamic type engine, try resolve it to
   valid engine instance. By default accepts keywords
   and functions."
@@ -60,11 +63,7 @@
    (instance? IFn engine) (engine)
    (instance? BlockCipher engine) engine))

-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Internal implementations
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defn key->poly1305key
+(defn- key->poly1305key
   "Noramalizes any length byte array key to poly1305
   formatted byte array key.

@@ -75,39 +74,47 @@
     (Poly1305KeyGenerator/clamp bkey)
     bkey))

+(defn poly1305-engine
+  "Create a hmac engine."
+  ([key iv] (poly1305-engine key iv :aes))
+  ([key iv alg]
+   (let [engine (resolve-engine alg)
+         mac    (Poly1305. engine)
+         kp     (KeyParameter. (key->poly1305key key))]
+     (.init mac (ParametersWithIV. kp iv))
+     (reify
+       proto/IMac
+       (update [_ input offset length]
+         (.update mac input offset length))
+       (end [_]
+         (let [buffer (byte-array (.getMacSize mac))]
+           (.doFinal mac buffer 0)
+           buffer))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Internal implementations
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
 (defn- make-poly1305-plain-impl
   "Calculate the poly1305 message authentication code
   for byte array objects."
-  [^bytes input ^bytes pkey ^bytes iv ^Keyword alg]
-  (let [engine (resolve-engine alg)
-        mac    (Poly1305. engine)
-        out    (byte-array 16)
-        kp     (KeyParameter. (key->poly1305key pkey))
-        pwi    (ParametersWithIV. kp iv)]
-    (doto mac
-      (.init pwi)
-      (.update input 0 (count input))
-      (.doFinal out 0))
-    out))
+  [^bytes input ^bytes key ^bytes iv ^Keyword alg]
+  (let [engine (poly1305-engine key iv alg)]
+    (proto/update! engine input)
+    (proto/end! engine)))

 (defn- make-poly1305-stream-impl
   "Calculate the poly1305 message authentication code
   for file like objects in most memory efficient way."
-  [^java.io.InputStream stream ^bytes pkey ^bytes iv ^Keyword alg]
-  (let [engine (resolve-engine alg)
-        mac    (Poly1305. engine)
-        out    (byte-array 16)
-        kp     (KeyParameter. (key->poly1305key pkey))
-        pwi    (ParametersWithIV. kp iv)
-        bfr    (byte-array 5120)]
-    (.init mac pwi)
+  [^java.io.InputStream input ^bytes key ^bytes iv ^Keyword alg]
+  (let [engine (poly1305-engine key iv alg)
+        buffer (byte-array 5120)]
     (loop []
-      (let [readed (.read stream bfr 0 5120)]
+      (let [readed (.read input buffer 0 5120)]
         (when-not (= readed -1)
-          (.update mac bfr 0 readed)
+          (proto/update! engine buffer 0 readed)
           (recur))))
-    (.doFinal mac out 0)
-    out))
+    (proto/end! engine)))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Low level interface


require namespace bug

require namespace bug

--- src/clojure/zensols/actioncli/parse.clj
+++ src/clojure/zensols/actioncli/parse.clj
@@ -110,12 +110,11 @@
 (defn- create-actions [action-context]
   (->> (:action-definitions action-context)
        (map (fn [[key package action-def]]
-              (let [req (list 'require `(quote (~package)))]
-                (eval req)
-                {key (-> (format "%s/%s" package action-def)
-                         symbol
-                         eval
-                         (assoc :name (name key)))})))
+              (eval (list 'require `(quote [~package])))
+              {key (-> (format "%s/%s" package action-def)
+                       symbol
+                       eval
+                       (assoc :name (name key)))}))
        (apply merge)))

 (defn- execute-action [key opts args]
@@ -198,7 +197,9 @@
         {:keys [options arguments errors summary]}
         (cli/parse-opts arguments option-defs :strict true)]
     (if (nil? app)
-      (throw (ex-info "Programmer error: missing app" {})))
+      (throw (ex-info (format "Programmer error: missing app: action=%s"
+                              action)
+                      {:action action})))
     (if errors
       (do
         (if print-errors?


Using the new insert-wishlist with better code generator

--- src/wishlistd/models/queries.clj
+++ src/wishlistd/models/queries.clj
@@ -44,11 +44,12 @@
       (sql/insert-records :wishlist wishlist))))

 (defn insert-wishlist [wishlist]
-  (let [inserted (helper-insert-wishlist wishlist) ; make wishlist
-        code (random-code code-length) ; make code
-        finished (assoc inserted :code code)] ; add code to list
-    (update-wishlist finished)
-    (get-wishlist finished)))
+  (let [code (random-code code-length)
+        finished (assoc wishlist :code code)]
+    (try
+      (helper-insert-wishlist finished)
+      (catch Exception _
+        (new-insert-wishlist wishlist))))) ; simply try again if it fails

 (defn delete-wishlist [{:keys [code]}] ; code is unique
   (first
@@ -80,12 +81,6 @@
     (sql/with-connection db
       (sql/update-values :wish ["id=?" id] wish))))

-; (defn get-code []
-;   (sql/with-connection db
-;     (sql/with-query-results results
-;       ["select last_value+1 as last_value from wishlist_id_seq"]
-;       (generate-code (:last_value (first (into [] results)))))))
-
 ;; ADVANCED STUFF

 (defn create-wishlist-with-wishes []


fixed reflection warnings

fixed reflection warnings


style(clojure-project-nature): fix indentation

--- ccw.core/src/clj/ccw/clojure_project_nature.clj
+++ ccw.core/src/clj/ccw/clojure_project_nature.clj
@@ -154,8 +154,8 @@
   (io!
 	  (let [classes-folder (-> java-project .getProject (.getFolder "classes"))
           classes-entry (jdt/library-entry {:path classes-folder
-                         :is-exported true
-                         :extra-attributes {jdt/optional "true"}})]
+                                            :is-exported true
+                                            :extra-attributes {jdt/optional "true"}})]
      (jdt/conj-entries! java-project [classes-entry]))))

 (defn- setup-clojure-project-classpath!


clojure: the new morphism function seems to work

--- clojure/org/gavrog/clojure/pgraph_morphisms.clj
+++ clojure/org/gavrog/clojure/pgraph_morphisms.clj
@@ -99,12 +99,18 @@
     (.set M* n m (Whole/ONE))
     M*))

+(defn equal-sigs? [a b]
+  (let [d (.minus (first (first a)) (first (first b)))]
+    (and (every? (partial instance? Whole)
+                 (map #(.get d %) (range (inc (.getDimension d)))))
+         (= (map-sig (Operator. d) b) a))))
+
 (defn morphism [net v w M]
   (when (.isUnimodularIntegerMatrix M)
     (let [sigs (node-signatures net)
           d (.minus (first (first (sigs w))) (first (first (sigs v))))
           op (.times (Operator. (extend-matrix M)) (Operator. d))
-          check-sigs (fn [v w] (= (map-sig op (sigs v)) (sigs w)))]
+          check-sigs (fn [a b] (equal-sigs? (map-sig op (sigs v)) (sigs w)))]
       (loop [src2img {}
              q (conj empty-queue [v w])]
         (let [[a b] (first q)]
@@ -135,11 +141,6 @@
                                  :when e2]
                              [e1 e2]))))))))))

-(comment "previous version using Java:"
-  (try
-    (Morphism. v w op)
-    (catch Morphism$NoSuchMorphismException ex nil)))
-
 (defn symmetries [net]
   (let [bases (iterator-seq (.iterator (.characteristicBases net)))
         b (first bases)


[scamp] clean up 'comment block

[scamp] clean up 'comment block

--- modules/scamp/src/scamp/core.clj
+++ modules/scamp/src/scamp/core.clj
@@ -411,14 +411,4 @@
 (comment
   [1] "Peer-to-Peer Membership Management for Gossip-Based Protocols"

-
-
-  (-> new-world
-      (add-node (node-contact-address->node "node-id0"))
-      (subscribe "node-id1" "node-id0")
-      do-comm
-      ;; TODO: add more nodes here, test handle-forwarded-subscription, test forward-subscription, etc.
-      (dissoc :config)
-      clojure.pprint/pprint)
-
   )


Add missing test on options for :no-warning-error.

--- test/cljs/replumb/repl_test.cljs
+++ test/cljs/replumb/repl_test.cljs
@@ -174,6 +174,7 @@
   ;; always check valid-opts-set for supported options
   (is (= (get :verbose (repl/valid-opts {:verbose :true :load-fn! :true}))))
   (is (= (get :load-fn! (repl/valid-opts {:verbose :true :load-fn! :true}))))
+  (is (= (get :no-warning-error (repl/valid-opts {:verbose :true :load-fn! :true :no-warning-error true}))))
   (is (= {} (repl/valid-opts {:asdasdasd :kk}))))

 (deftest macros


Revert "Add incompat test"

Revert "Add incompat test"

This reverts commit 497c09b6ce5bba4aa1d3896fbf15a45ff70e7d56.

--- test/dependable/resolve_test.clj
+++ test/dependable/resolve_test.clj
@@ -730,17 +730,3 @@
             :present-packages {"c" package-c}
             :conflicts {"e" [nil]}))))))

-(deftest
-  ^:resolve-basic incompatibility
-  (testing "The wind in the willows"
-    (let [spec #(< (:version %) 5)]
-    (is
-     (= [:incompatible "a" spec]
-    (resolve-dependencies
-     [[(present "a" 5 spec)]]
-     (map-query {})
-     :present-package {"a" (->package
-                            "a"
-                            5
-                            "a_loc5"
-                            nil)}))))))


typo fix 2000

typo fix 2000

--- test/metabase/api/query_test.clj
+++ test/metabase/api/query_test.clj
@@ -46,7 +46,7 @@
     ;; delete any other rando test DBs made by other tests
     (cascade-delete Database :organization_id @org-id :id [not-in (set (filter identity
                                                                                [(datasets/when-testing-dataset :generic-sql
-                                                                                db-id)
+                                                                                @db-id)
                                                                                (datasets/when-testing-dataset :mongo
                                                                                @mongo-test-data/mongo-test-db-id)]))])
     ((user->client :rasta) :get 200 "query/form_input" :org @org-id)))


om-component? test

om-component? test

--- test/om_bootstrap/util_test.cljs
+++ test/om_bootstrap/util_test.cljs
@@ -3,6 +3,7 @@
              :include-macros true
              :refer [deftest is are use-fixtures]]
             [om.core :as om]
+            [om-bootstrap.button :refer [dropdown]]
             [om-bootstrap.util :as u]
             [om-tools.core :refer-macros [defcomponentk]]
             [om-tools.dom :as d :include-macros true]
@@ -90,6 +91,11 @@
         "The chained version executes the side effects of `adder`
         twice, incrementing the counter by two more.")))

+(deftest om-component-test
+  []
+  (is (not (u/om-component? (d/p "Just a p"))))
+  (is (u/om-component? (dropdown {:title "Title!"}))))
+
 (deftest merge-props-test
   (is (= (u/merge-props {:face "cake" :class "first"}
                         {:cake "face" :className "second"})


Update tests to reflect changes to query languages and generation

--- src/test/workflo/macros/query_test.cljc
+++ src/test/workflo/macros/query_test.cljc
@@ -32,19 +32,43 @@

 (deftest parse-one-join
   (and (is (= (q/conform-and-parse '[{foo ...}])
-              '[{:name foo :type :join :join-target ...}]))
+              '[{:name foo
+                 :type :join
+                 :join-source {:name foo :type :property}
+                 :join-target ...}]))
        (is (= (q/conform-and-parse '[{bar User}])
-              '[{:name bar :type :join :join-target User}]))
+              '[{:name bar
+                 :type :join
+                 :join-source {:name bar :type :property}
+                 :join-target User}]))
        (is (= (q/conform-and-parse '[{baz 5}])
-              '[{:name baz :type :join :join-target 5}]))))
+              '[{:name baz
+                 :type :join
+                 :join-source {:name baz :type :property}
+                 :join-target 5}]))
+       (is (= (q/conform-and-parse '[{[foo _] [bar baz]}])
+              '[{:name foo
+                 :type :join
+                 :join-source {:name foo :type :link :link-id _}
+                 :join-target [{:name bar :type :property}
+                               {:name baz :type :property}]}]))))

 (deftest parse-three-joins
   (and (is (= (q/conform-and-parse '[{foo ...}
                          {bar User}
                          {baz 5}])
-              '[{:name foo :type :join :join-target ...}
-                {:name bar :type :join :join-target User}
-                {:name baz :type :join :join-target 5}]))))
+              '[{:name foo
+                 :type :join
+                 :join-source {:name foo :type :property}
+                 :join-target ...}
+                {:name bar
+                 :type :join
+                 :join-source {:name bar :type :property}
+                 :join-target User}
+                {:name baz
+                 :type :join
+                 :join-source {:name baz :type :property}
+                 :join-target 5}]))))

 (deftest parse-basic-child-props
   (and (is (= (q/conform-and-parse '[foo [bar]])
@@ -62,14 +86,29 @@

 (deftest parse-join-child-props
   (and (is (= (q/conform-and-parse '[foo [{bar Baz}]])
-              '[{:name foo/bar :type :join :join-target Baz}]))
+              '[{:name foo/bar
+                 :type :join
+                 :join-source {:name foo/bar :type :property}
+                 :join-target Baz}]))
        (is    (= (q/conform-and-parse '[foo [{bar Baz} {baz Ruux}]])
-                 '[{:name foo/bar :type :join :join-target Baz}
-                   {:name foo/baz :type :join :join-target Ruux}]))
+                 '[{:name foo/bar
+                    :type :join
+                    :join-source {:name foo/bar :type :property}
+                    :join-target Baz}
+                   {:name foo/baz
+                    :type :join
+                    :join-source {:name foo/baz :type :property}
+                    :join-target Ruux}]))
        (is (= (q/conform-and-parse '[foo [{bar ...}]])
-              '[{:name foo/bar :type :join :join-target ...}]))
+              '[{:name foo/bar
+                 :type :join
+                 :join-source {:name foo/bar :type :property}
+                 :join-target ...}]))
        (is (= (q/conform-and-parse '[foo [{bar 5}]])
-              '[{:name foo/bar :type :join :join-target 5}]))))
+              '[{:name foo/bar
+                 :type :join
+                 :join-source {:name foo/bar :type :property}
+                 :join-target 5}]))))

 (deftest parse-link-child-props
   (and (is (= (q/conform-and-parse '[foo [[bar _]]])
@@ -112,7 +151,7 @@
 (deftest queries-with-links
   (and (is (= (-> '[[current-user _]]
                   q/conform-and-parse om/query)
-              '[[:current-user '_]]))
+              '[[:current-user _]]))
        (is (= (-> '[[user 123]]
                   q/conform-and-parse om/query)
               '[[:user 123]]))


Remove unused code from workspace header.

--- src/uxbox/main/ui/workspace/header.cljs
+++ src/uxbox/main/ui/workspace/header.cljs
@@ -54,17 +54,6 @@

 ;; --- Header Component

-(defn on-download-clicked
-  [event page]
-  (udl/open! :download)
-  #_(let [content (.-innerHTML (.getElementById js/document "page-layout"))
-        width (:width page)
-        height (:height page)
-        html (str "<svg width='" width  "' height='" height  "'>" content "</svg>")
-        data (js/Blob. #js [html] #js {:type "application/octet-stream"})
-        url (.createObjectURL (.-URL js/window) data)]
-    (set! (.-href (.-currentTarget event)) url)))
-
 (defn on-view-clicked
   [event project page]
   (let [token (:share-token project)
@@ -80,7 +69,8 @@
         toggle #(rs/emit! (dw/toggle-flag %))
         on-undo #(rs/emit! (udh/backwards-to-previous-version))
         on-redo #(rs/emit! (udh/forward-to-next-version))
-        on-image #(udl/open! :new-image)]
+        on-image #(udl/open! :import-image)
+        on-download #(udl/open! :download)]
     (html
      [:header#workspace-bar.workspace-bar
       [:div.main-icon
@@ -133,10 +123,9 @@
          :on-click on-redo}
          i/redo]]
        [:ul.options-btn
-        ;; TODO: refactor
         [:li.tooltip.tooltip-bottom
          {:alt "Export (Ctrl + E)"
-          :on-click on-download-clicked}
+          :on-click on-download}
          i/export]
         [:li.tooltip.tooltip-bottom
          {:alt "Image (Ctrl + I)"


Show company page

Show company page

--- src/webapp/client/react/components/company_details.cljs
+++ src/webapp/client/react/components/company_details.cljs
@@ -50,6 +50,12 @@
      )
    (dom/div #js {:style #js {:padding-bottom "20px"}} "")

+   (dom/pre nil
+            (str "<iframe  width='100%' height='100%' src='http://connecttous.co/connecttous/connecttous.html?company_url="
+                 (str (-> company-details :company-url))
+                 "' />")
+            )
+

    ))


specify the web socket implementation figwheel uses with FIGWHEEL_WEBSOCKET_CLASS

--- support/src/figwheel/client/socket.cljs
+++ support/src/figwheel/client/socket.cljs
@@ -5,20 +5,26 @@
    [cljs.reader :refer [read-string]]))

 (defn get-websocket-imp []
-  (cond
-    (utils/html-or-react-native-env?) (gobj/get js/window "WebSocket")
-    (utils/node-env?) (try (js/require "ws")
-                           (catch js/Error e
-                             nil))
-    (utils/worker-env?) (gobj/get js/self "WebSocket")
-    :else nil))
+  (or
+   (gobj/get goog.global "FIGWHEEL_WEBSOCKET_CLASS")
+   (gobj/get goog.global "WebSocket")
+   (cond
+     ;; TODO remove
+     (utils/html-or-react-native-env?) (gobj/get js/window "WebSocket")
+     (utils/node-env?) (try (js/require "ws")
+                            (catch js/Error e
+                              nil))
+     ;; TODO remove
+     (utils/worker-env?) (gobj/get js/self "WebSocket")
+     :else nil)))
+

 ;; messages have the following formats

 ;; files-changed message
 ;; { :msg-name :files-changed
 ;;   :files    [{:file "/js/compiled/out/example/core.js",
-;;               :type :javascript,
+;;               :type :javascript,
 ;;               :msg-name :file-changed,
 ;;               :namespace "example.core" }] }


aded form validation for adding new conferences | fs / sg | #62

--- src/cljs/conference_rating/add_conference_page/add_conference_page.cljs
+++ src/cljs/conference_rating/add_conference_page/add_conference_page.cljs
@@ -18,7 +18,14 @@

 (defn conference-series-input [data-atom]
   (fn []
-    [:input {:field :text :on-blur (fn [e] (swap! data-atom #(assoc % :series (-> e .-target .-value)))) :id :series :class "form-control" :placeholder "Name of the conference series, e.g. EuroClojure for the EuroClojure 2015 conference" :data-e2e "input-conference-series" :defaultValue (:series @data-atom)}]))
+    [:input {:field :text
+             :on-blur (fn [e] (swap! data-atom #(assoc % :series (-> e .-target .-value))))
+             :id :series
+             :class "form-control"
+             :placeholder "Name of the conference series, e.g. EuroClojure for the EuroClojure 2015 conference"
+             :data-e2e "input-conference-series"
+             :required true
+             :defaultValue (:series @data-atom)}]))

 (defn conference-series-suggestions [q cb]
   (backend/load-series-suggestions q cb))
@@ -42,13 +49,39 @@

 (defn conference-form-template [data-atom]
   [:div
-   (form-input "Series" [(conference-series-component data-atom)])
-   (form-input "Name" [:input {:field :text :id :name :class "form-control" :placeholder "Name of the conference" :data-e2e "input-conference-name"}])
+   (form-input "Series *" [(conference-series-component data-atom)])
+   (form-input "Name *" [:input {:field :text
+                               :id :name
+                               :class "form-control"
+                               :placeholder "Name of the conference"
+                               :data-e2e "input-conference-name"
+                               :required true}])
    [:div {:class "row"}
-    [:div {:class "col-md-6" :data-e2e "date-conference-from"} (form-input "From" [:div (assoc-when {:field :datepicker :id :from-date :date-format "yyyy/mm/dd" :inline false :auto-close? true} :defaultValue (:from @data-atom))])]
-    [:div {:class "col-md-6" :data-e2e "date-conference-to"} (form-input "To" [:div (assoc-when {:field :datepicker :id :to-date :date-format "yyyy/mm/dd" :inline false :auto-close? true} :defaultValue (:to @data-atom))])]]
-   (form-input "Link" [:input {:field :text :id :link :class "form-control" :placeholder "Link to the conference page" :data-e2e "input-conference-link"}])
-   (form-input "Description" [:textarea {:field :textarea :rows 5 :id :description :class "form-control" :placeholder "More information about the conference" :data-e2e "input-conference-description"}])])
+    [:div {:class "col-md-6" :data-e2e "date-conference-from"} (form-input "From *" [:div (assoc-when {:field :datepicker
+                                                                                :id :from-date
+                                                                                :date-format "yyyy/mm/dd"
+                                                                                :inline false
+                                                                                :auto-close? true
+                                                                                :required true} :defaultValue (:from @data-atom))])]
+    [:div {:class "col-md-6" :data-e2e "date-conference-to"} (form-input "To *" [:div (assoc-when {:field :datepicker
+                                                                                :id :to-date
+                                                                                :date-format "yyyy/mm/dd"
+                                                                                :inline false
+                                                                                :auto-close? true
+                                                                                :required true} :defaultValue (:to @data-atom))])]]
+   (form-input "Link *" [:input {:field :text
+                               :id :link
+                               :class "form-control"
+                               :placeholder "Link to the conference page"
+                               :data-e2e "input-conference-link"
+                               :required true }])
+   (form-input "Description *" [:textarea {:field :textarea
+                                         :rows 5
+                                         :id :description
+                                         :class "form-control"
+                                         :placeholder "More information about the conference"
+                                         :data-e2e "input-conference-description"
+                                         :required true}])])

 (defn create-conference [save-to-backend-fn]
   (fn [data-atom]
@@ -70,9 +103,13 @@
       [:div {:class "row"}
        [:div {:class "col-lg-2"}]
        [:div {:class "col-lg-8"}
-        [:div {:class "add-conference-form-container bg-light"}
-         [forms/bind-fields (conference-form-template doc) doc]
-         [:button {:class "btn btn-primary btn-md btn-orange" :on-click #(on-click-function doc) :data-e2e "button-create-conference"} save-button-label]]]
+        [:form {:on-submit #(on-click-function doc)}
+         [:div {:class "add-conference-form-container bg-light"}
+          [forms/bind-fields (conference-form-template doc) doc]
+          [:input {:type "submit"
+                   :class "btn btn-primary btn-md btn-orange"
+                   :data-e2e "button-create-conference"
+                   :value save-button-label}]]]]
        [:div {:class "col-lg-2"}]]]]))

 (defn add-conference-page []


pass around system map instead of iniconfig in inihelper-test

--- test/brainbot/nozzle/inihelper_test.clj
+++ test/brainbot/nozzle/inihelper_test.clj
@@ -1,9 +1,12 @@
 (ns brainbot.nozzle.inihelper-test
   (:require [clojure.test :refer :all]
+            [brainbot.nozzle.sys :as sys]
             [brainbot.nozzle.inihelper :refer :all]
             [brainbot.nozzle.fsfilter :as fsfilter]))

 (deftest test-loading-dotfiles
-  (let [relpath-filter (dynaload-section {"dotfile" {"type" "dotfile"}} "dotfile")]
+  (let [relpath-filter (dynaload-section
+                        (sys/make-system {"dotfile" {"type" "dotfile"}} [])
+                        "dotfile")]
     (is (true? ((fsfilter/make-match-entry? relpath-filter) {:relpath ".foo"})))
     (is (false?((fsfilter/make-match-entry? relpath-filter) {:relpath "foo"})))))


Fix scatter bug

Fix scatter bug

--- backend/src/akvo/lumen/lib/aggregation/commons.clj
+++ backend/src/akvo/lumen/lib/aggregation/commons.clj
@@ -13,12 +13,13 @@
     (:columnName column)))

 (defn sql-aggregation-subquery [aggregation-method column]
-  (let [v (cast-to-decimal column)]
-    (case aggregation-method
-      nil ""
-      ("min" "max" "count" "sum") (str aggregation-method "(" v "::decimal)")
-      "mean" (str "avg(" v "::decimal)")
-      "median" (str "percentile_cont(0.5) WITHIN GROUP (ORDER BY " v ")")
-      "distinct" (str "COUNT(DISTINCT " v ")")
-      "q1" (str "percentile_cont(0.25) WITHIN GROUP (ORDER BY " v ")")
-      "q3" (str "percentile_cont(0.75) WITHIN GROUP (ORDER BY " v ")"))))
+  (when column
+    (let [v (cast-to-decimal column)]
+      (case aggregation-method
+        nil ""
+        ("min" "max" "count" "sum") (str aggregation-method "(" v "::decimal)")
+        "mean" (str "avg(" v "::decimal)")
+        "median" (str "percentile_cont(0.5) WITHIN GROUP (ORDER BY " v ")")
+        "distinct" (str "COUNT(DISTINCT " v ")")
+        "q1" (str "percentile_cont(0.25) WITHIN GROUP (ORDER BY " v ")")
+        "q3" (str "percentile_cont(0.75) WITHIN GROUP (ORDER BY " v ")")))))


CMR-2814 Renames and documents parameter

--- access-control-app/src/cmr/access_control/services/acl_authorization.clj
+++ access-control-app/src/cmr/access_control/services/acl_authorization.clj
@@ -54,32 +54,35 @@
   (format "Permission to %s ACL is denied" (name action)))

 (defn- can?
-  "Returns true if current context user has permission to perform action on given acl."
-  [context action acl]
+  "Returns true if any ACLs grant the current context user the given permission
+  keyword (:create, :update, etc.) on the given acl."
+  [context permission acl]
   (cond
     ;; system token or system-level ANY_ACL permission can do anything
     (or (transmit-config/echo-system-token? context)
-        (has-system-access? context action "ANY_ACL"))
+        (has-system-access? context permission "ANY_ACL"))
     true
+
+    ;; If the user does not have system-level permissions, they may not perform any actions
+    ;; on system-level ACLs.
+    (:system-identity acl)
+    false

     (:provider-identity acl)
     (if (= (:target (:provider-identity acl)) "CATALOG_ITEM_ACL")
-      (has-provider-access? context action "CATALOG_ITEM_ACL"
+      (has-provider-access? context permission "CATALOG_ITEM_ACL"
                             (:provider-id (:provider-identity acl)))
-      (has-provider-access? context action "PROVIDER_OBJECT_ACL"
+      (has-provider-access? context permission "PROVIDER_OBJECT_ACL"
                             (:provider-id (:provider-identity acl))))

     (:catalog-item-identity acl)
-    (has-provider-access? context action "CATALOG_ITEM_ACL"
+    (has-provider-access? context permission "CATALOG_ITEM_ACL"
                           (:provider-id (:catalog-item-identity acl)))

     (:single-instance-identity acl)
     (let [target-group (group-service/get-group context (get-in acl [:single-instance-identity :target-id]))]
       (and (:provider-id target-group)
-           (has-provider-access? context action "PROVIDER_OBJECT_ACL" (:provider-id target-group))))
-
-    (:system-identity acl)
-    false))
+           (has-provider-access? context permission "PROVIDER_OBJECT_ACL" (:provider-id target-group))))))

 (defn authorize-acl-action
   "Throws service error if user doesn't have permission to intiate a given action for a given acl.


added test for submitting topology with invalid number of executors

--- test/clj/backtype/storm/nimbus_test.clj
+++ test/clj/backtype/storm/nimbus_test.clj
@@ -440,6 +440,22 @@
                        ))))
       )))

+(deftest test-submit-invalid
+  (with-simulated-time-local-cluster [cluster
+    :daemon-conf {SUPERVISOR-ENABLE false
+                  TOPOLOGY-ACKER-EXECUTORS 0}]
+    (letlocals
+      (bind topology (thrift/mk-topology
+                        {"1" (thrift/mk-spout-spec (TestPlannerSpout. true) :parallelism-hint 0 :conf {TOPOLOGY-TASKS 1})}
+                        {}))
+
+      (is (thrown? InvalidTopologyException
+        (submit-local-topology (:nimbus cluster)
+                               "test"
+                               {}
+                               topology)))
+      )))
+
 (deftest test-cleans-corrupt
   (with-inprocess-zookeeper zk-port
     (with-local-tmp [nimbus-dir]


Improve with-test-db to always delete database

--- test/clj/comic_reader/database_test.clj
+++ test/clj/comic_reader/database_test.clj
@@ -47,8 +47,10 @@
 (defmacro with-test-db [db-binding & body]
   `(let [test-system# (component/start (database-test-system))
          ~db-binding (:database test-system#)]
-     ~@body
-     (d/delete-database (get-in test-system# [:config :database-uri]))))
+     (try
+       ~@body
+       (finally
+         (d/delete-database (get-in test-system# [:config :database-uri]))))))

 (deftest test-get-and-store-sites
   (testing "returns no results for empty database"