CMR-4493: Minor refactoring.

CMR-4493: Minor refactoring.

--- metadata-db-app/int_test/cmr/metadata_db/int_test/concepts/delete_test.clj
+++ metadata-db-app/int_test/cmr/metadata_db/int_test/concepts/delete_test.clj
@@ -74,6 +74,18 @@
         (util/delete-concept (:concept-id service))
         (is (= true (is-association-tombstone? service-association)))))))

+(defn- assert-collection-tombstone
+  "Make sure that the saved tombstone has expected concept-id, revision-id, user-id,
+  empty metadata, and deleted = true."
+  [origin-coll deleted-coll revision-id user-id]
+  (is (= (dissoc (assoc origin-coll
+                        :deleted true
+                        :metadata ""
+                        :revision-id revision-id
+                        :user-id user-id)
+                 :revision-date :transaction-id)
+         (dissoc deleted-coll :revision-date :transaction-id))))
+
 ;; collections must be tested separately to make sure granules are deleted as well
 (deftest delete-collection-using-delete-end-point-test
   (doseq [provider-id ["REG_PROV" "SMAL_PROV"]]
@@ -85,7 +97,7 @@
           variable-association (util/create-and-save-variable-association coll1 variable 1 1)
           service (util/create-and-save-service provider-id 1)
           service-association (util/create-and-save-service-association coll1 service 1 1)]
-
+
       ;; variable association is not a tombstone before collection is deleted
       (is (= false (is-association-tombstone? variable-association)))
       ;; service association is not a tombstone before collection is deleted
@@ -103,13 +115,9 @@
                {:status status
                 :revision-id revision-id}))

-        (is (= (dissoc (assoc saved-coll1
-                              :deleted true
-                              :metadata ""
-                              :revision-id revision-id
-                              :user-id nil)
-                       :revision-date :transaction-id)
-               (dissoc deleted-coll1 :revision-date :transaction-id)))
+        ;; Make sure that the saved tombstone has expected concept-id, revision-id,
+        ;; user-id, empty metadata, and deleted = true.
+        (assert-collection-tombstone saved-coll1 deleted-coll1 revision-id nil)

         ;; Make sure that a deleted collection gets it's own unique revision date
         (is (t/after? (:revision-date deleted-coll1) (:revision-date saved-coll1))
@@ -158,15 +166,9 @@
                {:status status
                 :revision-id revision-id}))

-        ;; Make sure that the saved tombstone has expected concept-id, revision-id, empty metadata,
-        ;; and deleted = true.
-        (is (= (dissoc (assoc saved-coll1
-                              :deleted true
-                              :metadata ""
-                              :revision-id revision-id
-                              :user-id "user101")
-                       :revision-date :transaction-id)
-               (dissoc deleted-coll1 :revision-date :transaction-id)))
+        ;; Make sure that the saved tombstone has expected concept-id, revision-id,
+        ;; user-id, empty metadata, and deleted = true.
+        (assert-collection-tombstone saved-coll1 deleted-coll1 revision-id "user101")

         ;; make sure that a deleted collection gets it's own unique transaction-id
         (is (> (:transaction-id deleted-coll1) (:transaction-id saved-coll1)))


fix a bunch of problems with Data Browser

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

--- plugins/DataBrowser/src/org/micromanager/browser/core.clj
+++ plugins/DataBrowser/src/org/micromanager/browser/core.clj
@@ -38,8 +38,6 @@

 (def settings-window (atom nil))

-(def headings (atom nil))
-
 (def collections (atom nil))

 (def current-data (atom nil))
@@ -62,10 +60,6 @@
 (defn get-icon [name]
   (SwingResourceManager/getIcon
     org.micromanager.MMStudioMainFrame (str "icons/" name)))
-
-(defn set-model [table m]
-  (.setModel table m)
-  (.setRowSorter table (TableRowSorter. m)))

 (defn set-filter [table text]
   (let [sorter (.getRowSorter table)
@@ -88,11 +82,7 @@
         (removeUpdate [_ _] (f))))))

 (defn get-model-column-index [table text]
-  (let [table-model (.getModel table)]
-    (-> (vec
-      (for [i (range (.getColumnCount table-model))]
-        (.getColumnName table-model i)))
-      (.indexOf text))))
+  (.. table (getColumn text) getModelIndex))

 (defn open-selected-files [table]
   (let [path-column (get-model-column-index table "Path")]
@@ -115,10 +105,25 @@
     (getValueAt [row column] (nth (nth @current-data row) column))
     (getColumnName [column] (nth tags column))))

