Enable book lookup in multiple books at once.

--- src/clojure/clj_chess/book.clj
+++ src/clojure/clj_chess/book.clj
@@ -276,37 +276,58 @@
     :purge false
     :compact false))

-(defn find-book-entries
-  "Returns a list of all book entries in the given book file for the given
-  board."
-  [book-file-name board]
+(defn ^:private merge-book-entry-lists
+  "Merges lists of lists of book entries from the same position to a single
+  list, by combining entries corresponding to the same move. Used when
+  looking up a move in multiple book files at once. Does not support
+  compact books."
+  [list-of-list-of-entries]
+  (let [moves (-> (mapcat #(map :move %) list-of-list-of-entries)
+                  distinct
+                  sort)
+        mergeable (map (fn [m]
+                         (keep (fn [es]
+                                 (first (filter #(= (:move %) m) es)))
+                               list-of-list-of-entries))
+                       moves)]
+    (map #(into {} (merge-entries %)) mergeable)))
+
+(defn ^:private find-book-entries-internal [board book-file-name]
   (with-open [f (RandomAccessFile. book-file-name "r")]
     (let [compact (= (.read f) 1)
           entry-size (if compact compact-entry-size entry-size)
           entry-count (quot (.length f) entry-size)]
       (when-let [i (find-key (.getKey board) f 0 entry-count entry-size)]
-        (let [entries (sort
-                        #(> (:score %1) (:score %2))
-                        (loop [i i
-                               result [(read-entry f i compact)]]
-                          (if (= (inc i) entry-count)
-                            result
-                            (let [next-entry (read-entry f (inc i) compact)]
-                              (if (not= (:key next-entry) (.getKey board))
-                                result
-                                (recur (inc i)
-                                       (conj result next-entry)))))))
-              score-sum (reduce + (map :score entries))]
-          (map (comp #(dissoc % :score)
-                     #(assoc % :probability
-                               (/ (:score %) score-sum)))
-               entries))))))
+        (sort
+          #(> (:score %1) (:score %2))
+          (loop [i i
+                 result [(read-entry f i compact)]]
+            (if (= (inc i) entry-count)
+              result
+              (let [next-entry (read-entry f (inc i) compact)]
+                (if (not= (:key next-entry) (.getKey board))
+                  result
+                  (recur (inc i)
+                         (conj result next-entry)))))))))))
+
+(defn find-book-entries
+  "Returns a list of all book entries for the given input board, read from
+  the supplied book files."
+  [board & book-file-names]
+  (let [entries (merge-book-entry-lists
+                  (map #(find-book-entries-internal board %)
+                       book-file-names))
+        score-sum (reduce + (map :score entries))]
+    (map (comp #(dissoc % :score)
+               #(assoc % :probability
+                         (/ (:score %) score-sum)))
+         entries)))

 (defn pick-book-move
   "Pick a random book move from the board position, based on their
   probabilities. Returns nil if no book move is found."
-  [book-file-name board]
-  (let [entries (find-book-entries book-file-name board)
+  [board & book-file-names]
+  (let [entries (find-book-entries board book-file-names)
         r (rand)]
     (first (first (filter #(> (second %) r)
                           (map (fn [e c] [(:move e) c])
@@ -316,8 +337,9 @@
 (defn ^:private pprint-entries
   "Pretty-print the book entries for the given board position to the standard
    output, for debugging."
-  [book-file board]
-  (doseq [entry (find-book-entries book-file board)]
+  [board & book-file-names]
+  (doseq [entry (sort-by (comp - :probability)
+                         (apply find-book-entries board book-file-names))]
     (if (:wins entry)
       (cl-format true
                  "~a ~v$% (+~a,=~a,-~a) ~a ~a ~a ~v$%~%"


Junit plugin requires :print-level to be :print-fact

--- src/midje/emission/plugins/junit.clj
+++ src/midje/emission/plugins/junit.clj
@@ -2,12 +2,18 @@
   midje.emission.plugins.junit
   (:use
     [midje.emission.util])
-  (:require [midje.data.fact :as fact]
+  (:require [midje.config :as config]
+            [midje.data.fact :as fact]
             [midje.emission.state :as state]
             [midje.emission.plugins.silence :as silence]
             [midje.emission.plugins.default-failure-lines :as lines]
             [clojure.string :as str]
             [clojure.xml :as xml :only [emit-element]]))
+
+
+;; This plugin requires all emission api calls to be
+;; forwarded to it.
+(config/change-defaults :print-level :print-facts)

 (def report-file "report.xml")


token based richness

token based richness

--- src/crawler/rich_extractor.clj
+++ src/crawler/rich_extractor.clj
@@ -96,6 +96,7 @@
                                               (not (some #{x} (set blacklist))))
                                             (xpaths-hrefs xpath)))))
                                candidates-ordered))]
+    (println candidates-ordered)
     to-sample-links))

 (defn score-xpaths
@@ -154,12 +155,14 @@
                                       (sort-by second xpaths-scored)))

                                         ; links at the chosen XPaths
-               decision-links       (flatten
+               decision-links       (into
+                                     {}
                                      (map
                                       (fn [[a-decision score]]
-                                        (map
-                                         #(-> % :href)
-                                         (in-host-xpaths-hrefs a-decision)))
+                                        [a-decision
+                                         (map
+                                          #(-> % :href)
+                                          (in-host-xpaths-hrefs a-decision))])
                                       decision))

                                         ; this guy is computing the score products of the decisions alone
@@ -172,17 +175,17 @@
           (do
             (println :url url)
             (println :decision decision)
-            {:links decision-links
-             :action-score decision-scores
-             :xpaths (map first decision)}))
+            {:decision decision-links
+             :score decision-scores}))

          (let [decision (-> url-ds :content-xpaths)
-               decision-links (flatten
-                               (map
-                                (fn [a-decision]
-                                  (map
-                                   #(-> % :href)
-                                   (in-host-xpaths-hrefs a-decision)))
+               decision-links (into
+                               {} (map
+                                   (fn [a-decision]
+                                     [a-decision
+                                      (map
+                                       #(-> % :href)
+                                       (in-host-xpaths-hrefs a-decision))])
                                 decision))
                decision-scores (/ (reduce
                                    (fn [acc a-decision]
@@ -194,9 +197,8 @@
              (println :url url)
              (println :decision decision)
              (println "PAGINATED")
-             {:links decision-links
-              :action-score decision-scores
-              :xpaths decision}))))))
+             {:decision decision-links
+              :score decision-scores}))))))

 (defn pagination?
   "Args:
@@ -265,32 +267,31 @@
    Args:
     page-src : body
     url-ds : url datastructure (bubbled with some info like are we paginated etc)
+    global-info : stores some global statistics the crawler has computed.
     blacklist : what not to get

    Returns:
     Pagination candidates
     (one or more xpaths)."
-  ([page-src url-ds]
-     (weak-pagination-detector page-src url-ds (set [])))
-
-  ([page-src url-ds blacklist]
-     (let [url (-> url-ds :url)
+  ([page-src url-ds global-info]
+     (weak-pagination-detector page-src url-ds global-info (set [])))
+
+  ([page-src url-ds global-info blacklist]
+     (let [url        (-> url-ds :url)
+           paginated? (-> url-ds :pagination?)
+           xpath      (-> url-ds :src-xpath)
+
+           vocabulary (-> global-info :paging-vocab)

-           paginated? (-> url-ds :pagination?)
-
-           xpaths (-> url-ds :paging-xpaths)
-
            in-host-xpaths-hrefs (state-action page-src url blacklist)
-
            xpaths-hrefs         (into
                                  {} (map
                                      (fn [[xpath nodes]]
                                        [xpath (map #(-> % :href) nodes)])
-                                     in-host-xpaths-hrefs))]
+                                     in-host-xpaths-hrefs))
+           xpaths-tokenized     (tokenize-actions in-host-xpaths-hrefs)]
        (if-not paginated?
-         (let [xpaths-tokenized     (tokenize-actions in-host-xpaths-hrefs)
-
-               xpaths-scored        (sort-by second
+         (let [xpaths-scored        (sort-by second
                                              (score-actions xpaths-tokenized))

                mean-richness        (/ (apply + (map second xpaths-scored))
@@ -303,14 +304,31 @@
                                       (fn [[xpath score]]
                                         (< score mean-richness))
                                       xpaths-scored))
+
+               xpaths-considered'   (if (and vocabulary (not (empty? vocabulary)))
+                                      (filter
+                                       (fn [[xpath links]]
+                                         (let [xpath-text-tokens (reduce
+                                                                  clojure.set/union
+                                                                  (map
+                                                                   (fn [a-tok-map]
+                                                                     (set (:text-tokens a-tok-map)))
+                                                                   (xpaths-tokenized xpath)))]
+                                           (not
+                                            (empty?
+                                             (clojure.set/intersection
+                                              vocabulary xpath-text-tokens)))))
+                                       xpaths-considered)
+                                      xpaths-considered)

                xpaths-samples       (map
                                      (fn [[xpath links]]
                                        [xpath (sample/sample-some-links links blacklist)])
-                                     xpaths-considered)
+                                     xpaths-considered')

                xpaths-samples-map   (into {} xpaths-samples)
-
+
+
                pagination-cands     (map
                                      first
                                      (filter
@@ -346,19 +364,33 @@

                picked-xpath         (pick-paginator-weakest pagination-token-ds)

-               picked-links         (reduce
-                                     concat
+               picked-links         (into
+                                     {}
                                      (map
-                                      #(xpaths-hrefs %)
+                                      (fn [x]
+                                        [x {:links (xpaths-hrefs x)
+                                            :vocab (reduce
+                                                    clojure.set/union
+                                                    (map
+                                                     (fn [tok-info]
+                                                       (set (-> tok-info :text-tokens)))
+                                                     (xpaths-tokenized x)))}])
                                       (map first picked-xpath)))]

-           [picked-xpath (distinct picked-links)])
+           picked-links)

          ;else just eval the submitted xpaths and deliver ze results
-         (let [picked-xpath xpaths
-               picked-links (reduce
-                             concat
-                             (map
-                              #(xpaths-hrefs %)
-                              (map first picked-xpath)))]
-           [picked-xpath (distinct picked-links)])))))
+         (let [picked-links {xpath {:links (xpaths-hrefs xpath)
+                                    :vocab (reduce
+                                            clojure.set/union
+                                            (map
+                                             (fn [tok-info]
+                                               (set (-> tok-info :text-tokens)))
+                                             (xpaths-tokenized xpath)))}}]
+           picked-links)))))
+
+(defn leaf?
+  [sum-score num-decisions cur-score]
+  (>= (* 0.75
+         (/ sum-score num-decisions))
+      cur-score))


add some idea from my original code

add some idea from my original code

Signed-off-by: Yen-Chin Lee <082d453d72dce940e12089a4ad48b97cfe1f3ec4@gmail.com>

--- src/emulator_chip8/opcode.cljc
+++ src/emulator_chip8/opcode.cljc
@@ -1,20 +1,205 @@
 (ns emulator-chip8.opcode
-  #?(:cljs (:require-macros [emulator-chip8.opcode :refer [defop to-opcode-func]])))
-
-#?(:clj
-   (defmacro defop
-     [name & body]
-     (let [name (symbol (str "opcode-" name))
-           args [{'r :registers 'm :memory :as 'cpu}
-                 'addr-mode
-                 ['n 'n-addr]]]
-       `(defn ~name ~args ~@body))))
-
-#?(:clj
-   (defmacro to-opcode-func [name]
-     (let [n  (symbol (str name))]
-       `(~n)
-       )))
+;;  #?(:cljs (:require-macros [emulator-chip8.opcode :refer [defop to-opcode-func]]))
+  )
+
+;; #?(:clj
+;;    (defmacro defop
+;;      [name & body]
+;;      (let [name (symbol (str "opcode-" name))
+;;            args [{'r :registers 'm :memory :as 'cpu}
+;;                  'addr-mode
+;;                  ['n 'n-addr]]]
+;;        `(defn ~name ~args ~@body))))
+
+;; #?(:clj
+;;    (defmacro to-opcode-func [name]
+;;      (let [n  (symbol (str name))]
+;;        `(~n)
+;;        )))
+
+(defn make-opcode-match-list
+  [opcode]
+  (let [code (format "%04X" opcode)
+        ZNNN (format "%SNNN" (subs code 0 1))
+        ZXNN (format "%SXNN" (subs code 0 1))
+        ZXYN (format "%SXYN" (subs code 0 1))
+        ZXYZ (format "%SXY%S" (subs code 0 1) (subs code 3 4))
+        ZXZZ (format "%SX%S"  (subs code 0 1) (subs code 2 4))]
+    (list code ZNNN ZXNN ZXZZ ZXYN ZXYZ)))
+
+(defn make-opcode-sets
+  [opcode]
+  ;; Create possible opcode set for handler-list
+  (->> (make-opcode-match-list opcode)
+       (map keyword)
+       (set)))
+
+(def handler-list
+  {;; Execute machine language subroutine at address NNN
+   :0NNN 'unimplement
+
+   ;; Clear the screen
+   :00E0 'clear-screen
+
+   ;; Return from a subroutine
+   :00EE 'return-from-subroutine
+
+   ;; Jump to address NNN
+   :1NNN 'jump-to-address
+
+   ;; Execute subroutine starting at address NNN
+   :2NNN 'call-subroutine
+
+   ;; Skip the following instruction if the value of register VX equals NN
+   :3XNN 'skip-when-VX-equal-NN
+
+   ;; Skip the following instruction if the value of register VX is
+   ;; not equal to NN
+   :4XNN 'skip-when-VX-not-equal-NN
+
+   ;; Skip the following instruction if the value of register VX is
+   ;; equal to the value of register VY
+   :5XY0 'skip-when-VX-equal-VY
+
+   ;; Store number NN in register VX
+   :6XNN 'store-NN-in-VX
+
+   ;; Add the value NN to register VX
+   :7XNN 'add-NN-to-VX
+
+   ;; Store the value of register VY in register VX
+   :8XY0 'store-VY-in-VX
+
+   ;; Set VX to VX OR VY
+   :8XY1 'set-VX-to-VX-or-VY
+
+   ;; Set VX to VX AND VY
+   :8XY2 'set-VX-to-VX-and-VY
+
+   ;; Set VX to VX XOR VY
+   :8XY3 'set-VX-to-VX-xor-VY
+
+   ;; Add the value of register VY to register VX
+   ;; Set VF to 1 if a carry occurs
+   ;; Set VF to 0 if a carry does not occur
+   :8XY4 'add-VY-to-VX
+
+   ;; Subtract the value of register VY from register VX
+   ;; Set VF to 0 if a borrow occurs
+   ;; Set VF to 1 if a borrow does not occur
+   :8XY5 'substract-VY-from-VX
+
+   ;; Store the value of register VY shifted right one bit in register VX
+   ;; Set register VF to the least significant bit prior to the
+   ;; shift
+   :8XY6 'unimplement
+
+   ;; Set register VX to the value of VY minus VX
+   ;; Set VF to 00 if a borrow occurs
+   ;; Set VF to 01 if a borrow does not occur
+   :8XY7 'unimplement
+
+   ;; Store the value of register VY shifted left one bit in register VX
+   ;; Set register VF to the most significant bit prior to the shift
+   :8XYE 'unimplement
+
+   ;; Skip the following instruction if the value of register VX is
+   ;; not equal to the value of register VY
+   :9XY0 'unimplement
+
+   ;; Store memory address NNN in register I
+   :ANNN 'store-NNN-in-I
+
+   ;; Jump to address NNN + V0
+   :BNNN 'unimplement
+
+   ;; Set VX to a random number with a mask of NN
+   :CXNN 'set-VX-random-mask-NN
+
+   ;; Draw a sprite at position VX, VY with N bytes of sprite data
+   ;; starting at the address stored in I
+   ;; Set VF to 01 if any set pixels are changed to unset, and 00
+   ;; otherwise
+   :DXYN 'unimplement
+
+   ;; Skip the following instruction if the key corresponding to
+   ;; the hex value currently stored in register VX is pressed
+   :EX9E 'unimplement
+
+   ;; Skip the following instruction if the key corresponding to the
+   ;; hex value currently stored in register VX is not pressed
+   :EXA1 'unimplement
+
+   ;; Store the current value of the delay timer in register VX
+   :FX07 'store-delay-timer-to-VX
+
+   ;; Wait for a keypress and store the result in register VX
+   :FX0A 'unimplement
+
+   ;; Set the delay timer to the value of register VX
+   :FX15 'store-VX-to-delay-timer
+
+   ;; Set the sound timer to the value of register VX
+   :FX18 'store-VX-to-sound-timer
+
+   ;; Add the value stored in register VX to register I
+   :FX1E 'unimplement
+
+   ;; Set I to the memory address of the sprite data corresponding
+   ;; to the hexadecimal digit stored in register VX
+   :FX29 'unimplement
+
+   ;; Store the binary-coded decimal equivalent of the value stored
+   ;; in register VX at addresses I, I + 1, and I + 2
+   :FX33 'unimplement
+
+   ;; Store the values of registers V0 to VX inclusive in memory
+   ;; starting at address I
+   ;; I is set to I + X + 1 after operation
+   :FX55 'unimplement
+
+   ;; Fill registers V0 to VX inclusive with the values stored in
+   ;; memory starting at address I
+   ;; I is set to I + X + 1 after operation
+   :FX65 'unimplement
+   })
+
+(defn find-match-handler
+  "Search for matching handler in handler list.
+If nothing find, return nil else return keyword."
+  [handler opcode]
+  (str "opcode-" (name (some (make-opcode-sets opcode) (keys handler))) )
+  )
+
+(defn make-handler-args
+  "Parse the code to find how many VX, VY, NNN, NN, N
+and create argument lists."
+  [opcode]
+  (let [code (format "%04X" opcode)]
+    {:NNN (subs code 1 4)
+     :NN  (subs code 2 4)
+     :N   (subs code 3 4)
+     :VX  (subs code 1 2)
+     :VY  (subs code 2 3)}))
+
+(comment
+  (make-opcode-sets 0xf155) ;; FX55
+  (make-handler-args 0xf155) ;; FX55
+
+  (find-match-handler handler-list 0xf155)
+
+  (keys handler-list)
+  )
+
+
+(defn find-match-handler
+  "Search for matching handler in handler list.
+If nothing find, return nil else return keyword."
+  [handler opcode]
+  (some (make-opcode-sets opcode) (keys handler)))
+
+
+

 ;; 0NNN
 (defop 0NNN


completed

completed


change name

change name

--- build.boot
+++ build.boot
@@ -40,7 +40,7 @@
 (swap! boot.repl/*default-middleware*
        conj 'lighttable.nrepl.handler/lighttable-ops)

-(deftask test
+(deftask run-test
   "Test"
   []
   (speak))


Update to 0.2.0-SNAPSHOT of boot-junit

Update to 0.2.0-SNAPSHOT of boot-junit

--- build.boot
+++ build.boot
@@ -1,6 +1,6 @@
 (set-env!
  :source-paths #{"src"}
- :dependencies '[[radicalzephyr/boot-junit "0.1.1" :scope "test"]
+ :dependencies '[[radicalzephyr/boot-junit "0.2.0-SNAPSHOT" :scope "test"]
                  [jeluard/boot-notify "0.1.2"      :scope "test"]
                  [net.sf.jopt-simple/jopt-simple "4.9"]])


Start working on 1.1.0

Start working on 1.1.0

--- build.boot
+++ build.boot
@@ -6,7 +6,7 @@
 (require
   '[adzerk.bootlaces :as deploy])

-(def +version+ "1.0.0")
+(def +version+ "1.1.0-SNAPSHOT")

 (deploy/bootlaces! +version+)


Correct implementation of ns splitting in build.boot

--- build.boot
+++ build.boot
@@ -110,10 +110,18 @@
  '[clojure.string :as str]
  '[boot.util :as util])

+(defn- get-ns-and-sym [sym]
+  (str/split (name sym) #"/" 2))
+
+(defn- get-ns [sym]
+  (let [[ns s] (get-ns-and-sym sym)]
+    (when s
+      (symbol ns))))
+
 (defn- exists-but-no-ns? [sym]
   (if (nil? sym)
     false
-    (let [[ns just-sym] (get-ns sym)]
+    (let [[ns just-sym] (get-ns-and-sym sym)]
       (if (nil? just-sym)
         true
         false))))
@@ -122,8 +130,7 @@
   "Run vars as a pre- and post- tasks."
   [b before SYM sym "The symbol to run inside a pre-wrap task"
    a after  SYM sym "The symbol to run inside a post-wrap task"]
-  (let [get-ns (fn [str] (let [[ns s] (str/split (name str) #"/" 2)] (when s (symbol ns))))
-        run-symbol (fn [s]
+  (let [run-symbol (fn [s]
                      (when s
                        (when-let [ns (get-ns s)]
                          (require ns))


0.0-2814-4

--- build.boot
+++ build.boot
@@ -6,7 +6,7 @@

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

-(def +version+ "0.0-2814-3")
+(def +version+ "0.0-2814-4")

 (bootlaces! +version+)


update version

update version

--- build.boot
+++ build.boot
@@ -19,7 +19,7 @@
 (require '[io.perun-test])
 (require '[boot.test :refer [runtests]])

-(def +version+ "0.4.1-SNAPSHOT")
+(def +version+ "0.4.2-SNAPSHOT")

 (bootlaces! +version+)


Add testing-task dependency on gloss

Add testing-task dependency on gloss

Because the streaming serialization test on which I'm currently working
has a problem for which it was specifically designed. At least, it's
the top example of how to use aleph.tcp.

Bumped some other library dependency versions while I was at it.

And added some comments about getting rid of my dependencies on logging libraries.

--- build.boot
+++ build.boot
@@ -3,16 +3,22 @@

 (set-env! :resource-paths #{"src/clojure"}
           :dependencies '[[adzerk/boot-test "RELEASE" :scope "test"]
-                          [aleph "0.4.3"]
-                          [org.apache.logging.log4j/log4j-core "2.8.2" :scope "test"]
-                          [org.apache.logging.log4j/log4j-1.2-api "2.8.2" :scope "test"]
-                          [org.clojure/clojure "1.9.0-beta1"]
-                          [org.clojure/spec.alpha "0.1.123"]
-                          [org.clojure/test.check "0.10.0-alpha2" :scope "test"]
-                          [org.clojure/tools.logging "0.4.0"]
-                          [samestep/boot-refresh "0.1.0" :scope "test"]
-                          [tolitius/boot-check "0.1.4" :scope "test"]]
-          :source-paths   #{"src/java" "test"})
+                          [aleph "0.4.4" :exclusions [org.clojure/tools.logging]]
+                          ;; TODO: Eliminate these logging dependencies.
+                          ;; I have no business imposing them on library
+                          ;; users
+                          [org.apache.logging.log4j/log4j-core "2.9.1" :scope "test"]
+                          [org.apache.logging.log4j/log4j-1.2-api "2.9.1" :scope "test"]
+                          [org.clojure/clojure "1.9.0-RC1"]
+                          [org.clojure/spec.alpha "0.1.143"]
+                          [org.clojure/test.check "0.10.0-alpha2" :scope "test" :exclusions [org.clojure/clojure]]
+                          ;; TODO: Eliminate this dependency. It's another one
+                          ;; that I really don't have any business imposing on anyone else
+                          [org.clojure/tools.logging "0.4.0" :exclusions [org.clojure/clojure]]
+                          ;; TODO: Move this into the dev task
+                          [samestep/boot-refresh "0.1.0" :scope "test" :exclusions [org.clojure/clojure]]
+                          [tolitius/boot-check "0.1.6" :scope "test"]]
+          :source-paths   #{"src/java"})

 (task-options!
  aot {:namespace   #{'frereth-cp.server 'frereth-cp.client}}
@@ -31,6 +37,8 @@

 (require '[samestep.boot-refresh :refer [refresh]])
 (require '[tolitius.boot-check :as check])
+(require '[adzerk.boot-test :refer [test]])
+(require '[boot.pod :as pod])

 (deftask build
   "Build the project locally as a JAR."
@@ -41,16 +49,34 @@
   (let [dir (if (seq dir) dir #{"target"})]
     (comp (javac) (aot) (pom) (uber) (jar) (target :dir dir))))

+(deftask check-conflicts
+  "Verify there are no dependency conflicts."
+  []
+  (with-pass-thru fs
+    (require '[boot.pedantic :as pedant])
+    (let [dep-conflicts (resolve 'pedant/dep-conflicts)]
+      (if-let [conflicts (not-empty (dep-conflicts pod/env))]
+        (throw (ex-info (str "Unresolved dependency conflicts. "
+                             "Use :exclusions to resolve them!")
+                        conflicts))
+        (println "\nVerified there are no dependency conflicts.")))))
+
 (deftask dev
   []
   (merge-env! :source-paths #{"dev" "dev-resources"})
+  identity)
+
+(deftask testing
+  []
+  (merge-env! :dependencies '[[gloss "0.2.6" :scope "test"]]
+              :source-paths #{"test"})
   identity)

 (deftask cider-repl
   "Set up a REPL for connecting from CIDER"
   []
   ;; Just because I'm prone to forget one of the vital helper steps
-  (comp (dev) (cider) (javac) (repl)))
+  (comp (dev) (testing) (check-conflicts) (cider) (javac) (repl)))

 (deftask run
   "Run the project."
@@ -60,5 +86,3 @@
   ;; Q: Does it make any sense to keep it around?
   (require '[frereth-cp.server :as app])
   (apply (resolve 'app/-main) file))
-
-(require '[adzerk.boot-test :refer [test]])


Set next version = 0.1.1

Set next version = 0.1.1

--- build.boot
+++ build.boot
@@ -1,6 +1,6 @@
 (set-env!
   :project 'irresponsible/overload
-  :version "0.1.0"
+  :version "0.1.1"
   :resource-paths #{"src"}
   :source-paths #{"src"}
   :description "Dynamic loading and lookup"


Switch position of table and title in table element to prepare for optional title and footer.

--- src/main/clojure/ssblog/md.clj
+++ src/main/clojure/ssblog/md.clj
@@ -115,12 +115,13 @@

 (defn preprocess-table
   [id [element body]]
-  (when-let [match (re-find #"(?s)([\d\.]+) \[([\w ]+)\] \[([^\]]+)\] \[([\w ]+)\]" body)]
-    (let [[_ number title table footer] match]
+  (when-let [match (re-find #"(?s)([\d\.]+) \[([^\]]+)\] \[([\w ]+)\] \[([\w ]+)\]" body)]
+    (let [[_ number table title footer] match]
       {:element element
        :number number
+       :table table
        :title title
-       :table table
+       :footer footer})))
        :footer footer})))

 (defn preprocess-special-element


bugfix - command nth

bugfix - command nth

--- src/todos/executor/exec_navigate.clj
+++ src/todos/executor/exec_navigate.clj
@@ -30,7 +30,7 @@
         current-todo (current-todolist)
         n (read-string joined-args)]
     (if (and (integer? n) (>= (dec n) 0) (< (dec n) (count ((current-todo :todos)))))
-      (swap! current-stack conj (nth ((current-todo :todos)) n))
+      (swap! current-stack conj (nth ((current-todo :todos)) (dec n)))
       (println "ID doesn't exist. There are only" (count ((current-todo :todos))) "ids")
       )))


Add post-mutation-params to all missing places on data fetch

--- src/untangled/client/data_fetch.cljc
+++ src/untangled/client/data_fetch.cljc
@@ -139,6 +139,7 @@
   - `without`: See `load-data`
   - `params`: See `load-data`
   - `post-mutation`: See `load-data`
+  - `post-mutation-params`: See `load-data`
   - `parallel`: See `load-data`
   - `fallback`: See `load-data`
   - `marker`: See `load-data`
@@ -150,21 +151,22 @@
   using an Om link (e.g. `[:ui/loading-data '_]`). The presence of the ident on components will enable query optimization, which can
   improve your frame rate because Om will not have to run a full root query.
   "
-  [component field & {:keys [without params remote post-mutation fallback parallel refresh marker]
+  [component field & {:keys [without params remote post-mutation post-mutation-params fallback parallel refresh marker]
                       :or   {remote :remote refresh [] marker true}}]
   (when fallback (assert (symbol? fallback) "Fallback must be a mutation symbol."))
   (om/transact! component (into [(list 'untangled/load
-                                   {:ident         (om/get-ident component)
-                                    :field         field
-                                    :query         (om/focus-query (om/get-query component) [field])
-                                    :params        params
-                                    :without       without
-                                    :remote        remote
-                                    :post-mutation post-mutation
-                                    :parallel      parallel
-                                    :marker        marker
-                                    :refresh       refresh
-                                    :fallback      fallback}) :ui/loading-data (om/get-ident component)] refresh)))
+                                   {:ident                (om/get-ident component)
+                                    :field                field
+                                    :query                (om/focus-query (om/get-query component) [field])
+                                    :params               params
+                                    :without              without
+                                    :remote               remote
+                                    :post-mutation        post-mutation
+                                    :post-mutation-params post-mutation-params
+                                    :parallel             parallel
+                                    :marker               marker
+                                    :refresh              refresh
+                                    :fallback             fallback}) :ui/loading-data (om/get-ident component)] refresh)))

 (defn load-data
   "
@@ -176,6 +178,7 @@

   Optional Named parameters
   - `post-mutation`: A mutation (symbol) invoked after the load succeeds.
+  - `post-mutation-params`: An optional map  that will be passed to the post-mutation when it is called. May only contain raw data, not code!
   - `fallback`: A mutation (symbol) invoked after the load fails. App state is in env, server error is in the params under :error.
   - `parallel`: Boolean to indicate that this load should happen in the parallel on the server (non-blocking load). Any loads marked this way will happen in parallel.
   - `marker`: A boolean (default true). If true, a marker is placed in the app state in place of the target data during the load. If false, no marker is produced.
@@ -185,20 +188,21 @@
   - `params`: A parameter map to augment onto the first element of the query
   - `remote`: A keyword naming which remote to query.
   "
-  [comp-or-reconciler query & {:keys [ident without remote params post-mutation fallback parallel refresh marker]
+  [comp-or-reconciler query & {:keys [ident without remote params post-mutation post-mutation-params fallback parallel refresh marker]
                                :or   {remote :remote refresh [] marker true}}]
   (when fallback (assert (symbol? fallback) "Fallback must be a mutation symbol."))
   (om/transact! comp-or-reconciler (into [(list 'untangled/load
-                                            {:ident         ident
-                                             :query         query
-                                             :params        params
-                                             :without       without
-                                             :remote        remote
-                                             :post-mutation post-mutation
-                                             :refresh       refresh
-                                             :marker        marker
-                                             :parallel      parallel
-                                             :fallback      fallback}) :ui/loading-data] refresh)))
+                                            {:ident                ident
+                                             :query                query
+                                             :params               params
+                                             :without              without
+                                             :remote               remote
+                                             :post-mutation        post-mutation
+                                             :post-mutation-params post-mutation-params
+                                             :refresh              refresh
+                                             :marker               marker
+                                             :parallel             parallel
+                                             :fallback             fallback}) :ui/loading-data] refresh)))

 (defn load-field-action
   "Queue up a remote load of a component's field from within an already-running mutation. Similar to `load-field`
@@ -215,21 +219,22 @@
     :action (fn []
        (load-field-action ...)
        ; other optimistic updates/state changes)}"
-  [app-state component-class ident field & {:keys [without remote params post-mutation fallback parallel refresh marker]
+  [app-state component-class ident field & {:keys [without remote params post-mutation post-mutation-params fallback parallel refresh marker]
                                             :or   {remote :remote refresh [] marker true}}]
   (impl/mark-ready
-    {:state         app-state
-     :field         field
-     :ident         ident
-     :query         (om/focus-query (om/get-query component-class) [field])
-     :params        params
-     :remote        remote
-     :without       without
-     :parallel      parallel
-     :refresh       refresh
-     :marker        marker
-     :post-mutation post-mutation
-     :fallback      fallback}))
+    {:state                app-state
+     :field                field
+     :ident                ident
+     :query                (om/focus-query (om/get-query component-class) [field])
+     :params               params
+     :remote               remote
+     :without              without
+     :parallel             parallel
+     :refresh              refresh
+     :marker               marker
+     :post-mutation        post-mutation
+     :post-mutation-params post-mutation-params
+     :fallback             fallback}))

 (defn load-data-action
   "


PLATFORM-2818: Fixing add-vary-header to cope with nil values

--- src/vignette/util/image_response.clj
+++ src/vignette/util/image_response.clj
@@ -10,7 +10,8 @@
             [vignette.storage.local :refer [create-stored-object]]
             [vignette.storage.protocols :refer :all]
             [vignette.util.thumbnail :refer :all]
-            [ring.util.codec :refer [url-encode]]))
+            [ring.util.codec :refer [url-encode]]
+            [io.clj.logging :as log]))

 (declare create-image-response
          add-content-disposition-header
@@ -110,6 +111,7 @@
   "Add Vary: Accept header for supported thumbail types if format was not specified in query params"
   [response-map image-map]
   (if (and
+        image-map
         (empty? (:requested-format image-map))
         (webp-supported? (original-path image-map)))
     (-> response-map


add custom-value-range fn

add custom-value-range fn

--- day3/src/day3/csv.clj
+++ day3/src/day3/csv.clj
@@ -62,6 +62,15 @@
         results   (into [] xf (rest rows))]
     results))

+(defn column-value-range
+  [rows id]
+  {:pre [(pos? (count rows)) (keyword? id)]
+   ; :post [(> (:avg %) 0.1)]
+   }
+  {:min (transduce (map id) min Double/MAX_VALUE temps)
+   :max (transduce (map id) max (- Double/MAX_VALUE) temps)
+   :avg (/ (transduce (map id) + 0 temps) (count temps))})
+
 (defn load-temperatures
   []
   (load-data


Update to boot-cljs-test 0.3.0

Update to boot-cljs-test 0.3.0

Note: this creates warnings.

See https://github.com/irresponsible/oolong/issues/6

--- build.boot
+++ build.boot
@@ -13,7 +13,7 @@
                   [org.clojure/clojurescript "1.9.518"          :scope "test"]
                   [adzerk/boot-cljs "1.7.228-2"                 :scope "test"]
                   [adzerk/boot-test "1.2.0"                     :scope "test"]
-                  [crisptrutski/boot-cljs-test "0.2.2"          :scope "test"]])
+                  [crisptrutski/boot-cljs-test "0.3.0"          :scope "test"]])

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


Turned expected-domain-data helper function into a macro to preserve correct line numbers if an assertion fails.

--- test/clj/elephantdb/service_test.clj
+++ test/clj/elephantdb/service_test.clj
@@ -15,14 +15,17 @@
 (defn multi-get-vals [elephant domain keys]
   (map (memfn get_data) (.multiGet elephant domain keys)))

-(defn expected-domain-data [handler domain & key-value-pairs]
-  (doseq [pair (partition 2 key-value-pairs)]
-    (let [key (first pair)
-          values (second pair)]
-      (if-not (nil? values)
-        (is (barr= (apply barr values)
-                   (get-val handler domain (barr key))))
-        (is (= values (get-val handler domain (barr key))))))))
+(defmacro expected-domain-data [handler domain & key-value-pairs]
+  (let [pair-sym (gensym "pair")
+        key-sym (gensym "key")
+        values-sym (gensym "values")]
+    `(doseq [~pair-sym '~(partition 2 key-value-pairs)]
+       (let [~key-sym (first ~pair-sym)
+             ~values-sym (second ~pair-sym)]
+         (if-not (nil? ~values-sym)
+           (is (barr= (apply barr ~values-sym)
+                      (get-val ~handler ~domain (barr ~key-sym))))
+           (is (= ~values-sym (get-val ~handler ~domain (barr ~key-sym)))))))))

 (deftest test-basic
   (with-sharded-domain [dpath


Fix assertions

Fix assertions

'is' was not used with contains-exactly?

--- test/clj_gatling/simulation_test.clj
+++ test/clj_gatling/simulation_test.clj
@@ -61,20 +61,20 @@

 (deftest simulation-returns-result-when-run-with-one-user
   (let [result (simulation/run-simulation [scenario] 1)]
-    (contains-exactly? result [{:name "Test scenario"
-                                :id 0
-                                :start anything
-                                :end anything
-                                :requests [{:name "Request1"
-                                            :id 0
-                                            :start anything
-                                            :end anything
-                                            :result true}
-                                           {:name "Request2"
-                                            :id 0
-                                            :start anything
-                                            :end anything
-                                            :result false}]}])))
+    (is (contains-exactly? result [{:name "Test scenario"
+                                    :id 0
+                                    :start anything
+                                    :end anything
+                                    :requests [{:name "Request1"
+                                                :id 0
+                                                :start anything
+                                                :end anything
+                                                :result true}
+                                               {:name "Request2"
+                                                :id 0
+                                                :start anything
+                                                :end anything
+                                                :result false}]}]))))

 (deftest simulation-passes-context-through-requests-in-scenario
   (let [result (first (simulation/run-simulation [context-testing-scenario] 1))]
@@ -89,16 +89,16 @@

 (deftest simulation-returns-result-when-run-with-multiple-scenarios-and-one-user
   (let [result (simulation/run-simulation [scenario scenario2] 1)]
-    (contains-exactly? result [{:name "Test scenario"
-                                :id 0
-                                :start anything
-                                :end anything
-                                :requests anything}
-                               {:name "Test scenario2"
-                                :id 0
-                                :start anything
-                                :end anything
-                                :requests anything}])))
+    (is (contains-exactly? result [{:name "Test scenario"
+                                    :id 0
+                                    :start anything
+                                    :end anything
+                                    :requests anything}
+                                   {:name "Test scenario2"
+                                    :id 0
+                                    :start anything
+                                    :end anything
+                                    :requests anything}]))))

 (deftest with-given-number-of-requests
   (let [result (simulation/run-simulation [scenario] 1 {:requests 4})]


Take out a println

Take out a println

--- frontend/controllers/navigation.cljs
+++ frontend/controllers/navigation.cljs
@@ -434,7 +434,6 @@
           docs (or (get-in current-state state/docs-data-path)
                    (let [api-result (<! (ajax/managed-ajax :get (get-in current-state [:render-context :doc_manifest_url])))]
                      (put! api-ch [:doc-manifest (:status api-result) api-result])
-                     (println "API RESULT:" api-result)
                      (doc-utils/format-doc-manifest (:resp api-result))))
           doc (get docs subpage)]
       (cond


♻ Test in terms of input events and output commands

Why:
- It's more in line with how process managers function logically.
  The projection is an implementation detail.

--- test/territory_bro/db_admin_test.clj
+++ test/territory_bro/db_admin_test.clj
@@ -48,37 +48,23 @@
 (defn- apply-events [events]
   (testutil/apply-events db-admin/projection events))

+(defn- generate-commands [events]
+  (->> events apply-events db-admin/generate-commands))
+
 (deftest projection-test
   (testing "congregation created"
-    (let [events [cong-created-event]
-          state (apply-events events)
-          expected {::db-admin/congregations {cong-id {:congregation/id cong-id
-                                                       :congregation/schema-name "cong1_schema"}}
-                    ::db-admin/pending-schemas #{{:congregation/id cong-id
-                                                  :congregation/schema-name "cong1_schema"}}}]
-      (is (= expected state))
+    (let [events [cong-created-event]]
       (is (= [{:command/type :db-admin.command/migrate-tenant-schema
                :congregation/id cong-id
                :congregation/schema-name "cong1_schema"}]
-             (db-admin/generate-commands state)))
+             (generate-commands events)))

       (testing "> schema is present"
-        (let [events (conj events schema-is-present-event)
-              state (apply-events events)
-              expected (merge expected {::db-admin/pending-schemas #{}})]
-          (is (= expected state))
-          (is (empty? (db-admin/generate-commands state)))))
+        (let [events (conj events schema-is-present-event)]
+          (is (empty? (generate-commands events)))))

       (testing "> GIS user created"
-        (let [events (conj events user-created-event)
-              state (apply-events events)
-              expected (merge expected
-                              {::db-admin/pending-gis-users
-                               {[cong-id user-id] {::db-admin/desired-state :present
-                                                   :gis-user/username "username123"
-                                                   :gis-user/password "password123"
-                                                   :congregation/schema-name "cong1_schema"}}})]
-          (is (= expected state))
+        (let [events (conj events user-created-event)]
           ;; TODO: these tests should not care about tenant schema migration
           (is (= [{:command/type :db-admin.command/migrate-tenant-schema
                    :congregation/id cong-id
@@ -89,23 +75,17 @@
                    :user/id user-id
                    :gis-user/password "password123"
                    :gis-user/username "username123"}]
-                 (db-admin/generate-commands state)))
+                 (generate-commands events)))

           (testing "> GIS user is present"
-            (let [events (conj events user-is-present-event)
-                  state (apply-events events)
-                  expected (merge expected {::db-admin/pending-gis-users {}})]
-              (is (= expected state))
+            (let [events (conj events user-is-present-event)]
               (is (= [{:command/type :db-admin.command/migrate-tenant-schema
                        :congregation/id cong-id
                        :congregation/schema-name "cong1_schema"}]
-                     (db-admin/generate-commands state)))))
+                     (generate-commands events)))))

           (testing "> GIS user is absent (undesired)"
-            (let [events (conj events user-is-absent-event)
-                  state (apply-events events)]
-              (is (= expected state)
-                  "no change")
+            (let [events (conj events user-is-absent-event)]
               (is (= [{:command/type :db-admin.command/migrate-tenant-schema
                        :congregation/id cong-id
                        :congregation/schema-name "cong1_schema"}
@@ -115,17 +95,10 @@
                        :user/id user-id
                        :gis-user/password "password123"
                        :gis-user/username "username123"}]
-                     (db-admin/generate-commands state)))))
+                     (generate-commands events)))))

           (testing "> GIS user deleted"
-            (let [events (conj events user-deleted-event)
-                  state (apply-events events)
-                  expected (merge expected
-                                  {::db-admin/pending-gis-users
-                                   {[cong-id user-id] {::db-admin/desired-state :absent
-                                                       :gis-user/username "username123"
-                                                       :congregation/schema-name "cong1_schema"}}})]
-              (is (= expected state))
+            (let [events (conj events user-deleted-event)]
               (is (= [{:command/type :db-admin.command/migrate-tenant-schema
                        :congregation/id cong-id
                        :congregation/schema-name "cong1_schema"}
@@ -134,13 +107,10 @@
                        :congregation/schema-name "cong1_schema"
                        :user/id user-id
                        :gis-user/username "username123"}]
-                     (db-admin/generate-commands state)))
+                     (generate-commands events)))

               (testing "> GIS user is present (undesired)"
-                (let [events (conj events user-is-present-event)
-                      state (apply-events events)]
-                  (is (= expected state)
-                      "no change")
+                (let [events (conj events user-is-present-event)]
                   (is (= [{:command/type :db-admin.command/migrate-tenant-schema
                            :congregation/id cong-id
                            :congregation/schema-name "cong1_schema"}
@@ -149,17 +119,14 @@
                            :congregation/schema-name "cong1_schema"
                            :user/id user-id
                            :gis-user/username "username123"}]
-                         (db-admin/generate-commands state)))))
+                         (generate-commands events)))))

               (testing "> GIS user is absent"
-                (let [events (conj events user-is-absent-event)
-                      state (apply-events events)
-                      expected (merge expected {::db-admin/pending-gis-users {}})]
-                  (is (= expected state))
+                (let [events (conj events user-is-absent-event)]
                   (is (= [{:command/type :db-admin.command/migrate-tenant-schema
                            :congregation/id cong-id
                            :congregation/schema-name "cong1_schema"}]
-                         (db-admin/generate-commands state))))))))))))
+                         (generate-commands events))))))))))))

 (deftest process-test
   (let [spy (spy/spy)


clean up collision test a bit

clean up collision test a bit

--- test/voke/system/collision_test.cljs
+++ test/voke/system/collision_test.cljs
@@ -8,36 +8,37 @@
             [voke.system.collision.util :as collision-util]
             [voke.test-utils :refer [blank-game-state]]))

+(defn make-entity [id x y]
+  {:id        id
+   :collision {:type :foo}
+   :shape     {:width  10
+               :height 10
+               :center {:x x :y y}}})
+
+(defn prepare-for-collision-test [entities collision-events-atom]
+  (doseq [entity entities]
+    (collision-util/-track-entity entity))
+
+  (events/subscribe-to-event :contact
+                             (fn [event]
+                               (swap! collision-events-atom conj event)))
+
+  (assoc blank-game-state
+         :entities
+         (into {}
+               (map (juxt :id identity) entities))))
+
 (deftest two-entities-moving-into-each-other
-  (let [entity-1 {:id        1
-                  :collision {:type :foo}
-                  :shape     {:width  10
-                              :height 10
-                              :center {:x 100
-                                       :y 100}}}
-        entity-2 {:id        2
-                  :collision {:type :foo}
-                  :shape     {:width  10
-                              :height 10
-                              :center {:x 115
-                                       :y 115}}}
-        game-state (-> blank-game-state
-                       (assoc-in [:entities 1] entity-1)
-                       (assoc-in [:entities 2] entity-2))
+  (let [entity-1 (make-entity 1 100 100)
+        entity-2 (make-entity 2 115 115)
         collision-events (atom [])
-        apply-movement-calls (atom [])]
-
-    (collision-util/-track-entity entity-1)
-    (collision-util/-track-entity entity-2)
-
-    (events/subscribe-to-event :contact
-                               (fn [event]
-                                 (swap! collision-events conj event)))
-
+        apply-movement-calls (atom [])
+        game-state (prepare-for-collision-test [entity-1 entity-2] collision-events)]

     (with-redefs [state/contacts-fired (atom #{})
                   collision-util/apply-movement (fn [& args]
                                                   (swap! apply-movement-calls conj args))]
+      ; Two 10x10 entities, moving diagonally into the same spot.
       (system/attempt-to-move! entity-1
                                {:x 105 :y 105}
                                {:x 5 :y 5}
@@ -57,12 +58,8 @@
              [[entity-1 {:x 104.9 :y 104.9} {:x 0 :y 0}]
               [entity-2 {:x 99.9 :y 99.9} {:x 0 :y 0}]])))

-
     (js/Collision.resetState)))

 ; next up: entity is moving up+right, is next to a wall on its right
-
-
 ; also test dead entities / projectiles
-
 ; test that collision type / collides-with works


CMR-7596 updating metadata-preview-gem dependency (#1290)

--- collection-renderer-lib/project.clj
+++ collection-renderer-lib/project.clj
@@ -12,7 +12,7 @@
   {:repo "https://git.earthdata.nasa.gov/scm/cmr/cmr_metadata_preview.git"
    :version "cmr_metadata_preview-0.2.9"
    :commit-id (or (System/getenv "CMR_METADATA_PREVIEW_COMMIT")
-                  "a63c41cadfa")})
+                  "4bdb1669787")})

 (def gem-install-path
   "The directory within this library where Ruby gems are installed."


add some performace notes on each serializer

--- internal/scribe/src/samsara/scribe/core.clj
+++ internal/scribe/src/samsara/scribe/core.clj
@@ -9,22 +9,61 @@
 (defmulti scribe :type)

+
+;; Performances:
+;;  - simple object roundtrip `{:test 1}`
+;;    - Execution time mean           : 2.38 µs
+;;    - Execution time std-deviation  : 110.73 ns
+;;    - Execution time lower quantile : 2.25 µs ( 2.5%)
+;;    - Execution time upper quantile : 2.57 µs (97.5%)
 (defmethod scribe :json
   [config]
   (json/make-json-scribe (dissoc config :type)))

+
+
+;; Performances:
+;;  - simple object roundtrip `{:test 1}`
+;;    - Execution time mean           : 3.84 µs
+;;    - Execution time std-deviation  : 347.84 ns
+;;    - Execution time lower quantile : 3.55 µs ( 2.5%)
+;;    - Execution time upper quantile : 4.27 µs (97.5%)
 (defmethod scribe :edn
   [config]
   (edn/make-edn-scribe (dissoc config :type)))

+
+
+;; Performances:
+;;  - simple object roundtrip `{:test 1}`
+;;    - Execution time mean           : 1.74 µs
+;;    - Execution time std-deviation  : 128.70 ns
+;;    - Execution time lower quantile : 1.51 µs ( 2.5%)
+;;    - Execution time upper quantile : 1.96 µs (97.5%)
 (defmethod scribe :nippy
   [config]
   (nippy/make-nippy-scribe (dissoc config :type)))

+
+
+;; Performances:
+;;  - simple object roundtrip `{:test 1}`
+;;    - Execution time mean : 5.30 µs
+;;    - Execution time std-deviation : 483.02 ns
+;;    - Execution time lower quantile : 4.65 µs ( 2.5%)
+;;    - Execution time upper quantile : 6.40 µs (97.5%)
 (defmethod scribe :fressian
   [_]
   (fressian/make-fressian-scribe))

+
+
+;; Performances:
+;;  - simple object roundtrip `{:test 1}`
+;;    - Execution time mean           : 9.01 µs
+;;    - Execution time std-deviation  : 355.23 ns
+;;    - Execution time lower quantile : 8.67 µs ( 2.5%)
+;;    - Execution time upper quantile : 9.82 µs (97.5%)
 (defmethod scribe :transit
   [config]
   (transit/make-transit-scribe (dissoc config :type)))


Abort run if time-out reached

Abort run if time-out reached

--- jar-async/src/slipstream/async/launcher.clj
+++ jar-async/src/slipstream/async/launcher.clj
@@ -49,7 +49,8 @@
         (if (nil? v)
           (do
             (log-error "Oops... timeout")
-            (swap! errors inc))
+            (swap! errors inc)
+            (Run/abort "Timeout launching run" (.getUuid run)))
           (do
             (log-info "Launched!")
             (swap! completed inc)))))


creating different headers for when a user is authenticated and anonymous

--- src-cljs/bitfondue/core.cljs
+++ src-cljs/bitfondue/core.cljs
@@ -73,6 +73,32 @@
                 (.preventDefault %)
                 (.setToken history token))})

+
+(defn anonymous-header
+  []
+  [:div.container
+   [:a.navbar-brand (nav-helper "/") "bitfondue"]
+   [:ul.nav.navbar-nav
+    [:li.nav-item
+     [:a.nav-link (nav-helper "/features") "Features"]]
+    [:li.nav-item
+     [:a.nav-link (nav-helper "/pricing") "Pricing"]]
+    [:li.nav-item
+     [:a.nav-link (nav-helper "/about") "About"]]]
+   [:ul.nav.navbar-nav.pull-right
+    [:li.nav-item
+     [:a.nav-link (nav-helper "/login") "Login"]]
+    [:li.nav-item
+     [:a.nav-link (nav-helper "/register") "Register"]]]])
+
+(defn authenticated-header
+  []
+  [:div.container
+   [:a.navbar-brand (nav-helper "/dashboard") "bitfondue"]
+   [:ul.nav.navbar-nav.pull-right
+    [:li.nav-item
+     [:a.nav-link (nav-helper "/logout") "Logout"]]]])
+
 (defn header
   []
   [:nav.navbar.navbar-light.bg-faded


compact some code

compact some code

--- src-cljs/flatride/utils.cljs
+++ src-cljs/flatride/utils.cljs
@@ -16,17 +16,12 @@
         lat1 (toRad (:lat from))
         lat2 (toRad (:lat to))
         a (+ (* (Math/sin (/ dLat 2))
-                (Math/sin (/ dLat 2))
-              )
-             (*
-                (Math/sin (/ dLon 2))
+                (Math/sin (/ dLat 2)))
+             (* (Math/sin (/ dLon 2))
                 (Math/sin (/ dLon 2))
                 (Math/cos lat1)
-                (Math/cos lat2)
-              ))
-        c (* 2
-             (Math/atan2 (Math/sqrt a) (Math/sqrt (- 1 a))))
-        ]
+                (Math/cos lat2)))
+        c (* 2 (Math/atan2 (Math/sqrt a) (Math/sqrt (- 1 a))))]
     (* R c)))

 (defn slope-total-distance [elev-objs]


Fixed bugs with cursor implementation from refactoring.

--- src-cljs/freactive/core.cljs
+++ src-cljs/freactive/core.cljs
@@ -374,7 +374,7 @@
   (swap! ref (fn [cur] (setter cur (f (getter cur)))))
   (.rawDeref cursor))

-(deftype ReactiveCursor [id ref getter setter dirty state meta watches fwatches watchers invalidation-watches iwatchers lazy invalidate add-watch-fn remove-watch-fn]
+(deftype ReactiveCursor [id ref getter setter dirty state meta watches fwatches watchers invalidation-watches iwatchers lazy add-watch-fn remove-watch-fn]
   Object
   (equiv [this other]
     (-equiv this other))
@@ -447,7 +447,7 @@

 (apply-js-mixin ReactiveCursor fwatch-mixin)
 (apply-js-mixin ReactiveCursor invalidates-mixin)
-(apply-js-mixin ReactiveExpression rx-mixin)
+(apply-js-mixin ReactiveCursor rx-mixin)

 (defn cursor* [ref korks-or-getter setter lazy]
   (let [id (new-reactive-id)
@@ -463,7 +463,7 @@
                 (when ks
                   (fn [cur new-sub] (assoc-in cur ks new-sub)))
                 (fn [_ _] (assert false "Cursor does not support updates")))
-        cursor (ReactiveCursor. id ref getter setter true nil nil nil #js {} 0 #js {} 0 lazy nil nil nil)
+        cursor (ReactiveCursor. id ref getter setter true nil nil nil #js {} 0 #js {} 0 lazy nil nil)
         ;; invalidate  (make-invalidate-fn cursor id)
         binding-fns (get-binding-fns ref)
         add-watch-fn


Remove Labels -> Collections data migration :tomato:

--- src/metabase/db/migrations.clj
+++ src/metabase/db/migrations.clj
@@ -320,36 +320,3 @@
     :base_type "type/*")
   (db/update-where! 'Field {:special_type [:not-like "type/%"]}
     :special_type nil))
-
-
-;;; +------------------------------------------------------------------------------------------------------------------------+
-;;; |                                                PEMISSIONS COLLECTIONS                                                  |
-;;; +------------------------------------------------------------------------------------------------------------------------+
-
-(s/defn ^:private ^:always-validate random-color :- collection/hex-color-regex
-  []
-  (format "#%06X" (rand-int (Math/pow 256 3))))
-
-(defn- get-or-create-collection!
-  "Create a new Collection for LABEL (if needed). If label had a color, keep it, otherwise give it a random new one."
-  [{label-name :name, icon :icon}]
-  (or (Collection :name label-name)
-      (println (u/format-color 'green "Creating a new collection for label '%s'..." label-name))
-      (db/insert! Collection
-        :name  label-name
-        :color (or (re-matches collection/hex-color-regex icon)
-                   (random-color)))))
-
-(defn- add-label-cards-to-collection!
-  "Add cards that have LABEL to COLLECTION, if they're not already in a Collection."
-  [{label-name :name, :as label} collection]
-  (doseq [card-label (db/select CardLabel :label_id (u/get-id label))]
-    (when-let [card (db/select-one Card :id (:card_id card-label), :collection_id nil)]
-      (println (u/format-color 'blue "Adding card '%s' to collection '%s'..." (:name card) label-name))
-      (db/update! Card (u/get-id card)
-        :collection_id (u/get-id collection)))))
-
-;; create new Collections for existing Labels, and add cards to the one of the newly created collections for them
-(defmigration ^{:author "camsaul", :added "0.22.0"} create-collections-for-labels
-  (doseq [label (db/select Label {:order-by [:%lower.name]})]
-    (add-label-cards-to-collection! label (get-or-create-collection! label))))


Update alfa.clj

Update alfa.clj

--- practice/alfa.clj
+++ practice/alfa.clj
@@ -79,6 +79,19 @@
         (if (= 1 (count ls))
             res
             (recur (rest ls) (conj res (first ls))))))
+
+;;keep
+(defn keep' [f col]
+  (if (= (count col) 0)
+    '()
+    (cons (f (first col)) (keep' f (rest col)))))
+
+(defn keep'' [f col]
+  (loop [i col
+         res []]
+    (if (= (count i) 0)
+      res
+      (recur (rest i) (conj res (f (first i)))))))

 ;; Reimplementing Clojure in pure recursion
 ;; last, butlast, keep, map, take, take-while, remove, drop, drop-while, distinct, range, for


Change status of current post only on publish, do not allow changes to it while PATCHing.

--- src/oc/storage/api/entries.clj
+++ src/oc/storage/api/entries.clj
@@ -74,7 +74,7 @@
         [false, {:reason (.getMessage e)}])) ; Not a valid new entry
     [false, {:reason "Invalid board."}])) ; couldn't find the specified board

-(defn- valid-entry-update? [conn entry-uuid entry-props user]
+(defn- valid-entry-update? [conn entry-uuid entry-props user entry-publish?]
   (if-let [existing-entry (entry-res/get-entry conn entry-uuid)]
     ;; Merge the existing entry with the new updates
     (let [new-board-slug (:board-slug entry-props) ; check if they are moving the entry
@@ -83,9 +83,13 @@
           old-board (when new-board
                       (board-res/get-board conn (:board-uuid existing-entry)))
           new-board-uuid (:uuid new-board)
+          without-status-props (dissoc entry-props :status)
+          with-status-props (if entry-publish?
+                              (assoc without-status-props :status :published)
+                              (assoc without-status-props :status (:status existing-entry)))
           props (if new-board-uuid
-                  (assoc entry-props :board-uuid new-board-uuid)
-                  (dissoc entry-props :board-uuid))
+                  (assoc with-status-props :board-uuid new-board-uuid)
+                  (dissoc with-status-props :board-uuid))
           merged-entry (merge existing-entry (entry-res/ignore-props props))
           updated-entry (-> merged-entry
                           (update :attachments #(entry-res/timestamp-attachments %))
@@ -378,7 +382,7 @@
     :get true
     :patch (fn [ctx] (and (slugify/valid-slug? org-slug)
                           (slugify/valid-slug? board-slug-or-uuid)
-                          (valid-entry-update? conn entry-uuid (:data ctx) (:user ctx))))
+                          (valid-entry-update? conn entry-uuid (:data ctx) (:user ctx) false)))
     :delete true})

   ;; Existentialism
@@ -589,7 +593,7 @@
     :options true
     :post (fn [ctx] (let [entry-props (:data ctx)]
                       (or (nil? entry-props) ; no updates during publish is fine
-                          (valid-entry-update? conn entry-uuid entry-props (:user ctx)))))})
+                          (valid-entry-update? conn entry-uuid entry-props (:user ctx) true))))})
   :new? false
   :respond-with-entity? true


Lower the base of the final chord.

Lower the base of the final chord.

--- src/overtunes/songs/at_all.clj
+++ src/overtunes/songs/at_all.clj
@@ -24,18 +24,21 @@
            (nth scale (+ root 2))
            (nth scale (+ root 4))]))

-(def I (triad ionian 0))
-(def II (triad ionian 1))
-(def V (triad ionian 4))
+(defn lower [note] (- note 12))
+(defn with-base [chord]
+  (assoc chord :base
+         (lower (:i chord))))

-(defn lower [note] (- note 12))
+(def I (with-base (triad ionian 0)))
+(def II (with-base (triad ionian 1)))
+(def V (with-base (triad ionian 4)))

-(def progression [I I II II II V I V])
+(def progression [I I II II II V I (assoc V :base (lower (:base V)))])

 (defn rythm-n-bass# [timing [chord & chords]]
   (do
-    (at (timing 0) (note# (lower (:i chord))))
-    (at (timing 2) (chord# chord))
+    (at (timing 0) (note# (:base chord)))
+    (at (timing 2) (chord# (dissoc chord :base)))
     (rythm-n-bass# (from timing 4) chords)))

 (rythm-n-bass# (bpm 130) (cycle progression))


Remove type hints due to Android dexing error

--- src/play_clj/core_graphics.clj
+++ src/play_clj/core_graphics.clj
@@ -11,7 +11,7 @@
   ([^String path]
     (or (u/load-asset path Pixmap)
         (Pixmap. (files! :internal path))))
-  ([^long width ^long height ^Pixmap$Format fmt]
+  ([width height fmt]
     (Pixmap. width height fmt)))

 (defmacro pixmap


elastic search client code

elastic search client code

--- src/protoml/elastic_search.clj
+++ src/protoml/elastic_search.clj
@@ -16,3 +16,16 @@
   (let [result (esd/create "protoml" "new-transform" document)]
     (info "Output protoml.elastic-search/create-new-transform: " result)
     result))
+
+(defn extract-source [results]
+  "extracts a list of source documents from search results"
+  (if (results :timed_out) [nil "Unable to extract documents, searching timed out"]
+    [(->> results
+         :hits
+         :hits
+         (map #(% :_source))) nil]))
+
+(defn search-new-transform [key value]
+  "searches the new-transform output for a value in a key"
+  (let [results (esd/search "protoml" "new-transform" :query (q/term key value))]
+    (extract-source results)))


Split test

Split test

--- test/beehive/future_test.clj
+++ test/beehive/future_test.clj
@@ -23,13 +23,18 @@
 (defn- remove-false [f ks]
   (filter (fn [func] (func f)) ks))

-(deftest future-status
-  (testing "Test that statuses work correctly."
+(deftest future-test
+  (testing "Test that pending futures work correctly."
     (let [eventual (Eventual.)
           future (f/->BeehiveFuture eventual)]
       (is (= :pending (:status future)))
       (is (:pending? future))
       (is (= [] (remove-false future pending)))
+      (.complete eventual 4)))
+
+  (testing "Test that success futures work correctly."
+    (let [eventual (Eventual.)
+          future (f/->BeehiveFuture eventual)]
       (.complete eventual 4)
       (is (= :success (:status future)))
       (is (:success? future))


Tests for when we are passing an optional salt

--- test/buddy/hashers_tests.clj
+++ test/buddy/hashers_tests.clj
@@ -35,6 +35,27 @@
                        (hashers/encrypt plain-password {:algorithm :sha256})))
     (is (hashers/check plain-password
                        (hashers/encrypt plain-password {:algorithm :md5})))))
+
+
+(deftest buddy-hashers-with-salt
+  (let [plain-password "my-test-password"
+        salt           "saltysalted"]
+    (is (hashers/check plain-password
+                       (hashers/encrypt plain-password {:salt salt})))
+    (is (hashers/check plain-password
+                       (hashers/encrypt plain-password {:algorithm :pbkdf2+sha1 :salt salt})))
+    (is (hashers/check plain-password
+                       (hashers/encrypt plain-password {:algorithm :pbkdf2+sha256 :salt salt})))
+    (is (hashers/check plain-password
+                       (hashers/encrypt plain-password {:algorithm :pbkdf2+sha3_256 :salt salt})))
+    (is (hashers/check plain-password
+                       (hashers/encrypt plain-password {:algorithm :bcrypt+sha512 :salt salt})))
+    (is (hashers/check plain-password
+                       (hashers/encrypt plain-password {:algorithm :scrypt :salt salt})))
+    (is (hashers/check plain-password
+                       (hashers/encrypt plain-password {:algorithm :sha256 :salt salt})))
+    (is (hashers/check plain-password
+                       (hashers/encrypt plain-password {:algorithm :md5 :salt salt})))))

 (deftest confirm-check-failure
@@ -82,3 +103,20 @@
                      :sha256
                      :md5
                      )))
+
+
+(deftest received-salt-embedded-in-hash
+  (let [plain-password "my-test-password"
+        salt           "abcdefgh"]
+    ;; Confirm that the algorithm used is always embedded at the start of the hash,
+    ;; and that the salt is also appended (after being converted to their byte values)
+    (are [algorithm] (.startsWith (hashers/encrypt plain-password {:algorithm algorithm :salt salt})
+                                  (str (name algorithm) "$" (-> salt str->bytes bytes->hex)))
+                     :pbkdf2+sha1
+                     :pbkdf2+sha256
+                     :pbkdf2+sha3_256
+                     :bcrypt+sha512
+                     :scrypt
+                     :sha256
+                     :md5
+                     )))


Added unit test for route map bindings

Added unit test for route map bindings

--- test/compojure/core_test.clj
+++ test/compojure/core_test.clj
@@ -4,7 +4,7 @@
         compojure.core
         compojure.response))

-(deftest route-parameter-arguments
+(deftest route-with-vector-arguments
   ((GET "/foo" [x y]
      (is (= x "bar"))
      (is (= y "baz"))
@@ -12,3 +12,11 @@
    {:request-method :get
     :uri "/foo"
     :params {:x "bar", :y "baz"}}))
+
+(deftest route-with-map-arguments
+  ((GET "/foo" {params :params}
+     (is (= (params {:x "a", :y "b"})))
+     nil)
+   {:request-method :get
+    :uri "/foo"
+    :params {:x "a", :y "b"}}))


persistence: use add-watch instead of error-prone run macro

--- contrib/persistence/src/carry_persistence/core.cljs
+++ contrib/persistence/src/carry_persistence/core.cljs
@@ -1,6 +1,5 @@
 (ns carry-persistence.core
-  (:require [cljs.core.match :refer-macros [match]])
-  (:require-macros [reagent.ratom :refer [run!]]))
+  (:require [cljs.core.match :refer-macros [match]]))

 (defn -save
   [storage key blacklist model]
@@ -25,7 +24,14 @@
                    (when (not= loaded-model :not-found)
                      ((load-wrapper load-from-storage) model loaded-model dispatch-signal))))

-               (run! (-save storage key blacklist @model)))
+               ; save for the first time and on every future change
+               (-save storage key blacklist @model)
+               (add-watch model
+                          [::persistence-watcher key]       ; unique key
+                          (fn [_key _atom old-state new-state]
+                            ; TODO: optimize: compare using blacklist
+                            (when (not= old-state new-state)
+                              (-save storage key blacklist new-state)))))

              [::on-load-from-storage key loaded-model]
              (dispatch-action [::load-from-storage key loaded-model])


testing multi element

testing multi element

--- test/iroh/test_java_util.clj
+++ test/iroh/test_java_util.clj
@@ -18,7 +18,7 @@
                      (object-array [1.0 2.0])))
   => '(1 2.0))

-(fact "paramArgTypeMatch"
+(fact "paramArgTypeMatch basics"
   (.isPrimitive Integer/TYPE)
   => true

@@ -33,3 +33,35 @@

   (.isAssignableFrom clojure.lang.PersistentHashMap java.util.Map)
   => false)
+
+(fact "paramArgTypeMatch"
+  (Util/paramArgTypeMatch Double/TYPE Float/TYPE)
+  => true
+
+  (Util/paramArgTypeMatch Float/TYPE Double/TYPE)
+  => true
+
+  (Util/paramArgTypeMatch Integer/TYPE Float/TYPE)
+  => false
+
+  (Util/paramArgTypeMatch Byte/TYPE Long/TYPE)
+  => false
+
+  (Util/paramArgTypeMatch Long/TYPE Byte/TYPE)
+  => true
+
+  (Util/paramArgTypeMatch Long/TYPE Long)
+  => true
+
+  (Util/paramArgTypeMatch Long Byte)
+  => false
+
+  (Util/paramArgTypeMatch clojure.lang.PersistentHashMap java.util.Map)
+  => false
+
+  (Util/paramArgTypeMatch java.util.Map clojure.lang.PersistentHashMap)
+  => true)
+
+
+(fact "isCongruent"
+  ())


Migrate update

Migrate update

--- src/clojure/clojurewerkz/cassaforte/new_query_api.clj
+++ src/clojure/clojurewerkz/cassaforte/new_query_api.clj
@@ -418,11 +418,6 @@
   (fn [column-name]
     (QueryBuilder/putAll column-name values)))

-(def ^:private insert-order
-  {:where   1
-   :values  2
-   :only-if 4})
-
 (defn- make-assignment
   [[k v]]
   (if (fn? v)
@@ -431,39 +426,60 @@

 (defn only-if
   [m]
-  [:only-if
-   (fn only-if-query [query-builder]
-     (let [[first & more] (to-clauses m)
-           query-builder  (.onlyIf query-builder first)]
-       (doseq [current more]
-         (.and query-builder current))
-       query-builder))])
+  [:only-if m])

 (defn- update-records-statement
   [m]
-  [:values
-   (if (empty? m)
-     (fn update-records-statement-inner [query-builder]
-       query-builder)
-     (fn update-records-statement-inner [query-builder]
-       (let [first-pair    (first m)
-             more-pairs    (rest m)
-             query-builder (.with query-builder (make-assignment first-pair))]
-         (doseq [kvp more-pairs]
-           (.and query-builder (make-assignment kvp)))
-         query-builder))
-     )])
-
-(defn update
-  [table-name records & statements]
-  (->> (conj statements (update-records-statement records))
-       (sort-by #(get insert-order (first %)))
-       (map second)
-       (reduce (fn [builder statement]
-                 (println statement builder)
-                 (statement builder))
-               (QueryBuilder/update (name table-name)))
-       (.toString)))
+  [:values m])
+
+(let [order {:where   1
+             :values  2
+             :only-if 4}
+      renderers
+      {:only-if (fn only-if-query [query-builder]
+                  (let [[first & more] (to-clauses m)
+                        query-builder  (.onlyIf query-builder first)]
+                    (doseq [current more]
+                      (.and query-builder current))
+                    query-builder))
+       :values  (if (empty? m)
+                  (fn update-records-statement-inner [query-builder]
+                    query-builder)
+                  (fn update-records-statement-inner [query-builder]
+                    (let [first-pair    (first m)
+                          more-pairs    (rest m)
+                          query-builder (.with query-builder (make-assignment first-pair))]
+                      (doseq [kvp more-pairs]
+                        (.and query-builder (make-assignment kvp)))
+                      query-builder)))
+       :where   (fn where-query [query-builder m]
+                  (let [query-builder (.where query-builder)]
+                    (doseq [clause (to-clauses m)]
+                      (.and query-builder clause))
+                    query-builder))
+       }
+      ]
+  (defn update
+    [table-name records & statements]
+    (->> (conj statements (update-records-statement records))
+         (sort-by #(get insert-order (first %)))
+         (map second)
+         (reduce (fn [builder statement]
+                   (println statement builder)
+                   (statement builder))
+                 (QueryBuilder/update (name table-name)))
+         (.toString))))
+
+;;
+;; Delete Query
+;;
+
+(comment
+  (defn delete
+    [table-name & ]
+    (->> statements)
+    ))
+

 ;; Delete.Builder delete(String... columns)
 ;; Delete.Selection delete()


fix copy/paste when coming out of overlay

--- src-cljs/frontend/clipboard.cljs
+++ src-cljs/frontend/clipboard.cljs
@@ -197,7 +197,10 @@
                             (sente/send-msg sente-state [:cust/store-clipboard {:key (:key reply)}])))))))

 (defn handle-copy! [app-state e]
-  (when (let [target (.-target e)]
+  (when (let [target js/document.activeElement
+              ;;(.-target e)
+              ;; Have to use activeElement, b/c target won't settle on canvas :/
+              ]
           ;; don't apply if input or textarea is focused, unless the copy-hack
           ;; element is selected (see components.canvas)
           (or (= "_copy-hack" (.-id target))


log start email jobs

log start email jobs

--- src/chat/server/email_digest.clj
+++ src/chat/server/email_digest.clj
@@ -171,5 +171,6 @@

 (defn add-jobs
   [scheduler]
+  (timbre/debugf "scheduling email digest jobs")
   (qs/schedule scheduler (daily-digest-job) (daily-digest-trigger))
   (qs/schedule scheduler (weekly-digest-job) (weekly-digest-trigger)))


Remove debugging code.

Remove debugging code.

--- src/circleci/web/views/index.clj
+++ src/circleci/web/views/index.clj
@@ -29,10 +29,8 @@
   center-vertically [[tag & args]]
     (let [[m & remaining] args
           property-map (into {:class "vcenter1"} (if (map? m) m {}))
-          inner-tags (if (map? m) remaining args)
-          x [tag property-map [:div.vcenter2 (apply vector :div.vcenter3 inner-tags)]]]
-      (println x)
-      x))
+          inner-tags (if (map? m) remaining args)]
+     [tag property-map [:div.vcenter2 (apply vector :div.vcenter3 inner-tags)]]))

 (defpage "/" []


Refresh token balances after adding custom token

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

--- src/status_im/wallet/core.cljs
+++ src/status_im/wallet/core.cljs
@@ -334,7 +334,9 @@
   (let [chain        (ethereum/chain-keyword db)
         settings     (update-toggle-in-settings cofx symbol true)
         new-settings (assoc-in settings [:wallet :custom-tokens chain address] token)]
-    (multiaccounts.update/update-settings cofx new-settings {})))
+    (fx/merge cofx
+              (multiaccounts.update/update-settings cofx new-settings {})
+              (update-balances nil))))

 (fx/defn remove-custom-token
   [{:keys [db] :as cofx} {:keys [symbol address]}]


Add missing translation strings related to icons page.

--- src/uxbox/main/locales/en.cljs
+++ src/uxbox/main/locales/en.cljs
@@ -13,11 +13,14 @@
                       "%s project"
                       "%s projects"]
    "ds.num-colors" ["No colors"
-                      "%s color"
-                      "%s colors"]
+                    "%s color"
+                    "%s colors"]
    "ds.num-images" ["No images"
-                      "%s image"
-                      "%s images"]
+                    "%s image"
+                    "%s images"]
+   "ds.num-icons" ["No icons"
+                   "%s icon"
+                   "%s icons"]
    "ds.project-ordering" "Sort by"
    "ds.project-ordering.by-name" "name"
    "ds.project-ordering.by-last-update" "last update"


Revert "Added save button to webpage"

Revert "Added save button to webpage"

This reverts commit 09bac4cb46ed5f4ce49fdf27e5ff37bb90a355f5.

--- src/wishlistd/views/common.clj
+++ src/wishlistd/views/common.clj
@@ -42,7 +42,6 @@
                 [:div.content
                  [:div.page-header
                   [:h1 "Wishlistd"]
-                  [:input {:id "save-wishlist" :class "btn primary" :type "submit" :value "Save" :style "margin-left:550px;margin-right:-100px"}]
                   [:input {:id "create-wishlist" :class "btn primary" :type "submit" :value "Create wishlist" :style "margin-left:550px;margin-right:-100px"}]]
                 [:div.row
                  [:div.span10


move up content type wrapper

move up content type wrapper

--- src/clj/clj_money/web/server.clj
+++ src/clj/clj_money/web/server.clj
@@ -272,10 +272,10 @@
                [wrap-json-response                  "json response"    api?]
                [wrap-params                         "params"]
                [wrap-exception-handling             "excpetion handling"]
-               [wrap-content-type                   "content-type"]
                [#(friend/wrap-authorize % #{:user}) "authorization"    (complement open?)]
                [wrap-authenticate                   "authentication"   (complement open?)]
                [#(wrap-resource % "public")         "public resources"]
+               [wrap-content-type                   "content-type"]
                [wrap-response-spy                   "response spy"]))

 (defroutes app


Bumped reducers, and added phantom keypair.

--- src/clj/forma/hadoop/cluster.clj
+++ src/clj/forma/hadoop/cluster.clj
@@ -69,7 +69,7 @@
   [nodecount]
   (let [lib-path (str fw-path "/usr/lib")
         mappers 4
-        reducers 2]
+        reducers 3]
     (cluster-spec :private
                   {
                    :jobtracker (node-group [:jobtracker :namenode])
@@ -79,6 +79,7 @@
                                       :hardware-id "m1.large"
                                       ;; :hardware-id "m2.4xlarge"
                                       :image-id "us-east-1/ami-08f40561"
+                                      ;; :key-pair "forma2"
                                       :spot-price (float 0.75)
                                       }
                   :base-props {:hadoop-env {:JAVA_LIBRARY_PATH native-path


Formatting

Formatting

--- src/clj/freestuffly/notifier.clj
+++ src/clj/freestuffly/notifier.clj
@@ -43,4 +43,5 @@

 (defn listen
   []
-  (send-email (presentable (content-for (parsed-html site-tree)))))
+  (send-email
+    (presentable (content-for (parsed-html site-tree)))))


Implement the abacus service routes

Implement the abacus service routes

--- src/clj/mdr2/routes/services.clj
+++ src/clj/mdr2/routes/services.clj
@@ -12,8 +12,10 @@
     [ring.util.http-response :refer :all]
     [clojure.string :refer [blank?]]
     [clojure.java.io :as io]
+    [de.otto.nom.core :as nom]
     [mdr2.db.core :as db]
-    [mdr2.auth :as auth]))
+    [mdr2.auth :as auth]
+    [mdr2.abacus.core :as abacus]))

 (def default-limit 100)

@@ -108,6 +110,46 @@
                          (not-found)))
             }}]]

+   ["/abacus"
+    {:swagger {:tags ["Abacus API"]}}
+
+    ["/new"
+     {:post {:summary "Add a production"
+             :parameters {:multipart {:file multipart/temp-file-part}}
+             :handler (fn [{{{:keys [file]} :multipart} :parameters}]
+                        (let [tempfile (:tempfile file)
+                              p (abacus/import-new-production tempfile)]
+                          (if-not (nom/anomaly? p)
+                            (created)
+                            (bad-request p))))}}]
+    ["/recorded"
+     {:post {:summary "Mark a production as recorded"
+             :parameters {:multipart {:file multipart/temp-file-part}}
+             :handler (fn [{{{:keys [file]} :multipart} :parameters}]
+                        (let [tempfile (:tempfile file)
+                              p (abacus/import-recorded-production tempfile)]
+                          (if-not (nom/anomaly? p)
+                            (no-content)
+                            (bad-request p))))}}]
+    ["/status"
+     {:post {:summary "Request the status of a production"
+             :parameters {:multipart {:file multipart/temp-file-part}}
+             :handler (fn [{{{:keys [file]} :multipart} :parameters}]
+                        (let [tempfile (:tempfile file)
+                              p (abacus/import-status-request tempfile)]
+                          (if-not (nom/anomaly? p)
+                            (no-content)
+                            (bad-request p))))}}]
+    ["/metadata"
+     {:post {:summary "Update the meta data of a production"
+             :parameters {:multipart {:file multipart/temp-file-part}}
+             :handler (fn [{{{:keys [file]} :multipart} :parameters}]
+                        (let [tempfile (:tempfile file)
+                              p (abacus/import-metadata-update tempfile)]
+                          (if-not (nom/anomaly? p)
+                            (no-content)
+                            (bad-request p))))}}]]
+
    ["/files"
     {:swagger {:tags ["files"]}}


edit a todo

edit a todo

--- labs/architecture-examples/om/src/todomvc/item.cljs
+++ labs/architecture-examples/om/src/todomvc/item.cljs
@@ -22,12 +22,13 @@
     false))

 (defn handle-edit [e todo {:keys [owner comm]}]
+  ;; NOTE: we have to grab the node here? - David
   (let [node (dom/get-node owner "editField")]
     (go
       (>! comm [:edit todo])
       (.focus node)
-      (.setSelectionRange node (.. node -value -length) (.. node -value -length))))
-  (om/replace! todo [:edit-text] (:title todo)))
+      (.setSelectionRange node (.. node -value -length) (.. node -value -length))
+      (om/replace! todo [:edit-text] (:title todo)))))

 (defn handle-key-down [e todo opts]
   (if (identical? (.-keyCode e) ESCAPE_KEY)
@@ -37,14 +38,14 @@
 (defn handle-change [e todo]
   (om/replace! todo [:edit-text] (.. e -target -value)))

-(defn todo-item [{:keys [id completed] :as todo} {:keys [comm editing]}]
+(defn todo-item [{:keys [id editing completed] :as todo} {:keys [comm]}]
   (reify
     dom/IRender
     (-render [_ owner]
       (let [m {:owner owner :comm comm}
             classes (cond-> []
                       completed (conj "completed")
-                      (= id editing) (conj "editing"))]
+                      editing   (conj "editing"))]
         (dom/li #js {:className (string/join " " classes)}
           (dom/div #js {:className "view"}
             (dom/input #js {:className "toggle" :type "checkbox"


Fix toggle complete todo function

Fix toggle complete todo function

--- src/cljs/todogo_cljs/db.cljs
+++ src/cljs/todogo_cljs/db.cljs
@@ -96,9 +96,7 @@
     PUT
     (str "/api/v1/list/" (:todo_list_id todo) "/todo/" (:id todo) "/")
     (fn [] (get-todos (:todo_list_id todo)))
-    :data {:title (:title todo)
-           :completed (if (= (:completed todo) true) false true)
-           :note (:note todo)}))
+    :data (assoc todo :completed (if (= (:completed todo) true) false true))))

 (defn update-todo [todo]
   (api-call


Remove unused reference

Remove unused reference

--- src/clojure/neko/context.clj
+++ src/clojure/neko/context.clj
@@ -12,8 +12,7 @@
 (ns neko.context
   "Utilities to aid in working with a context."
   {:author "Daniel Solano Gómez"}
-  (:use [neko.resource :only [get-layout]]
-        [neko.-utils :only [keyword->static-field integer-or-keyword?]])
+  (:use [neko.-utils :only [keyword->static-field integer-or-keyword?]])
   (:import android.content.Context))

 (def ^{:doc "Stores Application instance that acts as context."}


Safely ordered and more thorough catch-all logging

We now log to stdout first, prior to using the system logger. This
avoids a situation where the system logger is misconfigured (or is
otherwise broken) and attempts to log to it would themselves trigger
an exception.

This also allows us to ensure that the information logged to stdout is
properly flushed prior to forwarding the exception to the system
logger. That means we can reduce the likelihood of interleaved output
on stdout.

Finally, we replace the call to `printStackTrace` with the
`print-cause-trace` function that's part of the clojure.stacktrace
library.

Signed-off-by: Deepak Giridharagopal <d11186354d1ef01ca06ae37d7e23e827da13e85f@puppetlabs.com>

--- src/com/puppetlabs/utils.clj
+++ src/com/puppetlabs/utils.clj
@@ -18,6 +18,7 @@
   (:use [clojure.core.incubator :only (-?>)]
         [clojure.java.io :only (reader)]
         [clojure.set :only (difference union)]
+        [clojure.stacktrace :only (print-cause-trace)]
         [clj-time.core :only [now]]
         [clj-time.format :only [formatters unparse]]
         [slingshot.slingshot :only (try+ throw+)]))
@@ -233,8 +234,9 @@
   ([exception]
      (catch-all-logger exception "Uncaught exception"))
   ([exception message]
-     (log/error exception message)
-     (.printStackTrace exception)))
+     (print-cause-trace exception)
+     (flush)
+     (log/error exception message)))

 (defn set-default-uncaught-exception-handler!
   "Sets the JVM global handler for uncaught exceptions to the supplied


Problem added - Map Construction

Problem added - Map Construction

--- src/foreclojure/data_set.clj
+++ src/foreclojure/data_set.clj
@@ -625,4 +625,15 @@
             :tags ["medium" "seqs" "core-functions"]
             :tests ["(= (take 5 (__ + (range))) [0 1 3 6 10])"
                     "(= (__ conj [1] [2 3 4]) [[1] [1 2] [1 2 3] [1 2 3 4]])"
-                    "(= (last (__ * 2 [3 4 5])) (reduce * 2 [3 4 5]) 120)"]})))
+                    "(= (last (__ * 2 [3 4 5])) (reduce * 2 [3 4 5]) 120)"]})
+
+      (insert! :problems
+           {:_id 61
+            :title "Map Construction"
+            :times-solved 0
+            :restricted ["zipmap"]
+            :description "Write a function which takes a vector of keys and a vector of values and constructs a map from them."
+            :tags ["easy" "core-functions"]
+            :tests ["(= (__ [:a :b :c] [1 2 3]) {:a 1, :b 2, :c 3})"
+                    "(= (__ [1 2 3 4] [\"one\" \"two\" \"three\"]) {1 \"one\", 2 \"two\", 3 \"three\"})"
+                    "(= (__ [:foo :bar] [\"foo\" \"bar\" \"baz\"]) {:foo \"foo\", :bar \"bar\"})"]})))


Updated docs for selected functions

Updated docs for selected functions

--- src/emender_jenkins/rest_api.clj
+++ src/emender_jenkins/rest_api.clj
@@ -22,6 +22,7 @@
 (require '[emender-jenkins.config           :as config])
 (require '[emender-jenkins.jenkins-api      :as jenkins-api])
 (require '[emender-jenkins.metadata-reader  :as metadata-reader])
+(require '[emender-jenkins.file-utils       :as file-utils])

 ; command names used by various REST API responses
 (def commands {
@@ -43,23 +44,28 @@
     :not-implemented       501})

 (defn read-request-body
+    "Read all informations from the request body."
     [request]
     (file-utils/slurp- (:body request)))

 (defn body->results
+    "Try to parse the request body as JSON format."
     [body]
     (json/read-str body))

 (defn body->job-info
+    "Try to parse the request body as JSON format and keywordize keys."
     [body]
     (json/read-str body :key-fn clojure.core/keyword))

 (defn get-job-name
+    "Common function to retrieve job name from given data structure."
     [json]
     (if json
         (get json :name)))

 (defn get-job-name-from-body
+    "Returns job name from request body or nil if any exception happens."
     [request]
     (try
         (-> (read-request-body request)
@@ -329,6 +335,7 @@
     (send-response {:status "ok"} request))

 (defn unknown-call-handler
+    "Function called for all unknown API calls."
     [request uri method]
     (let [response {:status :error
                     :error "Unknown API call"


remove unneeded :init option

remove unneeded :init option

--- ex2b/src/ex2b/filter.clj
+++ ex2b/src/ex2b/filter.clj
@@ -1,8 +1,7 @@
 (ns ex2b.filter
   (:import (javax.servlet Filter FilterChain FilterConfig
                           ServletRequest ServletResponse))
-  (:gen-class :implements [javax.servlet.Filter]
-              :init finit))
+  (:gen-class :implements [javax.servlet.Filter]))

 (defn -doFilter
   [^Filter this


fix unread chat count when you've never read a chat

--- src-cljs/frontend/models/chat.cljs
+++ src-cljs/frontend/models/chat.cljs
@@ -18,7 +18,7 @@

 (defn compute-unread-chat-count [db last-read-time]
   (if-not last-read-time
-    0
+    (find-count db)
     (count (chat-timestamps-since db last-read-time))))

 (defn display-name [chat sente-id]


fix issue with firefox focus

fix issue with firefox focus

--- iwaswhere-web/src/cljs/iwaswhere_web/ui/edit.cljs
+++ iwaswhere-web/src/cljs/iwaswhere_web/ui/edit.cljs
@@ -41,7 +41,7 @@
                              md-string])}))

 (defn autocomplete-tags
-  ""
+  "Render autocomplete option for the partial tag (or mention) before the cursor."
   [before-cursor regex-prefix tags]
   (let [current-tag (re-find (js/RegExp. (str regex-prefix h/tag-char-class "+$") "m") before-cursor)
         current-tag-regex (js/RegExp. current-tag "i")
@@ -104,10 +104,10 @@
                                 (when (and curr-mention (seq f-mentions))
                                   (tag-replace-fn curr-mention (first f-mentions)))
                                 (.preventDefault ev))))]
-
-        (when-not (= @last-saved latest-entry) (reset! last-saved latest-entry)
-                                               (reset! local-display-entry latest-entry)
-                                               (reset! local-saved-entry latest-entry))
+        (when (and (not new-entry?) (not= @last-saved latest-entry))
+          (reset! last-saved latest-entry)
+          (reset! local-display-entry latest-entry)
+          (reset! local-saved-entry latest-entry))
         [:div.edit-md
          [:pre [editable-code-elem md-string update-temp-fn on-keydown-fn edit-elem-atom]]
          [suggestions entry f-tags curr-tag tag-replace-fn "hashtag"]


Starting SG indicies now vary wildly, from -70 to 70

--- src/hphelper/shared/indicies.clj
+++ src/hphelper/shared/indicies.clj
@@ -34,11 +34,11 @@
                              inds)))))

 (defn create-base-indicies-list
-  "Combines the base indicies with sg indicies, and sets them all to 0"
+  "Combines the base indicies with sg indicies, sets sector indices to 0 and sg indicies to random number between -70 and 70"
   []
   (merge
    (reduce merge (map (fn [k] {k 0}) sectorIndicies))
-   (reduce merge (map (fn [k] {k 0}) (map (comp keyword :sg_abbr)
+   (reduce merge (map (fn [k] {k (- (rand-int 141) 70)}) (map (comp keyword :sg_abbr)
                                           (sql/query "SELECT sg_abbr FROM sg"))))))

 (defn normalise-specific-indicies
@@ -68,7 +68,8 @@
 (defn fuzzify-indicies
   "Randomly adds, subtracts, or leaves alone each of the indicies"
   [indicies]
-  ((apply comp (map (fn [kw] (fn [ind] (update-in ind [kw] + (dec (rand-int 3)))))
+  ((apply comp (map (fn [kw] (fn [ind]
+                               (update-in ind [kw] + (dec (rand-int 3)))))
                     (keys indicies))
           )
    indicies))


Fix tracker operation label to place period in right place

--- src/io/aviso/rook/dispatcher.clj
+++ src/io/aviso/rook/dispatcher.clj
@@ -439,7 +439,7 @@
 (defn- expand-namespace-entry
   [[context ns-sym arg-resolvers middleware ns-metadata]]
   (t/track
-    #(format "Identifying endpoints in namespace `%s.'" ns-sym)
+    #(format "Identifying endpoints in namespace `%s'." ns-sym)
     (let [ns-metadata' (dissoc ns-metadata :doc)
           arg-resolvers' (merge-arg-resolver-maps arg-resolvers (:arg-resolvers ns-metadata'))]
       (->> ns-sym


Adjust the way route parameters are extracted from a request for a specific endpoint

--- src/io/aviso/rook/dispatcher.clj
+++ src/io/aviso/rook/dispatcher.clj
@@ -374,20 +374,28 @@
    (fn [request]
      (let [[request-method request-path] (request-route-spec request)]
        (loop [remaining-path request-path
-              dispatch dispatch-map
-              route-param-vals []]
+              dispatch dispatch-map]
          (if-let [seg (first remaining-path)]
            (if (contains? dispatch seg)
-             (recur (next remaining-path) (get dispatch seg) route-param-vals)
+             (recur (next remaining-path) (get dispatch seg))
+             ;; ::param is a special value that indicates a keyword parameter
+             ;; in the route at that point, which matches any value. If so,
+             ;; the value is more dispatch map so recurse into it.
              (if-let [dispatch' (::param dispatch)]
-               (recur (next remaining-path) dispatch' (conj route-param-vals seg))
-               ;; no match on path
+               (recur (next remaining-path) dispatch')
+               ;; Hit a term on the request path that does not map to either a sub-tree
+               ;; or a leaf, so give up.
                not-found-response))
-           (if-let [{:keys [handler route-param-keys]}
-                    (or (get dispatch request-method)
-                        (get dispatch :all))]
-             (let [route-params (zipmap route-param-keys route-param-vals)]
-               (handler (assoc request :route-params route-params)))
+           ;; Having exhausted the string (or parameter) terms in the
+           ;; request path, this final match is on the method.
+           ;; Some endpoints are mapped to :all. That gets us to a leaf node,
+           ;; which defines the handler (a wrapper around the endpoint function)
+           ;; and the mapping of route parameters.
+           (if-let [{:keys [handler route-params]} (or (get dispatch request-method)
+                                                       (get dispatch :all))]
+             (-> request
+                 (assoc :route-params (medley/map-vals (partial nth request-path) route-params))
+                 handler)
              ;; unsupported method for path
              not-found-response)))))))

@@ -501,10 +509,20 @@
   [dispatch-map method pathvec handler]
   (let [pathvec' (mapv #(if (variable? %) ::param %) pathvec)
         dispatch-path (conj pathvec' method)
-        route-params (filterv variable? pathvec)]
+        ;; maps keyword (from the route) to index into the path for the value.
+        ;; This is used inside map-traversal-dispatcher to set the :route-params
+        ;; request key.
+        route-params (reduce-kv (fn [m i elem]
+                                  (if (variable? elem)
+                                    (assoc m (keyword elem) i)
+                                    m))
+                                {} pathvec)]
+    ;; This dispatch path is a vector of strings (or the ::param placeholder for a keyword
+    ;; route parameter), terminated with a method keyword (:get, :put, etc., or :all). The
+    ;; value is the leaf node, identifying the particular endpoint function to invoke.
     (assoc-in dispatch-map dispatch-path
-              {:handler          handler
-               :route-param-keys (mapv keyword route-params)})))
+              {:handler      handler
+               :route-params route-params})))

 (defn- build-dispatch-map
   "Returns a dispatch-map for use with map-traversal-dispatcher."