Commenting.

Commenting.

--- src/poky/benchmark/simple.clj
+++ src/poky/benchmark/simple.clj
@@ -12,10 +12,17 @@
 (def pg-default-date (tf/formatter pg-default-time-fmt))

 (defn csv-time->timestamp
+  "Convert a timestamp in it's default format to something that JDBC can use for comparison to a timestamp."
   [str-ts]
   (tc/to-timestamp (tf/parse pg-default-date str-ts)))

 (defn load-lookup-set
+  "Load the rows from the given file hashed by the first column which should be the bucket. The expected format is:
+
+  bucket,key,modified_at
+
+  The modified_at should be rounded to the second.
+  "
   [m file]
   (let [lines (util/read-file file)
         csv (map #(clojure.string/split % #",") lines)]
@@ -25,11 +32,22 @@
                          conj {:key (second row) :modified_at (csv-time->timestamp (last row)) }))
             m csv)))

+
 (defn load-lookup-sets
-  [files]
-  (reduce load-lookup-set {} files))
+  "Loads all of the files into an empty map"
+  ([m files]
+   (reduce load-lookup-set m files))
+  ([files]
+   (load-lookup-sets {} files)))

 (defn create-mget-bench-input
+  "Create mget benchmark input. This function takes a loaded map from (load-lookup-sets) and creates tupels of
+  of the form
+
+  (bucket {:key \"k1\" :modified_at \"ts\"} ...)
+
+  with request-size maps for input into jdbc-mget.
+  "
   [m request-size]
   (let [by-bucket (map (fn [bucket]
                          ; split the k,v pairs up into the request size blocks
@@ -41,13 +59,13 @@

 (comment
-  (bench/bench
+  (bench/bench-jdbc-mget
     (connection (system/store S))
     ["tmp/mothering.csv" "tmp/basenotes.csv" "tmp/avsforum.csv" "tmp/headfi.csv"]
     30))

 (defn bench-jdbc-mget
-  "Benchmark jdbc-mget."
+  "Benchmark jdbc-mget using the given list of input files and a request size."
   [conn input-files request-size &{:keys [check] :or [check #(count (get % :data ""))]}]
   (let [m (load-lookup-sets input-files)
         sets (create-mget-bench-input m request-size)


Twiddling with the db-spec format to get something that plays will on both Heroku and dev

--- src/org/gensym/viddy/run.clj
+++ src/org/gensym/viddy/run.clj
@@ -12,8 +12,22 @@
            (* 1000 60))]
     (fn [] (sched/shutdown! s))))

+
+(defn- to-db-spec [uristring]
+  (let [uri (java.net.URI. uristring)
+        without-auth     {:subprotocol "postgresql"
+                          :subname (str "//" (.getHost uri) ":"
+                                        (.getPort uri)
+                                        (.getPath uri))}]
+    (if-let [user-info (.getUserInfo uri)]
+      (let [[user password] (clojure.string/split user-info #":")]
+        (merge  without-auth
+                {:user user
+                 :password password}))
+      without-auth)))
+
 (defn start [port]
-  (let [db-spec  {:connection-uri (str "jdbc:" (System/getenv "DATABASE_URL"))}
+  (let [db-spec (to-db-spec  (System/getenv "DATABASE_URL"))
         server (jetty/make-jetty-server (webapp/handler db-spec) port)
         schedulers (start-schedulers db-spec)]
     (.start server)
@@ -21,6 +35,8 @@
       (schedulers)
       (.stop server))))

+
+
 (defn -main []
   (let [port (Integer/parseInt
               (or (System/getenv "PORT") "8080"))]


Use when instead of if for one case conditional

--- src/petulant_life/shader.clj
+++ src/petulant_life/shader.clj
@@ -23,9 +23,8 @@

 ;; Loading a shader if it exists.
 (defn load-if-exists [path type]
-  (if (.exists (as-file path))
-    (load-shader path type)
-    nil))
+  (when (.exists (as-file path))
+    (load-shader path type)))

 ;; Loading a bunch of shaders and returning them in one map.
 (defn load-shaders [src-path]


Multiple tabs working a bit better.

Multiple tabs working a bit better.

--- src/brevis/ui/core.clj
+++ src/brevis/ui/core.clj
@@ -24,7 +24,8 @@
            (java.io ByteArrayInputStream)
            [java.io File]
            [javax.swing.filechooser FileSystemView]
-           java.awt.Font)
+           java.awt.Font
+           [java.awt Component])
   (:require
     [brevis.ui.keybinds :as keybinds]
     [clojure.string :as string]
@@ -38,6 +39,10 @@
     [leiningen.core.main :as lein-main])
   (:use [clojure.java.io :only [file]]
         [clojure.pprint]
+        [seesaw.util :only [illegal-argument to-seq check-args
+                            constant-map resource resource-key?
+                            to-dimension to-insets to-url try-cast
+                            cond-doto to-mnemonic-keycode]]
         [seesaw core font color graphics chooser mig tree]
         [brevis.ui.profile])
   (:gen-class
@@ -83,56 +88,10 @@
 (def repl-outputstream
   (atom nil))

+(def content-pane-params (atom {}))
+
 (def ui-window
   "The complete UI panel." (atom nil))
-
-#_(def keybind-handlers
-   "Map of keybinds."
-   (atom {}))
-
-#_(defn add-keybind-handler
-   "Add a keybind handler.
-event-type is a map with at least
-  - :type in [:keyPressed]
-  - :context in [:input-type]]
-predicate is (fn [e] ...)
-response is (fn [e context] ...) where e is an Event, and context is a hash-map with relevant widgets and such"
-   [name event-type predicate response]
-   #_(println "Adding keybind:" name)
-   (swap! keybind-handlers assoc
-          (str "keybind_" name) #_(gensym "keybind")
-          {:event-type event-type,
-           :predicate predicate,
-           :response response}))
-
-#_(defn add-keybind-handler
-    "Add a keybind handler.
-event-type is a map with at least
-  - :type in [:keyPressed]
-  - :context in [:input-type]]
-keystroke :
-KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,
-                            java.awt.event.InputEvent.CTRL_DOWN_MASK)
-or
-KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,
-                       java.awt.event.InputEvent.CTRL_DOWN_MASK
-                       | java.awt.event.InputEvent.SHIFT_DOWN_MASK)
-response is (fn [e context] ...) where e is an Event, and context is a hash-map with relevant widgets and such"
-    [name event-type keystroke response]
-    #_(println "Adding keybind:" name)
-    (swap! keybind-handlers assoc
-           (str "keybind_" name) #_(gensym "keybind")
-           {:event-type event-type,
-            :keystroke keystroke,
-            :response response}))
-
-;component.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,
-;                            java.awt.event.InputEvent.CTRL_DOWN_MASK),
-;                    "actionMapKey");
-;component.getActionMap().put("actionMapKey",
-;                     someAction);
-
-;;

 (def chooser (javax.swing.JFileChooser.)) ; FileChooser hack to get system icons
 (def current-filename (atom nil))
@@ -166,10 +125,22 @@
           (.setText (:text-area (get-editor)) "")
           #_(set-status "Created a new file.")))))

+(defn is-open?
+  "Check if a file is already open."
+  [filename]
+  (let [num-tabs (.getTabCount (:tabbed-panel @editor-window))
+        tab-names (map #(.getName (.getTabComponentAt (:tabbed-panel @editor-window) %)) (range num-tabs))]
+    (some #(= filename %) tab-names)))
+
+(declare add-content-tab-from-filename)
+(defn open-file
+  "Open a file and add  the tab if it isnt already open."
+  [filename]
+  (when-not (is-open? filename);; could make tab active if it is already open
+    (add-content-tab-from-filename filename @content-pane-params)))
+
 (defn a-open [e]
-  (let [selected (select-file)] #_(set-current-file selected)
-    (.setText (:text-area (get-editor)) (slurp selected))
-    #_(set-status "Opened " filename ".")))
+  (open-file (select-file)))

 (defn a-save [e]
   (spit @current-filename (.getText (:text-area (get-editor))))
@@ -279,83 +250,66 @@
     (make-project-window proj)
     #_(println "Switching project:" proj)))

-#_(defn make-editor-window
-     "Make an editor window."
-     [params]
-     (let [
-           textArea (RSyntaxTextArea. 42 115)
-           ;textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
-           ;textArea.setCodeFoldingEnabled(true);
-           sp (RTextScrollPane. textArea)
-           a-new (action :handler a-new :name "New" :tip "Create a new file.")
-           a-open (action :handler a-open :name "Open" :tip "Open a file")
-           a-save (action :handler a-save :name "Save" :tip "Save the current file.")
-           a-exit (action :handler a-exit :name "Exit" :tip "Exit the editor.")
-           a-copy (action :handler a-copy :name "Copy" :tip "Copy selected text to the clipboard.")
-           a-paste (action :handler a-paste :name "Paste" :tip "Paste text from the clipboard.")
-           a-cut (action :handler a-cut :name "Cut" :tip "Cut text to the clipboard.")
-           a-save-as (action :handler a-save-as :name "Save As" :tip "Save the current file.")
-           a-eval-file (action :handler a-eval-file :name "Evaluate" :tip "Evaluate the current file.")
-           a-projects (map #(action :handler (make-a-active-project %)
-                                    :name (str (:group %) "/" (:name %))
-                                    :tip (str (:group %) "/" (:name %)))
-                           (:projects @current-profile))
-           menus (menubar
-                   :items [(menu :text "File" :items [a-new a-open a-save a-save-as a-exit])
-                           (menu :text "Edit" :items [a-copy a-cut a-paste])
-                           (menu :text "Run" :items [a-eval-file])
-                           (menu :text "Projects" :items (into [] a-projects))
-                           (menu :text "Git" :items [])
-                           #_(menu :text "My Project" :items [(action :handler (fn [e] nil) :name "Open a project")
-                                                             (action :handler (fn [e] nil) :name "in")
-                                                             (action :handler (fn [e] nil) :name "projects menu")])])
-           f (frame :title "Brevis - Editor Window" :menubar menus)]
-       (.setSyntaxEditingStyle textArea (cond (= (:language params) :java)
-                                              (SyntaxConstants/SYNTAX_STYLE_JAVA)
-                                              :else
-                                              (SyntaxConstants/SYNTAX_STYLE_CLOJURE)))
-       (.setCodeFoldingEnabled textArea true)
-       (display f sp)
-       (-> f pack! show!)
-       (.setLocation f 0 0)
-       {:frame f
-        :text-area textArea
-        :scroll-pane sp
-        :menus menus}))
-
-#_(def input-text-keyhandler
-   (proxy [java.awt.event.KeyAdapter] []
-     (keyPressed [#^java.awt.event.KeyEvent e]
-       (doseq [[kid keybind] @keybind-handlers]
-         (println "Testing keybind:" kid)
-         (println (= (:context (:event-type keybind)) :input-text)
-                    (= (:type (:event-type keybind)) :keyPressed)
-                    ((:predicate keybind) e))
-         (when (and (= (:context (:event-type keybind)) :input-text)
-                    (= (:type (:event-type keybind)) :keyPressed)
-                    ((:predicate keybind) e))
-           (try ((:response keybind) e
-                                     (get-editor))
-             (catch Exception e (println (.getMessage e))))
-           (.consume e))))))
-
+(def ^{:private true} make-icon icon)
+
+(defn add-content-tab
+  "Add a tab to the content pane."
+  [tab-map]
+  (let [tp (:tabbed-panel @editor-window)
+        {:keys [title content tip icon]} tab-map
+        title-cmp (try-cast Component title)
+        index (.getTabCount tp)]
+    (cond-doto tp
+               true (.addTab (if-not title-cmp (resource title)) (make-icon icon) (make-widget content) (resource tip))
+               title-cmp (.setTabComponentAt index title-cmp))))
+
+(defn add-content-tab-from-filename
+  "Add a tab for a filename, autoconstruct the component."
+  [filename params]
+  (let [textArea (RSyntaxTextArea. 42 115)
+        sp (RTextScrollPane. textArea)]
+    (when (:keybinds params)
+             (doseq [keybind (:keybinds params)]
+               #_(println keybind)
+               (.put (.getInputMap textArea)
+                 (:keystroke keybind)
+                 (:action keybind))
+               #_(.put (.getActionMap textArea)
+                  (:name keybind)
+                  (:action keybind))))
+    (.setSyntaxEditingStyle textArea (cond (= (:language params) :java)
+                                           (SyntaxConstants/SYNTAX_STYLE_JAVA)
+                                           :else
+                                           (SyntaxConstants/SYNTAX_STYLE_CLOJURE)))
+    (.setCodeFoldingEnabled textArea true)
+    (.setText textArea (slurp filename))
+    (add-content-tab {:title (label;; title is not a string but a label component
+                               :id (str (gensym "editor-panel"))
+                               ;; current-filename isn't set when this function is called
+                               :text filename #_(last (string/split @current-filename #"/")) #_@current-filename;; with text set to txt
+                               :foreground :blue)
+                      ;:filename @current-filename
+                      :tip @current-filename
+                      :icon (.getIcon chooser (file @current-filename))
+                      :content (RTextScrollPane. textArea)})))
+
 (defn make-editor-window
      "Make an editor window."
      [params]
-     (let [textArea (RSyntaxTextArea. 42 115)
+     (let [;textArea (RSyntaxTextArea. 42 115)
            ;textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
            ;textArea.setCodeFoldingEnabled(true);
-           sp (RTextScrollPane. textArea)
+           ;sp (RTextScrollPane. textArea)
            tabs (tabbed-panel :placement :top ;:overflow :wrap
-                              :tabs [{:title (label;; title is not a string but a label component
-                                                   :id (str (gensym "editor-panel"))
-                                                   ;; current-filename isn't set when this function is called
-                                                   :text "*current*"#_(last (string/split @current-filename #"/")) #_@current-filename;; with text set to txt
-                                                   :foreground :blue)
-                                      #_@current-filename
-                                      :tip @current-filename
-                                      :icon (.getIcon chooser (file @current-filename))
-                                      :content sp}])
+                              :tabs [#_{:title (label;; title is not a string but a label component
+                                                    :id (str (gensym "editor-panel"))
+                                                    ;; current-filename isn't set when this function is called
+                                                    :text @current-filename #_(last (string/split @current-filename #"/")) #_@current-filename;; with text set to txt
+                                                    :foreground :blue)
+                                       #_@current-filename
+                                       :tip @current-filename
+                                       :icon (.getIcon chooser (file @current-filename))
+                                       :content sp}])
            a-new (action :handler a-new :name "New" :tip "Create a new file.")
            a-open (action :handler a-open :name "Open" :tip "Open a file")
            a-save (action :handler a-save :name "Save" :tip "Save the current file.")
@@ -381,28 +335,29 @@
            ;f (frame :title "Brevis - Editor Window" :menubar menus)
            ]
        #_(.addKeyListener textArea input-text-keyhandler)
-       (when (:keybinds params)
-         (doseq [keybind (:keybinds params)]
-           #_(println keybind)
-           (.put (.getInputMap textArea)
-             (:keystroke keybind)
-             (:action keybind))
-           #_(.put (.getActionMap textArea)
-              (:name keybind)
-              (:action keybind))))
-       (.setSyntaxEditingStyle textArea (cond (= (:language params) :java)
-                                              (SyntaxConstants/SYNTAX_STYLE_JAVA)
-                                              :else
-                                              (SyntaxConstants/SYNTAX_STYLE_CLOJURE)))
-       (.setCodeFoldingEnabled textArea true)
+       #_(when (:keybinds params)
+          (doseq [keybind (:keybinds params)]
+            #_(println keybind)
+            (.put (.getInputMap textArea)
+              (:keystroke keybind)
+              (:action keybind))
+            #_(.put (.getActionMap textArea)
+               (:name keybind)
+               (:action keybind))))
+       #_(.setSyntaxEditingStyle textArea (cond (= (:language params) :java)
+                                               (SyntaxConstants/SYNTAX_STYLE_JAVA)
+                                               :else
+                                               (SyntaxConstants/SYNTAX_STYLE_CLOJURE)))
+       #_(.setCodeFoldingEnabled textArea true)
        #_(display f sp)
        #_(-> f pack! show!)
        #_(.setLocation f 0 0)
        {;:frame f
-        :text-area textArea
+        ;:text-area textArea
         :tabbed-panel tabs
-        :scroll-pane sp
-        :menus menus}))
+        ;:scroll-pane sp
+        :menus menus
+        }))

 (defn get-repl-inputstream
   "Return the input stream for the REPL."
@@ -413,76 +368,6 @@
   "Return the output stream for the REPL."
   []
   @repl-outputstream)