-(defn add-browser-table-row [s]
-  (swap! current-data conj (vec s))
-  (let [r (dec (count @current-data))]
-    (.fireTableRowsInserted (.getModel (@browser :table)) r r)))
+(defn get-row-path [row]
+  (nth row (.indexOf tags "Path")))
+
+(defn refresh-row [rows new-row]
+  (let [changed (atom false)
+        new-path (get-row-path new-row)
+        data
+          (vec
+            (for [row rows]
+              (if (= (get-row-path row) new-path)
+                (do (reset! changed true) new-row)
+                row)))]
+    (if @changed
+      data
+      (conj data new-row))))
+
+(defn add-browser-table-row [new-row]
+  (swap! current-data refresh-row (vec new-row))
+  (.fireTableDataChanged (.getModel (@browser :table))))

 (defn remove-browser-table-row [n]
   (swap! current-data remove-nth n)
@@ -193,15 +198,15 @@
 (defn add-summary-maps [browser map-list headings]
   (send-off scanning-agent
             (fn [_] (doseq [m map-list]
-                      (awt-event
-                        (add-browser-table-row
-                          (map #(get m %) headings)))))))
+                      (Thread/sleep 5)
+                      (add-browser-table-row
+                        (map #(get m %) headings))))))

 (defn add-location [location]
   (.. (get-in @settings-window [:locations :table])
       getModel (addRow (Vector. (list location))))
   (let [maps (get-summary-maps location)]
-    (add-summary-maps @browser maps @headings)))
+    (add-summary-maps @browser maps tags)))

 (defn user-add-location []
   (when-let [loc (choose-directory nil
@@ -215,63 +220,76 @@
         :when (= index (.getModelIndex (.getColumn column-model i)))]
           i))))

-(defn show-columns [display-columns]
-  (println "show-columns" display-columns)
-  (let [table (:table @browser)
-        column-model (.getColumnModel (:table @browser))
-        total-width (.getWidth table)]
-    (dorun (map #(.removeColumn column-model %)
-                (doall (enumeration-seq (.getColumns column-model)))))
-    (doseq [display-column display-columns]
-      (let [tag (:title display-column)
-            model-index (get-model-column-index table tag)]
-        (.addColumn column-model
-          (doto (TableColumn. model-index)
-            (.setHeaderValue tag)
-            (.setPreferredWidth (* total-width (:width display-column)))))))))
-
-(defn update-column [tags-model col]
-  (when (:table @browser)
-    (let [on (.getValueAt tags-model col 0)
-          tag (.getValueAt tags-model col 1)
-          table (:table @browser)
-          column-model (.getColumnModel table)
-          model-index (get-model-column-index table tag)
-          display-index (get-display-index table model-index)]
-      (when (<= 0 model-index)
-        (when (and (not on) display-index)
-          (.removeColumn column-model (.getColumn column-model display-index)))
-        (when (and on (not display-index))
-          (println model-index)
-          (.addColumn column-model
-            (doto (TableColumn. model-index)
-              (.setHeaderValue tag))))))))
-
-(defn update-all-columns [tags-model]
-  (dorun (map #(update-column tags-model %) (range (.getRowCount tags-model)))))
+(defn update-browser-column [])
+
+(defn add-browser-column [tag]
+  (let [column (doto (TableColumn. (.indexOf tags tag))
+                 (.setHeaderValue tag))]
+    (.addColumn (@browser :table) column)
+    column))
+
+(defn column-visible? [tag]
+  (true?
+    (some #{true}
+      (for [col (enumeration-seq (.getColumns (->@browser :table .getColumnModel)))]
+        (= (.getIdentifier col) tag)))))
+
+(defn set-column-visible [tag visible]
+      (let [table (@browser :table)]
+        (if (and visible (not (column-visible? tag)))
+          (add-browser-column tag))
+        (if (and (not visible) (column-visible? tag))
+          (.removeColumn (.getColumnModel table)
+            (.getColumn table tag)))))
+
+(defn create-column-model []
+   (proxy [AbstractTableModel] []
+                (getRowCount [] (count tags))
+                (getColumnCount [] 2)
+                (getValueAt [row column]
+                  (let [tag (nth tags row)]
+                    (condp = column
+                      0 (column-visible? tag)
+                      1 tag)))
+                (setValueAt [val row column]
+                  (when (zero? column)
+                    (let [tag (nth tags row)]
+                      (set-column-visible tag val))))
+                (getColumnClass [column]
+                  (get [Boolean String] column))))

 (defn create-column-table []
   (let [table (proxy [JTable] []
                 (isCellEditable [_ i] (get [true false] i)))
-        model (proxy [DefaultTableModel] [0 2]
-                (getColumnClass [i]
-                  (get [Boolean String] i)))]
+        model (create-column-model)]
     (doto table
       (.setModel model)
       (.setRowSelectionAllowed false)
       (.setFocusable false)
       (.. getColumnModel (getColumn 0) (setMinWidth 20))
       (.. getColumnModel (getColumn 0) (setMaxWidth 20)))
-      (.addTableModelListener model
-        (reify TableModelListener
-          (tableChanged [_ e]
-            (dorun (map #(update-column model %)
-              (range (.getFirstRow e) (inc (.getLastRow e))))))))
-    (doseq [tag tags]
-      (.addRow model (Vector. [false tag])))
     table))

+(defn update-collection-menu [name ]
+  (let [menu (@browser :collection-menu)
+        names (sort (keys @collections))
+        listeners (.getItemListeners menu)]
+    (dorun (map #(.removeItemListener menu %) listeners))
+    (.removeAllItems menu)
+    (dorun (map #(.addItem menu %) names))
+    (.addItem menu "New...")
+    (.setSelectedItem (@browser :collection-menu) name)
+    (dorun (map #(.addItemListener menu %) listeners))))
+
 ;; collection files
+
+
+(defn save-last-collection [name]
+  (write-value-to-prefs prefs "last-collection" name))
+
+(defn load-last-collection []
+  (or (read-value-from-prefs prefs "last-collection")
+    (System/getProperty "user.name")))

 (defn read-collection-map []
   (reset! collections
@@ -305,30 +323,31 @@

 (defn apply-data-and-settings [settings]
   (awt-event
-  (let [table (@browser :table)
-        model (.getModel table)
-        {:keys [browser-model-data
-                browser-model-headings
-                window-size display-columns
-                locations sorted-column]} settings]
-    (println "apply:" display-columns)
-    (reset! current-data browser-model-data)
-    (doto model (.fireTableDataChanged) (.fireTableStructureChanged))
-    (-> @settings-window :locations :table .getModel
-      (.setDataVector
-        (Vector. (map #(Vector. (list %)) (seq locations)))
-        (Vector. (list "Locations"))))
-    (let [column-model (-> @settings-window :columns :table .getModel)]
-      (doseq [row (range (.getRowCount column-model))]
-        (.setValueAt column-model
-          (not (nil? (some #{(.getValueAt column-model row 1)}
-                           (map :title display-columns))))
-          row 0))
-      (show-columns display-columns)
-      (update-all-columns))
-    (println display-columns)
-    (println window-size)
-    )))
+    (let [table (@browser :table)
+          model (.getModel table)
+          {:keys [browser-model-data
+                  browser-model-headings
+                  window-size display-columns
+                  locations sorted-column]} settings]
+      (def dc display-columns)
+      (reset! current-data browser-model-data)
+      (doto model (.fireTableDataChanged) (.fireTableStructureChanged))
+      (-> @settings-window :locations :table .getModel
+        (.setDataVector
+          (Vector. (map #(Vector. (list %)) (seq locations)))
+          (Vector. (list "Locations"))))
+      (let [column-model (.. table getColumnModel)]
+        (println (-> column-model .getColumns enumeration-seq count))
+        (dorun (map #(.removeColumn column-model %)
+             (-> column-model .getColumns enumeration-seq reverse))))
+      (println display-columns)
+      (let [total-width (.getWidth table)]
+        (doseq [col display-columns]
+          (println col)
+          (doto (add-browser-column (:title col))
+            (.setPreferredWidth (* total-width (:width col)))))))
+      (-> @settings-window :columns :table
+                           .getModel .fireTableDataChanged)))

 (defn save-data-and-settings [collection-name]
   (println "save-data-and-settings" collection-name)
@@ -337,9 +356,10 @@
   (println "saved data and settings: " (:display-columns (get-current-data-and-settings))))

 (defn load-data-and-settings [name]
+  (save-last-collection name)
   (let [f (get @collections name)]
     (apply-data-and-settings (read-json (slurp f))))
-    (.setSelectedItem (@browser :collection-menu) name))
+  (update-collection-menu name))

 (defn user-creates-collection []
   (let [prompt-msg "Please enter a name for the new collection."]
@@ -354,17 +374,6 @@
                          prompt-msg))
            :else collection-name)))))

-(defn update-collection-menu []
-  (let [menu (@browser :collection-menu)
-        names (sort (keys @collections))
-        listeners (.getItemListeners menu)]
-    (dorun (map #(.removeItemListener menu %) listeners))
-    (.removeAllItems menu)
-    (dorun (map #(.addItem menu %) names))
-    (.addItem menu "New...")
-    (.addItem menu "Load...")
-    (dorun (map #(.addItemListener menu %) listeners))))
-
 (defn new-data-and-settings []
   (let [collection-name (user-creates-collection)]
     (swap! collections assoc collection-name
@@ -374,7 +383,7 @@
     (save-collection-map)
     (save-data-and-settings collection-name)
     (awt-event
-      (update-collection-menu)
+      (update-collection-menu collection-name)
         (let [m (-> @browser :table .getModel)]
           (.fireTableDataChanged m)
              ))))
@@ -383,8 +392,14 @@
   (reify ImageStorageListener
     (imageStorageFinished [_ path]
       (add-summary-maps @browser
-                        (list (get-summary-map path "")) @headings))))
+                        (list (get-summary-map path "")) tags))))

+(defn refresh-collection []
+  (let [n (.indexOf tags "Location")
+        locations (distinct (map #(get % n) @current-data))]
+    ; blah blah
+  ))
+
 ;; windows

 (defn create-settings-window []
@@ -448,6 +463,7 @@
         scroll-pane (JScrollPane. table)
         search-field (JTextField.)
         search-label (JLabel. (get-icon "zoom.png"))
+        refresh-button (create-button "Refresh" refresh-collection)
         settings-button (create-button "Settings..."
                           #(.show (:frame @settings-window)))
         collection-label (JLabel. "Collection:")
@@ -480,17 +496,17 @@
     (gen-map frame table scroll-pane settings-button search-field
              collection-menu)))

+(defn init-columns []
+  (vec (map #(vec (list % false)) tags)))
+
 (defn start-browser []
   (load-mm)
   (read-collection-map)
   (reset! settings-window (create-settings-window))
   (reset! browser (create-browser))
-  (reset! headings tags)
   (MMImageCache/addImageStorageListener (create-image-storage-listener))
   (.setModel (:table @browser) (create-browser-table-model tags))
-  (update-all-columns (.getModel (get-in @settings-window [:columns :table])))
-  (update-collection-menu)
-  (add-location "/Users/arthur/qqqq")
+  (load-data-and-settings (load-last-collection))
   (.show (@browser :frame))
   browser)


make even even even more compatible with clojure 1.3

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

--- plugins/DataBrowser/src/org/micromanager/browser/core.clj
+++ plugins/DataBrowser/src/org/micromanager/browser/core.clj
@@ -289,15 +289,16 @@
   (doto (Thread.
             (fn []
               (try
-                (dorun (loop []
-                  (Thread/sleep 5)
-                  (let [location (.take pending-locations)]
-                    (when-not (= location pending-locations)
-                      (doseq [data-set (find-data-sets location)]
-                       ; (println "data-set:" data-set)
-                        (.put pending-data-sets [data-set location]))
-                        (recur)))
-                  (catch Exception e nil)))))
+                (dorun
+                  (loop []
+                    (Thread/sleep 5)
+                    (let [location (.take pending-locations)]
+                      (when-not (= location pending-locations)
+                        (doseq [data-set (find-data-sets location)]
+                          ; (println "data-set:" data-set)
+                          (.put pending-data-sets [data-set location]))
+                        (recur))))
+                  (catch Exception e nil))))
           "data browser scanning thread") .start))


prevent deselection of rows during scanning updates

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

--- plugins/DataBrowser/src/org/micromanager/browser/core.clj
+++ plugins/DataBrowser/src/org/micromanager/browser/core.clj
@@ -124,14 +124,18 @@
         (changedUpdate [_ _] (f))
         (removeUpdate [_ _] (f))))))

+(defn row-index-to-path [i]
+  (let [table (@browser :table)]
+    (.. table getModel
+        (getValueAt (.convertRowIndexToModel table i)
+                    (.indexOf tags "Path")))))
+
 (defn open-selected-files [table]
-  (let [path-column (.indexOf tags "Path")]
-    (doseq [i (.getSelectedRows table)]
-      (let [f (.. table getModel
-                  (getValueAt (.convertRowIndexToModel table i) path-column))]
-        (if (.exists (File. f))
-          (.openAcquisitionData gui f)
-          (ReportingUtils/showError "File not found."))))))
+  (doseq [i (.getSelectedRows table)]
+    (let [f (row-index-to-path i)]
+      (if (.exists (File. f))
+        (.openAcquisitionData gui f)
+        (ReportingUtils/showError "File not found.")))))

 (defn listen-to-open [table]
   (.addMouseListener table
@@ -177,13 +181,25 @@
       data
       (conj data new-row))))

+(defn update-browser-table []
+  (let [table (@browser :table)
+        selected-rows (.getSelectedRows table)
+        selected-paths (set (map row-index-to-path selected-rows))]
+    (.. table getModel fireTableDataChanged)
+    (doseq [selected-row selected-rows]
+      (.addRowSelectionInterval table selected-row selected-row))
+;    (doseq [row (range (.getRowCount table))]
+;      (when (selected-paths (row-index-to-path row))
+;        (.addRowSelectionInterval table row row)))))
+))
+
 (defn add-browser-table-row [new-row]
   (let [row-vec (vec new-row)
         location (row-vec (.indexOf tags "Location"))]
     (dosync
       (if (or (contains? @current-locations location) (= location ""))
         (alter current-data refresh-row row-vec))))
-  (awt-event (.fireTableDataChanged (.getModel (@browser :table)))))
+  (awt-event (update-browser-table)))

 (defn remove-location [loc]
   (dosync
@@ -191,7 +207,7 @@
     (let [location-column (.indexOf tags "Location")]
       (alter current-data
              (fn [coll] (vec (remove #(= (nth % location-column) loc) coll))))))
-  (awt-event (-> @browser :table .getModel .fireTableDataChanged)
+  (awt-event (update-browser-table)
              (-> @settings-window :locations :table .getModel .fireTableDataChanged)
 ))


UI tweaks in conn list window.

UI tweaks in conn list window.

Do not rebuild entire table, replace model instead.

--- src/sqls/ui.clj
+++ src/sqls/ui.clj
@@ -17,6 +17,13 @@
    :conn-data conn})

+(defn build-connection-list-model
+  "Return model for UI table based on connection list."
+  [connections]
+  [:columns [:name :desc :class]
+   :rows (map build-connection-list-item connections)])
+
+
 (defn build-connection-list-table
   "Create a UI component that contains list of connections, bo be added to respective container.
   Parameter connections contains a list of conn-data maps, this parameter can be nil."
@@ -24,8 +31,7 @@
   (let [t (table
             :id :conn-list-table
             :preferred-size [480 :by 320]
-            :model [:columns [:name :desc :class]
-                    :rows (map build-connection-list-item connections)])]
+            :model (build-connection-list-model connections))]
     t))

@@ -33,6 +39,21 @@
   "Just close the dialog"
   [e]
   (dispose! e))
+
+
+(defn set-conn-list-frame-bindings!
+  [frame]
+  (let [conn-list-table (select frame [:#conn-list-table])
+        btn-connect (select frame [:#btn-connect])
+        btn-delete (select frame [:#btn-delete])]
+    (assert (not= conn-list-table nil))
+    (assert (not= btn-connect nil))
+    (assert (not= btn-delete nil))
+    (b/bind
+      (b/selection conn-list-table)
+      (b/transform (fn [s] (not= s nil)))
+      (b/property btn-connect :enabled?)
+      (b/property btn-delete :enabled?))))

 (defn on-btn-add-connection-click
@@ -44,7 +65,6 @@
   2. Replace connections list in parent frame.
   3. Close add connection dialog."
   [conn-list-frame e]
-  (println "conn-list-frame" conn-list-frame)
   (let [
         root (to-root e)
         conn-name (value (select root [:#name]))
@@ -56,13 +76,9 @@
                    "jdbc-conn-str" conn-jdbc-conn-str
                    "desc" conn-desc}
         new-connections (stor/add-connection! conn-data)
-        old-conn-list-table (select conn-list-frame [:#conn-list-table])
-        _ (println "old-conn-list-table" old-conn-list-table)
-        new-conn-list-table (build-connection-list-table new-connections)
-        _ (println "new-conn-list-table" new-conn-list-table)
+        conn-list-table (select conn-list-frame [:#conn-list-table])
         ]
-    (replace! (.getParent old-conn-list-table) old-conn-list-table new-conn-list-table)
-    ; (pack! conn-list-frame)
+    (config! conn-list-table :model (build-connection-list-model new-connections))
     (dispose! e)
     )
   )
@@ -98,9 +114,9 @@

 (defn on-btn-add-click
+  "Add connection button, conn list frame."
   [e]
-  (let [
-        add-connection-win (build-add-connection-ui (to-root e))]
+  (let [add-connection-win (build-add-connection-ui (to-root e))]
     (show! add-connection-win)
   )
 )
@@ -128,9 +144,8 @@
     (if (not= conn-data nil)
       (let [name (conn-data "name")
             new-connections (stor/delete-connection! name)
-            old-conn-list-table (select frame [:#conn-list-table])
-            new-conn-list-table (build-connection-list-table new-connections)]
-        (replace! (.getParent old-conn-list-table) old-conn-list-table new-conn-list-table)))))
+            conn-list-table (select frame [:#conn-list-table])]
+        (config! conn-list-table :model (build-connection-list-model new-connections))))))

 (defn on-btn-connect-click
@@ -147,21 +162,6 @@
   (let [conn-data (get-selected-conn-data conn-list-frame)]
     (println "conn-data:" conn-data)
     (create-worksheet! conn-data)))
-
-
-(defn set-conn-list-frame-bindings!
-  [frame]
-  (let [conn-list-table (select frame [:#conn-list-table])
-        btn-connect (select frame [:#btn-connect])
-        btn-delete (select frame [:#btn-delete])]
-    (assert (not= conn-list-table nil))
-    (assert (not= btn-connect nil))
-    (assert (not= btn-delete nil))
-    (b/bind
-      (b/selection conn-list-table)
-      (b/transform (fn [s] (not= s nil)))
-      (b/property btn-connect :enabled?)
-      (b/property btn-delete :enabled?))))

 (defn create-login-ui
@@ -185,8 +185,7 @@
                                         :items [
                                                 (scrollable (build-connection-list-table connections))
                                                 (horizontal-panel :border 4
-                                                                  :items [
-                                                                          btn-add
+                                                                  :items [btn-add
                                                                           btn-delete
                                                                           btn-connect])])
                :on-close :exit)]


stop scanning if the window has been closed

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

--- plugins/DataBrowser/src/org/micromanager/browser/core.clj
+++ plugins/DataBrowser/src/org/micromanager/browser/core.clj
@@ -174,9 +174,8 @@
         (map remove-location
           (remove nil?
             (for [location-row selected-rows]
-              (do (println (.getValueAt location-model location-row 0))
-                  (.getValueAt location-model location-row 0))))))
-      (.fireTableDataChanged location-model))))
+              (.getValueAt location-model location-row 0))))))
+      (.fireTableDataChanged location-model)))

 (defn clear-history []
   (remove-location ""))
@@ -232,7 +231,7 @@
                   (let [location (.take pending-locations)]
                     (if-not (= location pending-locations)
                       (do (doseq [data-set (find-data-sets location)]
-                            (println "data-set:" data-set)
+                           ; (println "data-set:" data-set)
                             (.put pending-data-sets [data-set location]))
                           (recur))
                     nil))
@@ -457,7 +456,7 @@
 (defn create-image-storage-listener []
   (reify ImageStorageListener
     (imageStorageFinished [_ path]
-      (println "image storage:" path)
+     ; (println "image storage:" path)
       (.put pending-data-sets [path ""]))))

 (defn refresh-collection []
@@ -522,7 +521,10 @@
           (save-data-and-settings item (get-current-data-and-settings)))))))

 (defn handle-exit []
-  (println "Shutting down Data Browser.")
+;  (println "Shutting down Data Browser.")
+  (clear-queues)
+  (.put pending-data-sets pending-data-sets)
+  (.put pending-locations pending-locations)
   (close-window (@browser :frame))
   (close-window (@settings-window :frame))
   true)
@@ -568,7 +570,7 @@
       (.addWindowListener
         (proxy [WindowAdapter] []
           (windowClosing [e]
-            (println frame)
+            (clear-queues)
             (save-data-and-settings
               (get-last-collection-name)
                 (get-current-data-and-settings))


Cleanup examples

Cleanup examples

--- test/clojure/example_usage.clj
+++ test/clojure/example_usage.clj
@@ -15,15 +15,19 @@
              :Results
              :county)))

-(defn hello [in-channel]
+(defn handle-success [success-channel]
   (go (loop []
-        (println "Success " (<! in-channel))
-        (recur))))
+        (let [success-future (<! success-channel)]
+          (println "Success")
+          (println (:result success-future))
+          (recur)))))

 (defn handle-error [err-channel]
   (go (loop []
-        (println "Error " (<! err-channel))
-        (recur))))
+        (let [error-future (<! err-channel)]
+          (println "Error")
+          (println (:status error-future))
+          (recur)))))

 (defn thing [in-channel out-channel err-channel]
   (go
@@ -43,7 +47,7 @@
         out-channel (async/chan 10)
         err-channel (async/chan 10)]
     (thing in-channel out-channel err-channel)
-    (hello out-channel)
+    (handle-success out-channel)
     (handle-error err-channel)
     in-channel))


you wanted moar benchmarks, you got moar benchmarks

--- test/selmer/benchmark.clj
+++ test/selmer/benchmark.clj
@@ -2,13 +2,18 @@
   (:require [clojure.test :refer :all]
             [selmer.parser :refer :all]
             [selmer.util :refer :all]
-            [criterium.core :as criterium]))
+            [criterium.core :as criterium])
+  (:import java.io.StringReader))

 (def user (repeat 10 [{:name "test" }]))

 (def nested-for-context {:users (repeat 10 user)})

 (def big-for-context {:users (repeat 100 user)})
+
+(def large-content (apply str (repeat 2500 "bitemyapp > * ")))
+
+(def filter-chain (apply str (repeat 100 "|inc")))

 (deftest ^:benchmark bench-for-typical []
   (println "BENCH: bench-for-typical")
@@ -31,3 +36,15 @@
   (println "BENCH: bench-assoc-in*")
   (criterium/quick-bench
    (assoc-in* {:a {:b {:c 0}}} [:a :b :c] 1)))
+
+(deftest ^:benchmark bench-inject []
+  (println "BENCH: bench-inject")
+  (criterium/quick-bench
+   (render-file "templates/child.html" {:content large-content})))
+
+(deftest ^:benchmark bench-filter-hot-potato []
+  (println "BENCH: bench-filter-hot-potato")
+  (criterium/quick-bench
+   (render-template (parse (java.io.StringReader. (str "{{bar" filter-chain "}}"))
+                        {:custom-filters
+                         {:inc (fn [s] (inc (Integer. s)))}}) {:bar "0"})))


started work on redis integration for collection entity / class and page / entity maps

--- corpusmaker.clj
+++ corpusmaker.clj
@@ -10,9 +10,36 @@
 ; based NLP algorithms out of Wikimedia dumps

 (ns corpusmaker
-    (:require [clojure.zip :as zip]
-              [clojure.contrib.lazy-xml :as lxml]
-              [clojure.contrib.zip-filter.xml :as zfx]))
+  (:require
+     [clojure.zip :as zip]
+     [clojure.contrib.lazy-xml :as lxml]
+     [clojure.contrib.zip-filter.xml :as zfx]
+     [redis])
+  (:use
+     [clojure.contrib.duck-streams :only (read-lines)]))
+
+; RE to parse a line of a N-TRIPLES RDF stream to find a type relationship
+; http://www.w3.org/TR/rdf-testcases/#ntriples
+(def *type-pattern* #"<([^<]+?)> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <([^<]+?)> \.")
+(def *page-pattern* #"<([^<]+?)> <http://xmlns.com/foaf/0.1/page> <([^<]+?)> \.")
+
+(defn collect-page
+  "Parse a N-TRIPLES statement and store the [instance page] pair if match"
+  [store-func statement]
+  (let [[_ inst page] (re-find *page-pattern* statement)]
+    (when inst (store-func page inst)))
+
+(defn process-file [filename line-func]
+  ; TODO: add start line and end line (max)
+  ; TODO: add version to pass an acc explicitly and reduce instead?
+  ; http://lethain.com/entry/2009/nov/15/reading-file-in-clojure/
+  (doall (map line-func (read-lines filename))))
+
+(defn collect-pages-redis
+  [filename]
+  (redis/with-server
+    {:host "127.0.0.1" :port 6379 :db 0}
+    (process-file filename #(collect-page redis/set %))))

 ; TODO: rewrite this using http://github.com/marktriggs/xml-picker-seq since
 ; using a zipper keeps all the parsed elements in memory which is not suitable
@@ -26,5 +53,7 @@
   "collect wikimarkup payload of a dump in seqable xml"
   [xml] (zfx/xml-> xml :page :revision :text zfx/text))

+
 ; sample timed run
 ; (time (dorun (collect-text (parse-xml "chunk-0001.xml"))))
+


Revert "Bump the reply dep to 0.3.6"

Revert "Bump the reply dep to 0.3.6"

This reverts commit 329de7e0aa275bff38ebcc71c7e98c9d797e266a and
reopens #168.

Reply version 0.3.6 has issues with pom.xml that prevent boot from
building.

--- boot/worker/project.clj
+++ boot/worker/project.clj
@@ -19,7 +19,7 @@
                  [boot/aether                 ~version]
                  ;; see https://github.com/boot-clj/boot/issues/82
                  [net.cgrand/parsley          "0.9.3" :exclusions [org.clojure/clojure]]
-                 [reply                       "0.3.6"]
+                 [reply                       "0.3.5"]
                  [cheshire                    "5.3.1"]
                  [clj-jgit                    "0.8.0"]
                  [clj-yaml                    "0.4.0"]


CMR-3489 try to get config working in CI

--- system-int-test/test/cmr/system_int_test/search/collection_usage_relevancy.clj
+++ system-int-test/test/cmr/system_int_test/search/collection_usage_relevancy.clj
@@ -8,14 +8,15 @@
    [cmr.common.config :as config]
    [cmr.common.util :as util :refer [are3]]
    [cmr.mock-echo.client.echo-util :as e]
+   [cmr.search.data.query-to-elastic :as query-to-elastic]
    [cmr.system-int-test.data2.collection :as dc]
    [cmr.system-int-test.data2.core :as d]
    [cmr.system-int-test.system :as s]
+   [cmr.system-int-test.utils.dev-system-util :as dev-sys-util]
    [cmr.system-int-test.utils.humanizer-util :as hu]
    [cmr.system-int-test.utils.index-util :as index]
    [cmr.system-int-test.utils.ingest-util :as ingest]
-   [cmr.system-int-test.utils.search-util :as search]
-   [cmr.search.data.query-to-elastic :as query-to-elastic]))
+   [cmr.system-int-test.utils.search-util :as search]))

 (use-fixtures :each (ingest/reset-fixture {"provguid1" "PROV1"}))

@@ -37,7 +38,7 @@
     (index/wait-until-indexed))))

 (deftest community-usage-relevancy-scoring
-  (query-to-elastic/set-sort-use-relevancy-score! true)
+  (dev-sys-util/eval-in-dev-sys (query-to-elastic/set-sort-use-relevancy-score! true))
   (ingest-community-usage-metrics)
   (d/ingest "PROV1" (dc/collection {:short-name "AMSR-L1A"
                                     :entry-title "Relevancy 1"
@@ -69,7 +70,7 @@
       (is (= ["Relevancy 4" "Relevancy 3" "Relevancy 2" "Relevancy 1"] (map :name results))))))

 (deftest keyword-relevancy-takes-precedence
-  (query-to-elastic/set-sort-use-relevancy-score! true)
+  (dev-sys-util/eval-in-dev-sys (query-to-elastic/set-sort-use-relevancy-score! true))
   (ingest-community-usage-metrics)
   (d/ingest "PROV1" (dc/collection {:short-name "AMSR-L1A"
                                     :entry-title "Relevancy 1"
@@ -97,7 +98,7 @@
              (map :name results))))))

 (deftest ingest-metrics-after-collections
-  (query-to-elastic/set-sort-use-relevancy-score! true)
+  (dev-sys-util/eval-in-dev-sys (query-to-elastic/set-sort-use-relevancy-score! true))
   (d/ingest "PROV1" (dc/collection {:short-name "AMSR-L1A"
                                     :entry-title "Relevancy 1"
                                     :version-id "3"}))
@@ -114,7 +115,7 @@
     (is (= ["Relevancy 2" "Relevancy 3" "Relevancy 1"] (map :name results)))))

 (deftest change-metrics
-  (query-to-elastic/set-sort-use-relevancy-score! true)
+  (dev-sys-util/eval-in-dev-sys (query-to-elastic/set-sort-use-relevancy-score! true))
   (ingest-community-usage-metrics)

   (d/ingest "PROV1" (dc/collection {:short-name "AMSR-L1A"
@@ -139,7 +140,7 @@

 ;; Outside of keyword search, allow the user to sort by community usage
 (deftest sort-by-community-usage
-  (query-to-elastic/set-sort-use-relevancy-score! true)
+  (dev-sys-util/eval-in-dev-sys (query-to-elastic/set-sort-use-relevancy-score! true))
   (ingest-community-usage-metrics)
   (d/ingest "PROV1" (dc/collection {:short-name "AMSR-L1A" ;10
                                     :entry-title "Relevancy 1"
@@ -171,7 +172,7 @@
        "AG_MAPSS,2,30\n"))

 (deftest community-usage-not-provided-versions
-  (query-to-elastic/set-sort-use-relevancy-score! true)
+  (dev-sys-util/eval-in-dev-sys (query-to-elastic/set-sort-use-relevancy-score! true))
   (ingest-community-usage-metrics sample-csv-not-provided-versions)
   (d/ingest "PROV1" (dc/collection {:short-name "AMSR-L1A"
                                     :entry-title "AMSR-L1A V3 Relevancy"


helper for testing stacktrace, formatting

--- test/logback_riemann_appender/core_test.clj
+++ test/logback_riemann_appender/core_test.clj
@@ -1,26 +1,37 @@
 (ns logback-riemann-appender.core-test
   (:require
    [clojure.test :refer :all]
-   [clojure.tools.logging :as log]))
+   [clojure.tools.logging :as log])
+  (:import
+   [com.github.kyleburton.logback RiemannAppender]))

 (deftest test-logging
-  (is (= 0 (.get com.github.kyleburton.logback.RiemannAppender/timesCalled)))
+  (is (= 0 (.get RiemannAppender/timesCalled)))

   (log/infof "log at info level")
-  (is (= 1 (.get com.github.kyleburton.logback.RiemannAppender/timesCalled)))
+  (is (= 1 (.get RiemannAppender/timesCalled)))

   (log/fatalf "log at fatal level")
-  (is (= 2 (.get com.github.kyleburton.logback.RiemannAppender/timesCalled)))
+  (is (= 2 (.get RiemannAppender/timesCalled)))

   (let [ex (RuntimeException. "Test Error")]
-   (log/fatalf ex "log with exception: %s" ex))
-  (is (= 3 (.get com.github.kyleburton.logback.RiemannAppender/timesCalled))))
+    (log/fatalf ex "log with exception: %s" ex))
+  (is (= 3 (.get RiemannAppender/timesCalled))))
+

 (comment
+  (defn testfnkrb []
+    (let [ex (RuntimeException. "Test exception for logging, what stacktrace do we get?")]
+      (log/infof ex "Testing Stacktrace: %s" ex)))

   (dotimes [ii 20]
     (log/info "test from clojure"))

-)+  (let [ex (RuntimeException. "Test exception for logging, what stacktrace do we get?")]
+    (log/infof ex "Testing Stacktrace: %s" ex))
+
+  (testfnkrb)
+
+  )


Улучшения и доработки

Улучшения и доработки

--- src-cljs/ixinfestor/omut.cljs
+++ src-cljs/ixinfestor/omut.cljs
@@ -1720,8 +1720,9 @@
   (assoc nav-tabs-app-state
          :tabs (nav-tabs-app-state-i-maker tabs)))

+
 (defn nav-tabs-active-tab [app]
-  (get-in @app [:active-tab] 0))
+  (get app :active-tab 0))

 (defn nav-tabs-enable-inly-one [app ii]
   (om/transact!
@@ -2196,10 +2197,10 @@
                            media-object))
            (dom/div #js {:className "media-body"}
                     (when href (dom/a #js {:style #js {:float "right"}
-                                           :href (or href "#")}
+                                           :href (or href "#") :target "_blank"}
                                       (dom/button #js {:className "btn btn-success"} "скачать")))
                     (when heading (dom/h4 #js {:className "media-heading"} heading
-                                          (when heading-2 (dom/small nil " " heading-2 ))))
+                                          (when heading-2 (dom/small nil " - " heading-2 ))))
                     body)))


Grammar fixes

Grammar fixes

--- src/redbrick_20/components/data.cljs
+++ src/redbrick_20/components/data.cljs
@@ -22,35 +22,6 @@
   :event-date "9th of April"
   :event-information "TBA"}))

-(def donationGoals (reagent/atom [
-    {
-      :value 0
-      :next_value 400 ;avoiding div by 0
-      :type "Our Thanks :)"
-    }
-    {
-      :value 400
-      :next_value 500 ;avoiding div by 0
-      :type "Balloon Man"
-    }
-    {
-      :value 500
-      :next_value 1000
-      :type "Photo Booth"
-    }
-    {
-      :value 1000
-      :next_value 5000
-      :type "Free Beer Tokens"
-    }
-    {
-      :value 5000
-      :next_value 10000
-      :type "zergless shaves his Beard"
-    }
-  ]))
-
-
 (def timeline [
   {
     :year 1996
@@ -65,8 +36,7 @@
   }
   {
     :year 1997
-    :supporting-data "Valentines' Event in The Fleet (Shift a Trinner?).
-                      Heres a picture of pooka have fun"
+    :supporting-data "Valentines' Event in The Fleet (Shift a Trinner?)."
     :supporting-image "http://wiki.redbrick.dcu.ie/mw/images/9/91/Rbwiki_RedbrickLogo_tiny_logo.gif"
   }
   {
@@ -86,7 +56,7 @@
   }
   {
     :year 2000
-    :supporting-data "Rag Week. Redbrick, the SU, and some other people (mostly redbrick though ;o))
+    :supporting-data "Rag, Redbrick, the SU, and some other people (mostly redbrick though ;o))
                       turned out on a _very_ cold Monday morning to collect for the Irish Cancer Society on
                       the Ballymun and Swords Roads (at the junctions with Collins Avenue). Then they did
                       the same again in the day at rush hour. Redbrick also had a bouncy castle in DCU.
@@ -115,7 +85,8 @@
     :supporting-data "Redbrick gets donated two Alpha servers. One from HEAnet and the other from DCU CSD.
                       Redbricks new server goes live and is named Deathray. The name is from a joke about
                       dimples using Redbrick's money to finance a death ray. or something.
-                      Deathray becomes the primary login server, all logins now accepted at login.redbrick.dcu.ie, redbrick.dcu.ie is no more. "
+                      Deathray becomes the primary login server, all logins now accepted at login.redbrick.dcu.ie,
+                      redbrick.dcu.ie is no more. "
     :supporting-image "http://wiki.redbrick.dcu.ie/mw/images/2/29/Rbwiki_RedbrickLogo_logo2-rb.gif"
   }
   {
@@ -128,7 +99,7 @@
   }
   {
     :year 2005
-    :supporting-data "There is literally nothing of relevance on the wiki for this year :(."
+    :supporting-data "This was the first year Redbrick went to TechWeek."
     :supporting-image "http://wiki.redbrick.dcu.ie/mw/images/2/29/Rbwiki_RedbrickLogo_logo2-rb.gif"
   }
   {
@@ -178,8 +149,9 @@
   }
   {
     :year 2012
-    :supporting-data "Redbrick go to FOSDEM, valuable lessions on Mutliple campuses and tee-shirts in winter
-                      were learned. Redbrick takes applications for this years IrlCPC Programming Competition in UCC.
+    :supporting-data "Redbrick go to FOSDEM, We Learn ULB has more than one Campus.
+                      Far too many people learn that winter in Brussles is very cold and Tee-Shirts are not good winter wear.
+                      Redbrick takes applications for this years IrlCPC Programming Competition in UCC.
                       Five teams are formed to attend the event. Redbrick member bunbun passed away"
     :supporting-image "https://pbs.twimg.com/profile_images/1662456750/logo_400x400.png"
   }
@@ -190,7 +162,7 @@
   }
   {
     :year 2014
-    :supporting-data "Redbrick relaunched TechWeek with the support of companys like Google & Amazon.
+    :supporting-data "Redbrick relaunched TechWeek with the support of companies like Google & Amazon.
                       We Join Google at the first Google Open day in their Dublin Ireland Office"
     :supporting-image "https://pbs.twimg.com/profile_images/1662456750/logo_400x400.png"
   }


Adapt to PR review

Adapt to PR review

--- backend/src/akvo/lumen/lib/auth.clj
+++ backend/src/akvo/lumen/lib/auth.clj
@@ -16,6 +16,7 @@
    [clojure.tools.logging :as log]
    [hugsql.core :as hugsql]
    [iapetos.core :as prometheus]
+   [iapetos.registry :as registry]
    [integrant.core :as ig]))

 (hugsql/def-db-fns "akvo/lumen/lib/visualisation.sql")
@@ -136,10 +137,8 @@
                                   :dashboard-ids auth-dashboards})))

 (defn- flow-check-permissions [flow-api request collector tenant data]
-  (let [t (prometheus/start-timer collector :app/flow-check-permissions {"tenant" tenant})
-        res (c.flow/check-permissions flow-api (jwt/jwt-token request) data)]
-    (t)
-    res))
+  (prometheus/with-duration (registry/get collector :app/flow-check-permissions {"tenant" tenant})
+    (c.flow/check-permissions flow-api (jwt/jwt-token request) data)))

 (defn- load-auth-data [dss rasters tenant-conn flow-api request collector tenant]
   (let [permissions         (->> (map :source dss)


Add dimmers to bloom.

Add dimmers to bloom.

--- src/afterglow/effects/fun.clj
+++ src/afterglow/effects/fun.clj
@@ -737,10 +737,26 @@
           furthest (transform/max-distance measure heads)
           f (fn [show snapshot target previous-assignment]
               (let [fraction (params/resolve-param fraction show snapshot target)
-                    level (/ fraction (/ (measure target) furthest))]
+                    level (if (zero? furthest)
+                            1
+                            (let [distance (measure target)]
+                              (if (zero? distance)
+                                1
+                                (/ fraction (/ distance furthest)))))]
                 (color-fx/fade-colors previous-assignment color level show snapshot target)))
           assigners (fx/build-head-assigners :color heads f)]
-      (Effect. "Bloom"
-               fx/always-active
-               (fn [show snapshot] assigners)
-               fx/end-immediately)))
+      (apply fx/scene "Bloom"
+             (concat [(Effect. "Bloom color"
+                               fx/always-active
+                               (fn [show snapshot] assigners)
+                               fx/end-immediately)]
+                     (for [fixture fixtures]
+                       (let [distance (measure fixture)
+                             level (if (or (zero? furthest) (zero? distance))
+                                     255
+                                     (params/build-param-formula
+                                      Number
+                                      (fn [fraction]
+                                        (* 255 (/ fraction (/ distance furthest))))
+                                      fraction))]
+                         (dimmer-fx/dimmer-effect level [fixture])))))))


+{:synsem {:subcat '()}}

+{:synsem {:subcat '()}}

--- src/babel/francais/writer.clj
+++ src/babel/francais/writer.clj
@@ -67,7 +67,8 @@
                                                     (.size
                                                      (map (fn [number]
                                                             (let [spec (unify spec
-                                                                              {:comp {:synsem {:agr {:number number}}}})
+                                                                              {:comp {:synsem {:agr {:number number}}}
+                                                                               :synsem {:subcat '()}})
                                                                   spec (dissoc spec
                                                                                :dag_unify.core/serialized)]
                                                               (log/debug (str "generating from spec: " spec))


add iOS easing function to sidebar

add iOS easing function to sidebar

--- src/braid/mobile/sidebar.cljs
+++ src/braid/mobile/sidebar.cljs
@@ -2,6 +2,9 @@
   (:require [reagent.core :as r]
             [reagent.ratom :include-macros true :refer-macros [reaction]]
             [garden.core :refer [css]]))
+
+(def easing-fn
+  "cubic-bezier(.43, 0, .58, 1)")

 (def style-view
   (fn []
@@ -19,7 +22,7 @@
            :right "100vw"
            :z-index 100}
           [:&.open :&.closed
-           {:transition "transform 0.25s ease-in-out"}]
+           {:transition (str "transform" " 0.25s " easing-fn)}]
           [:&.closed
            {:transform "translate3d(0,0,0)"}]
           [:&.open


remove primary-network and add arch

remove primary-network and add arch

--- src/clj/runbld/facts/oshi.clj
+++ src/clj/runbld/facts/oshi.clj
@@ -12,7 +12,7 @@
    (oshi.json SystemInfo)))

 ;; just wanted the defrecord near the top
-(declare facts primary-network)
+(declare facts arch)

 (defrecord Oshi [facts]
   Facter
@@ -20,15 +20,10 @@
   (raw [x] x)

   (arch [{x :facts}]
-    (get-in x [:properties :os.arch]))
+    (arch x))

   (model [{x :facts}]
-    ;; The field that we use from facter is [:os :hardware] which
-    ;; appears to basically return the system architecture.
-    (let [arch (get-in x [:properties :os.arch])]
-      (if (= "amd64" arch)
-        "x86_64"
-        arch)))
+    (arch x))

   (cpu-type [{x :facts}]
     (get-in x [:hardware :processor :name]))
@@ -109,19 +104,11 @@
              " days"
              " day")))))

-(defn primary-network
-  "Takes the set of facts and returns a vector of [ipv4 ipv6] for the
-  primary network adapter.  Is somewhat naive in that it picks the
-  primary adapter based on total bytes sent and received."
-  [facts]
-  ;; TODO - is this sufficient to find the "primary"?
-  (->> (get-in facts [:hardware :networks])
-       (remove (comp empty? :ipv4))
-       (sort-by #(+ (:bytesSent %)
-                    (:bytesRecv %)))
-       last
-       ((juxt :ipv4 :ipv6))
-       (map first)))
+(defn arch [facts]
+  (let [arch (get-in facts [:properties :os.arch])]
+    (if (= "amd64" arch)
+      "x86_64"
+      arch)))

 (defn uname [{:keys [platform] :as facts}]
   (let [platform (string/lower-case platform)]


Moar WIP

Moar WIP


redraw the map on a new search

redraw the map on a new search

--- src/cljs/ontheway/modern.cljs
+++ src/cljs/ontheway/modern.cljs
@@ -16,6 +16,9 @@
 ;; (def tile-url "https://{s}.tiles.mapbox.com/v3/{id}/{z}/{x}/{y}.png")
 (def tile-url "http://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}")
 (def mappy (-> L (.map "mappy")))
+(def directions-layer (-> L (.layerGroup [])))
+(def biz-layer (-> L (.layerGroup [])))
+(def biz-layer-items (atom {}))
 (def autocompleteFrom (google.maps.places.Autocomplete.
                        (dom/getElement "directions-from")))
 (def autocompleteTo (google.maps.places.Autocomplete.
@@ -48,7 +51,8 @@
     (.-value (dom/getElement "directions-to"))))

 (defn remove-explanation-text []
-  (.remove (dom/getElement "explanation")))
+  (if-let [node (dom/getElement "explanation")]
+    (.remove node)))

 (defn section-id [num]
   (str "biz-" num))
@@ -114,6 +118,14 @@
   (.setAttribute (dom/getElement "biz-container")
                  "class" "col-md-4"))

+(defn hide-biz-sidebar []
+  (.setAttribute (dom/getElement "map-container")
+                 "class" "col-md-12")
+  (.setAttribute (dom/getElement "biz-container")
+                 "class" ""))
+(defn clear-biz-sidebar []
+  (let [sidebar (dom/getElement "biz-container")]
+    (dom/removeChildren sidebar)))

 (defn setup-map [m lat lng]
   (-> m (.setView [lat lng] 12))
@@ -122,19 +134,23 @@
                               :id "examples.map-i875mjb7"})
       (.addTo m)))