-
-#_(defn make-repl-input-window
-     "Make a REPL input window."
-     [params]
-     (let [textArea (RSyntaxTextArea. 25 115)
-           ;textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
-           ;textArea.setCodeFoldingEnabled(true);
-           sp (RTextScrollPane. textArea)
-           a-new (action :handler a-new :name "New" :tip "Create a new file.")
-           a-open (action :handler a-open :name "Open" :tip "Open a file")
-           a-save (action :handler a-save :name "Save" :tip "Save the current file.")
-           a-exit (action :handler a-exit :name "Exit" :tip "Exit the editor.")
-           a-copy (action :handler a-copy :name "Copy" :tip "Copy selected text to the clipboard.")
-           a-paste (action :handler a-paste :name "Paste" :tip "Paste text from the clipboard.")
-           a-cut (action :handler a-cut :name "Cut" :tip "Cut text to the clipboard.")
-           a-save-as (action :handler a-save-as :name "Save As" :tip "Save the current file.")
-           menus (menubar
-                   :items [#_(menu :text "File" :items [a-new a-open a-save a-save-as a-exit])
-                           (menu :text "Edit" :items [a-copy a-cut a-paste])])
-           f (frame :title "Brevis - REPL Input" :menubar menus)]
-       (.addKeyListener textArea
-         (proxy [java.awt.event.KeyAdapter] []
-           (keyPressed [#^java.awt.event.KeyEvent e]
-             (when (= (.getKeyCode e) java.awt.event.KeyEvent/VK_UP)
-               (try
-                 (let [startPosition 0]
-                   (.remove (.getDocument textArea) startPosition (- (.getLength (.getDocument textArea)) startPosition 1))
-                   (.setText textArea (nth @repl-input (- (dec (count @repl-input)) @repl-input-index)))
-                   (reset! repl-input-index (min (inc @repl-input-index) (dec (count @repl-input))))
-                   #_(.setText textArea (last @repl-input)))
-                 (catch Exception e (println (.getMessage e))))
-               (.consume e))
-             (when (= (.getKeyCode e) java.awt.event.KeyEvent/VK_DOWN)
-               (try
-                 (let [startPosition 0]
-                   (.remove (.getDocument textArea) startPosition (- (.getLength (.getDocument textArea)) startPosition 1))
-                   (.setText textArea (nth @repl-input (- (dec (count @repl-input)) @repl-input-index)))
-                   (reset! repl-input-index (max (dec @repl-input-index) 0))
-                   #_(.setText textArea (last @repl-input)))
-                 (catch Exception e (println (.getMessage e))))
-               (.consume e))
-             (when (= (.getKeyCode e) java.awt.event.KeyEvent/VK_ENTER)
-               (.append textArea "\n")
-               ;; This shouldn't be here:
-               #_(text! (:text-area @repl-output-window) (.toString (get-repl-outputstream)))
-               (try
-                 (let [startPosition 0
-                       line (.getText textArea startPosition (- (.getLength (.getDocument textArea)) startPosition 1))
-                       ;response-vals (nrepl/message (:client @repl) {:op "eval" :code line})
-                       #_session-sender #_(nrepl/client-session @reply.eval-modes.nrepl/current-connection :session @reply.eval-modes.nrepl/current-session)]
-                   (reset! repl-input-index 0)
-                   (.setText textArea "")
-                   (eval-and-print line true)
-                   ;; Add to a console history
-                   )
-                 (catch Exception e (println (.getMessage e))))
-               (.consume e)))))
-       (.setSyntaxEditingStyle textArea (cond (= (:language params) :java)
-                                              (SyntaxConstants/SYNTAX_STYLE_JAVA)
-                                              :else
-                                              (SyntaxConstants/SYNTAX_STYLE_CLOJURE)))
-       #_(.setCodeFoldingEnabled textArea true)
-       (display f sp)
-       (-> f pack! show!)
-       #_(println (.getLocation f))
-       (.setLocation f 0 680)
-       {:frame f
-        :text-area textArea
-        :scroll-pane sp
-        :menus menus}))

 (defn make-repl-input-window
      "Make a REPL input window."
@@ -555,28 +440,6 @@
         :scroll-pane sp
         :menus menus}))

-#_(defn make-repl-output-window
-    "Make an editor window."
-    [params]
-    (let [f (frame :title "Brevis - REPL Output" :width 800 :height 200 :minimum-size [800 :by 360])
-          text-area (text :multi-line? true :font "MONOSPACED-PLAIN-14"
-                                           :text "> ")
-          area (scrollable text-area)
-          listener-thread (Thread. (fn []
-                                     (loop []
-                                       (let [resp (nrepl.transport/recv (:client @repl) 20)]
-                                         (when resp
-                                           (when (:out resp) (write-stdout-repl (:out resp)))
-                                           (when (:value resp) (write-value-repl (:value resp)))))
-                                       (recur))))]
-     (display f area)
-     (-> f pack! show!)
-     (.setLocation f 850 650)
-     {:frame f
-      :scrollable area
-      :listener-thread listener-thread
-      :text-area text-area}))
-
 (defn make-repl-output-window
     "Make an editor window."
     [params]
@@ -671,9 +534,11 @@
               (if-let [dir (last (selection e))]
                 (let [files (.listFiles dir)]
                   (when (and (.isFile dir)
-                             (or (.contains (.toString dir) "clj") (.contains (.toString dir) "java")))
-                    (reset! current-filename (.toString dir))
-                    (.setText (:text-area (get-editor)) (slurp @current-filename)))
+                             (or (.contains (.toString dir) "clj")
+                                 (.contains (.toString dir) "java")))
+                    #_(reset! current-filename (.toString dir))
+                    #_(.setText (:text-area (get-editor)) (slurp @current-filename))
+                    (open-file (.toString dir)))
                   #_(println dir)
                   (config! (select f [:#current-dir]) :text (.getAbsolutePath dir))
                   (config! (select f [:#status]) :text (format "Ready (%d items)" (count files)))
@@ -688,10 +553,11 @@
   "Start from command line."
   [& args]
   (init-ui)
-  (let [ew (make-editor-window {:language :clojure
-                                :keybinds keybinds/standard})
-        ri (make-repl-input-window {:language :clojure})
-        ro (make-repl-output-window {:language :clojure})
+  (let [params {:language :clojure
+                :keybinds keybinds/standard}
+        ew (make-editor-window params)
+        ri (make-repl-input-window params)
+        ro (make-repl-output-window params)
         r-is System/in #_(java.io.ByteArrayInputStream.
                           #_(.getBytes "(println 'foobar)\nexit\n(println 'foobar)\n"))
         r-os (java.io.ByteArrayOutputStream.)
@@ -714,8 +580,9 @@
                               (server-forms project cfg (ack-port project)
                                             true))
         pb (make-project-browser {})
-        ]
+        ]
     #_(.start repl-client-thread)
+    (reset! content-pane-params params)
     (reset! repl {:server repl-server ;:client-thread repl-client-thread
                   ;:repl-inputstream r-is :repl-outputstream r-os})
                   ;:client (nrepl/client @reply.eval-modes.nrepl/current-connection Long/MAX_VALUE)
@@ -731,8 +598,9 @@
     (reset! current-filename (:current-filename @current-profile))
     (make-ui)
     (load-file (str "src" File/separator "brevis" File/separator "ui" File/separator "keybinds.clj"))
-    (when-not (empty? (:current-filename @current-profile))
-      (.setText (:text-area ew) (slurp @current-filename)))))
+    (add-content-tab-from-filename @current-filename params)
+    #_(when-not (empty? (:current-filename @current-profile))
+       (.setText (:text-area ew) (slurp @current-filename)))))

 (when (find-ns 'ccw.complete)
   (-main))


Better debug msg.

Better debug msg.

--- src/cbfg/world/t2.cljs
+++ src/cbfg/world/t2.cljs
@@ -123,7 +123,7 @@
    "add" cbfg.world.base/example-add
    "sub" cbfg.world.base/example-add
    "count" cbfg.world.base/example-count
-   "lane-close" #(println "NEVER REACHED")
+   "lane-close" #(println "NEVER REACHED / :lane-close handled by lane pump")
    "lane-state" #(msg-req %1 :lane-state-ch %2)})

 (defn rq-handler [actx m] ((get rq-handlers (:op m)) actx m))


fix refactor

fix refactor

--- src/chat/server/db.clj
+++ src/chat/server/db.clj
@@ -653,7 +653,7 @@
               [?sub :user/subscribed-tag ?t]
               [?th :thread/tag ?t]]
             (d/db *conn*) user-id)
-       (map (fn [tag-id threads-count subscribers-count]
+       (map (fn [[tag-id threads-count subscribers-count]]
               [tag-id {:tag/threads-count threads-count
                        :tag/subscribers-count subscribers-count}]))
        (into {})))


remove debug logging

remove debug logging

--- src/clj/ceres/core.clj
+++ src/clj/ceres/core.clj
@@ -58,23 +58,23 @@
   (case topic
     :greeting {:recent-tweets (mapv extract-tweet-data (:recent-tweets @twitter-state))}))

+
 (defn tweet-handler [request]
   (let [out-chan (chan)]
     (with-channel request channel
       (swap! twitter-state update-in [:out-chans] conj out-chan)
       (go-loop [m (<! out-chan)]
         (when m
-          (debug "sending msg to" out-chan ":" (pr-str m))
           (send! channel (pr-str m))
           (recur (<! out-chan))))
       (on-close channel
                 (fn [status]
                   (swap! twitter-state update-in [:out-chans] (fn [old new] (vec (remove #(= new %) old))) out-chan)
                   (close! out-chan)
-                  (info "tweet channel closed: " status)))
+                  (info "tweet channel closed: " status "!")))
       (on-receive channel
                   (fn [data]
-                    (info (str "receiving msg: " (java.util.Date.)))
+                    (info "tweet channel opened!")
                     (send! channel (str (dispatch (read-string data)))))))))


embrace re-frame

embrace re-frame

--- src/cljs/uix/core.cljs
+++ src/cljs/uix/core.cljs
@@ -13,126 +13,145 @@
 ;; -------------------------
 ;; Views

-
-(def ui-state
-  (atom
-   {:current [:editors 0 0]
-    :views {:editors [[:1 :2]
-                      [:3 :4 :5]]
-            :animators [[:8 :6 :7]]}
-
-    :pages {:1 {:type :editor :formalism :classical-b :kind :machine :file "m1"}
-            :2 {:type :editor :formalism :classical-b :kind :machine :file "m0"}
-            :3 {:type :editor :formalism :event-b :kind :machine :file "m2"}
-            :4 {:type :editor :formalism :event-b :kind :machine :file "m0"}
-            :5 {:type :editor :formalism :event-b :kind :context :file "ctx0"}
-            :6 {:editor :3 :model "animator0" :trace "212" :type :state-view}
-            :7 {:editor :3 :model "animator0" :trace "212" :type :events-view}
-            :8 {:editor :3 :model "animator0" :trace "212" :type :history-view}
-            }}))
-
-
-(defn ^:extern right []
-  (let [[page row col] (:current @ui-state)
-        r-size (count (get-in @ui-state [:views page row]))]
-    (swap! ui-state assoc :current [page row (mod (inc col) r-size)])))
-
-(defn ^:extern left []
-  (let [[page row col] (:current @ui-state)
-        r-size (count (get-in @ui-state [:views page row]))]
-    (swap! ui-state assoc :current [page row (mod (dec col) r-size)])))
-
-(defn ^:extern down []
-  (let [[page row col] (:current @ui-state)
-        row-cnt (count (get-in @ui-state [:views page]))
-        next-row-number (mod (inc row) row-cnt)
-        r-size (count (get-in @ui-state [:views page next-row-number]))
-        n-col (min col (dec r-size))]
-    (.log js/console "c " col " nc " n-col " nr " next-row-number " rs " r-size)
-    (swap! ui-state assoc :current [page next-row-number n-col])))
-
-(defn ^:extern up []
-  (let [[page row col] (:current @ui-state)
-        row-cnt (count (get-in @ui-state [:views page]))
-        next-row-number (mod (dec row) row-cnt)
-        r-size (count (get-in @ui-state [:views page next-row-number]))
-        n-col (min col (dec r-size))]
-    (.log js/console "c " col " nc " n-col " nr " next-row-number " rs " r-size)
-    (swap! ui-state assoc :current [page next-row-number n-col])))
-
-(defn ^:extern esc []
-  (swap! ui-state (fn [x] (assoc x :overview? true))))
-
-(defn ^:extern desktop []
-  (swap! ui-state
-         (fn [{[page row column] :current :as x}]
-           (assoc x :current [({:editors :animators, :animators :editors} page) 0 0]))))
-
-(defn ^extern select
-  ([] (let [[_ r c] (:current @ui-state)]
-        (select r c)))
-  ([row column]
-   (swap! ui-state
-          (fn [x]
-            (assoc x
-                   :overview? false
-                   :current (into [(first (:current x))] [row column]))))))
+(defn init-state []
+  {:current [:editors 0 0]
+   :views {:editors [[:1 :2]
+                     [:3 :4 :5]]
+           :animators [[:8 :6 :7]]}
+   :overview? false
+   :pages {:1 {:type :editor :formalism :classical-b :kind :machine :file "m1"}
+           :2 {:type :editor :formalism :classical-b :kind :machine :file "m0"}
+           :3 {:type :editor :formalism :event-b :kind :machine :file "m2"}
+           :4 {:type :editor :formalism :event-b :kind :machine :file "m0"}
+           :5 {:type :editor :formalism :event-b :kind :context :file "ctx0"}
+           :6 {:editor :3 :model "animator0" :trace "212" :type :state-view}
+           :7 {:editor :3 :model "animator0" :trace "212" :type :events-view}
+           :8 {:editor :3 :model "animator0" :trace "212" :type :history-view}
+           }})
+
+(rf/register-handler
+ :init-db
+ (fn [db _]
+   (init-state)))
+
+(rf/register-sub
+ :current
+ (fn [db] (reaction (:current @db))))
+
+(rf/register-sub
+ :view
+ (fn [db] (reaction (:views @db))))
+
+(rf/register-sub
+ :pages
+ (fn [db] (reaction (:pages @db))))
+
+(rf/register-sub
+ :overview?
+ (fn [db] (reaction (:overview? @db))))
+
+(rf/register-sub
+ :current-page
+ (fn [db] (reaction (first (:current @db)))))
+
+(rf/register-sub
+ :current-row
+ (fn [db] (reaction (second (:current @db)))))
+
+(rf/register-sub
+ :current-column
+ (fn [db] (reaction (last (:current @db)))))
+
+
+(defn left-right [{[page row column] :current views :views :as db} f]
+  (let [r-size (count (get-in views [page row]))]
+    (assoc db :current [page row (mod (f column) r-size)])))
+
+
+(defn up-down [{[page row column] :current views :views :as db} f]
+  (let [rc (count (get views page))
+        nr (mod (f row) rc)
+        rs (dec (count (get-in views [page nr])))
+        nc (min column rs)]
+    (assoc db :current [page nr nc])))
+
+(defn desktop [{[page row column] :current :as db}]
+  (assoc db :current [({:editors :animators, :animators :editors} page) 0 0]))
+
+(defn esc [db]
+  (assoc db :overview? true))
+
+(defn select-view
+  ([{[_ r c] :current :as db}] (select-view db r c))
+  ([{[p r c] :current :as db} row column]
+   (assoc db
+          :overview? false
+          :current [p row column])))

 (rf/register-handler
  :navigate
+ rf/debug
  (fn [db [_ direction]]
-   (if (:overview? @ui-state)
-     (desktop)
+   (if (:overview? db)
+     (desktop db)
      (case direction
-       :up (up)
-       :down (down)
-       :left (left)
-       :right (right)))
-   db))
+       :up (up-down db dec)
+       :down (up-down db inc)
+       :left (left-right db dec)
+       :right (left-right db inc)))))

 (rf/register-handler
  :navigate-ov
  (fn [db [_ direction]]
-   (when (:overview? @ui-state)
+   (if (:overview? db)
      (case direction
-       :up (up)
-       :down (down)
-       :left (left)
-       :right (right)))
-   db))
+       :up (up-down db dec)
+       :down (up-down db inc)
+       :left (left-right db dec)
+       :right (left-right db inc))
+     db)))

 (rf/register-handler
  :esc
- (fn [db _] (if (:overview? @ui-state) (select) (esc)) db))
+ (fn [db _]
+   (if (:overview? db)
+     (select-view db)
+     (esc db))))

 (rf/register-handler
  :enter
- (fn [db _] (when (:overview? @ui-state) (select)) db))
+ (fn [db _] (if (:overview? db) (select-view db) db)))
+
+(rf/register-handler
+ :select
+ (fn [db [_ row column]] (select-view db row column)))

 (defn show [shown? page row column]
-  (let [c (:current @ui-state)]
-    (when-not (and shown? (= c [page row column])) {:class " hidden "})))
+  (let [c (rf/subscribe [:current])]
+    (when-not (and shown? (= @c [page row column])) {:class " hidden "})))

 (defmulti render-thumbnail (fn [e _] (:type e)))

 (defmethod render-thumbnail :editor [{:keys [formalism file kind row column]} shown?]
-  [:div.thumb.editor-thumbnail
-   {:key (str "tned-" row "-" column)
-    :class (str (if shown? "" " hidden ")
-                (if (= 0 column) " main-component " "")
-                "tn-" (name formalism) "-" (name kind)
-                (if (= [row column] (rest (:current @ui-state))) " selected " ""))
-    :on-click #(select row column)}
-   [:div.editor-thumbnail-text {:key (str "tnedtext-" row "-" column) } file]]
+  (let [c (rf/subscribe [:current])]
+    [:div.thumb.editor-thumbnail
+     {:key (str "tned-" row "-" column)
+      :class (str (if shown? "" " hidden ")
+                  (if (= 0 column) " main-component " "")
+                  "tn-" (name formalism) "-" (name kind)
+                  (if (= [row column] (rest @c)) " selected " ""))
+      :on-click #(rf/dispatch [:select row column])}
+     [:div.editor-thumbnail-text {:key (str "tnedtext-" row "-" column) } file]])
   )

 (defmethod render-thumbnail :default [{:keys [model type row column]} shown?]
-  [:div.thumb.view-thumbnail
-   {:key (str "tnv-" row "-" column)
-    :class (str (if shown? "" " hidden ")
-                "tn-" (name type)
-                (if (= [row column] (rest (:current @ui-state))) " selected " ""))
-    :on-click #(select row column)}])
+  (let [c (rf/subscribe [:current])]
+    [:div.thumb.view-thumbnail
+     {:key (str "tnv-" row "-" column)
+      :class (str (if shown? "" " hidden ")
+                  "tn-" (name type)
+                  (if (= [row column] (rest @c)) " selected " ""))
+      :on-click #(rf/dispatch [:select row column])}]))

 (defmulti render-view (fn [e _] (:type e)))

@@ -185,29 +204,35 @@
   [:div.row {:key (str "row" y)}
    (doall (map-indexed
            (fn [x key]
-             (let [e (assoc (get-in @ui-state [:pages key]) :column x :row y)
-                   overview? (:overview? @ui-state)
-                   page (:cpage @ui-state)]
-               [:div {:key (str  "view-elem-" x y)} (render-thumbnail e overview?)
-                [render-view e (not overview?)]]))
+             (let [pages (rf/subscribe [:pages])
+                   e (assoc (get @pages key) :column x :row y)
+                   overview? (rf/subscribe [:overview?])]
+               [:div {:key (str  "view-elem-" x y)}
+                (render-thumbnail e @overview?)
+                [render-view e (not @overview?)]]))
            columns))])

 (defn render-page [[section rows]]
-  [:div.page (merge {:key section}
-                    (when-not (= section (first (:current @ui-state))) {:class "hidden"}))
-   (doall (map-indexed render-row rows))
-   ])
+  (let [page (rf/subscribe [:current-page])]
+    [:div.page (merge {:key section}
+                      (when-not (= section @page) {:class "hidden"}))
+     (doall (map-indexed render-row rows))
+     ]))

 (defn home-page []
-  (let [views (:views @ui-state)]
+  (let [views (rf/subscribe [:view])]
     [:div.ui
-     (doall (map render-page views))]))
+     (doall (map render-page @views))]))

 ;; -------------------------
 ;; Initialize app
-(defn mount-root []
-  (reagent/render [home-page] (.getElementById js/document "app")))
+
+(rf/register-handler
+ :mount
+ (fn [db _]
+   (reagent/render [home-page] (.getElementById js/document "app"))
+   db))

 (defn init! []
   (.add js/shortcut "Shift+Left" #(rf/dispatch [:navigate :left]))
@@ -220,4 +245,5 @@
   (.add js/shortcut "Down" #(rf/dispatch [:navigate-ov :down]))
   (.add js/shortcut "Escape" #(rf/dispatch [:esc]))
   (.add js/shortcut "Enter" #(rf/dispatch [:enter]))
-  (mount-root))
+  (rf/dispatch [:init-db])
+  (rf/dispatch [:mount]))


Moved XML Schema validation code into cmr-common-lib.

--- src/cmr/common/xml.clj
+++ src/cmr/common/xml.clj
@@ -2,7 +2,13 @@
   "Contains XML helpers for extracting data from XML structs created using clojure.data.xml.
   See the test file for examples."
   (:require [cmr.common.date-time-parser :as p]
-            [clojure.string :as str]))
+            [clojure.string :as str]
+            [clojure.java.io :as io])
+  (:import javax.xml.validation.SchemaFactory
+           javax.xml.XMLConstants
+           javax.xml.transform.stream.StreamSource
+           org.xml.sax.ext.DefaultHandler2
+           java.io.StringReader))

 (defn remove-xml-processing-instructions
   "Removes xml processing instructions from XML so it can be embedded in another XML document"
@@ -104,3 +110,39 @@
   [xml-struct path]
   (first (datetimes-at-path xml-struct path)))

+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; XML Schema Validation
+
+
+(defn- sax-parse-exception->str
+  "Converts a SaxParseException to a String"
+  [e]
+  (format "Line %d - %s" (.getLineNumber e) (.getMessage e)))
+
+(defn- create-error-handler
+  "Creates an instance of DefaultHandler2 that will save all schema errors in the errors-atom."
+  [errors-atom]
+  (proxy [DefaultHandler2] []
+    (error
+      [e]
+      (swap! errors-atom conj (sax-parse-exception->str e)))
+    (fatalError
+      [e]
+      (swap! errors-atom conj (sax-parse-exception->str e)))))
+
+(defn validate-xml
+  "Validates the XML against the schema in the given resource. schema-resource should be a classpath
+  resource as returned by clojure.java.io/resource.
+  Returns a list of errors in the XML schema."
+  [schema-resource xml]
+  (let [factory (SchemaFactory/newInstance XMLConstants/W3C_XML_SCHEMA_NS_URI)
+        schema (.newSchema factory schema-resource)
+        validator (.newValidator schema)
+        errors-atom (atom [])]
+    (.setErrorHandler validator (create-error-handler errors-atom))
+    (try
+      (.validate validator (StreamSource. (StringReader. xml)))
+      (catch org.xml.sax.SAXParseException e
+        ;; An exception can be thrown if it is completely invalid XML.
+        (reset! errors-atom [(sax-parse-exception->str e)])))
+    (seq @errors-atom)))


clean u demand examples

clean u demand examples

--- test/example/demand.clj
+++ test/example/demand.clj
@@ -51,7 +51,7 @@
         (pan2 (* 0.1 src))))

 (def buf (buffer 8))
-(buffer-write! buf 0 8 (map #(+ 12 %) [50 50 54 50 57 50 45 49]))
+(buffer-write! buf 0 (map #(+ 12 %) [50 50 54 50 57 50 45 49]))

 (demo 20
       (let [trig (impulse:kr 8)
@@ -65,7 +65,7 @@
 (buffer-set! buf 3 85)
 (buffer-set! buf 3 80)
 (buffer-set! buf 7 20)
-
+(stop)

 (demo 4
       (let [freq (duty (drand [0.2 0.4 0.8 0.6] INF)
@@ -81,12 +81,6 @@

 ; Generate a series of values, incrementing linearly.
-(demo 8
-      (let [trig (impulse:kr 2)
-            freqs (internal:dseries 100 50 2)
-            note-gen (demand:kr trig 0 freqs)
-            src (sin-osc note-gen)]
-        (pan2 (* 0.2 src))))

 (demo 8
       (let [trig (impulse:kr 10)


Add nested loop test

Add nested loop test

--- test/fixtures/loop.cljs
+++ test/fixtures/loop.cljs
@@ -24,4 +24,12 @@
        (if-not match
          result
          (recur (re-find matcher)    ;loop with 2 new arguments
-                (conj result match))))))+                (conj result match))))))
+
+(loop [i 0]
+  (when (< i 10)
+    (loop [j 0]
+      (when (< j 10)
+        (.log js/console i j)
+        (recur (inc j))))
+    (recur (inc i))))


[sum-of-multiples] remove unused code in example

Due to the changes in the test suite, there was an unused functionclause
left in the examples, which gets removed by this commit.

--- exercises/sum-of-multiples/src/example.clj
+++ exercises/sum-of-multiples/src/example.clj
@@ -5,7 +5,6 @@
   ([n d] (zero? (rem n d))))

 (defn sum-of-multiples
-  ([n] (sum-of-multiples [3 5] n))
   ([multiples n]
    (reduce (fn [sum x] (cond-> sum (some (divides? x) multiples) (+ x)))
            0 (range 1 n))))


filter-parser split-filter-val now removes the double dot once the split has taken place

--- src/selmer/filter_parser.clj
+++ src/selmer/filter_parser.clj
@@ -72,8 +72,10 @@
   "Split accessors like foo.bar.baz by the dot.
    But if there is a double dot '..' then it will leave it"
   [s]
-  (let [ks (s/split s #"(?<!\.)\.(?!\.)")]
-    (fix-accessor ks)))
+  (let [ks (clojure.string/split s #"(?<!\.)\.(?!\.)")
+        kss (map
+              (fn [s] (clojure.string/replace s ".." ".")) ks)] ;we remove the double dot here
+    (fix-accessor kss)))

 (defn fix-filter-args
   "Map any sort of needed fixes to the arguments before passing them


Rename solution to leap.clj & prefix calls with ns

--- leap/leap_test.clj
+++ leap/leap_test.clj
@@ -1,16 +1,16 @@
 (ns leap.test (:require [clojure.test :refer :all]))
-(load-file "leap_year.clj")
+(load-file "leap.clj")

 (deftest vanilla-leap-year
-  (is (leap-year? 1996)))
+  (is (leap/leap-year? 1996)))

 (deftest any-old-year
-  (is (not (leap-year? 1997))))
+  (is (not (leap/leap-year? 1997))))

 (deftest century
-  (is (not (leap-year? 1900))))
+  (is (not (leap/leap-year? 1900))))

 (deftest exceptional-century
-  (is (leap-year? 2400)))
+  (is (leap/leap-year? 2400)))

 (run-tests)


Added void-element RenderOption

Added void-element RenderOption

--- src/shared/hyjinks/core.cljc
+++ src/shared/hyjinks/core.cljc
@@ -257,6 +257,7 @@

 ;; Declaring rendering options

+(def void-element (r-opts :void-element true))
 (def self-close (r-opts :self-close true))
 (def both-tags (r-opts :both-tags true))
 (def no-escape (r-opts :no-escape true))
@@ -270,7 +271,7 @@
 (def h4 (tag "h4"))
 (def h5 (tag "h5"))
 (def h6 (tag "h6"))
-(def hr (tag "hr"))
+(def hr (tag "hr" void-element))
 (def ul (tag "ul"))
 (def ol (tag "ol"))
 (def li (tag "li"))
@@ -293,10 +294,10 @@
 (def mark (tag "mark"))
 (def dbo (tag "dbo"))
 (def a (tag "a"))
-(def img (tag "img"))
-(def embed (tag "embed"))
-(def object (tag "object"))
-(def param (tag "param"))
+(def img (tag "img" void-element))
+(def embed (tag "embed" void-element))
+(def object (tag "object" void-element))
+(def param (tag "param" void-element))
 (def iframe (tag "iframe"))
 (def audio (tag "audio"))
 (def video (tag "video"))
@@ -304,7 +305,7 @@
 (def span (tag "span"))
 (def div (tag "div"))
 (def nav (tag "nav"))
-(def br (tag "br"))
+(def br (tag "br" void-element))
 (def canvas (tag "canvas"))
 (def textarea (tag "textarea"))
 (def table (tag "table"))
@@ -315,7 +316,7 @@
 (def tr (tag "tr"))
 (def td (tag "td"))
 (def caption (tag "caption"))
-(def col (tag "col"))
+(def col (tag "col" void-element))
 (def colgroup (tag "colgroup"))
 (def address (tag "address"))
 (def article (tag "article"))
@@ -333,15 +334,15 @@
 (def optgroup (tag "optgroup"))
 (def fieldset (tag "fieldset"))
 (def label (tag "label"))
-(def input (tag "input"))
+(def input (tag "input" void-element))
 (def button (tag "button"))
 (def progress (tag "progress"))
 (def html (tag "html"))
 (def head (tag "head"))
 (def title (tag "title"))
-(def link (tag "link"))
+(def link (tag "link" void-element))
 (def style (tag "style"))
-(def base (tag "base"))
+(def base (tag "base" void-element))
 (def body (tag "body"))
 (def noscript (tag "noscript"))


Add clamping function

Add clamping function

Nodes now "stick" to the side of the screen. Looks bad now, but will
hopefully be better after adding opacity changes.

--- src/graphito/core.cljs
+++ src/graphito/core.cljs
@@ -79,7 +79,9 @@
   (merge-with - v1 v2))

 (defn scalar-multiply [v c]
-  (-> v (update :x * c) (update :y * c)))
+  (if (= c 1)
+    v
+    (math-vec (* c (:x v)) (* c (:y v)))))

 (defn neg-vec [v]
   (scalar-multiply v -1))
@@ -88,6 +90,11 @@
   (scalar-multiply v (/ l (vec-length v))))

 (def vec-distance (comp vec-length subtract-vec))
+
+(defn vec-clamp-to-bounds [v bounds]
+  (let [ratios (merge-with (comp js/Math.abs /) bounds v)
+        max-ratio (min 1 (:x ratios) (:y ratios))]
+    (scalar-multiply v max-ratio)))

 ;; D3 magic

@@ -100,6 +107,7 @@
     (/ (vec-distance (:camera-pos state) pos) corner-distance)))

 (defn elliptic-distance-from-camera [state pos]
+  "An alternate method of computing distance, currently unused."
   (let [{:keys [view-size camera-pos]} state
         rx (/ (:x view-size) 2)
         ry (/ (:y view-size) 2)
@@ -122,12 +130,12 @@
         displacement (subtract-vec pos camera-pos)
         r (scaled-distance-from-camera state pos)
         projected-r (project-displacement r)]
-    (add-vec view-center (scalar-multiply displacement
-                                        (/ projected-r r)))))
+      (add-vec view-center
+            (vec-clamp-to-bounds (scalar-multiply displacement (/ projected-r r)) view-center))))

 (defn project-radius [t]
-    (+ min-radius (* (- max-radius min-radius)
-                     (min 1 (/ 1 (.pow js/Math 2 (* 2 (- t 0.25))))))))
+  (+ min-radius (* (- max-radius min-radius)
+                   (min 1 (/ 1 (.pow js/Math 2 (* 2 (- t 0.25))))))))

 (defn view-radius [state pos]
   (let [r (scaled-distance-from-camera state pos)]
@@ -326,12 +334,12 @@
           (.empty rx-observable)
           (let [{:keys [vx vy]} a]
             (.generateWithRelativeTime rx-observable
-              (math-vec (* update-interval-ms (or vx 0))
-                        (* update-interval-ms (or vy 0)))
-              (fn [v] (> (vec-length-sq v) min-slide-speed-sq))
-              dampen
-              identity
-              (constantly update-interval-ms))))))))
+                                       (math-vec (* update-interval-ms (or vx 0))
+                                                 (* update-interval-ms (or vy 0)))
+                                       (fn [v] (> (vec-length-sq v) min-slide-speed-sq))
+                                       dampen
+                                       identity
+                                       (constantly update-interval-ms))))))))

 (defn move-camera-on-swipe! [manager current-state]
   (.subscribe


Improved logging on startup.

Improved logging on startup.

--- src/ruuvi_server/launcher.clj
+++ src/ruuvi_server/launcher.clj
@@ -65,6 +65,8 @@
   ))

 (defn- read-config-file [config-file params]
+  (info "Reading configuration from" config-file)
+  (info "Overriding configuration file with parameters" params)
   (let [config (conf/read-config config-file)
         config (update-in config [:environment] #(or (:env params) % :prod))
         config (update-in config [:server :type] #(or (:platform params) % :standalone))


add more debugging vars

add more debugging vars

--- src/riak_mesos/scheduler.clj
+++ src/riak_mesos/scheduler.clj
@@ -13,6 +13,11 @@
         ;;this contains pairs of [executor-id slave-id]
         active-executors (atom #{})
         slave-id->host+exec (atom {})]
+    (def active-executors active-executors)
+    (def slave-id->host+exec slave-id->host+exec)
+    (def used-hosts used-hosts)
+    (def pending pending)
+    (def running running)
     (clj-mesos.scheduler/scheduler
       (statusUpdate [driver status]
                     (future


have to turn the crate object into a jquery one to make it seqable

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -63,7 +63,7 @@
   (val ($ ".title")))

 (defn wishes-from-html []
-  (for [el wish-li]
+  (for [el ($ wish-li)]
     {:description (val (find el ".description"))
      :url (val (find el ".url"))}))


Allow passing values that are not strings as :value (#183)

--- src/sablono/interpreter.cljc
+++ src/sablono/interpreter.cljc
@@ -43,7 +43,7 @@
               (object/getValueByKeys event "target" property))))

          (componentWillReceiveProps [this new-props]
-           (let [state-value (object/getValueByKeys this "state" property)
+           (let [state-value (str (object/getValueByKeys this "state" property))
                  element-value (object/get (js/ReactDOM.findDOMNode this) property)]
              ;; On IE, onChange event might come after actual value of
              ;; an element have changed. We detect this and render


adjust defview so that componen-map can be passed as the second arg

--- src/status_im/utils/views.clj
+++ src/status_im/utils/views.clj
@@ -45,7 +45,10 @@
                        rest-body)
         [subs component-map body] (case (count rest-body')
                                     1 [nil {} (first rest-body')]
-                                    2 [(first rest-body') {} (second rest-body')]
+                                    2 (let [first-element (first rest-body')]
+                                        (if (map? first-element)
+                                          [nil first-element (second rest-body')]
+                                          [(first rest-body') {} (second rest-body')]))
                                     3 rest-body')
         [subs-bindings vars-bindings] (prepare-subs subs)]
     `(do


Add support for truncation-len to the frontend

--- src-cljs/frontend/components/build_steps.cljs
+++ src-cljs/frontend/components/build_steps.cljs
@@ -95,7 +95,9 @@
                  :download "BuildOutput.txt"
                  :target "_blank"}
              (if (:truncated action)
-               "Download the first 4MB as a file."
+               (if-let [l (:truncation-len action)]
+                 (format "Download the first %s as a file." l)
+                 "Download the first 4MB as a file.")
                "Download the full output as a file.")])])))))

 (defn action [action owner {:keys [container-id uses-parallelism?] :as opts}]


Fix command-line arg parsing

Fix command-line arg parsing

Some commands were no longer working: :parse, build-deps, freshen, and retag
Moved all voom-specific subcommands to keyword-like syntax, so :build-deps and :freshen
Removed retag in favor of :retag-all-repos

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -387,13 +387,12 @@
       (let [tag (str "voom-branch--" branch)]
         (git {:gitdir gitdir} "tag" "-f" tag (str "origin/" branch))))))

-(defn tag-all-repos
-  [& {:keys [fetch]}]
+(defn p-repos
+  "Call f once for each repo dir, in parallel. When all calls are
+  done, return nil."
+  [f]
   (->> (all-repos-dirs)
-       (map #(future
-               (when fetch
-                 (fetch-all [%]))
-               (tag-repo-projects %)))
+       (map #(future (f %)))
        doall
        (map deref)
        dorun))
@@ -406,13 +405,6 @@
     (when (seq tags)
       (apply git {:gitdir gitdir} "tag" "--delete" tags)
       nil)))
-
-(defn retag
-  "Clear and retag all repos in .voom-repos"
-  [project & args]
-  (doseq [gitdir (all-repos-dirs)]
-    (clear-voom-tags gitdir)
-    (tag-repo-projects gitdir)))

 (defn parse-tag
   [tag]
@@ -491,7 +483,7 @@
   (let [voom-meta (:voom (meta dep))
         ver-spec (or (:version voom-meta)
                      (re-find #"^[^.]+." ver))
-        groups (->> (newest-voom-ver-by-spec prj ver-spec voom-meta)
+        groups (->> (newest-voom-ver-by-spec prj (assoc voom-meta :version ver-spec))
                     (map #(assoc % :voom-ver (format-voom-ver
                                               (update-in % [:sha] subs 0 7))))
                     (group-by :voom-ver))]
@@ -522,7 +514,7 @@
           replacement-map))

 (defn freshen [project & args]
-  (tag-all-repos :fetch true)
+  (p-repos (fn [p] (fetch-all [p]) (tag-repo-projects p)))
   (let [prj-file-name (str (:root project) "/project.clj")
         old-deps (:dependencies project)
         desired-new-deps (doall (map #(fresh-version %) old-deps))]
@@ -624,7 +616,7 @@

 (defn box-add
   [proj & adeps]
-  (tag-all-repos)
+  (p-repos (fn [p] (tag-repo-projects p)))
   (doseq [:let [deps (fold-args-as-meta adeps)]
           dep deps
           :let [full-projs (resolve-short-proj (pr-str dep))
@@ -644,12 +636,6 @@

 ;; TODO: Consider revamping these entry points. Separate top-level
 ;; lein commands?  Separate lein plugins?
-(def sub-commands
-  {"build-deps" build-deps
-   "freshen" freshen
-   "retag" retag
-   "new-task" nope})
-
 (defn ^:no-project-needed voom
   "Usage:
     lein voom [flags] [lein command ...]
@@ -665,21 +651,21 @@
     lein voom [:long-sha] :print
     lein voom :parse <version-str>"
   [project & args]
-  (let [symargs (map edn/read-string args)
-        [kargs sargs] (split-with keyword? symargs)
-        kargset (set kargs)
+  (let [[kw-like more-args] (split-with #(re-find #"^:" %) args)
+        kargset (set (map edn/read-string kw-like))
+        sargs (map edn/read-string more-args)
         long-sha (kargset :long-sha)
         new-project (delay (update-proj-version project long-sha))]
     ;; TODO throw exception if upstream doesn't contain this commit :no-upstream
     (cond
      (:print kargset) (println (:version @new-project))
-     (:parse kargset) (prn (ver-parse (first sargs)))
+     (:parse kargset) (prn (ver-parse (first more-args)))
      (:find-box kargset) (prn (find-box))
-     (:box-add kargset) (apply box-add project sargs)
-     (:retag-all-repos kargset) (time (doall (mapcat (juxt clear-voom-tags tag-repo-projects) (all-repos-dirs))))
-     :else (if-let [f (get sub-commands (first sargs))]
-             (apply f @new-project (rest sargs))
-             (if (and (dirty-wc? (:root @new-project))
-                      (not (:insanely-allow-dirty-working-copy kargset)))
-               (lmain/abort "Refusing to continue with dirty working copy. (Hint: Run 'git status')")
-               (lmain/resolve-and-apply @new-project sargs))))))
+     (:box-add kargset) (apply box-add project (map edn/read-string more-args))
+     (:retag-all-repos kargset) (time (p-repos (fn [p] (clear-voom-tags p) (tag-repo-projects p))))
+     (:freshen kargset) (freshen project)
+     (:build-deps kargset) (build-deps project)
+     :else (if (and (dirty-wc? (:root @new-project))
+                    (not (:insanely-allow-dirty-working-copy kargset)))
+             (lmain/abort "Refusing to continue with dirty working copy. (Hint: Run 'git status')")
+             (lmain/resolve-and-apply @new-project more-args)))))


Remove Buffering on Publisher Channel

Remove Buffering on Publisher Channel

--- src/lens/event_bus.clj
+++ src/lens/event_bus.clj
@@ -6,7 +6,7 @@
 (defrecord Bus [name]
   component/Lifecycle
   (start [this]
-    (let [publisher (async/chan 10)]
+    (let [publisher (async/chan)]
       (assoc this :publisher publisher
                   :publication (async/pub publisher #(:topic %)))))
   (stop [this]


No longer output nil returns from expressions.

--- src/tryclojure/views/eval.clj
+++ src/tryclojure/views/eval.clj
@@ -8,8 +8,8 @@
         data (if error
                res
                (let [[out res] result]
-                 {:expr (pr-str expr)
-                  :result (str out (pr-str res))}))]
+                 {:expr (print-str expr)
+                  :result (str out (print-str (or res "")))}))]

     (if jsonp
       (resp/jsonp jsonp data)


Cosmetic improvement on constants definition on workspace events ns.


Don't overwrite poster

Don't overwrite poster

--- src/video_server/metadata.clj
+++ src/video_server/metadata.clj
@@ -75,12 +75,13 @@

 (defn save-poster
   "Downloads the poster for the specified video."
-  [title url]
+  [title url & [overwrite]]
   (let [file (io/file (title-dir title) (str (norm-title (:title title)) (file-ext url)))]
-    (log/info "downloading poster for" (:title title))
-    (when-let [contents (retrieve-image url)]
-      (with-open [w (io/output-stream file)]
-        (.write w contents)))))
+    (when (or overwrite (not (.exists file)))
+      (log/info "downloading poster for" (:title title))
+      (when-let [contents (retrieve-image url)]
+        (with-open [w (io/output-stream file)]
+          (.write w contents))))))

 (defn title-parts
   "Extracts the year from the title to aid in metadata lookup."


Removed unneeded argument in fluokitten/map-entries-i.

--- src/clojure/uncomplicate/neanderthal/internal/host/fluokitten.clj
+++ src/clojure/uncomplicate/neanderthal/internal/host/fluokitten.clj
@@ -47,12 +47,10 @@
 (defmacro entry*
   ([vtype v i]
    `(.entry ~(with-meta v {:tag vtype}) ~i))
-  ([vtype v i e]
-   `(entry* ~vtype ~v ~i double ~e))
   ([vtype v i etype e]
    `(.set ~(with-meta v {:tag vtype}) ~i (~etype ~e))))

-(defmacro map-entries-i [vtype etype f i & xs]
+(defmacro map-entries-i [vtype f i & xs]
   `(~f ~@(map #(list `entry* vtype % i) xs)))

 (defmacro vector-fmap* [vtype etype res f & xs]
@@ -60,7 +58,7 @@
     `(do
        (if (check-vector-dimensions ~@xs)
          (dotimes [i# (dim ~res)]
-           (entry* ~vtype ~res i# (~etype (map-entries-i ~vtype ~etype ~f i# ~@xs))))
+           (entry* ~vtype ~res i# ~etype (map-entries-i ~vtype ~f i# ~@xs)))
          (dragan-says-ex DIMENSIONS_MSG {:xs (map str ~xs)}))
        ~res)
     `(dragan-says-ex "Vector fmap supports up to 4 vectors.")))
@@ -71,7 +69,7 @@
        (let [dim-x# (dim ~(first xs))]
          (loop [i# 0 acc# (~acctype ~init)]
            (if (< i# dim-x#)
-             (recur (inc i#) (~acctype (~f acc# (~etype (map-entries-i ~vtype ~etype + i# ~@xs)))))
+             (recur (inc i#) (~acctype (~f acc# (~etype (map-entries-i ~vtype + i# ~@xs)))))
              acc#)))
        (dragan-says-ex DIMENSIONS_MSG {:xs (map str ~xs)}))
     `(dragan-says-ex "Vector fold supports up to 4 vectors.")))
@@ -82,7 +80,7 @@
        (let [dim-x# (dim ~(first xs))]
          (loop [i# 0 acc# (~acctype ~init)]
            (if (< i# dim-x#)
-             (recur (inc i#) (~acctype (~f acc# (~etype (map-entries-i ~vtype ~etype ~g i# ~@xs)))))
+             (recur (inc i#) (~acctype (~f acc# (~etype (map-entries-i ~vtype ~g i# ~@xs)))))
              acc#)))
        (dragan-says-ex DIMENSIONS_MSG {:xs (map str ~xs)}))
     `(dragan-says-ex "Vector foldmap supports up to 4 vectors.")))
@@ -93,7 +91,7 @@
        (let [dim-x# (dim ~(first xs))]
          (loop [i# 0 acc# (~acctype ~init)]
            (if (< i# dim-x#)
-             (recur (inc i#) (~acctype (~f acc# i# (~etype (map-entries-i ~vtype ~etype + i# ~@xs)))))
+             (recur (inc i#) (~acctype (~f acc# i# (~etype (map-entries-i ~vtype + i# ~@xs)))))
              acc#)))
        (dragan-says-ex DIMENSIONS_MSG {:xs (map str ~xs)}))
     `(dragan-says-ex "Vector fold supports up to 4 vectors.")))
@@ -104,7 +102,7 @@
        (let [dim-x# (dim ~(first xs))]
          (loop [i# 0 acc# (~acctype ~init)]
            (if (< i# dim-x#)
-             (recur (inc i#) (~acctype (~f acc# i# (~etype (map-entries-i ~vtype ~etype ~g i# ~@xs)))))
+             (recur (inc i#) (~acctype (~f acc# i# (~etype (map-entries-i ~vtype ~g i# ~@xs)))))
              acc#)))
        (dragan-says-ex DIMENSIONS_MSG {:xs (map str ~xs)}))
     `(dragan-says-ex "Vector foldmap supports up to 4 vectors.")))


preliminary support for groups - does not support group pushing

--- src/mirthsync/core.clj
+++ src/mirthsync/core.clj
@@ -58,25 +58,31 @@
     nil))

 (def config
-  {:channel {:find-elements [:list :channel]
-             :find-id [:id zip/down zip/node]
-             :find-name [:name zip/down zip/node]
-             :path "channels"}
+  {:configurationMap {:find-elements [:map]
+                      :find-id [(fn [_] nil)]
+                      :find-name [(fn [_] "configurationMap")]
+                      :path "server/configurationMap"}

    :codeTemplate {:find-elements [:list :codeTemplate]
                   :find-id [:id zip/down zip/node]
                   :find-name [:name zip/down zip/node]
                   :path "codeTemplates"}

-   :configurationMap {:find-elements [:map]
-                      :find-id [(fn [_] nil)]
-                      :find-name [(fn [_] "configurationMap")]
-                      :path "server/configurationMap"}
-
    :globalScripts {:find-elements [:map]
                    :find-id [(fn [_] nil)]
                    :find-name [(fn [_] "globalScripts")]
                    :path "server/globalScripts"}
+
+   :channelGroup {:find-elements [:list :channelGroup]
+                  :find-id [:id zip/down zip/node]
+                  :find-name [:name zip/down zip/node]
+                  :path "channelgroups"
+                  :prevent-push true}
+
+   :channel {:find-elements [:list :channel]
+             :find-id [:id zip/down zip/node]
+             :find-name [:name zip/down zip/node]
+             :path "channels"}
    })

@@ -98,12 +104,15 @@

 (defn upload
   ""
-  [base-url target-dir {:keys [find-id path]}]
-  (cli/output 0 (str "Uploading " path))
-  (let [files (.listFiles (io/file (str target-dir (File/separator) path)))]
-    (cli/output 0 (str "found " (count files) " files"))
-    (doseq [f files]
-      (upload-node base-url path find-id (to-zip (slurp f))))))
+  [base-url target-dir {:keys [find-id path prevent-push]}]
+  (if prevent-push
+    (cli/output 0 (str "Uploading " path " is not currently supported - skipping"))
+    (do
+      (cli/output 0 (str "Uploading " path))
+      (let [files (.listFiles (io/file (str target-dir (File/separator) path)))]
+        (cli/output 0 (str "found " (count files) " files"))
+        (doseq [f files]
+          (upload-node base-url path find-id (to-zip (slurp f))))))))

 (defn run
   "App logic. Returns nil."
@@ -119,7 +128,8 @@
 (defn exit! [status msg]
   "Print message and System/exit with status code"
   (cli/output msg)
-  (System/exit status))
+  ;; (System/exit status)
+  )

 (defn -main
   [& args]


change the URL path to match the orchestration endpoint path indicated in src/main/scala/org/broadinstitute/dsde/firecloud/service/MethodsService.scala

--- src/cljs/org/broadinstitute/firecloud_ui/page/workspace/method_config_importer.cljs
+++ src/cljs/org/broadinstitute/firecloud_ui/page/workspace/method_config_importer.cljs
@@ -177,9 +177,7 @@
         :else [comps/Spinner {:text "Loading configurations for import..."}])])
    :component-did-mount
    (fn [{:keys [state props]}]
-     (utils/ajax-orch
-       (str "/workspaces/" (:selected-workspace-namespace props)
-         "/" (:selected-workspace props) "/methodconfigs")
+     (utils/ajax-orch (str "/configurations")
        {:on-done (fn [{:keys [success? xhr]}]
                    (if success?
                      (do


🚨 Fix reflection warning

🚨 Fix reflection warning

Why:
- The .getNotifications call could not be found without reflection

--- src/territory_bro/gis_db.clj
+++ src/territory_bro/gis_db.clj
@@ -165,7 +165,7 @@
     (db/use-master-schema conn)
     (jdbc/execute! conn ["LISTEN gis_change"])
     (let [timeout (Duration/ofSeconds 30)
-          pg-conn ^PGConnection (-> (jdbc/db-connection conn)
+          ^PGConnection pg-conn (-> (jdbc/db-connection conn)
                                     (.unwrap PGConnection))]
       (log/info "Started listening for GIS changes")
       (loop []


Minor syntax error has been fixed

Minor syntax error has been fixed

--- core/src/cljc/hellhound/component.cljc
+++ core/src/cljc/hellhound/component.cljc
@@ -107,12 +107,12 @@
   `hellhound.components.defaults/stop-fn` as the `start-fn` and `stop-fn`
   which basically do nothing (`start-fn` attaches the context to the component)."
   [component-name & body]
-  `(def ~component-name))
-p     {:hellhound.component/name       (keyword (str *ns*) ~(str component-name))}
+  `(def ~component-name
+     {:hellhound.component/name       (keyword (str *ns*) ~(str component-name))
       :hellhound.component/start-fn   hellhound.components.default/start-fn
       :hellhound.component/stop-fn    hellhound.components.default/stop-fn
       :hellhound.component/depends-on []
-      :hellhound.component/fn         ~(list* `fn body)
+      :hellhound.component/fn         ~(list* `fn body)}))

 (defmacro deftransform


Version 0.0.9-SNAPSHOT

Version 0.0.9-SNAPSHOT

--- api/project.clj
+++ api/project.clj
@@ -1,4 +1,4 @@
-(defproject coffee-table "0.0.8"
+(defproject coffee-table "0.0.9-SNAPSHOT"
   :description "A site for Gaelan's café reviews"
   :url "http://github.com/RobotDisco/coffee-table"
   :license {:name "Eclipse Public License - v 1.0"


Some imports from jayq

Some imports from jayq

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -1,6 +1,7 @@
 (ns overtoneinterface.client.main
 (ns wishlistd.client.main
   (:require [crate.core :as crate])
+  (:use [jayq.core :only [$ append delegate data]])
   (:use-macros [crate.macros :only [defpartial]]))

 (defpartial wish-li [desc url]


removed extra printlns

removed extra printlns

--- src/paredit/parser.clj
+++ src/paredit/parser.clj
@@ -75,13 +75,6 @@
 (defn default-accumulator
   [#^String text offset line col parents parser-state accumulated-state]
     [#^String text offset line col parents parser-state accumulated-state]
-    (println "offset:" offset ", parser-state:" parser-state ", current:")
-    (pr (-> accumulated-state peek :tag))
-    (println "will go into :eof section:" (or
-        (< (count parents) (count accumulated-state))
-        (and (= :eof parser-state) (= \a (-> accumulated-state peek :tag)))))
-    (println "accumulated-state:" accumulated-state)
-    (println "")
     (cond
       (> (count parents) (count accumulated-state))
         ; enter a sublevel


Added hippie completion support via views

--- src/paredit/parser.clj
+++ src/paredit/parser.clj
@@ -6,7 +6,8 @@
 	(:require [clojure.zip :as zip])
   (:require [net.cgrand.parsley :as p])
   (:require [net.cgrand.parsley.lrplus :as lr+])
-  (:require [net.cgrand.regex :as r]))
+  (:require [net.cgrand.regex :as r])
+  (:require [clojure.string :as str]))

 #_(set! *warn-on-reflection* true)

@@ -210,8 +211,7 @@
     (= :comment t) (token :comment count)
     (= :discard t) (token :comment count)
     (= :net.cgrand.parsley/root t) (concat (mapcat identity (view-children-seq tokens-view abstract-children)) (token :eof))
-    :else (token :unexpected count)
-    ))
+    :else (token :unexpected count)))

 (defn tokens-view
   ([abstract-leaf s] (do ;(print "(tokens-view) abstract-leaf:") (prn (list s))
@@ -219,6 +219,38 @@
   ([abstract-node t abstract-children]
     ;(print "(tokens-view) abstract-children:") (prn abstract-children)
     (tokens t abstract-children (node-count abstract-node))))
+
+#_(defn hippie-view
+  ([abstract-leaf s] nil)
+  ([abstract-node t abstract-children]
+    (letfn [(proposals [abstract-node pos]
+              (let [t (-> (abstract-node parse-tree-view) :content (get pos))]
+                #{t (str ":" t)}))]
+      (cond
+        (= :symbol t) (proposals abstract-node 0)
+        (= :keyword t) (proposals abstract-node 1)
+        :else (let [child-views (map #(% hippie-view) abstract-children)]
+                (reduce into #{} child-views))))))
+
+(defn- proposals [abstract-node pos]
+  (-> (abstract-node parse-tree-view) :content (get pos)))
+
+(defn hippie-symbol-view
+  ([abstract-leaf s] nil)
+  ([abstract-node t abstract-children]
+    (cond
+      (= :symbol t) #{(proposals abstract-node 0)}
+      (= :keyword t) #{(proposals abstract-node 1)}
+      :else (let [child-views (map #(% hippie-symbol-view) abstract-children)]
+              (reduce into #{} child-views)))))
+
+(defn hippie-keyword-view
+  ([abstract-leaf s] nil)
+  ([abstract-node t abstract-children]
+    (cond
+      (= :keyword t) #{(str ":" (proposals abstract-node 1))}
+      :else (let [child-views (map #(% hippie-keyword-view) abstract-children)]
+              (reduce into #{} child-views)))))

 #_(defn nesting-level-view
   [abstract-node t abstract-children]


shift insertion point if we remove delimiters on same line (fix #1)

--- src/parinfer/core.cljs
+++ src/parinfer/core.cljs
@@ -184,7 +184,7 @@
    :line-no -1                         ;; current line number we are processing.
    :track-indent? false                ;; "true" when we are looking for the first char on a line to signify indentation.
    :delim-trail {:start nil :end nil}  ;; track EOL delims since we replace them wholesale with inferred delims.
-   :insert {:line nil :col nil}        ;; the place to insert closing delimiters whenever we hit appropriate indentation.
+   :insert {:line-no nil :x-pos nil}   ;; the place to insert closing delimiters whenever we hit appropriate indentation.
    :stack []})                         ;; the delimiter stack

 (defn close-delims
@@ -243,16 +243,23 @@
       :delim-trail delim-trail)))

 (defn remove-delim-trail
-  [{:keys [delim-trail line-no backup stack] :as result}]
-  (if-let [{:keys [start end]} delim-trail]
-    (let [[backup stack] (loop [backup backup, stack stack]
-                           (if (empty? backup)
-                             [backup stack]
-                             (recur (pop backup) (conj stack (peek backup)))))]
-      (-> result
-          (update-in [:lines line-no] remove-str-range start end)
-          (assoc :backup backup :stack stack)))
-    result))
+  [{:keys [delim-trail insert line-no backup stack] :as result}]
+  (let [{:keys [start end]} delim-trail]
+    (if (and start end)
+      (let [[backup stack] (loop [backup backup, stack stack]
+                             (if (empty? backup)
+                               [backup stack]
+                               (recur (pop backup) (conj stack (peek backup)))))
+            result (-> result
+                       (update-in [:lines line-no] remove-str-range start end)
+                       (assoc :backup backup :stack stack))
+
+
+            insert-line? (= (:line-no insert) line-no)
+            result (cond-> result
+                     insert-line? (update-in [:insert :x-pos] min start))]
+        result)
+      result)))

 (defn process-char
   "Update the given result by processing the given character and its position."


Optimise Riak handler

Optimise Riak handler

--- src/photon/db/riak.clj
+++ src/photon/db/riak.clj
@@ -23,9 +23,10 @@
 (defn riak-url [rdb id]
   (str (bucket-url rdb) "/" id))

-(def riak (Riak. bucket "photon" (into-array String nodes)))
+(defn m-riak [] (Riak. bucket "photon" (into-array String nodes)))
+(def riak (memoize m-riak))

-(defrecord RiakDB [riak nodes bucket]
+(defrecord RiakDB []
   db/DB
   (driver-name [this] "riak")
   (fetch [this stream-name id]
@@ -49,14 +50,14 @@
       (client/put (riak-url this id) {:body wrapper :content-type :json})))
   (search [this id] (:body (client/get (riak-url this id))))
   (store [this payload]
-    (.persist riak "__all__" "event" (json/generate-string payload)))
+    (.persist (riak) "__all__" "event" (json/generate-string payload)))
   (distinct-values [this k] ["events"])
   (lazy-events [this stream-name date]
     (db/lazy-events-page this stream-name date 1))
   (lazy-events-page [this stream-name date page]
     (let [l-date (if (string? date) (read-string date) date)
           res (map #(clojure.walk/keywordize-keys (into {} %))
-                   (into [] (.eventsSince riak l-date stream-name page)))]
+                   (into [] (.eventsSince (riak) l-date stream-name page)))]
       (if (< (.size res) 1)
         []
         (concat res


Maps instead of vectors

Maps instead of vectors

--- src/piper/template.clj
+++ src/piper/template.clj
@@ -95,28 +95,29 @@
                                                 ([[:name "fragment"]]
                                                   nil)
                                                 ([[:name close-tag-name]]
-                                                  [:text (str "</" close-tag-name ">")]))
+                                                  {:text (str "</" close-tag-name ">")}))
+                             :text            (fn [text] {:text text})
                              :attr            (fn [attr] attr)
                              :attr-with-value (fun ([[:name name] [:attr-value attr-value]] {:name  name
                                                                                :value attr-value}))
                              :attr-no-value   (fun ([[:name name]] {:name  name
                                                                     :value nil}))
                              :tag             (fun ([[:name "slot"] & attrs] {:slot (into {} attrs)})
-                                                   ([[:name "fragment"] & attrs] {:fragment (into {} attrs)})
+                                                   ([[:name "fragment"] & attrs] {:fragment attrs})
                                                    ([[:name tag-name] & attrs]
-                                                     [:text (str "<" tag-name (add-leading-space
-                                                                                (attrs-to-string attrs)) ">")]))
+                                                     {:text (str "<" tag-name (add-leading-space
+                                                                                (attrs-to-string attrs)) ">")}))
                              :closed-tag      (fun ([[:name "slot"] & attrs] {:slot (into {} attrs)})
-                                                   ([[:name "fragment"] & attrs] {:fragment (into {} attrs)})
+                                                   ([[:name "fragment"] & attrs] {:fragment attrs})
                                                    ([[:name tag-name] & attrs]
-                                                     [:text (str "<" tag-name (add-leading-space
-                                                                                (attrs-to-string attrs)) "/>")]))}
-                            (parser template-1))]
+                                                     {:text (str "<" tag-name (add-leading-space
+                                                                                (attrs-to-string attrs)) "/>")}))}
+                            (parser template))]

     (reduce (fn [result next]
               (let [last (last result)]
                 (match [last next]
-                       [[:text t1] [:text t2]] (conj (vec (drop-last result)) [:text (str t1 t2)])
+                       [{:text t1} {:text t2}] (conj (vec (drop-last result)) {:text (str t1 t2)})
                        [last nil] result
                        [last next] (conj result next))))
             []


slight reorg

slight reorg

--- lancet/ant/ant.clj
+++ lancet/ant/ant.clj
@@ -26,6 +26,13 @@
 (defmethod lancet/coerce [org.apache.tools.ant.types.Path String] [_ str]
   (org.apache.tools.ant.types.Path. ant-project str))

+(defn instantiate-data-type [project name props]
+  (let [obj (.createDataType project name)]
+    (throw-if (nil? obj) (str "No task named " name))
+    (set-properties! obj props)
+    obj))
+
+
 ;; commented out target stuff becomes necessary if some tasks depend on a (dummy?) target
 (defn instantiate-task [project name props]
   (let [task (.createTask project name)]
@@ -38,19 +45,21 @@
     ; (.addTask target task)
     task))

-(defn instantiate-data-type [project name props]
-  (let [obj (.createDataType project name)]
-    (throw-if (nil? obj) (str "No task named " name))
-    (set-properties! obj props)
-    obj))
+(defn create-ant-task [task-name]
+  (fn f
+    ([]
+       (f {}))
+    ([props]
+       (let [task (instantiate-task ant-project task-name props)]
+	 (.execute task)))))
+
+(defmacro define-ant-task [task-name]
+  `(def ~(symbol task-name) (create-ant-task ~task-name)))

-(defmacro define-ant-task [task-name]
-  `(defn ~task-name
-    ([]
-       (~task-name {}))
-    ([props#]
-       (let [task# (instantiate-task ant-project ~(str task-name) props#)]
-	 (.execute task#)))))
+;; (doseq td (.getTaskDefinitions ant-project)
+;;  (do
+;;    (println (.getKey td))
+;;    (define-ant-task (.getKey td))))

 ;; (defmacro define-data-type [type-name]
 ;;   `(defn ~type-name
@@ -58,10 +67,6 @@
 ;;      ([props#]
 ;; 	(instantiate-data-type ant-project ~type-name props#))))

-(doseq td (.getTaskDefinitions ant-project)
- (do
-   (println (.getKey td))
-   (define-ant-task (.getKey td))))

 ; TODO: replace with reflective approach (above)
 ;; (define-ant-task echo)


slinky

slinky

--- src/com/billpiel/mem_tracer/string_output.clj
+++ src/com/billpiel/mem_tracer/string_output.clj
@@ -19,19 +19,59 @@
                                                            :class-delimiter [:cyan]
                                                            :class-name      [:cyan]}}))

+(defn arg-indent
+  [& {:keys [start end]
+      :or {start " "
+           end " "}}]
+  [:start start
+   -1 "-"
+   :default (fn [i]
+              {:fg* i :text "|"})
+   :end end])

-(defn color-code
-  [& {:keys [fg bg bold]}]
-  (str "\033["
-       (->> [(when (#{true 1} bold)
-               1)
-             (when fg
-               (+ 30 (mod fg 10)))
-             (when bg
-               (+ 40 (mod bg 10)))]
-            (remove nil?)
-            (clojure.string/join ";"))
-       "m"))
+(defn slicky-match
+  [i len sl]
+  (when-not (-> sl first #{:start :end})
+    (let [[fi se] sl
+          [lo hi] (cond (sequential? fi) fi
+                        (= :default fi) [java.lang.Integer/MIN_VALUE java.lang.Integer/MAX_VALUE]
+                        (number? fi) [fi fi])]
+      (when (or (<= lo i hi)
+                (<= lo (- len i) hi))
+        se))))
+
+(defn slinky-first-match
+  [sl i len]
+  (some (partial slicky-match i len)
+        (partition 2 sl)))
+
+(defn slinky-map->str
+  [m]
+  (str (->> (dissoc m :text)
+            (mapcat identity)
+            (apply color-code))
+       (:text m)))
+
+(defn slinky-part->str
+  [p n]
+  (cond
+    (string? p) p
+    (fn? p) (recur (p n) n)
+    (map? p) (slinky-map->str p)))
+
+(defn slinky->str
+  [sl n]
+  (let [[& {:keys [start end]}] sl]
+    (->> [[(slinky-part->str start nil)]
+          (map #(slinky-part->str
+                 (slinky-first-match sl
+                                     %
+                                     n)
+                 %)
+               (range 0 n))
+          [(slinky-part->str end nil)]]
+         (apply concat)
+         (apply str))))

 (defn apply-color-palette
   [n]
@@ -52,22 +92,10 @@

 (def reset-color-code (color-code))

-(defn header-indent
-  [depth]
-  (str depth (clojure.string/join "" (repeat depth "|"))))
-
 (defn indent
-  [depth & {:keys [start end]
-            :or   {start " " end " "}}]
-  (format "%s%s%s"
-          start
-          (->> depth
-               inc
-               (range 1)
-               (map #(str (color-code :fg* %)
-                          "|"))
-               (clojure.string/join ""))
-          end))
+  [depth & rest]
+  (slinky->str (apply arg-indent rest)
+               depth))

 (defn indent-line-breaks
   [s depth & rest]
@@ -80,15 +108,14 @@

 (defn header->string
   [entry]
-  (let [depth (:depth entry)]
-    (clojure.string/join "" [(color-code :fg* depth)
-                             (indent depth :end "" )
-                             (color-code :fg 10 :bg* depth :bold true)
-                             "-"
-                             (color-code :bg 0)
-                             (fg-color-code depth)
-                             (:name entry)
-                             reset-color-code])))
+  (let [{:keys [depth name]} entry]
+    (if name
+      (clojure.string/join "" [(indent depth :end {:fg 7
+                                                   :bold true
+                                                   :text ">"})
+                               (color-code :fg* (dec depth) :bg 0 :bold false)
+                               (:name entry)
+                               reset-color-code]))))

 (defn args-str
   [entry]


Implementing call a system process

Implementing call a system process

--- src/power/py_relay.clj
+++ src/power/py_relay.clj
@@ -14,7 +14,7 @@
   [resource]
   (slurp (io/resource resource)))

-(defn- create-temp-file
+(defn- create-resource-file
   [dest-file content]
   (let [temp-file (io/file (str destination-resource-dir dest-file))]
     (do
@@ -40,5 +40,5 @@
 (defn make-relay-device
   []
   (if-let [dev-resource-content (resource-content device-resource)]
-    (let [driver-file (create-temp-file device-resource dev-resource-content)]
+    (let [driver-file (create-resource-file device-resource dev-resource-content)]
       (Relay. driver-file))))


CMR-1030: Made test comparision of cache contents independent of the order of the returned items.

--- system-int-test/test/cmr/system_int_test/admin/cache_api_test.clj
+++ system-int-test/test/cmr/system_int_test/admin/cache_api_test.clj
@@ -170,8 +170,7 @@
     (testing "lookup value for cache key"
       (are [url cache cache-key value]
            (let [response (get-cache-value url cache cache-key admin-read-token)]
-             (is (= value response)))
-
+             (is (= (set value) (set response))))
            (url/indexer-read-caches-url) "acls" "acls" [{:aces
                                                          [{:permissions ["read"], :user-type "guest"}
                                                           {:permissions ["read"], :user-type "registered"}],


in testing code : rename println to tprintln to avoid conflicting

--- test/clojure/nginx/clojure/coroutine_socket_handlers_for_test.clj
+++ test/clojure/nginx/clojure/coroutine_socket_handlers_for_test.clj
@@ -23,19 +23,19 @@

 (def tlog (TinyLogService/createDefaultTinyLogService))
 ;
-(defn println [& args]
+(defn tprintln [& args]
   (.info tlog (first args) (into-array  Object (rest args))))

 (defn do-simple-selfresume [selfresume]
-  (println "enter do-simple-response")
-  (println "before yield")
+  (tprintln "enter do-simple-response")
+  (tprintln "before yield")
 ;  (.printStackTrace (Exception. "debug stack trace"))
   (if selfresume
     (let [cr (Coroutine/getActiveCoroutine)]
-     (future (java.lang.Thread/sleep 3000) (println "before resume") (try  (.resume cr) (catch Throwable e (.printStackTrace e))))))
+     (future (java.lang.Thread/sleep 3000) (tprintln "before resume") (try  (.resume cr) (catch Throwable e (.printStackTrace e))))))
   (Coroutine/yield)
-  (println "after yield")
+  (tprintln "after yield")
   {:status 200, :headers {"content-type" "text/plain"}, :body "Simple Response\n"})


Get rid of the bogus var quote helper

Get rid of the bogus var quote helper

--- test/desdemona/query_test.clj
+++ test/desdemona/query_test.clj
@@ -44,31 +44,29 @@
     (#'q/dsl->logic '(and (= (:ip x) "10.0.0.1")
                           (= (:type x) "egress")))))

-(def dsl->logic
-  @#'desdemona.query/dsl->logic)
-
 (deftest dsl->logic-tests
-  (is (thrown? IllegalArgumentException (dsl->logic '(BOGUS BOGUS BOGUS))))
+  (is (thrown? IllegalArgumentException
+               (#'q/dsl->logic '(BOGUS BOGUS BOGUS))))
   (is (= '(clojure.core.logic/featurec x {:ip "10.0.0.1"})
-         (dsl->logic '(= (:ip x) "10.0.0.1"))
-         (dsl->logic '(= "10.0.0.1" (:ip x)))))
+         (#'q/dsl->logic '(= (:ip x) "10.0.0.1"))
+         (#'q/dsl->logic '(= "10.0.0.1" (:ip x)))))
   (testing "logical conjunction"
     (is (= '(clojure.core.logic/conde
              [(clojure.core.logic/featurec x {:ip "10.0.0.1"})
               (clojure.core.logic/featurec x {:type "egress"})])
-           (dsl->logic '(and (= (:ip x) "10.0.0.1")
-                             (= (:type x) "egress"))))))
+           (#'q/dsl->logic '(and (= (:ip x) "10.0.0.1")
+                                 (= (:type x) "egress"))))))
   (testing "logical disjunction"
     (is (= '(clojure.core.logic/conde
              [(clojure.core.logic/featurec x {:ip "10.0.0.1"})]
              [(clojure.core.logic/featurec x {:type "egress"})])
-           (dsl->logic '(or (= (:ip x) "10.0.0.1")
-                            (= (:type x) "egress")))))
+           (#'q/dsl->logic '(or (= (:ip x) "10.0.0.1")
+                                (= (:type x) "egress")))))
     (is (= '(clojure.core.logic/conde
              [(clojure.core.logic/featurec x {:type "egress"})]
              [(clojure.core.logic/featurec x {:ip "10.0.0.1"})])
-           (dsl->logic '(or (= (:type x) "egress")
-                            (= (:ip x) "10.0.0.1")))))))
+           (#'q/dsl->logic '(or (= (:type x) "egress")
+                                (= (:ip x) "10.0.0.1")))))))

 (def events
   [{:ip "10.0.0.1"}


Add list-prior-versions-test

Add list-prior-versions-test

--- test/grimoire/api/fs_test.clj
+++ test/grimoire/api/fs_test.clj
@@ -38,6 +38,14 @@
     (is (= ["a.core" "a.impl.clj" "a.impl.cljs"]
            (sort (map :name nss))))))

+(deftest list-prior-versions-test
+  (let [ns (t/->Ns "org.foo" "a" "1.0.0" "a.core")
+        defs (api/thing->prior-versions test-config ns)]
+    (is (= ["org.foo/a/0.1.0-SNAPSHOT/a.core"
+            "org.foo/a/0.1.0/a.core"
+            "org.foo/a/1.0.0/a.core"]
+           (sort (map :uri defs))))))
+
 (deftest list-def-test
   (let [ns (t/->Ns "org.foo" "a" "1.0.0" "a.core")
         defs (api/list-defs test-config ns)]


generate id

generate id

--- src/s7p/master/web.clj
+++ src/s7p/master/web.clj
@@ -114,15 +114,24 @@
     (not winnotice)                     {:status :error :msg "winnotice url cannot be blank"}
     true                                {:status :ok}))

+(def id-count (atom 0))
+
+(defn id-gen []
+  (swap! id-count inc)
+  (str @id-count))
+
 (defn to-req [line]
   (let [fp (line 1)]
-   {:req
-    {:site       (line 0)
-     :floorPrice (if (= "NA" fp) nil (Integer. fp))
-     :device     (line 2)
-     :user       (line 3)
-     :test       @testing}
-    :result      (mapv #(Integer. %) (subvec line 4))}))
+    (let [req      {:req
+                    {:id         (id-gen)
+                     :site       (line 0)
+                     :floorPrice (if (= "NA" fp) nil (Integer. fp))
+                     :device     (line 2)
+                     :user       (line 3)
+                     :test       @testing}
+                    :result      (mapv #(Integer. %) (subvec line 4))}]
+      (println req)
+      req)))

 (defn -main [& args]
   (let [context (zmq/zcontext 1)


CLJ-2123 Add :as-alias option to ::libspec

Signed-off-by: Alex Miller <99328387f8334f68433c424d2dfd83062f62754b@cognitect.com>

--- src/main/clojure/clojure/core/specs/alpha.clj
+++ src/main/clojure/clojure/core/specs/alpha.clj
@@ -123,10 +123,12 @@
     (s/cat :prefix simple-symbol?
            :libspecs (s/+ ::libspec))))

+(s/def ::as-alias simple-symbol?)
+
 (s/def ::libspec
   (s/alt :lib simple-symbol?
          :lib+opts (s/spec (s/cat :lib simple-symbol?
-                                  :options (s/keys* :opt-un [::as ::refer])))))
+                                  :options (s/keys* :opt-un [::as ::refer ::as-alias])))))

 (s/def ::ns-require
   (s/spec (s/cat :clause #{:require}


fix diameter

fix diameter


get rid of unneeded let

get rid of unneeded let

--- src/sketches/five.cljc
+++ src/sketches/five.cljc
@@ -40,17 +40,16 @@
    lower))

 (defn point-on-arc [point radius degrees]
-  (let [[x y] [(:x point) (:y point)]]
-    (->Point (->> degrees
-                  (to-radians)
-                  (cos)
-                  (* radius)
-                  (+ x))
-             (->> degrees
-                  (to-radians)
-                  (sin)
-                  (* radius)
-                  (+ y)))))
+  (->Point (->> degrees
+                (to-radians)
+                (cos)
+                (* radius)
+                (+ (:x point)))
+           (->> degrees
+                (to-radians)
+                (sin)
+                (* radius)
+                (+ (:y point)))))

 (defn random-point-on-arc [origin-point angle-bounds radius]
   (let [degrees (random-angle angle-bounds)]


Check if node is started before triggering a workflow

--- resources/rest-service/cloudify/triggers/execute_workflow.clj
+++ resources/rest-service/cloudify/triggers/execute_workflow.clj
@@ -2,21 +2,29 @@
   [ctx]
     (let [deployment-id         (:deployment-id ctx)
           parameters            (:trigger-parameters ctx)
+          node-id               (:node-id ctx)
           manager-ip            (or (System/getenv "MANAGEMENT_IP") "127.0.0.1")
           raw-manager-rest-port (or (System/getenv "MANAGER_REST_PORT") "80")
           manager-rest-port     (Integer/parseInt raw-manager-rest-port)
           base-uri              (str "http://" manager-ip ":" manager-rest-port)
           endpoint              (str "/executions")
           resource-uri          (str base-uri endpoint)
+          node-endpoint         (str "/node-instances/" node-id)
+          node-resource-uri     (str base-uri node-endpoint)
           body                  (cheshire.core/generate-string {
                                   :deployment_id           deployment-id
                                   :workflow_id             (:workflow parameters)
                                   :force                   (:force parameters)
                                   :allow_custom_parameters (:allow_custom_parameters parameters)
-                                  :parameters              (:workflow_parameters parameters)})]
-      (clj-http.client/post resource-uri
-        {:content-type   :json
-         :accept         :json
-         :socket-timeout (:socket_timeout parameters)
-         :conn-timeout   (:conn_timeout parameters)
-         :body           body})))
+                                  :parameters              (:workflow_parameters parameters)})
+          get-node              (fn [] (clj-http.client/get node-resource-uri {
+                                         :accept         :json
+                                         :socket-timeout (:socket_timeout parameters)
+                                         :conn-timeout   (:conn_timeout parameters)}))]
+      (if (= (:state (cheshire.core/parse-string (:body (get-node)) true)) "started")
+        (clj-http.client/post resource-uri
+          {:content-type   :json
+           :accept         :json
+           :socket-timeout (:socket_timeout parameters)
+           :conn-timeout   (:conn_timeout parameters)
+           :body           body}))))


Add delete button

Add delete button

--- src/cljs/elevent_client/pages/events/owned.cljs
+++ src/cljs/elevent_client/pages/events/owned.cljs
@@ -7,7 +7,12 @@
             [elevent-client.api :as api]
             [elevent-client.state :as state]
             [elevent-client.routes :as routes]
-            [elevent-client.locale :as locale]))
+            [elevent-client.locale :as locale]
+            [elevent-client.components.action-button :as action-button]))
+
+(defn delete-event [form]
+  (fn [callback]
+    (api/events-endpoint :delete form #(callback))))

 (defn page []
   (let [created-events
@@ -58,7 +63,11 @@
                 [:a.ui.right.floated.small.button
                  {:href (routes/event-edit event)}
                  "Edit"
-                 [:i.right.chevron.icon]]]]])]
+                 [:i.right.chevron.icon]]
+                [action-button/component
+                 {:class "ui right floated small negative"}
+                 "Delete"
+                 (delete-event event)]]]])]
           [:p "You don't own any events."])]]
       [:div.ui.dimmer {:class (when (empty? @api/events) :active)}
        [:div.ui.loader]]]]))


added group, date and save; renamed db-object -> to-dbo, and clojure-object -> to-clj

--- src/karras.clj
+++ src/karras.clj
@@ -2,26 +2,39 @@
   (:use [clojure.contrib.def :only [defnk]])
   (:import [com.mongodb Mongo DB DBCollection BasicDBObject
             DBObject DBCursor DBAddress MongoOptions
-            ObjectId]))
+            ObjectId]
+           [java.util Calendar]))
+
+(defn date [& [year month date hour minute second milli]]
+  (let [c  (Calendar/getInstance)
+        z? #(int (or % 0))]
+    (.set c Calendar/YEAR        (z? year))
+    (.set c Calendar/MONTH       (z? (- month 1)))
+    (.set c Calendar/DATE        (z? date))
+    (.set c Calendar/HOUR_OF_DAY (z? hour))
+    (.set c Calendar/MINUTE      (z? minute))
+    (.set c Calendar/SECOND      (z? second))
+    (.set c Calendar/MILLISECOND (z? milli))
+    (.getTime c)))

 (defn has-option? [options k]
   (boolean (some #{k} options)))

-(defn db-object [m]
+(defn to-dbo [m]
   (let [to-s #(if (keyword? %) (name %) (str %))
-        to-v #(if (map? %) (db-object %) %)
+        to-v #(if (map? %) (to-dbo %) %)
         dbo  (BasicDBObject.)]
     (doseq [[k v] m]
       (.put dbo (to-s k) (to-v v)))
     dbo))

-(defn clojure-object [dbo]
+(defn to-clj [dbo]
   (apply merge (map (fn [#^java.util.Map$Entry e]
                        (let [k (.getKey e)
                              v (.getValue e)]
                          {(keyword k)
                           (if (instance? DBObject v)
-                            (clojure-object v)
+                            (to-clj v)
                             v)}))
                     (seq dbo))))

@@ -42,16 +55,20 @@

 (defn insert [#^DBCollection collection & objs]
   (if (= 1 (count objs))
-    (clojure-object
-     (.insert collection #^DBObject (db-object (first objs))))
-    (map clojure-object
-         (.insert collection #^java.util.List (map db-object objs)))))
+    (to-clj
+     (.insert collection #^DBObject (to-dbo (first objs))))
+    (map to-clj
+         (.insert collection #^java.util.List (map to-dbo objs)))))
+
+(defn save [#^DBCollection collection & objs]
+  (doseq [o objs]
+    (.save collection (to-dbo o))))

 (defn update [#^DBCollection collection query obj & options]
   (let [o? #(has-option? options %)]
-    (clojure-object (.update collection
-                             (db-object query)
-                             (db-object obj)
+    (to-clj (.update collection
+                             (to-dbo query)
+                             (to-dbo obj)
                              (o? :upsert)
                              (o? :multi)))))

@@ -70,14 +87,26 @@
 (defn search* [#^DBCollection collection query keys limit skip order-by count?]
   (let [cursor (if query
                  (if keys
-                   (.find collection #^DBObject (db-object query) #^DBObject (db-object keys))
-                   (.find collection #^DBObject (db-object query)))
+                   (.find collection
+                          #^DBObject (to-dbo query)
+                          #^DBObject (to-dbo keys))
+                   (.find collection
+                          #^DBObject (to-dbo query)))
                  (.find collection ))
-        cursor (if limit (.limit cursor limit) cursor)
-        cursor (if skip (.skip cursor skip) cursor)
-        cursor (if order-by (.sort cursor (db-object (apply merge order-by))) cursor)
-        cursor (if count? (.count cursor) cursor)]
-    (map clojure-object cursor)))
+        cursor (if limit
+                 (.limit cursor limit)
+                 cursor)
+        cursor (if skip
+                 (.skip cursor skip)
+                 cursor)
+        cursor (if order-by
+                 (.sort cursor (to-dbo
+                                (apply merge order-by)))
+                   cursor)]
+    (if count?
+      (.count cursor)
+      (map to-clj cursor))
+))

 (defnk fetch [collection query :limit nil :skip nil :include nil :exclude nil :order-by nil :count false]
   (search* collection
@@ -103,8 +132,17 @@
 (defn distinct-values [#^DBCollection collection s]
   (seq (.distinct collection (name s))))

+(defn group [#^DBCollection collection keys cond initial reduce]
+  (map to-clj (.group collection
+                              (to-dbo (zipmap (map name keys)
+                                                 (repeat true)))
+                              (to-dbo cond)
+                              (to-dbo initial)
+                              #^String reduce)))
+
 (defn delete [#^DBCollection collection obj]
-  (.remove collection (db-object obj)))
+  (.remove collection (to-dbo obj)))
+

 (defn asc [k]  {k 1})
 (defn desc [k] {k -1})
@@ -145,13 +183,13 @@
   [#^DBCollection collection fields & options]
   (let [o? #(has-option? options %)]
     (.ensureIndex collection #^DBObject
-                  (db-object fields)
+                  (to-dbo fields)
                   (boolean (o? :force))
                   (boolean (o? :unique)))))

 (defn drop-index [#^DBCollection collection o]
-  (.dropIndex collection #^DBObject (db-object o)))
+  (.dropIndex collection #^DBObject (to-dbo o)))

-(defn drop-index-named [#^DBCollection collection #^String s]
-  (.dropIndex collection s))
+(defn drop-index-named [#^DBCollection collection kw]
+  (.dropIndex collection (name kw)))


use configured values for tagtime gap and first seed

--- src/tictag/tagtime.clj
+++ src/tictag/tagtime.clj
@@ -1,10 +1,11 @@
 (ns tictag.tagtime
   (:require [clojure.string :as str]
             [clj-time.coerce :as tc]
-            [clojure.java.io :as io]))
+            [clojure.java.io :as io]
+            [tictag.config :as config]))

-(def gap (* 30 60))
-(def FIRSTSEED 666)
+(def gap (:tagtime-gap config/config))
+(def FIRSTSEED (:tagtime-seed config/config))
 (def IA 16807)
 (def IM 2147483647)
 (def FIRSTPING 1184083200)