-(defn add-numbered-marker [lat lng num]
-  (let [NumberedDivIcon (.-NumberedDivIcon js/L)]
-    (-> L (.marker [lat, lng]
-                   {:icon (NumberedDivIcon. {:number (str num)})})
-        (.on "click" #(aset js/window "location" (str "#" (section-id num))))
-        (.addTo mappy))))
-
-(defn add-numbered-marker-active [lat lng num]
-  (let [NumberedDivIconActive (.-NumberedDivIconActive js/L)]
-    (-> L (.marker [lat, lng]
-                   {:icon (NumberedDivIconActive. {:number (str num)})})
-        (.on "click" #(aset js/window "location" (str "#" (section-id num))))
-        (.addTo mappy))))
+(defn add-numbered-marker [layer lat lng num]
+  (let [NumberedDivIcon (.-NumberedDivIcon js/L)
+        marker (-> L (.marker [lat, lng]
+                              {:icon (NumberedDivIcon. {:number (str num)})})
+                   (.on "click" #(aset js/window "location"
+                                       (str "#" (section-id num)))))
+        new-layer (.addLayer layer marker)]
+    (swap! biz-layer-items assoc num new-layer)))
+
+(defn add-numbered-marker-active [layer lat lng num]
+  (let [NumberedDivIconActive (.-NumberedDivIconActive js/L)
+        marker (-> L (.marker [lat, lng]
+                              {:icon (NumberedDivIconActive. {:number (str num)})})
+                   (.on "click" #(aset js/window "location"
+                                       (str "#" (section-id num)))))
+        new-layer (.addLayer layer marker)]
+    (swap! biz-layer-items assoc num new-layer)))

 ;; Allows handling Nodelist like a seq
 (extend-type js/NodeList
@@ -150,11 +166,10 @@
 (defn find-marker-2 []
   (dom/getElementsByClass "number"))

-(defn remove-marker [num]
-  (if-let [element (first
-                    (filter #(= (str num) (.-innerText %))
-                            (dom/getElementsByClass "number")))]
-    (-> element .-parentNode .remove)))
+(defn remove-marker [layer num]
+  (let [marker (get @biz-layer-items num)]
+    (swap! biz-layer-items dissoc num)
+    (.removeLayer layer marker)))

 (defn url-encode [s]
   (js/encodeURIComponent s))
@@ -286,15 +301,14 @@
                    [start-lat start-lng])
                  lat-lngs)
                 [[(:end-lat last-lat-lng) (:end-lng last-lat-lng)]])
-         map-bounds (max-box-corners lat-lngs)]
-     ;; draw start/end points
-     (-> L (.circle (vec start-point) 8 {:color "green"})
-         (.addTo m))
-     (-> L (.circle (vec end-point) 8 {:color "red"})
-         (.addTo m))
-     ;; draw map directions
-     (-> L (.polyline lines)
-         (.addTo m))
+         map-bounds (max-box-corners lat-lngs)
+         start-circle (-> L (.circle (vec start-point) 8 {:color "green"}))
+         end-circle (-> L (.circle (vec end-point) 8 {:color "red"}))
+         lines (-> L (.polyline lines))]
+     ;; draw directions
+     (doseq [l [start-circle end-circle lines]]
+       (.addLayer directions-layer l))
+     (.addTo directions-layer m)
      (.fitBounds m
                  [[(:sw-lat map-bounds) (:sw-lng map-bounds)]
                   [(:ne-lat map-bounds) (:ne-lng map-bounds)]])
@@ -313,7 +327,8 @@
        (doseq [biz numbered-biz]
          (let [{:keys [id name url]} biz
                {:keys [latitude longitude]} (-> biz :location :coordinate)]
-           (add-numbered-marker latitude longitude id)))
+           (add-numbered-marker biz-layer latitude longitude id)))
+       (.addTo biz-layer m)
        (dommy/append! (sel1 :#biz-container)
                       (biz-template start-point end-point numbered-biz))
        (doseq [biz numbered-biz]
@@ -324,13 +339,13 @@
            (go
             (while true
               (<! mouseover)
-              (remove-marker id)
-              (add-numbered-marker-active latitude longitude id)))
+              (remove-marker biz-layer id)
+              (add-numbered-marker-active biz-layer latitude longitude id)))
            (go
             (while true
               (<! mouseout)
-              (remove-marker id)
-              (add-numbered-marker latitude longitude id)))))
+              (remove-marker biz-layer id)
+              (add-numbered-marker biz-layer latitude longitude id)))))
        (expand-biz-sidebar) ;; reduce map size to allow for biz sidebar
        (.fitBounds m
                    [[(:sw-lat map-bounds) (:sw-lng map-bounds)]
@@ -344,8 +359,16 @@
         (.start (.create js/Ladda ;; starts loading spinner
                          (dom/getElement "btn-go")))
         ;; clear existing map's directions
-        (remove-explanation-text) ;; clear text (if not already cleared)
-        (direction-steps mappy (from-query) (to-query)) ;; draw map's directions
+        (.clearLayers directions-layer)
+        ;; clear existing business markers
+        (.clearLayers biz-layer)
+        ;; clear the sidebar
+        (hide-biz-sidebar)
+        (clear-biz-sidebar)
+        ;; clear text (if not already cleared)
+        (remove-explanation-text)
+        ;; draw map's directions and businesses
+        (direction-steps mappy (from-query) (to-query))
         )))

 (defn geolocation [position]


Bind activity var only in debug builds when :def is provided

--- src/clojure/neko/activity.clj
+++ src/clojure/neko/activity.clj
@@ -153,7 +153,9 @@
              [~(vary-meta 'this assoc :tag name),
               ^android.os.Bundle ~'savedInstanceState]
              (.superOnCreate ~'this ~'savedInstanceState)
-             (def ~(vary-meta def assoc :tag name) ~'this)
+             ~(when (and (not (:neko.init/release-build *compiler-options*))
+                         def)
+                `(def ~(vary-meta def assoc :tag name) ~'this))
              (neko.init/init (.getApplicationContext ~'this))
              (~on-create ~'this ~'savedInstanceState)))
        ~(when on-create-options-menu


Bring in the core.logic namespace

Bring in the core.logic namespace

--- src/clojure/nightmod/core.clj
+++ src/clojure/nightmod/core.clj
@@ -1,5 +1,6 @@
 (ns nightmod.core
-  (:require [clojure.java.io :as io]
+  (:require [clojure.core.logic]
+            [clojure.java.io :as io]
             [nightcode.customizations :as custom]
             [nightcode.editors :as editors]
             [nightcode.shortcuts :as shortcuts]


Starting to add sprint11 demo. Removing scheduler from ingest when in memory mode

--- src/cmr/dev_system/system.clj
+++ src/cmr/dev_system/system.clj
@@ -77,7 +77,8 @@
             :indexer (indexer-system/create-system)
             :index-set (index-set-system/create-system)
             :ingest (-> (ingest-system/create-system)
-                        (assoc :db (ingest-data/create-in-memory-acl-hash-store)))
+                        (assoc :db (ingest-data/create-in-memory-acl-hash-store))
+                        (dissoc :scheduler))
             :search (assoc-in (search-system/create-system)
                               [:metadata-db :db]
                               in-memory-db)}


Allow non ILifecycle components in defsystem

--- src/com/palletops/leaven.cljx
+++ src/com/palletops/leaven.cljx
@@ -31,8 +31,8 @@
   implement ILifecycle and IStatus by calling the protocol methods
   on each of the components."
   [record-name components]
-  (letfn [(start-subcomp [k] `(update-in [~k] protocols/start))
-          (stop-subcomp [k] `(update-in [~k] protocols/stop))
+  (letfn [(start-subcomp [k] `(update-in [~k] start))
+          (stop-subcomp [k] `(update-in [~k] stop))
           (status-subcomp [k] `(update-in [~k] status))]
     `(defrecord ~record-name
          [~@(map (comp symbol name) components)]


changed styles

changed styles

--- src/com/podviaznikov/book.clj
+++ src/com/podviaznikov/book.clj
@@ -17,7 +17,7 @@
     [:body
       (views/header)
       [:main.ph3.pb3.pt2.ph5-ns.pb5-ns.pt2-ns
-        [:h1.lh-title.f2.athelas (:title book)]
+        [:h1.lh-title.f3.athelas (:title book)]
         [:h2.lh-title.f5.athelas (:author book)]
         [:span.i.f6 "ISBN: "]
         [:span.lh-title.f6 (:ISBN book)]


added additional special chars to distillery.processing/no-punctuation?

--- src/distillery/processing.clj
+++ src/distillery/processing.clj
@@ -57,7 +57,13 @@
           (.endsWith text ";")
           (= text "@")
           (= text "(")
-          (= text ")")))))
+          (= text ")")
+          (= text "[")
+          (= text "]")
+          (= text "{")
+          (= text "}")
+          (= text "§")
+          (= text "$")))))

 (defn not-short?
   "Checks whether a word is long enough to be relevant."
@@ -224,6 +230,3 @@
        (group-by (comp char-to-index-letter first first))
        (map-values #(apply sorted-map (apply concat %)))))

-
-
-


Make parent dir(s) when writing to a handle

--- src/grimoire/api/fs/write.clj
+++ src/grimoire/api/fs/write.clj
@@ -13,6 +13,7 @@
         _      (assert thing)
         handle (thing->meta-handle config thing)
         _      (assert handle)]
+    (.mkdirs (.getParentFile handle))
     (spit handle (pr-str data))
     nil))

@@ -25,6 +26,7 @@
         _      (assert thing)
         handle (thing->notes-handle config thing)
         _      (assert thing)]
+    (.mkdirs (.getParentFile handle))
     (spit handle data)))

 ;; FIXME: add write-example
@@ -35,6 +37,7 @@
         _      (assert (isa? :def thing))
         handle (thing->related-handle config thing)
         _      (assert thing)]
+    (.mkdirs (.getParentFile handle))
     (doseq [thing related-things]
       (spit handle (str (thing->path thing) \newline)
             :append true))))


Deletes unused subscription

Deletes unused subscription

--- src/hundred_pushups/subs.cljs
+++ src/hundred_pushups/subs.cljs
@@ -2,12 +2,6 @@
   (:require [re-frame.core :refer [reg-sub]]
             [hundred-pushups.core :as core]
             [hundred-pushups.db :as db]))
-
-;; FIXME - delete after android no longer uses this
-(reg-sub
-  :get-greeting
-  (fn [db _]
-    (:greeting db)))

 (reg-sub
  :stage


Update persistence.clj

Update persistence.clj

--- src/iyye/bios/persistence.clj
+++ src/iyye/bios/persistence.clj
@@ -1,5 +1,5 @@
 ; Iyye - AI agent
-; Copyright (C) 2016-2017  Sasha Yumzya
+; Copyright (C) 2016-2018  Sasha Yumzya

 ; This program is free software: you can redistribute it and/or modify
 ; it under the terms of the GNU Affero General Public License as
@@ -15,34 +15,34 @@
 ; along with this program.  If not, see <http://www.gnu.org/licenses/>.

 (ns iyye.bios.persistence
-   (:require
-     [clojure.tools.logging :as log]
-     [extras.mongowrapper :as mongo]))
+  (:require
+    [clojure.tools.logging :as log]
+    [extras.mongowrapper :as mongo]))

 (defn local-time-to-string []
-  (let [ date (java.util.Date.)]  (.format (java.text.SimpleDateFormat. "MM_dd_yyyy_HH_mm_ss") date)))
+  (let [date (java.util.Date.)] (.format (java.text.SimpleDateFormat. "MM_dd_yyyy_HH_mm_ss") date)))

 (def iyye-name (ref ()))
 (def iyye-main "iyye_main")

 (defn iyye-exists? [name]
   (let [entry (mongo/get-entry iyye-main "iyye_list" {:name name})]
-    (if (first entry)  true false)))
+    (if (first entry) true false)))

 (defn add-iyye [name]
   (if (iyye-exists? name)
     false
-    (mongo/add-entry iyye-main "iyye_list" {:name name :time (local-time-to-string)} )))
+    (mongo/add-entry iyye-main "iyye_list" {:name name :time (local-time-to-string)})))

 (defn list-iyye []
   (log/info "nothing list")
   (let [entries (mongo/get-entry iyye-main "iyye_list" {})]
-    (if entries (map :name entries)  false)))
+    (if entries (map :name entries) false)))

 (defn set-current-iyye [name]
   (dorun
     [(add-iyye name)
-    (dosync (ref-set iyye-name name))]))
+     (dosync (ref-set iyye-name name))]))

 (defn load-current-iyye [name]
   (dosync (ref-set iyye-name name)))
@@ -55,23 +55,19 @@
 (defn load-days []
   (mongo/get-count iyye-main (str "days_" @iyye-name) {}))

-(defn current-time-to-string []
-  (str (.format (java.text.SimpleDateFormat. "MM_dd_yyyy_HH_mm_ss") (java.util.Date.))))
-
 (defn write-io-to-db [days IO dir input]
   (let [doc (str "IO_day_" days)
         dbname (str @iyye-name "_IO_" (:name IO))
-        entry {:time current-time-to-string dir input}]
+        entry {:time (local-time-to-string) dir input}]
     (mongo/add-entry dbname doc entry)))

- (defn write-knowledge-to-db [doc-name fact]
-   (let [dbname (str @iyye-name "_knowledge")]
-     (log/info "add list: " (str fact))
-     (mongo/add-entry dbname doc-name fact)))
+(defn write-knowledge-to-db [doc-name fact]
+  (let [dbname (str @iyye-name "_knowledge")]
+    (log/info "add list: " (str fact))
+    (mongo/add-entry dbname doc-name fact)))

 ; (apply str (rest (str (:When {:When :ALWAYS}))))

 (defn read-knowledge-from-db [doc-name query]
   (let [dbname (str @iyye-name "_knowledge")]
     (mongo/get-entry dbname doc-name query)))
-


Fix order of play.

Fix order of play.


Add TODO.

Add TODO.

--- src/lein_xjc/internal/xjc.clj
+++ src/lein_xjc/internal/xjc.clj
@@ -7,6 +7,7 @@

 (defn xjc-main
   [argv]
+  ;; TODO: fork process to avoid driver killing currently executing jvm
   (Driver/main (into-array String argv)))

 (defn call-xjc


[l.d.build] Ensure proguard config for multi-dex

--- src/leiningen/droid/build.clj
+++ src/leiningen/droid/build.clj
@@ -61,6 +61,7 @@
   classes have to be kept in primary dex."
   [{{:keys [multi-dex-proguard-conf-path multi-dex-root-classes-path]} :android
     :as project} target-paths]
+  (ensure-paths multi-dex-proguard-conf-path)
   (let [proguard-bin (sdk-binary project :proguard)
         android-jar (io/file (get-sdk-build-tools-path project)
                              "lib" "shrinkedAndroid.jar")]


Spraffbot can now respond to !comment commands, by picking a random comment from YouTube.

--- Spraff/src/spraff/core.clj
+++ Spraff/src/spraff/core.clj
@@ -11,6 +11,7 @@
     (:use
         [clojure.contrib.command-line]
         [clojure.java.io]
+        [clojure.xml]
         [clojure.string :only [join]]
         [irclj.core]
     )
@@ -215,7 +216,49 @@
     ", please!"
 ))

-; BURRITO!
+; End BURRITO!
+
+; YOUTUBE!
+
+(defn elements-with-tag [tag x]
+    (cond
+        (map? x)
+            (if (= (:tag x) tag)
+                [x]
+                (elements-with-tag tag (:content x)))
+        (coll? x)
+            (apply concat (map (partial elements-with-tag tag) x))
+        :else
+            []
+            ))
+
+(defn get-all-comment-urls [x]
+    (apply concat (map
+        (fn [k]
+            (map
+                (fn [e] (:href (:attrs e)))
+                (filter
+                    (fn [e] (= :gd:feedLink (:tag e)))
+                    (:content k))))
+        (elements-with-tag :gd:comments x))))
+
+
+(defn get-all-comments [x]
+    (apply concat (map
+        (fn [k] (:content k))
+        (elements-with-tag :content x))))
+
+; Could use something other than the most commented video list:
+; https://developers.google.com/youtube/2.0/reference#Standard_feeds
+(defn pick-random-youtube-comment []
+    (let [
+       feed-xml (clojure.xml/parse "https://gdata.youtube.com/feeds/api/standardfeeds/most_discussed")
+       comments-url (rand-nth (get-all-comment-urls feed-xml))
+       comments-xml (clojure.xml/parse comments-url)
+       comment (rand-nth (get-all-comments comments-xml))]
+       comment))
+
+; End YOUTUBE!

 (defn on-message [{:keys [nick channel message irc]} state-ref]
     (log-sentence! message)
@@ -228,6 +271,9 @@
     (if (.startsWith message "!burrito")
         (send-message irc channel
             (generate-burrito)))
+    (if (.startsWith message "!comment")
+        (send-message irc channel
+            (pick-random-youtube-comment)))
     (if (.startsWith message "!memory")
         (send-message irc channel
             (let [


(PE-6014) Fixed reference to misspelled dir

--- test/puppetlabs/services/ca/certificate_authority_disabled_test.clj
+++ test/puppetlabs/services/ca/certificate_authority_disabled_test.clj
@@ -10,7 +10,7 @@
             [puppetlabs.trapperkeeper.testutils.bootstrap :as tk-testutils]))

 (def puppet-conf
-  "./dev-resources/puppetlabs/services/ca/certificate_authority_dissabled_test/master/conf/puppet.conf")
+  "./dev-resources/puppetlabs/services/ca/certificate_authority_disabled_test/master/conf/puppet.conf")

 (use-fixtures :each (jruby-testutils/with-puppet-conf puppet-conf))


Hide modal by ESC pressing.

Hide modal by ESC pressing.

--- src/cljs/hatnik/web/client/form.cljs
+++ src/cljs/hatnik/web/client/form.cljs
@@ -14,3 +14,14 @@
 (om/root widget/action-form-footer state/app-state
          {:target (. js/document (getElementById "iActionFormFooter"))})

+
+;; Keyboard actions
+
+;; Hidden modal by ESC
+(.keydown ($ js/document)
+           (fn [e]
+             (when (= 27 (.-keyCode e))
+               (.modal ($ :#iModal) "hide")
+               (.modal ($ :#iModalProject) "hide")
+               (.modal ($ :#iModalProjectMenu) "hide"))))
+


add basic phone list html

add basic phone list html

--- src/cljs/phonecat_re_frame/core.cljs
+++ src/cljs/phonecat_re_frame/core.cljs
@@ -12,7 +12,13 @@
 ;; Views

 (defn home-page []
-  [:p "Nothing here " (str "yet" "!")])
+  [:ul
+   [:li
+    [:span "Nexus S"]
+    [:p "Fast just got faster with Nexus S."]]
+   [:li
+    [:span "Motorola XOOM with Wi-Fi"]
+    [:p "The Next, Next Generation tablet."]]])

 (defn current-page []
   [:div [(session/get :current-page)]])


PLATFORM-2817: better Content-Disposition handling

--- src/vignette/util/image_response.clj
+++ src/vignette/util/image_response.clj
@@ -75,7 +75,9 @@
      (let [target-filename
            (if-let [requested-path
                     (when image-object (extension-for-name (content-type image-object)))]
-                      (string/replace filename #"\.\w+$" requested-path)
+                      (if (re-matches #"\.\w+$" filename)
+                        (string/replace filename #"\.\w+$" requested-path)
+                        (str filename requested-path))
                       filename)]
        (header response-map "Content-Disposition" (format "inline; filename=\"%s\"; filename*=UTF-8''%s" target-filename (url-encode target-filename))))
      response-map))


fix js-invalid-requires log missing resource-name

--- src/main/shadow/build/npm.clj
+++ src/main/shadow/build/npm.clj
@@ -515,7 +515,8 @@
             ;; moment.js has require('./locale/' + name); inside a function
             ;; it shouldn't otherwise hurt though
             (when (seq js-invalid-requires)
-              (log/info ::js-invalid-requires {:requires js-invalid-requires}))
+              (log/info ::js-invalid-requires {:resource-name resource-name
+                                               :requires js-invalid-requires}))

             (-> info
                 (assoc


Catch invalid configuration

Catch invalid configuration

--- src/matchmaker_sparql/cli.clj
+++ src/matchmaker_sparql/cli.clj
@@ -37,6 +37,8 @@
   [params]
   (validate-params params)
   (try+ (mount/start-with-args params)
+        (catch [:type ::util/invalid-config] {:keys [message]}
+          (util/die (format "Invalid configuration:\n %s" message)))
         (catch [:type ::sparql/endpoint-not-found] _
           (util/die (format "SPARQL endpoint <%s> was not found."
                             (get-in config [:sparql ::sparql/url])))))


fixing property in validation set

fixing property in validation set

--- src/aws/validations.clj
+++ src/aws/validations.clj
@@ -19,7 +19,7 @@
   )

 (defvalidatorset entity-validation
-  :aws aws
+  :aws aws-entity
   :machine machine-entity)

 (defn validate-entity


remove comps-map

remove comps-map

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -145,8 +145,7 @@
                     (if (= false (get-in bolt-at [:phrasal]))
                       [(do-defaults (assoc-in bolt path bolt-at) model)]
                       (let [comp-paths (find-comp-paths bolt-at)
-                            comps-map (comp-paths-to-bolts-map bolt-at comp-paths model (+ 1 depth) max-depth)
-                            comp-bolts (vals comps-map)]
+                            comp-bolts (vals (comp-paths-to-bolts-map bolt-at comp-paths model (+ 1 depth) max-depth))]
                         (when (not (some empty? comp-bolts))
                           (mapfn #(do-defaults (assoc-in bolt path %) model)
                                  (add-comps bolt-at
@@ -164,8 +163,7 @@
   (flatten
    (mapfn (fn [bolt]
             (let [comp-paths (find-comp-paths bolt)
-                  comps-map (comp-paths-to-bolts-map bolt comp-paths model 0 max-total-depth)
-                  comp-bolts (vals comps-map)]
+                  comp-bolts (vals (comp-paths-to-bolts-map bolt comp-paths model 0 max-total-depth))]
               ;; filter by the following constraint:
               ;; that for every path that points to a complement of a bolt,
               ;; there is a non-empty set of bolts that satisfies


fix typo: second argument to parse/fo-ps should be the morphology function to be applied to a single leaf rather than a parse tree

--- src/babel/italiano.cljc
+++ src/babel/italiano.cljc
@@ -50,7 +50,7 @@
                        show-notes true}}]
    ;; modeled after babel.english/morph:
    ;; most arguments are simply discarded for italian.
-   (parse/fo-ps expr (:morph-ps model))))
+   (parse/fo-ps expr (:morph model))))

 (defn fo-ps [expr]
   (parse/fo-ps expr #(get-string (get-in % [:italiano]))))


Add #'ensure-path-exists! file helper fn

--- src/overtone/helpers/file.clj
+++ src/overtone/helpers/file.clj
@@ -327,6 +327,12 @@
   (let [path (canonical-path path)
         f (file path)]
     (.exists f)))
+
+(defn ensure-path-exists!
+  "Throws an exception if path does not exist."
+  [path]
+  (when-not (path-exists? path)
+    (throw (Exception. (str "Error: unable locate path: " path)))))

 (defn file-exists?
   "Returns true if a file specified by path exists"


cleanup; Added more badge examples

cleanup; Added more badge examples

--- src/css-guide/styles/components.cljs
+++ src/css-guide/styles/components.cljs
@@ -58,7 +58,11 @@
 (defexample badge-button
   "### In a button"
   (dom/p #js {}
+    (dom/button #js {:className "c-button c-button--raised"} " Messages "
+      (dom/span #js {:className "c-badge"} "37"))
     (dom/button #js {:className "c-button c-button--raised c-button--primary"} " Messages "
+      (dom/span #js {:className "c-badge"} "37"))
+    (dom/button #js {:className "c-button c-button--raised c-button--accent"} " Messages "
       (dom/span #js {:className "c-badge"} "37"))))


c-name shouldn't repeat last part of ns

c-name shouldn't repeat last part of ns

It's crypto_generichash, not crypto_generichash_generichash

--- src/caesium/binding.clj
+++ src/caesium/binding.clj
@@ -234,10 +234,10 @@
   "Resolves the fn name in the current ns to the fn name in the equivalent
   libsodium C pseudo-namespace."
   [^clojure.lang.Namespace namespace ^clojure.lang.Symbol fn-name]
-  (let [adjusted-name (-> (name fn-name) (s/replace "-" "_"))
+  (let [fn-name (-> (name fn-name) (s/replace "-" "_"))
         prefix (-> namespace ns-name str (s/split #"\.") rest vec)
-        full-path (conj prefix adjusted-name)]
-    (symbol (s/join "_" full-path))))
+        path (into prefix (when-not (= (last prefix) fn-name) [fn-name]))]
+    (symbol (s/join "_" path))))

 (defn ^:private java-call-sym
   "Creates the Clojure Java method call syntax to call a method on the


Batch timeout now needed. Use absolute path for now.

--- src/onyx_benchmark/submit.clj
+++ src/onyx_benchmark/submit.clj
@@ -8,8 +8,8 @@
             [onyx.api]))

 (defn -main [id batch-size & args]
-  (def zk-addr (slurp "zookeeper.txt"))
-  (def riemann-host (slurp "metrics.txt"))
+  (def zk-addr (slurp "/home/ubuntu/zookeeper.txt"))
+  (def riemann-host (slurp "/home/ubuntu/metrics.txt"))

   (let [batch-size (Integer/parseInt batch-size)]

@@ -24,7 +24,6 @@
         :onyx/type :input
         :onyx/medium :generator
         :onyx/consumption :concurrent
-        :onyx/batch-timeout batch-timeout
         :onyx/batch-size batch-size}

        {:onyx/name :inc


Add test for error file output

Add test for error file output

--- test/clj_gatling/simulation_test.clj
+++ test/clj_gatling/simulation_test.clj
@@ -3,7 +3,8 @@
   (:require [clj-gatling.simulation :as simulation]
             [clj-gatling.httpkit :as httpkit]
             [clj-gatling.simulation-util :refer [choose-runner
-                                                 weighted-scenarios]]
+                                                 weighted-scenarios
+                                                 create-dir]]
             [clj-containment-matchers.clojure-test :refer :all]
             [clj-async-test.core :refer :all]
             [clojure.core.async :refer [go <! <!! timeout]]
@@ -16,6 +17,16 @@
       results)))

 (def error-file-path "target/test-results/error.log")
+
+(defn- setup-error-file-path
+  [f]
+  (let [file (clojure.java.io/file error-file-path)]
+    (when (not (.exists file))
+      (create-dir (.getParent file))))
+  (f))
+
+;; Just setup the file path once
+(use-fixtures :once setup-error-file-path)

 (defn- run-legacy-simulation [scenarios concurrency & [options]]
   (let [step-timeout (or (:timeout-in-ms options) 5000)]
@@ -201,11 +212,14 @@
                                      :result false}]}]))))

 (deftest when-function-throws-exception-it-is-logged
+  ;; delete previous log data
+  (clojure.java.io/delete-file error-file-path)
   (let [result (-> {:name "Exception logging scenario"
                     :steps [{:name "Throwing" :request (fn [_] (throw (Exception. "Simulated")))}]}
                    ;; FIXME: output will probably be jumbled with concurrency > 1
                    (run-single-scenario :concurrency 1))]
-    ))
+    (is (-> (slurp error-file-path)
+            (clojure.string/includes? "Simulated")))))

 (deftest simulation-passes-context-through-requests-in-scenario
   (let [result (run-single-scenario {:name "scenario"


Refer to tracked users as "subjects"

Refer to tracked users as "subjects"

It better represents what they are: the users whose data are being
collected.

--- src/chameleon/users.clj
+++ src/chameleon/users.clj
@@ -4,6 +4,6 @@

 (def ^{:private true} coll "users")

-(def users (mc/find-maps db/db coll))
+(def subjects (mc/find-maps db/db coll))

-(def user-ids (map (fn [e] (long (:_id e))) users))
+(def subject-ids (map (fn [e] (long (:_id e))) subjects))


runSilent

runSilent

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

--- acqEngine/src/org/micromanager/acq_engine.clj
+++ acqEngine/src/org/micromanager/acq_engine.clj
@@ -799,6 +799,11 @@
 (defn -init []
   [[] (atom {:stop false})])

+(defn -runSilent [this acq-settings acq-eng]
+  (load-mm)
+  (let [settings (convert-settings acq-settings)]
+    (run-acquisition-with-processors this settings acq-eng)))
+
 (defn -run [this acq-settings acq-eng]
   (load-mm)
   (let [settings (convert-settings acq-settings)


Remove duplicates in public api

Remove duplicates in public api

--- src/alfresco_technical_validation/alfresco_public_api.clj
+++ src/alfresco_technical_validation/alfresco_public_api.clj
@@ -33,5 +33,5 @@
          api-list-text ^String (.substring api-page-html (+ (.indexOf api-page-html api-list-open-tag) (.length api-list-open-tag))
                                                          (.indexOf api-page-html api-list-close-tag))
          api-list              (map #(s/replace % #"\s" "") (s/split-lines api-list-text))   ; Strip whitespace chars *within* API names, due to https://issues.alfresco.com/jira/browse/MNT-10346
-         sorted-api-list       (sort api-list)]
+         sorted-api-list       (sort (set api-list))]
      sorted-api-list)))


Starting down the path of adding the functional combinators.  comp is available right away.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -382,6 +382,39 @@
   "Returns a number one less than num."
   [x] (- x 1))

+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; fn stuff ;;;;;;;;;;;;;;;;
+;; at the moment only comp has the necessary pieces in place
+
+(defn comp
+  "Takes a set of functions and returns a fn that is the composition
+  of those fns.  The returned fn takes a variable number of args,
+  applies the rightmost of fns to the args, the next
+  fn (right-to-left) to the result, etc."
+  ([] identity)
+  ([f] f)
+  ([f g]
+     (fn
+       ([] (f (g)))
+       ([x] (f (g x)))
+       ([x y] (f (g x y)))
+       ([x y z] (f (g x y z)))
+       ([x y z & args] (f (apply g x y z args)))))
+  ([f g h]
+     (fn
+       ([] (f (g (h))))
+       ([x] (f (g (h x))))
+       ([x y] (f (g (h x y))))
+       ([x y z] (f (g (h x y z))))
+       ([x y z & args] (f (g (apply h x y z args))))))
+  ([f1 f2 f3 & fs]
+    (let [fs (reverse (list* f1 f2 f3 fs))]
+      (fn [& args]
+        (loop [ret (apply (first fs) args) fs (next fs)]
+          (if fs
+            (recur ((first fs) ret) (next fs))
+            ret))))))
+
+
 (comment
   (use 'cljs.compiler)


CLJS-285: fix type hints on TransientHashMap's fields

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -4640,10 +4640,10 @@
               (recur (inc i) (assoc! out (aget ks i) (aget vs i)))
               (persistent! out))))))

-(deftype TransientHashMap [^{:mutable true :tag 'boolean} edit
+(deftype TransientHashMap [^:mutable ^boolean edit
                            ^:mutable root
                            ^:mutable count
-                           ^{:mutable true :tag 'boolean} has-nil?
+                           ^:mutable ^boolean has-nil?
                            ^:mutable nil-val]
   Object
   (conj! [tcoll o]


Updated contains? to return false for nil collection argument. Refs #14

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -518,7 +518,7 @@
   range of indexes. 'contains?' operates constant or logarithmic time;
   it will not perform a linear search for a value.  See also 'some'."
   [coll v]
-  (when-not (nil? coll) (-contains? coll v)))
+  (if (nil? coll) false (-contains? coll v)))

 (defn disj
   "disj[oin]. Returns a new set of the same (hashed/sorted) type, that


* src/cljs/cljs/core.cljs: add missing (declare vec) before shuffle definition

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -995,6 +995,8 @@
             @nval
             (recur nval (next coll))))
         val))))
+
+(declare vec)

 (defn shuffle
   "Return a random permutation of coll"


URL to be parsed wasn't quoted. Project should compile now.

--- scraper/src/scraper/core.clj
+++ scraper/src/scraper/core.clj
@@ -8,9 +8,10 @@
 (defn exp [y]
   (reduce * (repeat b y)))

+;we'll have to create a method to walk through the vector tree to extract tags/attributes
 (defn -main
   "Entry point to scraper methods. Pulls in data from project1999's wiki to insert into an SQLite DB."
   [& args]
   ;The main wiki page detailing the first 200 factions. This is where we will get a list of faction links to scrape
-  (tagsoup/parse http://wiki.project1999.com/index.php?title=Category:Factions)
+  (tagsoup/parse "http://wiki.project1999.com/index.php?title=Category:Factions")
       )


CLJS-256: fix inconsistencies in nth's behaviour

This fixes a problem in nth's linear traversal helper whereas an
index-out-of-bounds might not be thrown in the appropriate
circumstances.

Also fixes a bug whereby the not-found argument might not be used.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -625,6 +625,7 @@
 (defn- linear-traversal-nth
   ([coll n]
      (cond
+       (nil? coll)     (throw (js/Error. "Index out of bounds"))
        (zero? n)       (if (seq coll)
                          (first coll)
                          (throw (js/Error. "Index out of bounds")))
@@ -633,11 +634,12 @@
        :else           (throw (js/Error. "Index out of bounds"))))
   ([coll n not-found]
      (cond
+       (nil? coll)     not-found
        (zero? n)       (if (seq coll)
                          (first coll)
                          not-found)
        (indexed? coll) (-nth coll n not-found)
-       (seq coll)      (linear-traversal-nth (next coll) (dec n))
+       (seq coll)      (linear-traversal-nth (next coll) (dec n) not-found)
        :else           not-found)))

 (defn nth
@@ -646,13 +648,16 @@
   also works for strings, arrays, regex Matchers and Lists, and,
   in O(n) time, for sequences."
   ([coll n]
-     (if (satisfies? IIndexed coll)
-       (-nth coll (.floor js/Math n))
-       (linear-traversal-nth coll (.floor js/Math n))))
+     (when (coercive-not= coll nil)
+       (if (satisfies? IIndexed coll)
+         (-nth coll (.floor js/Math n))
+         (linear-traversal-nth coll (.floor js/Math n)))))
   ([coll n not-found]
-     (if (satisfies? IIndexed coll)
-       (-nth coll (.floor js/Math n) not-found)
-       (linear-traversal-nth coll (.floor js/Math n) not-found))))
+     (if (coercive-not= coll nil)
+       (if (satisfies? IIndexed coll)
+         (-nth coll (.floor js/Math n) not-found)
+         (linear-traversal-nth coll (.floor js/Math n) not-found))
+       not-found)))

 (defn get
   "Returns the value mapped to key, not-found or nil if key not present."


* src/cljs/cljs/core.cljs: clean up type fn

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -305,8 +305,7 @@
   (coercive-= x nil))

 (defn type [x]
-  (if (or (nil? x) (undefined? x))
-    nil
+  (when-not (nil? x)
     (.-constructor x)))

 ;;;;;;;;;;;;;;;;;;; protocols on primitives ;;;;;;;;


Allow tools.nrepl to be a transitive dep of wildfly lib [IMMUTANT-536]

It's in lein's :base profile, which results in its "test" scope in the
generated pom unless we remove it.

See https://github.com/technomancy/leiningen/issues/1771

--- wildfly/project.clj
+++ wildfly/project.clj
@@ -19,4 +19,6 @@

   :dependencies [[org.immutant/core _]
                  [org.clojure/tools.nrepl "_"]
-                 [org.projectodd.wunderboss/wunderboss-wildfly _]])
+                 [org.projectodd.wunderboss/wunderboss-wildfly _]]
+
+  :profiles {:base {:dependencies []}})


little more logic

little more logic

--- src/main/cljc/clojure_club/spiral_challenge/mbastian.cljc
+++ src/main/cljc/clojure_club/spiral_challenge/mbastian.cljc
@@ -1,4 +1,14 @@
 (ns clojure-club.spiral-challenge.mbastian)

-(def seed [0])
+(def seed [[0]])
+
+(def dirs [[1 0] [0 1] [-1 0] [0 -1]])
+
+(def dir-map (zipmap dirs (drop 1 (cycle dirs))))
+
+(defn step [{:keys [grid dir loc f]}]
+  (let [turn? (nil? (get-in grid (mapv + loc (dirs dir))))]
+    {:grid grid :dir dir :loc n f}))
+
+(step {:grid [[0]] :dir [1 0] :loc [0 0] :f inc})


Handle empty :where SQL clauses in query.

--- src/datomish/query.cljc
+++ src/datomish/query.cljc
@@ -170,11 +170,12 @@
              [(map row columns-in-order) nil])))))

 (defn context->sql-clause [context]
-  {:select (sql-projection context)
-   :from (:from context)
-   :where (if (empty? (:wheres context))
-            nil
-            (cons :and (:wheres context)))})
+  (merge
+    {:select (sql-projection context)
+     :from (:from context)}
+    (if (empty? (:wheres context))
+      {}
+      {:where (cons :and (:wheres context))})))

 (defn context->sql-string [context]
   (->


sudoku example: whitespaces removed

sudoku example: whitespaces removed


fix parsing of NaN buglet

fix parsing of NaN buglet

--- src/flo_invest/core.clj
+++ src/flo_invest/core.clj
@@ -26,7 +26,7 @@
 (defn- parse-income [income]
   (for [line income
         :when (= "Revenue" (first line))]
-    {:annual_sales (* 1e6 (Double/parseDouble (nth line (- (count line) 2) Double/NaN)))}))
+    {:annual_sales (* 1e6 (Double/parseDouble (nth line (- (count line) 2) "NaN")))}))

 (defn- parse-balance [balance] {})
 (defn- parse-keyratios [keyratios] {})


Don't make dirs when taking a handle

Don't make dirs when taking a handle

--- src/grimoire/api/fs.clj
+++ src/grimoire/api/fs.clj
@@ -31,9 +31,6 @@
                       (util/munge (:name thing))
                       (:name thing))
         h           (io/file p (str n e))]
-    (.mkdirs (.getParentFile h))
-    (when (= :examples which)
-      (.mkdirs h))
     h))

 (defn thing->notes-handle


Suppress warning

Suppress warning

--- src/grimoire/things.clj
+++ src/grimoire/things.clj
@@ -1,4 +1,5 @@
 (ns grimoire.things
+  (:refer-clojure :exclude [isa?])
   (:require [clojure.string :as string]))

 (defn isa? [t o]


Optimize tail recursion

Optimize tail recursion

--- src/harnocode/core.cljs
+++ src/harnocode/core.cljs
@@ -77,11 +77,10 @@
         [this-line-tokens ts-rest _] (reduce fill-group [[] ts 0] groups)]
     [(string/join this-line-tokens) ts-rest]))

-(defn arrange-tokens [ts img]
-  (if (empty? img)
-    []
+(defn arrange-tokens [ts img result]
+  (if (or (empty? ts) (empty? img)) result
     (let [[line ts-rest] (arrange-tokens-line ts (first img))]
-      (conj (arrange-tokens ts-rest (rest img)) line))))
+      (recur ts-rest (rest img) (conj result line)))))

 (defn analyze-code [code]
@@ -89,7 +88,6 @@
         token-to-text (fn [token] (if (= (:type token) "Punctuator")
                                     (str (:value token))
                                     (str (:value token))))]
-    (println (map :value tokens))
     (map :value tokens)))

 ;; TODO
@@ -115,7 +113,6 @@
        quoted-chunks (map #(str quote % quote) chunks)
        quoted-tokens (map (fn [t] {:value t :type "String"}) quoted-chunks)
        interleaved (butlast (interleave quoted-tokens (cycle [plus])))]
-    (println plus)
     interleaved))

 (defn split-string-literals [tokens l]


124 finished

124 finished

--- stuf/src/sandbox/4clojure.clj
+++ stuf/src/sandbox/4clojure.clj
@@ -890,18 +890,30 @@
 ;;122 Read a binary number
 #(Integer/parseInt % 2)

-;;124
-(def r '[[e e e e]
-         [e w b e]
-         [e b w e]
-         [e e e e]])
-
-(defn chk
-  ([[y x] fy fx] (chk [(fy y) (fx x)] fy fx []))
-  ([[y x :as p] fy fx res]
-   (cond
-     (= 'w (get-in r p)) (chk [(fy y) (fx x)] fy fx (conj res p))
-     (= 'b (get-in r p)) res
-     :else [])))
+;;124 Analyze Reversi
+(defn f [r color]
+  (let [rcolor {'b 'w 'w 'b}
+        fxy (for [i [identity inc dec]
+                  j [identity inc dec]
+                  :when (not= i j identity)] [i j])
+        empty (for [y (range 0 (count r))
+                    x (range 0 (count (first r)))
+                    :when (= 'e (get-in r [y x]))] [y x])
+        flip-rec (fn flip-rec [[y x :as p] fy fx res]
+                   (cond
+                     (= (rcolor color) (get-in r p))
+                     (flip-rec [(fy y) (fx x)]
+                               fy
+                               fx
+                               (conj res p))
+                     (= color (get-in r p)) res
+                     :else []))
+        flip (fn [[y x] [fy fx]]
+               (flip-rec [(fy y) (fx x)] fy fx []))
+        check-point (fn [point]
+                      (vector point (set (mapcat #(flip point %) fxy))))]
+    (->> (map #(check-point %) empty)
+         (remove (comp empty? second))
+         (into {}))))


CMR-2900 Adds test case for collection not in entry title list

--- access-control-app/int_test/cmr/access_control/int_test/permission_check_test.clj
+++ access-control-app/int_test/cmr/access_control/int_test/permission_check_test.clj
@@ -86,6 +86,7 @@
                              {"Echo-Token" token}))))

 (deftest collection-simple-catalog-item-identity-permission-check-test
+  ;; tests ACLs which grant access to collections based on provider id and/or entry title
   (let [token (e/login (u/conn-context) "user1" ["group-create-group"])
         ;; helper for easily creating a group, returns concept id
         create-group #(:concept_id (u/create-group token (u/make-group %)))
@@ -98,6 +99,7 @@
                                                            :short-name %})
         coll1 (ingest-prov1-collection "coll1")
         coll2 (ingest-prov1-collection "coll2")
+        coll3 (ingest-prov1-collection "coll3")
         gran1 (ingest/ingest-concept (u/conn-context)
                                      {:format "application/echo10+xml"
                                       :metadata granule-metadata
@@ -194,18 +196,26 @@
                                        :collection_applicable true
                                        :collection_identifier {:entry_titles ["coll2 entry title"]}
                                        :provider_id "PROV1"}})
-            (are [user permissions]
-              (= {"C1200000002-PROV1" permissions}
-                 (get-permissions user "C1200000002-PROV1"))
-              :guest ["read"]
-              :registered [])))))
+            (testing "for collection in ACL's entry titles"
+              (are [user permissions]
+                (= {"C1200000002-PROV1" permissions}
+                   (get-permissions user "C1200000002-PROV1"))
+                :guest ["read"]
+                :registered []))
+            (testing "for collection not in ACL's entry titles"
+              (are [user permissions]
+                (= {"C1200000003-PROV1" permissions}
+                   (get-permissions user "C1200000003-PROV1"))
+                :guest []
+                :registered []))))))

     (testing "granule level permissions"
       (testing "no permissions granted"
-        (is (= {"G1200000003-PROV1" []}
+        (is (= {"G1200000004-PROV1" []}
                (get-granule-permissions "user1")))))))

 (deftest collection-catalog-item-identifier-access-value-test
+  ;; tests ACLs which grant access to collections based on their access value
   (let [token (e/login (u/conn-context) "user1" [])
         ingest-access-value-collection (fn [short-name access-value]
                                          (ingest-collection token {:entry-title (str short-name " entry title")
@@ -377,6 +387,7 @@
 ;; * granule permissions applied for collection applicable false??? <-- ask Jason

 (deftest collection-provider-level-permission-check-test
+  ;; Tests ACLs which grant the provider-level update/delete permissions to collections
   (let [token (e/login (u/conn-context) "user1" ["group-create-group"])
         ;; then create a group that contains our user, so we can find collections that grant access to this user
         group (u/make-group {:name "groupwithuser1" :members ["user1"]})


Updates from @mbossenbroek's feedback.

Updates from @mbossenbroek's feedback.

--- language-adaptors/rxjava-clojure/src/main/clojure/rx/lang/clojure/core.clj
+++ language-adaptors/rxjava-clojure/src/main/clojure/rx/lang/clojure/core.clj
@@ -96,7 +96,7 @@
 (declare unsubscribed?)

 (defn ^Subscriber subscriber
-  ""
+  "Experimental, subject to change or deletion."
   ([o on-next-action] (subscriber o on-next-action nil nil))
   ([o on-next-action on-error-action] (subscriber o on-next-action on-error-action nil))
   ([^Subscriber o on-next-action on-error-action on-completed-action]
@@ -125,7 +125,9 @@
   (Subscriptions/create ^Action0 (iop/action* handler)))

 (defn ^Observable$Operator operator*
-  "Returns a new implementation of rx.Observable$Operator that calls the given
+  "Experimental, subject to change or deletion.
+
+  Returns a new implementation of rx.Observable$Operator that calls the given
   function with a rx.Subscriber. The function should return a rx.Subscriber.

   See:
@@ -188,6 +190,13 @@
 ;################################################################################

 (defn ^Subscription subscribe
+  "Subscribe to the given observable.
+
+  on-X-action is a normal clojure function.
+
+  See:
+    rx.Observable/subscribe
+  "

   ([^Observable o on-next-action]
     (.subscribe o
@@ -283,6 +292,11 @@
 ; Operators

 (defn synchronize
+  "Synchronize execution.
+
+  See:
+    rx.Observable/synchronize
+  "
   ([^Observable xs]
   (.synchronize xs))
   ([lock ^Observable xs]


Start dev server automatically

Start dev server automatically

When starting the application in development mode, the server should
be running immediately. This makes it easier for developers.

--- dev/src/dev.clj
+++ dev/src/dev.clj
@@ -23,3 +23,5 @@
   (load "local"))

 (integrant.repl/set-prep! (comp duct/prep read-config))
+
+(go)


Max method config name editor text box 100% of window

--- src/cljs/main/broadfcui/page/workspace/method_configs/method_config_editor.cljs
+++ src/cljs/main/broadfcui/page/workspace/method_configs/method_config_editor.cljs
@@ -201,7 +201,7 @@
         (create-section
           (if editing?
             [:div {}
-             (style/create-text-field {:ref "confname" :style {:maxWidth 500}
+             (style/create-text-field {:ref "confname" :style {:width "100%"}
                                        :data-test-id "edit-method-config-name-input"
                                        :defaultValue (:name config)
                                        :onKeyDown (common/create-key-handler [:space] #(.preventDefault %))})


sha 384

sha 384

--- test/buddy/core/mac_tests.clj
+++ test/buddy/core/mac_tests.clj
@@ -45,19 +45,29 @@
         (is (= result (bytes->hex (mac/hash data {:key key :alg :hmac :digest :sha256}))))
         (is (= result (bytes->hex (mac/hash data {:key key :alg :hmac :digest (SHA256Digest.)}))))))

-    (testing "Test simple hmac256"
+    (testing "Test simple hmac sha256"
       (let [secretkey "b"
             data "a"
             sig (bytes->hex (mac/hash data {:key secretkey :alg :hmac+sha256}))
             result "cb448b440c42ac8ad084fc8a8795c98f5b7802359c305eabd57ecdb20e248896"]
         (is (= result sig))))

-    (testing "Test simple hmac512"
+
+    (testing "Test simple hmac sha384"
+      (let [secretkey "b"
+            data "a"
+            sig (bytes->hex (mac/hash data {:key secretkey :alg :hmac+sha384}))
+            result "40292a79a280f609aef472272d2a2a0d148bfb83fa18fd2806440d07d16e31d9f0d398891063c11f6c73891e6f646106"]
+        (is (= result sig))))
+
+    (testing "Test simple hmac sha512"
       (let [secretkey "b"
             data "a"
             sig (bytes->hex (mac/hash data {:key secretkey :alg :hmac+sha512}))
             result "68c1687fa7cb5170ff800580a0cec29dc0ccb515aaf95587bdfe5c923730a7852e2beefefd6be31d97aa612ad8b8569bba61ed2c339cd9b28409751b0b9e96a0"]
         (is (= result sig))))
+
+

     (testing "Sign/Verify string"


Helper fns for job seq

Helper fns for job seq

--- src/onyx/coordinator/log/datomic.clj
+++ src/onyx/coordinator/log/datomic.clj
@@ -67,6 +67,25 @@
         active-tasks (find-active-task-ids db sorted-tasks)]
     (filter (fn [t] (not (contains? active-tasks (:db/id t)))) sorted-tasks)))

+(defn all-active-jobs-ids [db]
+  (let [query '[:find ?job ?tx :where
+                [?job :job/task ?task ?tx]
+                [?task :task/complete? false]]]
+    (map first (sort-by second (d/q query db)))))
+
+(defn last-offered-job [db]
+  (let [query '[:find ?job ?tx :where
+                [?job :job/task ?task ?tx]
+                [?peer :peer/task ?task]
+                [?peer :peer/status :acking]]
+        result (d/q query (d/history db))]
+    (first (last (sort-by second result)))))
+
+(defn job-candidate-seq [job-seq last-offered]
+  (->> (cycle job-seq)
+       (drop (.indexOf job-seq last-offered))
+       (take (count job-seq))))
+
 (defmethod extensions/mark-peer-born Datomic
   [log place]
   (let [tx [[:onyx.fn/add-peer (d/tempid :onyx/log) :idle place]]]
@@ -87,6 +106,8 @@
 (defmethod extensions/next-tasks Datomic
   [log]
   (let [db (d/db (:conn log))]
+    (prn (all-active-jobs-ids db))
+    (prn (last-offered-job db))
     (next-essential-task db)))

 (defn select-nodes [ent]


small comment

small comment

--- dev/user.clj
+++ dev/user.clj
@@ -55,6 +55,7 @@

 (comment

+  ;; TODO: put working examples here
   (navigator/create-competency (:db-conn nt-config/system) "I will keep typing" "v1" :comp.status/active :comp/id-sk "jeep")
   (ptouch-that '[:find ?e :where [?e :comp/name]])


apparently immutant.dev cannot be found in 1.1.1

--- dev/user.clj
+++ dev/user.clj
@@ -1,8 +1,5 @@
 (ns user
-  (:require [immutant.util :refer [in-immutant?] :as util]
-            [immutant.dev :refer [reload-project!] :as dev]
-            [immutant.messaging :as msg]
-            [clojure.data.json :as json]
+  (:require [clojure.data.json :as json]
             [clojure.java.io :as io]
             [clojure.string :as str]
             [clojure.pprint :refer (pprint)]
@@ -23,14 +20,12 @@
    It makes you feel better."
   []
   (stop!)
-  (reload-project!)
   (start!))

 (defn reset-and-delete-db! [delete-db]
   (when (= :delete-db delete-db)
     (stop!)
     (d/delete-database (get-in galleon/system [:config :datomic-url]))
-    (reload-project!)
     (start!)))

 (defn touch-that
@@ -49,7 +44,7 @@
 (defn ptouch-that
   "Example: (ptouch-that '[:find ?e :where [?e :user/username]])"
   [query & data-sources]
-  (pprint (apply touch-that query data-sources)))
+  (pprint (apply touch-that query data-sources)))

 (comment
   (navigator/create-competency (:db-conn galleon/system) "comp1" "v1" :comp.status/active)