Format db_interface.clj by zprint

Format db_interface.clj by zprint

--- src/zg/db_interface.clj
+++ src/zg/db_interface.clj
@@ -20,128 +20,154 @@
 (require '[zg.format-date :as format-date])

 (defn status->int
-    "Convert word status (:deleted, :undeleted) into an integer."
-    [status]
-    (if (= status :deleted)
-        1
-        0))
+  "Convert word status (:deleted, :undeleted) into an integer."
+  [status]
+  (if (= status :deleted)
+      1
+      0))

 (defn dictionary-type->char
-    "Convert dictionary type (:whitelist, :blacklist) into a one character."
-    [dictionary-type]
-    (condp = dictionary-type
-        :whitelist    "w"
-        :blacklist    "b"
-        :atomic-typos "a"
-        :glossary     "u"
-                      "o"))
+  "Convert dictionary type (:whitelist, :blacklist) into a one character."
+  [dictionary-type]
+  (condp = dictionary-type
+    :whitelist    "w"
+    :blacklist    "b"
+    :atomic-typos "a"
+    :glossary     "u"
+                  "o"))

 (defn insert-word-into-dictionary
-    "Try to insert new word into the dictionary. If insert fails, exception
+  "Try to insert new word into the dictionary. If insert fails, exception
      is thrown and it needs to be caught outside this function."
-    [word correct-form description user-name dictionary-type datetime]
-    (jdbc/insert! db-spec/zg-db
-        :dictionary {:word       word
-                     :correct    correct-form
-                     :dictionary (dictionary-type->char dictionary-type)
-                     :user       user-name
-                     :datetime   datetime
-                     :deleted     0
-                     :description description}))
+  [word correct-form description user-name dictionary-type datetime]
+  (jdbc/insert! db-spec/zg-db
+                :dictionary
+                {:word       word,
+                 :correct    correct-form,
+                 :dictionary (dictionary-type->char dictionary-type),
+                 :user       user-name,
+                 :datetime   datetime,
+                 :deleted     0,
+                 :description description}))

 (defn insert-word-into-glossary
-    "Try to insert new word into the dictionary. If insert fails, exception
+  "Try to insert new word into the dictionary. If insert fails, exception
      is thrown and it needs to be caught outside this function."
-    [word description class use-it internal copyright source correct-forms incorrect-forms user-name dictionary-type datetime]
-    (jdbc/insert! db-spec/zg-db
-        :dictionary {:word       word
-                     :class      class
-                     :dictionary (dictionary-type->char dictionary-type)
-                     :use        use-it
-                     :internal   internal
-                     :copyrighted copyright
-                     :source     source
-                     :correct_forms correct-forms
-                     :incorrect_forms incorrect-forms
-                     :user       user-name
-                     :datetime   datetime
-                     :deleted     0
-                     :description description}))
+  [word description class use-it internal copyright source correct-forms incorrect-forms user-name dictionary-type datetime]
+  (jdbc/insert! db-spec/zg-db
+                :dictionary
+                {:word       word,
+                 :class      class,
+                 :dictionary (dictionary-type->char dictionary-type),
+                 :use        use-it,
+                 :internal   internal,
+                 :copyrighted copyright,
+                 :source     source,
+                 :correct_forms correct-forms,
+                 :incorrect_forms incorrect-forms,
+                 :user       user-name,
+                 :datetime   datetime,
+                 :deleted     0,
+                 :description description}))

 (defn add-new-word-into-dictionary
-    "Add new word into the dictionary. If the word already exist, it is
+  "Add new word into the dictionary. If the word already exist, it is
      simply updated (make sense only for blacklist)."
-    ([word user-name dictionary-type]
-    (let [datetime (format-date/format-current-date)]
-        (log/info "storing" datetime word)
-        (try
-            (insert-word-into-dictionary word nil nil user-name dictionary-type datetime)
-            (catch Exception e
-                (log/error e "insert word into dictionary")))))
-    ([word description user-name dictionary-type]
-    (let [datetime (format-date/format-current-date)]
-        (log/info "storing" datetime word)
-        (try
-            (insert-word-into-dictionary word nil description user-name dictionary-type datetime)
-            (catch Exception e
-                (try
-                    (jdbc/update! db-spec/zg-db
-                          :dictionary {:description description} ["word=?" word])
-                    (catch Exception e
-                        (log/error e "insert word into dictionary")))))))
-    ([word correct-form description user-name dictionary-type]
-    (let [datetime (format-date/format-current-date)]
-        (log/info "storing" datetime word)
-        (try
-            (insert-word-into-dictionary word correct-form description user-name dictionary-type datetime)
-            (catch Exception e
-                (try
-                    (jdbc/update! db-spec/zg-db
-                          :dictionary {:description description} ["word=?" word])
-                    (catch Exception e
-                        (log/error e "insert word into dictionary")))))))
-    ([word description class use-it internal copyright source correct-forms incorrect-forms user-name dictionary-type]
-    (let [datetime (format-date/format-current-date)]
-        (log/info "storing" datetime word)
-        (try
-            (insert-word-into-glossary word description class use-it internal copyright source correct-forms incorrect-forms user-name dictionary-type datetime)
-            (catch Exception e
-                (try
-                    (jdbc/update! db-spec/zg-db
-                          :dictionary {:description description} ["word=?" word])
-                    (catch Exception e
-                        (log/error e "insert word into dictionary"))))))))
+  ([word user-name dictionary-type]
+   (let [datetime (format-date/format-current-date)]
+     (log/info "storing" datetime word)
+     (try (insert-word-into-dictionary word
+                                       nil
+                                       nil
+                                       user-name
+                                       dictionary-type
+                                       datetime)
+          (catch Exception e (log/error e "insert word into dictionary")))))
+  ([word description user-name dictionary-type]
+   (let [datetime (format-date/format-current-date)]
+     (log/info "storing" datetime word)
+     (try (insert-word-into-dictionary word
+                                       nil
+                                       description
+                                       user-name
+                                       dictionary-type
+                                       datetime)
+          (catch Exception e
+            (try (jdbc/update! db-spec/zg-db
+                               :dictionary
+                               {:description description}
+                               ["word=?" word])
+                 (catch Exception e
+                   (log/error e "insert word into dictionary")))))))
+  ([word correct-form description user-name dictionary-type]
+   (let [datetime (format-date/format-current-date)]
+     (log/info "storing" datetime word)
+     (try (insert-word-into-dictionary word
+                                       correct-form
+                                       description
+                                       user-name
+                                       dictionary-type
+                                       datetime)
+          (catch Exception e
+            (try (jdbc/update! db-spec/zg-db
+                               :dictionary
+                               {:description description}
+                               ["word=?" word])
+                 (catch Exception e
+                   (log/error e "insert word into dictionary")))))))
+  ([word description class use-it internal copyright source correct-forms incorrect-forms user-name dictionary-type]
+   (let [datetime (format-date/format-current-date)]
+     (log/info "storing" datetime word)
+     (try (insert-word-into-glossary word
+                                     description
+                                     class
+                                     use-it
+                                     internal
+                                     copyright
+                                     source
+                                     correct-forms
+                                     incorrect-forms
+                                     user-name
+                                     dictionary-type
+                                     datetime)
+          (catch Exception e
+            (try (jdbc/update! db-spec/zg-db
+                               :dictionary
+                               {:description description}
+                               ["word=?" word])
+                 (catch Exception e
+                   (log/error e "insert word into dictionary"))))))))

 (defn set-word-status
-    "Set or change status of given word in the dictionary (:deleted, :undeleted)."
-    [word dictionary-type status]
-    (try
-        (jdbc/update! db-spec/zg-db
-                      :dictionary {:deleted (status->int status)}
-                                   ["word = ? and dictionary = ?" word (dictionary-type->char dictionary-type)])
-        (catch Exception e
-            (log/error e "set/update word status")
-            [])))
+  "Set or change status of given word in the dictionary (:deleted, :undeleted)."
+  [word dictionary-type status]
+  (try (jdbc/update! db-spec/zg-db
+                     :dictionary {:deleted (status->int status)}
+                                  ["word = ? and dictionary = ?" word (dictionary-type->char dictionary-type)])
+       (catch Exception e
+         (log/error e "set/update word status")
+         [])))

 (defn delete-word
-    "Mark the selected word with the flag 'deleted'. The word remains in the
+  "Mark the selected word with the flag 'deleted'. The word remains in the
      dictionary so it can be undeleted in the future."
-    [word dictionary-type]
-    (set-word-status word dictionary-type :deleted))
+  [word dictionary-type]
+  (set-word-status word dictionary-type :deleted))

 (defn undelete-word
-    "Mark the selected word with the flag 'active' (ie it's 'undeleted')."
-    [word dictionary-type]
-    (set-word-status word dictionary-type :undeleted))
+  "Mark the selected word with the flag 'active' (ie it's 'undeleted')."
+  [word dictionary-type]
+  (set-word-status word dictionary-type :undeleted))

 (defn read-all-words
-    "Read all words from both dictionaries (dictionary-type is nil) or
+  "Read all words from both dictionaries (dictionary-type is nil) or
      from selected dictionary (dictionary-type is specified)."
-    [dictionary-type]
-    (try
-        (if dictionary-type
-            (jdbc/query db-spec/zg-db
-                ["select word, description,
+  [dictionary-type]
+  (try
+    (if dictionary-type
+      (jdbc/query
+        db-spec/zg-db
+        ["select word, description,
                     class,
                     source,
                     deleted,
@@ -152,9 +178,10 @@
                   from dictionary
                   where dictionary=?
                   order by word"
-                    (dictionary-type->char dictionary-type)])
-            (jdbc/query db-spec/zg-db
-                ["select word, description,
+         (dictionary-type->char dictionary-type)])
+      (jdbc/query
+        db-spec/zg-db
+        ["select word, description,
                     class,
                     source,
                     deleted,
@@ -164,101 +191,93 @@
                     (select product from products where products.id=dictionary.product) as product
                  from dictionary
                     order by word"]))
-        (catch Exception e
-            (log/error e "read all words")
-            [])))
+    (catch Exception e
+      (log/error e "read all words")
+      [])))

 (defn read-words-for-pattern
-    "Read all words that are like specified pattern from both dictionaries
+  "Read all words that are like specified pattern from both dictionaries
      (dictionary-type is nil) or from selected dictionary (dictionary-type is specified)."
-    [pattern dictionary-type]
-    (try
-        (jdbc/query db-spec/zg-db
-                        ["select * from dictionary where word like ? and dictionary=? order by word"
-                        (str "%" pattern "%") (dictionary-type->char dictionary-type)])
-        (catch Exception e
-            (log/error e "read words for given pattern" pattern)
-            nil)))
+  [pattern dictionary-type]
+  (try (jdbc/query db-spec/zg-db
+                   ["select * from dictionary where word like ? and dictionary=? order by word"
+                   (str "%" pattern "%") (dictionary-type->char dictionary-type)])
+       (catch Exception e
+         (log/error e "read words for given pattern" pattern)
+         nil)))

 (defn read-words-with-status
-    "Read all words with specified status (deleted/active) from both dictionaries
+  "Read all words with specified status (deleted/active) from both dictionaries
      (dictionary-type is nil) or from selected dictionary (dictionary-type is specified)."
-    [status dictionary-type]
-    (try
-        (jdbc/query db-spec/zg-db
-                        ["select * from dictionary where deleted = ? and dictionary=? order by word"
-                        (status->int status) (dictionary-type->char dictionary-type)])
-        (catch Exception e
-            (log/error e "read words with given status" status)
-            [])))
+  [status dictionary-type]
+  (try (jdbc/query db-spec/zg-db
+                   ["select * from dictionary where deleted = ? and dictionary=? order by word"
+                   (status->int status) (dictionary-type->char dictionary-type)])
+       (catch Exception e
+         (log/error e "read words with given status" status)
+         [])))

 (defn read-deleted-words
-    "Read all deleted words from both dictionaries (dictionary-type is nil) or
+  "Read all deleted words from both dictionaries (dictionary-type is nil) or
      from selected dictionary (dictionary-type is specified)."
-    [dictionary-type]
-    (read-words-with-status :deleted dictionary-type))
+  [dictionary-type]
+  (read-words-with-status :deleted dictionary-type))

 (defn read-active-words
-    "Read all undeleted words from both dictionaries (dictionary-type is nil) or
+  "Read all undeleted words from both dictionaries (dictionary-type is nil) or
      from selected dictionary (dictionary-type is specified)."
-    [dictionary-type]
-    (read-words-with-status :undeleted dictionary-type))
+  [dictionary-type]
+  (read-words-with-status :undeleted dictionary-type))

 (defn read-changes-statistic
-    "Read basic statistic about changes made by all users. For each user, number of changes is displayed."
-    []
-    (try
-        (jdbc/query db-spec/zg-db
-                        ["select user, count(*) as cnt from dictionary group by user order by cnt desc"])
-        (catch Exception e
-            (log/error e "read changes statistic")
-            [])))
+  "Read basic statistic about changes made by all users. For each user, number of changes is displayed."
+  []
+  (try (jdbc/query db-spec/zg-db
+                   ["select user, count(*) as cnt from dictionary group by user order by cnt desc"])
+       (catch Exception e
+         (log/error e "read changes statistic")
+         [])))

 (defn read-changes
-    "Read all changes sorted by date and time the change has been made."
-    []
-    (try
-        (jdbc/query db-spec/zg-db
-                        ["select * from dictionary order by datetime"])
-        (catch Exception e
-            (log/error e "read changes")
-            [])))
+  "Read all changes sorted by date and time the change has been made."
+  []
+  (try (jdbc/query db-spec/zg-db
+                   ["select * from dictionary order by datetime"])
+       (catch Exception e
+         (log/error e "read changes")
+         [])))

 (defn read-different-spelling-words
-    "Read all words that have different spelling."
-    []
-    (try
-        (jdbc/query db-spec/zg-db
-                        ["select word, count(word) cnt from dictionary d where dictionary='u' group by word having cnt>1"])
-        (catch Exception e
-            (log/error e "read different spelling words")
-            [])))
+  "Read all words that have different spelling."
+  []
+  (try (jdbc/query db-spec/zg-db
+                   ["select word, count(word) cnt from dictionary d where dictionary='u' group by word having cnt>1"])
+       (catch Exception e
+         (log/error e "read different spelling words")
+         [])))

 (defn read-changes-for-user
-    "Read all changes for selected user sorted by date and time the change has been made."
-    [user-name]
-    (try
-        (jdbc/query db-spec/zg-db
-                        ["select * from dictionary where user=? order by datetime" user-name])
-        (catch Exception e
-            (log/error e "read changes for user" user-name)
-            [])))
+  "Read all changes for selected user sorted by date and time the change has been made."
+  [user-name]
+  (try (jdbc/query db-spec/zg-db
+                   ["select * from dictionary where user=? order by datetime" user-name])
+       (catch Exception e
+         (log/error e "read changes for user" user-name)
+         [])))

 (defn read-sources
-    []
-    (try
-        (jdbc/query db-spec/zg-db
-                        ["select id, source from sources order by source"])
-        (catch Exception e
-            (log/error e "read sources")
-            [])))
+  []
+  (try (jdbc/query db-spec/zg-db
+                   ["select id, source from sources order by source"])
+       (catch Exception e
+         (log/error e "read sources")
+         [])))

 (defn read-word-classes
-    []
-    (try
-        (jdbc/query db-spec/zg-db
-                        ["select id, class from classes order by class"])
-        (catch Exception e
-            (log/error e "read classes")
-            [])))
-
+  []
+  (try (jdbc/query db-spec/zg-db
+                   ["select id, class from classes order by class"])
+       (catch Exception e
+         (log/error e "read classes")
+         [])))
+


insights: fix :optimization :advanced issues

- Object property was accessed directly with `.-` notation, which gets
  transformed during optimization.

--- src-cljs/frontend/components/insights.cljs
+++ src-cljs/frontend/components/insights.cljs
@@ -78,21 +78,21 @@
         (.append "rect")
         (.attr #js {"width" square-size
                     "height" square-size
-                    "class" #(.-classname %)
+                    "class" #(aget % "classname")
                     "transform"
                     (fn [item i]
                       (gstring/format "translate(%s,%s)" 0  (- (+ square-size))))}))
     (-> left-legend-item
         (.append "text")
         (.attr #js {"x" (+ square-size spacing)})
-        (.text #(.-text %)))
+        (.text #(aget % "text")))

     ;; right legend
     (-> right-legend-item
         (.append "rect")
         (.attr #js {"width" square-size
                     "height" square-size
-                    "class" #(.-classname %)
+                    "class" #(aget % "classname")
                     "transform"
                     (fn [item i]
                       (gstring/format "translate(%s,%s)" 0  (- (+ square-size))))}))
@@ -100,7 +100,7 @@
         (.append "text")
         (.attr #js {"x" (+ square-size
                            spacing)})
-        (.text #(.-text %)))))
+        (.text #(aget % "text")))))

 (defn visualize-insights-bar! [elem builds]
   (let [y-max (apply max (mapcat #((juxt :queued_time_minutes :build_time_minutes) %)
@@ -185,20 +185,20 @@
     ;; positive bar
     (-> enter
         (.insert "rect")
-        (.attr #js {"class" #(str "bar " (.-outcome %))
-                    "y" #(y-pos-scale (.-build_time_minutes %))
-                    "x" #(x-scale (.-build_num %))
+        (.attr #js {"class" #(str "bar " (aget % "outcome"))
+                    "y" #(y-pos-scale (aget % "build_time_minutes"))
+                    "x" #(x-scale (aget % "build_num"))
                     "width" (.rangeBand x-scale)
-                    "height" #(- y-middle (y-pos-scale (.-build_time_minutes %)))}))
+                    "height" #(- y-middle (y-pos-scale (aget % "build_time_minutes")))}))

     ;; negative (queue time) bar
     (-> enter
         (.insert "rect")
         (.attr #js {"class" "bar queue"
                     "y" y-middle
-                    "x" #(x-scale (.-build_num %))
+                    "x" #(x-scale (aget % "build_num"))
                     "width" (.rangeBand x-scale)
-                    "height" #(- (y-neg-scale (.-queued_time_minutes %)) y-middle)}))))
+                    "height" #(- (y-neg-scale (aget % "queued_time_minutes")) y-middle)}))))

 (defn chartable-builds [builds]
   (->> builds
@@ -212,7 +212,6 @@
     (reify
       om/IDidUpdate
       (did-update [_ prev-props prev-state]
-        (.error js/console  "update called.")
         (let [el (om/get-node owner)]
           (visualize-insights-bar! el chart-builds)))
       om/IRender


Missing pieces of bpm sync feedback commit.

Remember to save the file in Emacs before committing, derp.

--- src/afterglow/controllers/ableton_push.clj
+++ src/afterglow/controllers/ableton_push.clj
@@ -423,9 +423,9 @@
     (aset (get (:next-display controller) 2) 16 (:up-arrow special-symbols))
     (do
       (aset (get (:next-display controller) 2) 9 (:down-arrow special-symbols))
-      (when-not (:showing (:metronome-mode controller))
+      (when-not (:showing @(:metronome-mode controller))
         ;; We need to display the sync mode in order to point at it
-        #_(write-display-cell controller 3 0
+        (write-display-cell controller 3 0
                             (str "         " (metronome-sync-label controller)))))))

 (defn sign-velocity
@@ -456,7 +456,8 @@
                  (captured-controls [this] #{72})
                  (captured-notes [this] #{1 9})
                  (adjust-interface [this controller]
-                   (bpm-adjusting-interface controller))
+                   (bpm-adjusting-interface controller)
+                   true)
                  (handle-control-change [this controller message]
                    (adjust-bpm-from-encoder controller message))
                  (handle-note-on [this controller message]
@@ -897,7 +898,8 @@
                  (captured-controls [this] #{15})
                  (captured-notes [this] #{9 1})
                  (adjust-interface [this controller]
-                   (bpm-adjusting-interface controller))
+                   (bpm-adjusting-interface controller)
+                   true)
                  (handle-control-change [this controller message]
                    (adjust-bpm-from-encoder controller message))
                  (handle-note-on [this controller message]


Datastore implementation improvements.

Datastore implementation improvements.

--- src/appengine_magic/services/datastore.clj
+++ src/appengine_magic/services/datastore.clj
@@ -24,24 +24,51 @@

 (defprotocol EntityProtocol
-  (create-key [this])
-  (save! [this]))
+  "Entities are Clojure records which conform to the EntityProtocol. Each Entity
+   must have a key. If an entity record field has a :key metadata tag, then that
+   field becomes the key. If a record has no :key metadata tags, then a key is
+   automatically generated for it. In either case, the key becomes part of the
+   entity's metadata. Entity retrieval operations must set the :key metadata on
+   returned entity records."
+  (get-key-object [this] "Returns nil if no tag is specified in the record
+                          definition, and no :key metadata exists. Otherwise
+                          returns a Key object.")
+  (get-key-value [this]  "Returns the Clojure value of the entity's Key object.")
+  (save! [this]          "Saves the entity to the datastore."))

-(defn entity-key-helper [entity-record parent key-info datastore-entity-name]
-  ;; TODO: Deal with parent entities.
-  (let [key-info (key-info entity-record)
-        key-object (if key-info
-                       (KeyFactory/createKey datastore-entity-name key-info)
-x                       ;; TODO: This looks really broken. Always 1?
-                       (.getStart (KeyRange. parent datastore-entity-name 1 1)))]
-    (clojure.pprint/pprint key-object)
-    key-object))
+(defn entity-get-key-object-helper [entity-record parent key-property datastore-entity-name]
+  ;; TODO: Handle parent entities.
+  (let [entity-record-metadata (meta entity-record)
+        metadata-key-value (when entity-record-metadata (:key entity-record-metadata))
+        key-property-value (when key-property (key-property entity-record))]
+    (cond
+     ;; neither exists: autogenerate
+     (and (nil? key-property-value) (nil? metadata-key-value))
+     nil
+     ;; key property exists
+     (not (nil? key-property-value))
+     (KeyFactory/createKey datastore-entity-name key-property-value)
+     ;; metadata key exists
+     (and (not (nil? metadata-key-value)) (instance? Key metadata-key-value))
+     metadata-key-value
+     ;; something's wrong
+     :else (throw (RuntimeException. "entity has no valid :key metadata, and has no fields marked :key")))))

-(defn entity-save-helper [entity-record]
-  (let [key-object (create-key entity-record)
-        entity (Entity. key-object)]
+(defn entity-get-key-value-helper [entity-record]
+  (let [key-object (get-key-object entity-record)]
+    (when key-object
+      (if-let [name (.getName key-object)]
+        name
+        (.getId key-object)))))
+
+
+(defn entity-save-helper [entity-record datastore-entity-name]
+  (let [key-object (get-key-object entity-record)
+        entity (if key-object
+                   (Entity. key-object)
+                   (Entity. datastore-entity-name))]
     (doseq [[property-kw value] entity-record]
       (let [property-name (.substring (str property-kw) 1)]
         (.setProperty entity property-name value)))
@@ -49,11 +76,14 @@
     (.put (get-datastore-service) entity)))

-(defn retrieve [entity-record-type key-info &
+(defn retrieve [entity-record-type key-value &
                 {:keys [parent datastore-entity-name]
                  :or {datastore-entity-name (unqualified-name (.getName entity-record-type))}}]
   ;; TODO: Allow optional :service argument!
-  (let [key-object (KeyFactory/createKey datastore-entity-name key-info)
+  ;; TODO: Deal with parent entities.
+  (let [key-object (KeyFactory/createKey datastore-entity-name (if (integer? key-value)
+                                                                   (long key-value)
+                                                                   key-value))
         entity (.get (get-datastore-service) key-object)
         properties (into {} (.getProperties entity))
         kw-keys-properties (reduce (fn [m [k v]] (assoc m (keyword k) v)) {} properties)
@@ -62,29 +92,30 @@
         ;; way to access any custom constructor defined by defentity, since that
         ;; constructor would be in a different namespace.
         entity-record (eval `(new ~entity-record-type ~@(repeat (count properties) nil)))]
-    (merge entity-record kw-keys-properties)))
+    (with-meta (merge entity-record kw-keys-properties) {:key (.getKey entity)})))

 (defmacro defentity [name properties &
-                     {:keys [parent key-fn datastore-entity-name]
+                     {:keys [parent datastore-entity-name]
                       :or {datastore-entity-name (unqualified-name name)}}]
   ;; All entities need keys. Verify that exactly one of the properties has a
-  ;; :key metadata tag, or a :key-fn optional parameter is given. :key metadata
-  ;; takes precedence over :key-fn.
+  ;; :key metadata tag.
   ;; TODO: This ain't checking for :tag :key!
-  (let [key-info (or (keyword (str (first (filter #(meta %) properties))))
-                     key-fn)]
-    (when-not key-info
-      (throw (RuntimeException. "either provide ^:key on one property, or a :key-fn")))
+  ;; FIXME: There are order-of-evaluation bugs here.
+  (let [key-property (keyword (str (first (filter #(meta %) properties))))]
     `(defrecord ~name ~properties
        EntityProtocol
-       (create-key [this#] (entity-key-helper this# ~parent ~key-info ~datastore-entity-name))
-       (save! [this#] (entity-save-helper this#)))))
+       (get-key-object [this#]
+         (entity-get-key-object-helper this# ~parent ~key-property ~datastore-entity-name))
+       (get-key-value [this#]
+         (entity-get-key-value-helper this#))
+       (save! [this#]
+         (entity-save-helper this# ~datastore-entity-name)))))

 ;; - Is type metadata necessary, or can it be determined at runtime?
 ;;   It helps with optional checking, improves error messages.
-;; - Either give a ^:key metadata to a property, or provide a key-fn.
+;;   Verify type behavior in general, e.g., dates.
 ;; - Implement transactions.


The verbose layout needs to include the timestamp

--- src/clojure/picard/log4j/VerboseLayout.clj
+++ src/clojure/picard/log4j/VerboseLayout.clj
@@ -2,11 +2,14 @@
   (:require
    [clojure.string :as str])
   (:import
-   [org.apache.log4j.spi
-    LoggingEvent])
+   java.util.Date
+   java.text.SimpleDateFormat
+   org.apache.log4j.spi.LoggingEvent)
   (:gen-class
    :name picard.log4j.VerboseLayout
    :extends org.apache.log4j.Layout))
+
+(def date-formatter (SimpleDateFormat. "dd/MMM/yyyy:kk:mm:ss Z"))

 (defn- format-value
   [val]
@@ -45,6 +48,7 @@
   (let [log-msg (.getMessage evt)]
     (str
      (str/upper-case (.getLoggerName evt)) " - "
+     (.format date-formatter (Date. (.getTimeStamp evt))) " - "
      (if (and (map? log-msg) (log-msg :msg))
        (pretty-format evt log-msg)
        (str log-msg "\n")))))


show visit duration in entry header

show visit duration in entry header

--- iwaswhere-web/src/cljs/iwaswhere_web/ui/entry.cljs
+++ iwaswhere-web/src/cljs/iwaswhere_web/ui/entry.cljs
@@ -57,15 +57,23 @@
                           (put-fn [:entry/remove-local {:timestamp ts}])
                           (put-fn [:cmd/trash {:timestamp ts}]))
             upvotes (:upvotes entry)
-            upvote-fn (fn [op] #(put-fn [:text-entry/update (update-in entry [:upvotes] op)]))]
+            upvote-fn (fn [op] #(put-fn [:text-entry/update (update-in entry [:upvotes] op)]))
+
+            arrival-ts (:arrival-timestamp entry)
+            departure-ts (:departure-timestamp entry)
+            dur (when (and arrival-ts departure-ts)
+                  (-> (- departure-ts arrival-ts) (/ 60000) (Math/floor)))
+            formatted-duration (when (< dur 99999)
+                                 (let [minutes (rem dur 60)
+                                       hours (Math/floor (/ dur 60))]
+                                   (str ", " (when (pos? hours) (str hours "h "))
+                                        (when (pos? minutes) (str minutes "m")))))]
         [:div.entry
          [:div.entry-header
           [:a {:href (str "/#" (.format (js/moment ts) "YYYY-MM-DD"))}
            [:span.timestamp (.format (js/moment ts) "dddd, MMMM Do YYYY")]]
-          [:span.timestamp (.format (js/moment ts) ", h:mm a")]
+          [:span.timestamp (.format (js/moment ts) ", h:mm a") formatted-duration]
           [:span.fa.toggle.tooltip {:class (if (pos? upvotes) "fa-thumbs-up" "fa-thumbs-o-up") :on-click (upvote-fn inc)}
-           #_(when (pos? upvotes) [:span.upvotes " " upvotes]
-                                )
            [:span.tooltiptext "upvote"]]
           (when (pos? upvotes) [:span.upvotes " " upvotes])
           (when (pos? upvotes) [u/span-w-tooltip "fa-thumbs-down" "dislike" (upvote-fn dec)])


browser url update fix

browser url update fix

--- src/cljs/salava/core/ui/badge_grid.cljs
+++ src/cljs/salava/core/ui/badge_grid.cljs
@@ -1,6 +1,6 @@
 (ns salava.core.ui.badge-grid
   (:require [salava.badge.ui.helper :as bh]
-            [salava.core.ui.helper :as h :refer [unique-values navigate-to path-for js-navigate-to plugin-fun]]
+            [salava.core.ui.helper :as h :refer [unique-values navigate-to path-for js-navigate-to plugin-fun current-path current-route-path]]
             [salava.core.i18n :as i18n :refer [t]]
             [salava.admin.ui.admintool :refer [admin-gallery-badge]]
             [salava.core.ui.modal :as mo]
@@ -46,6 +46,7 @@
               :on-click #(delete-badge id state init-data)}
      (t :core/Delete)]]])

+
 (defn badge-grid-element [element-data state badge-type init-data]
   (let [{:keys [id image_file name description visibility expires_on revoked issuer_content_name issuer_content_url recipients badge_id assertion_url meta_badge meta_badge_req]} element-data
         expired? (bh/badge-expired? expires_on)
@@ -66,29 +67,34 @@
                                                                                {:size :lg})) :title (t :badge/Delete)} [:i {:class "fa fa-trash"}]]])
                                  [:a {:href "#" :on-click #(mo/open-modal [:badge :info] {:badge-id id} {:hide (fn [] (init-data state))})}
                                   (if image_file
-                                   [:div.media-left
-                                    [:img.badge-img {:src (str "/" image_file)
-                                                     :alt name}]])
-                                 [:div.media-body
-                                  [:div.media-heading
-                                   [:p.heading-link name]]
-                                  [:div.media-issuer
-                                   [:p issuer_content_name]]]
-                                 ]]
+                                    [:div.media-left
+                                     [:img.badge-img {:src (str "/" image_file)
+                                                      :alt name}]])
+                                  [:div.media-body
+                                   [:div.media-heading
+                                    [:p.heading-link name]]
+                                   [:div.media-issuer
+                                    [:p issuer_content_name]]]
+                                  ]]
                                 [:div {:class (str "media-content " (if expired? "media-expired") (if revoked " media-revoked"))}
                                  [:a {:href "#" :on-click #(do
-                                                             (.replaceState js/history "" "Badge modal" (path-for (str "/badge?id=" id)))
-                                                             (mo/open-modal [:badge :info] {:badge-id id} {:hide (fn []
-                                                                                (.replaceState js/history "" "Badge modal" (path-for "/badge"))
-                                                                                (init-data state))}))}
+                                                             (mo/open-modal [:badge :info] {:badge-id id} {
+                                                                                :shown (fn [] (.replaceState js/history {} "Badge modal" (path-for (str "/badge?id=" id))))
+                                                                                :hidden (fn []
+                                                                                (do
+                                                                                (if (clojure.string/includes? (str js/window.location.href) (path-for (str "/badge?id=" id)))
+                                                                                (.replaceState js/history {} "Badge modal" (path-for "/badge"))
+                                                                                (navigate-to (current-route-path)))
+                                                                                (init-data state)))
+                                                                                }))}
                                   [:div.icons
-                                     [:div.visibility-icon.inline
+                                   [:div.visibility-icon.inline
                                     (case visibility
                                       "private" [:i {:class "fa fa-lock"}]
                                       "internal" [:i {:class "fa fa-group"}]
                                       "public" [:i {:class "fa fa-globe"}]
                                       nil)
-                                     (if metabadge-icon-fn [:div.pull-right [metabadge-icon-fn id]])]
+                                    (if metabadge-icon-fn [:div.pull-right [metabadge-icon-fn id]])]

                                    (if expires_on
                                      [:div.righticon
@@ -109,38 +115,38 @@
                                   ]])

        #_(= "export" badge-type) #_[:div {:key id}
-                                [:div.media-content
-                                 [:a {:href "#" :on-click #(mo/open-modal [:badge :info] {:badge-id id})}
-                                  [:div.visibility-icon
-                                   (case visibility
-                                     "private" [:i {:class "fa fa-lock"}]
-                                     "internal" [:i {:class "fa fa-group"}]
-                                     "public" [:i {:class "fa fa-globe"}]
-                                     nil)]
-                                  (if image_file
-                                    [:div.media-left
-                                     [:img {:src (str "/" image_file) :alt name}]])
-                                  [:div.media-body
-                                   [:div.media-heading name]
-                                   [:div.media-issuer issuer_content_name]]]]
-                                [:div.media-bottom
-                                 [:div.row
-                                  [:div.col-xs-9
-                                   (let [checked? (boolean (some #(= id %) (:badges-selected @state)))]
-                                     [:div.checkbox
-                                      [:label {:for (str "checkbox-" id)}
-                                       [:input {:type "checkbox"
-                                                :id (str "checkbox-" id)
-                                                :on-change (fn []
-                                                             (if checked?
-                                                               (swap! state assoc :badges-selected (remove #(= % id) (:badges-selected @state)))
-                                                               (swap! state assoc :badges-selected (conj (:badges-selected @state) id))))
-                                                :checked checked?}]
+                                    [:div.media-content
+                                     [:a {:href "#" :on-click #(mo/open-modal [:badge :info] {:badge-id id})}
+                                      [:div.visibility-icon
+                                       (case visibility
+                                         "private" [:i {:class "fa fa-lock"}]
+                                         "internal" [:i {:class "fa fa-group"}]
+                                         "public" [:i {:class "fa fa-globe"}]
+                                         nil)]
+                                      (if image_file
+                                        [:div.media-left
+                                         [:img {:src (str "/" image_file) :alt name}]])
+                                      [:div.media-body
+                                       [:div.media-heading name]
+                                       [:div.media-issuer issuer_content_name]]]]
+                                    [:div.media-bottom
+                                     [:div.row
+                                      [:div.col-xs-9
+                                       (let [checked? (boolean (some #(= id %) (:badges-selected @state)))]
+                                         [:div.checkbox
+                                          [:label {:for (str "checkbox-" id)}
+                                           [:input {:type "checkbox"
+                                                    :id (str "checkbox-" id)
+                                                    :on-change (fn []
+                                                                 (if checked?
+                                                                   (swap! state assoc :badges-selected (remove #(= % id) (:badges-selected @state)))
+                                                                   (swap! state assoc :badges-selected (conj (:badges-selected @state) id))))
+                                                    :checked checked?}]

-                                       (t :badge/Exporttobackpack)]])]
-                                  [:div {:class "col-xs-3 text-right"}
-                                   [:a {:href (str obf_url "/c/receive/download?url="(js/encodeURIComponent assertion_url)) :class "badge-download"}
-                                    [:i {:class "fa fa-download"}]]]]]]
+                                           (t :badge/Exporttobackpack)]])]
+                                      [:div {:class "col-xs-3 text-right"}
+                                       [:a {:href (str obf_url "/c/receive/download?url="(js/encodeURIComponent assertion_url)) :class "badge-download"}
+                                        [:i {:class "fa fa-download"}]]]]]]

        (= "gallery" badge-type) [:div
                                  [:a {:href "#" :on-click #(mo/open-modal [:gallery :badges] {:badge-id badge_id})


renaming to jump

renaming to jump

--- src/cljs/triboard/logic/transition.cljs
+++ src/cljs/triboard/logic/transition.cljs
@@ -11,16 +11,16 @@
 ;; Public Types
 ;; -----------------------------------------

-(s/def ::point ::board/coord)
+(s/def ::destination ::board/coord)
 (s/def ::taken (s/coll-of ::board/coord))
 (s/def ::winner ::player/player)
 (s/def ::looser ::player/playable-cell)
-(s/def ::conversion (s/keys :req-un [::point ::taken ::winner ::looser]))
-(s/def ::transition (s/every ::conversion))
+(s/def ::jump (s/keys :req-un [::destination ::taken ::winner ::looser]))
+(s/def ::transition (s/every ::jump))

 (s/def ::transitions
   (s/map-of ::player/player
-    (s/map-of ::board/coord ::transition)))
+    (s/map-of ::destination ::transition)))

 ;; -----------------------------------------
@@ -39,18 +39,18 @@

 (defn- available-cells-by-dir
   "Indicates the convertible cells when clicking at [x y]"
-  [board [x-init y-init :as init-coord] [dx dy]]
+  [board [x-init y-init :as destination] [dx dy]]
   (loop [x (+ x-init dx)
          y (+ y-init dy)
          looser nil
          taken []]
     (let [cell (aboard-cell-at board x y)]
       (cond
-        (is-not-convertible? cell) nil                      ;; No move: reached end and only 1 type of cell
-        (and looser (not= looser cell)) {:winner cell       ;; Who wins the cells
-                                         :looser looser     ;; Who looses the cells
-                                         :point init-coord  ;; The move performed
-                                         :taken taken}      ;; The cells taken
+        (is-not-convertible? cell) nil                            ;; No move: reached end and only 1 type of cell
+        (and looser (not= looser cell)) {:winner cell             ;; Who wins the cells
+                                         :looser looser           ;; Who looses the cells
+                                         :destination destination ;; The move performed
+                                         :taken taken}            ;; The cells taken
         :else (recur
                 (+ x dx)
                 (+ y dy)
@@ -58,7 +58,7 @@
                 (conj taken [x y])))
       )))

-(defn- available-conversions-at
+(defn- available-jumps-at
   "Provides the list of moves that can be done from a cell"
   [board point]
   (eduction
@@ -68,21 +68,21 @@
 (defn- empty-cell-conversion
   "Create a move to take an empty cell"
   [player point]
-  {:point point
+  {:destination point
    :winner player
    :looser :empty
    :taken [point]})

-(defn- apply-conversion
+(defn- apply-jump
   "Apply a move onto the board, yielding a new board"
   [board {:keys [winner taken]}]
   (reduce #(board/convert-cell %1 %2 winner) board taken))

-(defn conversions->transition
-  [conversions]
-  (if-let [{:keys [winner point]} (first conversions)]
-    (conj conversions (empty-cell-conversion winner point))
-    conversions))
+(defn add-destination
+  [jumps]
+  (if-let [{:keys [winner destination]} (first jumps)]
+    (conj jumps (empty-cell-conversion winner destination))
+    jumps))

 (defn- map-transition-tree
   [xf game-tree]
@@ -100,15 +100,15 @@
   [board]
   (let [aboard (board/board->array board)]
     (map-transition-tree
-      conversions->transition
+      add-destination
       (transduce
-        (mapcat #(available-conversions-at aboard %))
-        (algo/group-by-reducer :winner :point)
+        (mapcat #(available-jumps-at aboard %))
+        (algo/group-by-reducer :winner :destination)
         (board/empty-cells board)))))

 (defn apply-transition
   [board transition]
-  (reduce apply-conversion board transition))
+  (reduce apply-jump board transition))

 ;; -----------------------------------------
 ;; TESTS


ideas

ideas

--- src/cljs/triboard/logic/transition.cljs
+++ src/cljs/triboard/logic/transition.cljs
@@ -148,6 +148,7 @@
 ;; - partition-by to get the zones of same color
 ;; - partition size 3 step 1 to get the surroundings
 ;; - filter on "one side exactly is :none" and you get the jumps
+;; TODO - A newp partition that gives the tag... for the group.

 ;; TODO - Completely change the algorithm (solution 2):
 ;; Search from the cells owned by a player... allows more incremental mode


remove unused require

remove unused require

--- src/cljc/clj_money/util.cljc
+++ src/cljc/clj_money/util.cljc
@@ -1,6 +1,5 @@
 (ns clj-money.util
   (:require [clojure.string :as string]
-            [dgknght.app-lib.core :refer [trace]]
             #?(:clj [clj-time.core :as t]
                :cljs [cljs-time.core :as t])))


Reorder blocks of the code

Reorder blocks of the code

--- src/cyanite_fetcher/core.clj
+++ src/cyanite_fetcher/core.clj
@@ -7,6 +7,120 @@
             [clojurewerkz.elastisch.rest.document :as esrd]
             [qbits.alia :as alia])
   (:gen-class))
+
+;;------------------------------------------------------------------------------
+;; Cassandra
+;;------------------------------------------------------------------------------
+
+(def ^:const keyspace "metric")
+
+(defn fetchq
+  "Yields a cassandra prepared statement of 7 arguments:
+
+* `paths`: list of paths
+* `tenant`: tenant identifier
+* `rollup`: interval between points at this resolution
+* `period`: rollup multiplier which determines the time to keep points for
+* `min`: return points starting from this timestamp
+* `max`: return points up to this timestamp
+* `limit`: maximum number of points to return"
+  [session]
+  (alia/prepare
+   session
+   (str
+    "SELECT path,data,time FROM metric WHERE "
+    "path = ? AND tenant = ? AND rollup = ? AND period = ? "
+    "AND time >= ? AND time <= ? ORDER BY time ASC;")))
+
+(defn par-fetch [session fetch! paths tenant rollup period from to]
+  (let [futures
+        (doall (map #(future
+                       (->> (alia/execute
+                             session fetch!
+                             {:values [% tenant (int rollup)
+                                       (int period)
+                                       from to]
+                              :fetch-size Integer/MAX_VALUE})
+                            ;;(map detect-aggregate)
+                            (seq)))
+                    paths))]
+    (seq (remove nil? (reduce into (map deref futures))))))
+
+(defn c-get-data
+  "Get data from C*."
+  [host paths tenant rollup period from to]
+  (let [session (-> (alia/cluster {:contact-points [host]})
+                    (alia/connect keyspace))
+        fetch! (fetchq session)]
+    (println "Getting data form Cassandra...")
+    (let [data (time (doall (par-fetch session fetch! paths tenant rollup
+                                       period from to)))]
+      data)))
+
+;;------------------------------------------------------------------------------
+;; ElasticSearch
+;;------------------------------------------------------------------------------
+
+(def ES_DEF_TYPE "path")
+(def ES_TYPE_MAP {ES_DEF_TYPE {:_all { :enabled false }
+                               :_source { :compress false }
+                               :properties {:tenant {:type "string" :index "not_analyzed"}
+                                            :path {:type "string" :index "not_analyzed"}}}})
+
+(def ^:const period 46)
+(def ^:const index "cyanite_paths")
+
+(defn path-depth
+  "Get the depth of a path, with depth + 1 if it ends in a period"
+  [path]
+  (loop [cnt 1
+         from-dex 0]
+    (let [dex (.indexOf path period from-dex)]
+      (if (= dex -1)
+        cnt
+        (recur (inc cnt) (inc dex))))))
+
+(defn build-es-filter
+  "generate the filter portion of an es query"
+  [path tenant leafs-only]
+  (let [depth (path-depth path)
+        p (str/replace (str/replace path "." "\\.") "*" ".*")
+        f (vector
+           {:range {:depth {:from depth :to depth}}}
+           {:term {:tenant tenant}}
+           {:regexp {:path p :_cache true}})]
+    (if leafs-only (conj f {:term {:leaf true}}) f)))
+
+(defn build-es-query
+  "generate an ES query to return the proper result set"
+  [path tenant leafs-only]
+  {:filtered {:filter {:bool {:must (build-es-filter path tenant leafs-only)}}}})
+
+(defn search
+  "search for a path"
+  [query scroll tenant path leafs-only]
+  (let [res (query :query (build-es-query path tenant leafs-only)
+                   :size 100
+                   :search_type "query_then_fetch"
+                   :scroll "1m")
+        hits (scroll res)]
+    (map #(:_source %) hits)))
+
+(defn lookup [host tenant path]
+  "Look up path."
+  (let [full-path-cache (atom #{})
+        conn (esr/connect host)
+        scrollfn (partial esrd/scroll-seq conn)
+        queryfn (partial esrd/search conn index ES_DEF_TYPE)]
+    (map :path (search queryfn scrollfn tenant path true))))
+
+(defn es-get-paths
+  "Get paths from ElasticSearch."
+  [host path tenant]
+  (println "Getting paths form ElasticSearch...")
+  (let [paths (time (doall (lookup host tenant path)))]
+    (println "Number of paths:" (count paths))
+    paths))

 ;;------------------------------------------------------------------------------
 ;; Rollups
@@ -61,120 +175,6 @@
     (some within (sort-by :rollup rollups))))

 ;;------------------------------------------------------------------------------
-;; Cassandra
-;;------------------------------------------------------------------------------
-
-(def ^:const keyspace "metric")
-
-(defn fetchq
-  "Yields a cassandra prepared statement of 7 arguments:
-
-* `paths`: list of paths
-* `tenant`: tenant identifier
-* `rollup`: interval between points at this resolution
-* `period`: rollup multiplier which determines the time to keep points for
-* `min`: return points starting from this timestamp
-* `max`: return points up to this timestamp
-* `limit`: maximum number of points to return"
-  [session]
-  (alia/prepare
-   session
-   (str
-    "SELECT path,data,time FROM metric WHERE "
-    "path = ? AND tenant = ? AND rollup = ? AND period = ? "
-    "AND time >= ? AND time <= ? ORDER BY time ASC;")))
-
-(defn par-fetch [session fetch! paths tenant rollup period from to]
-  (let [futures
-        (doall (map #(future
-                       (->> (alia/execute
-                             session fetch!
-                             {:values [% tenant (int rollup)
-                                       (int period)
-                                       from to]
-                              :fetch-size Integer/MAX_VALUE})
-                            ;;(map detect-aggregate)
-                            (seq)))
-                    paths))]
-    (seq (remove nil? (reduce into (map deref futures))))))
-
-(defn c-get-data
-  "Get data from C*."
-  [host paths tenant rollup period from to]
-  (let [session (-> (alia/cluster {:contact-points [host]})
-                    (alia/connect keyspace))
-        fetch! (fetchq session)]
-    (println "Getting data form Cassandra...")
-    (let [data (time (doall (par-fetch session fetch! paths tenant rollup
-                                       period from to)))]
-      data)))
-
-;;------------------------------------------------------------------------------
-;; ElasticSearch
-;;------------------------------------------------------------------------------
-
-(def ES_DEF_TYPE "path")
-(def ES_TYPE_MAP {ES_DEF_TYPE {:_all { :enabled false }
-                               :_source { :compress false }
-                               :properties {:tenant {:type "string" :index "not_analyzed"}
-                                            :path {:type "string" :index "not_analyzed"}}}})
-
-(def ^:const period 46)
-(def ^:const index "cyanite_paths")
-
-(defn path-depth
-  "Get the depth of a path, with depth + 1 if it ends in a period"
-  [path]
-  (loop [cnt 1
-         from-dex 0]
-    (let [dex (.indexOf path period from-dex)]
-      (if (= dex -1)
-        cnt
-        (recur (inc cnt) (inc dex))))))
-
-(defn build-es-filter
-  "generate the filter portion of an es query"
-  [path tenant leafs-only]
-  (let [depth (path-depth path)
-        p (str/replace (str/replace path "." "\\.") "*" ".*")
-        f (vector
-           {:range {:depth {:from depth :to depth}}}
-           {:term {:tenant tenant}}
-           {:regexp {:path p :_cache true}})]
-    (if leafs-only (conj f {:term {:leaf true}}) f)))
-
-(defn build-es-query
-  "generate an ES query to return the proper result set"
-  [path tenant leafs-only]
-  {:filtered {:filter {:bool {:must (build-es-filter path tenant leafs-only)}}}})
-
-(defn search
-  "search for a path"
-  [query scroll tenant path leafs-only]
-  (let [res (query :query (build-es-query path tenant leafs-only)
-                   :size 100
-                   :search_type "query_then_fetch"
-                   :scroll "1m")
-        hits (scroll res)]
-    (map #(:_source %) hits)))
-
-(defn lookup [host tenant path]
-  "Look up path."
-  (let [full-path-cache (atom #{})
-        conn (esr/connect host)
-        scrollfn (partial esrd/scroll-seq conn)
-        queryfn (partial esrd/search conn index ES_DEF_TYPE)]
-    (map :path (search queryfn scrollfn tenant path true))))
-
-(defn es-get-paths
-  "Get paths from ElasticSearch."
-  [host path tenant]
-  (println "Getting paths form ElasticSearch...")
-  (let [paths (time (doall (lookup host tenant path)))]
-    (println "Number of paths:" (count paths))
-    paths))
-
-;;------------------------------------------------------------------------------
 ;; Benchmark
 ;;------------------------------------------------------------------------------


Small improvement to clojure tabs

Small improvement to clojure tabs

--- nightweb-android/src/clojure/net/nightweb/tabs.clj
+++ nightweb-android/src/clojure/net/nightweb/tabs.clj
@@ -250,16 +250,17 @@
     (let [context (get-state this :context)
           title (get-state this :title)
           icon-view (get-state this :icon-view)
-          close (get-state this :close)
-          lp (.getLayoutParams this)]
+          close (get-state this :close)]
       (.setTextAppearance title context (if selected (get-resource :style :TabTitleSelected) (get-resource :style :TabTitleUnselected)))
       (.setVisibility icon-view (if selected android.view.View/GONE android.view.View/VISIBLE))
       (.setVisibility close (if selected android.view.View/VISIBLE android.view.View/GONE))
       (.setHorizontalFadingEdgeEnabled this (not selected))
       (.superSetActivated this selected)
-;      (set! (. lp width) (get-state this :tab-width))
-;      (set! (. lp height) android.view.ViewGroup$LayoutParams/MATCH_PARENT)
-;      (.setLayoutParams this lp)
+      (if-let [lp (.getLayoutParams this)]
+        (do
+          (set! (. lp width) (get-state this :tab-width))
+          (set! (. lp height) android.view.ViewGroup$LayoutParams/MATCH_PARENT)
+          (.setLayoutParams this lp)))
       (.setFocusable this (not selected))
       (.postInvalidate this)))
   (defn tab-view-setTitle


CMR-4806 OldRevisionConceptCleanupJob taking multiple weeks to complete (#509)

* CMR-4806 limits cleanup job to prevent near endless cleanup

* CMR-4806 some refactoring

* CMR-4806 fixes failing tests

--- metadata-db-app/src/cmr/metadata_db/services/concept_service.clj
+++ metadata-db-app/src/cmr/metadata_db/services/concept_service.clj
@@ -785,24 +785,35 @@
                 (swap! failed-concept-ids conj (:concept-id c))))))
         (recur)))))

+(defn- call-force-deletes
+  "Calls functions that do the deletion of concepts or that publish events to message queue."
+  [context db provider concept-type tombstone-delete? concept-id-revision-id-tuples concept-truncation-batch-size]
+  (when concept-id-revision-id-tuples
+    (info "Deleting" (count concept-id-revision-id-tuples)
+          "old concept revisions for provider" (:provider-id provider))
+    (when (and tombstone-delete?
+               (= :granule concept-type))
+      ;; Remove any reference to granule from deleted-granule index
+      (doseq [[concept-id revision-id] concept-id-revision-id-tuples]
+        (ingest-events/publish-tombstone-delete-msg context concept-type concept-id revision-id)))
+    (doseq [[concept-id revision-id] concept-id-revision-id-tuples]
+      ;; performs the cascading delete actions first
+      (force-delete-cascading-events context concept-type concept-id (long revision-id)))
+    (c/force-delete-concepts db provider concept-type concept-id-revision-id-tuples)))
+
 (defn force-delete-with
   "Continually force deletes concepts using the given function concept-id-revision-id-tuple-finder
   to find concept id revision id tuples to delete. Stops once the function returns an empty set."
-  [context provider concept-type tombstone-delete? concept-id-revision-id-tuple-finder]
+  [context provider concept-type tombstone-delete? concept-id-revision-id-tuple-finder concept-truncation-batch-size]
   (let [db (util/context->db context)]
-    (cutil/while-let
-     [concept-id-revision-id-tuples (seq (concept-id-revision-id-tuple-finder))]
-     (info "Deleting" (count concept-id-revision-id-tuples)
-           "old concept revisions for provider" (:provider-id provider))
-     (when (and tombstone-delete?
-                (= :granule concept-type))
-       ;; Remove any reference to granule from deleted-granule index
-       (doseq [[concept-id revision-id] concept-id-revision-id-tuples]
-         (ingest-events/publish-tombstone-delete-msg context concept-type concept-id revision-id)))
-     (doseq [[concept-id revision-id] concept-id-revision-id-tuples]
-       ;; performs the cascading delete actions first
-       (force-delete-cascading-events context concept-type concept-id (long revision-id)))
-     (c/force-delete-concepts db provider concept-type concept-id-revision-id-tuples))))
+    (loop [concept-id-revision-id-tuples (seq (concept-id-revision-id-tuple-finder))]
+      (if (< (count concept-id-revision-id-tuples) concept-truncation-batch-size)
+        (call-force-deletes
+          context db provider concept-type tombstone-delete? concept-id-revision-id-tuples concept-truncation-batch-size)
+        (do
+          (call-force-deletes
+            context db provider concept-type tombstone-delete? concept-id-revision-id-tuples concept-truncation-batch-size)
+          (recur (seq (concept-id-revision-id-tuple-finder))))))))

 (defn delete-old-revisions
   "Delete concepts to keep a fixed number of revisions around. It also deletes old tombstones that
@@ -824,7 +835,8 @@
          concept-type
          (get num-revisions-to-keep-per-concept-type
               concept-type)
-         concept-truncation-batch-size))
+         concept-truncation-batch-size)
+      concept-truncation-batch-size)

     (info "Starting deletion of tombstoned" concept-type-name "for provider" (:provider-id provider))
     (force-delete-with
@@ -834,4 +846,5 @@
          provider
          concept-type
          tombstone-cut-off-date
-         concept-truncation-batch-size))))
+         concept-truncation-batch-size)
+      concept-truncation-batch-size)))


added tests for register-selector! and fully qualified selectors

--- test/kioo/core_test.cljs
+++ test/kioo/core_test.cljs
@@ -9,9 +9,11 @@
             [kioo.test :refer [render-dom]]
             [goog.dom :as gdom])
   (:require-macros [kioo.core :refer [component  snippet template
-                                    defsnippet deftemplate supress-whitespace]]
+                                    defsnippet deftemplate supress-whitespace
+                                      register-selector!]]
                    [cljs.test :refer [are is deftest testing]]))

+(register-selector! test-sel kioo.core/first-match)

 (deftest render-test
   (testing "basic render test"
@@ -19,7 +21,7 @@
       (is (= "
test
" (render-dom comp)))))
   (testing "content replace"
     (let [comp (component "simple-div.html"
-                          {[:div] (content "success")})]
+                 {[:div] (content "success")})]
       (is (= "
success
" (render-dom comp)))))
   (testing "first-of-type naked symbol"
     (let [comp (component "list.html" [:ul [:li first-of-type]] {})]
@@ -33,19 +35,27 @@
     (let [comp (component "list.html" [:ul [:li (nth-match 2)]] {})]
       (is (= "
2
" (render-dom comp)))))

+  (testing "registering a custom selector"
+    (let [comp (component "list.html" [:ul [:li (test-sel)]] {})]
+      (is (= "
1
" (render-dom comp)))))
+
+  (testing "fully qualified selector"
+    (let [comp (component "list.html" [:ul [:li (kioo.core/nth-match 2)]] {})]
+      (is (= "
2
" (render-dom comp)))))
+
   (testing "attr= content replace"
     (let [comp (component "simple-attr-div.html"
-                          {[(attr= :data-id "tmp")]
-                           (content "success")})]
+                 {[(attr= :data-id "tmp")]
+                  (content "success")})]
       (is (= "
success
" (render-dom comp)))))
   (testing "attr? content replace"
     (let [comp (component "simple-attr-div.html"
-                          {[(attr? :data-id)]
-                           (content "success")})]
+                 {[(attr? :data-id)]
+                  (content "success")})]
       (is (= "
success
" (render-dom comp)))))
   (testing "append test"
     (let [comp (component "simple-div.html"
-                          {[:div] (append "success")})]
+                 {[:div] (append "success")})]
       ;;note that ract wraps text nodes in span tags
       ;;this is expected to be corrected soon in react but
       ;;for now this is correct
@@ -53,92 +63,92 @@
              (render-dom comp)))))
   (testing "prepend test"
     (let [comp (component "simple-div.html"
-                          {[:div] (prepend "success")})]
+                 {[:div] (prepend "success")})]
       (is (= "
successtest
"
              (render-dom comp)))))
   (testing "set-attr test"
     (let [comp (component "simple-div.html"
-                          {[:div] (set-attr :id "success")})]
+                 {[:div] (set-attr :id "success")})]
       (is (= "
test
"
              (render-dom comp)))))
   (testing "remove-attr test"
     (let [comp (component "simple-div.html"
-                          {[:div] (remove-attr :id)})]
+                 {[:div] (remove-attr :id)})]
       (is (= "
test
"
              (render-dom comp)))))
   (testing "before test"
     (let [comp (component "simple-div.html"
-                          {[:div] (before "success")})]
+                 {[:div] (before "success")})]
       (is (= "success
test
"
              (render-dom comp)))))
   (testing "after test"
     (let [comp (component "simple-div.html"
-                          {[:div] (after "success")})]
+                 {[:div] (after "success")})]
       (is (= "
test
success"
              (render-dom comp)))))
   (testing "add-class test"
     (let [comp (component "class-span.html" [:span]
-                          {[:#s] (add-class "suc")})]
+                 {[:#s] (add-class "suc")})]
       (is (= "testing"
              (render-dom comp)))))
   (testing "add-class when no class exists"
     (let [comp (component "simple-div.html"
-                          {[:div] (add-class "suc")})]
+                 {[:div] (add-class "suc")})]
       (is (= "
test
"
              (render-dom comp)))))
   (testing "remove-class test"
     (let [comp (component "class-span.html" [:span]
-                          {[:#s] (remove-class "cl")})]
+                 {[:#s] (remove-class "cl")})]
       (is (= "testing"
              (render-dom comp)))))
   (testing "set-class test"
     (let [comp (component "class-span.html" [:span]
-                          {[:#s] (set-class "cl")})]
+                 {[:#s] (set-class "cl")})]
       (is (= "testing"
              (render-dom comp)))))
   (testing "set-style test"
     (let [comp (component "style-span.html" [:span]
-                          {[:#s] (set-style :display "none")})]
+                 {[:#s] (set-style :display "none")})]
       (is (= "testing"
              (render-dom comp)))))
   (testing "remove-style test"
     (let [comp (component "style-span.html" [:span]
-                          {[:#s] (remove-style :color)})]
+                 {[:#s] (remove-style :color)})]
       (is (= "testing"
              (render-dom comp)))))
   (testing "do-> test"
     (let [comp (component "style-span.html" [:span]
-                          {[:#s] (do->
-                                  (remove-attr :id)
-                                  (remove-style :color))})]
+                 {[:#s] (do->
+                         (remove-attr :id)
+                         (remove-style :color))})]
       (is (= "testing"
              (render-dom comp)))))
   (testing "wrap test"
     (let [comp (component "wrap-test.html" [:span]
-                          {[:#s] (wrap :div {:id "test"})})]
+                 {[:#s] (wrap :div {:id "test"})})]
       (is (= "
testing
"
              (render-dom comp)))))
   (testing "unwrap test"
     (let [comp (component "wrap-test.html" [:div]
-                          {[:div] unwrap})]
+                 {[:div] unwrap})]
       (is (= "testing"
              (render-dom comp)))))
   (testing "html test"
     (let [comp (component "simple-div.html"
-                          {[:div] (content (html [:h1 {:class "t"}
-                                                  [:span "t1"]]))})]
+                 {[:div] (content (html [:h1 {:class "t"}
+                                         [:span "t1"]]))})]
       (is (= "

t1

"
              (render-dom comp)))))
   (testing "html-content test"
     (let [comp (component "simple-div.html"
-                          {[:div] (html-content "
t1
t2")})]
+                 {[:div] (html-content "
t1
t2")})]
       (is (= "

t1
t2
"
              (render-dom comp)))))
   (testing "listen on render"
-     (let [atm (atom "fail")
+    (let [atm (atom "fail")
           comp (component "simple-div.html"
-                     {[:div] (listen :on-render
-                                     #(reset! atm "success"))})]
+                 {[:div] (listen :on-render
+                                 #(reset! atm "success"))})]
       (render-dom comp)
       (is (= "success" @atm))))
   (testing "lifecycle tests"
@@ -151,36 +161,36 @@
           will-mount (atom "fail")
           did-mount (atom "fail")
           comp (component "simple-div.html"
-                          {[:div] (lifecycle
-                                   {:init-state (fn [this] (reset! init-state "success") {})
-                                    :default-props (fn [this] (reset! default-props "success"))
-                                    :should-update
-                                    (fn [this next-props next-state]
-                                      (reset! should-update "success")
-                                      true)
-                                    :will-mount (fn [this] (reset! will-mount "success"))
-                                    :did-mount (fn [this] (reset! did-mount "success"))
-                                    :will-receive-props (fn [this next-props]
-                                                          (reset! will-receive-props "success"))
-                                    :will-update (fn [this next-props next-state]
-                                                   (reset! will-update "success"))
-                                    :did-update (fn [this prev-props prev-state]
-                                                  (reset! did-update "success"))})})]
+                 {[:div] (lifecycle
+                          {:init-state (fn [this] (reset! init-state "success") {})
+                           :default-props (fn [this] (reset! default-props "success"))
+                           :should-update
+                           (fn [this next-props next-state]
+                             (reset! should-update "success")
+                             true)
+                           :will-mount (fn [this] (reset! will-mount "success"))
+                           :did-mount (fn [this] (reset! did-mount "success"))
+                           :will-receive-props (fn [this next-props]
+                                                 (reset! will-receive-props "success"))
+                           :will-update (fn [this next-props next-state]
+                                          (reset! will-update "success"))
+                           :did-update (fn [this prev-props prev-state]
+                                         (reset! did-update "success"))})})]
       (render-dom comp)
       (is (= "success" @init-state))
       (is (= "success" @will-mount))
       (is (= "success" @did-mount))

       ;;need to workout how to test these
-      ;(is (= "success" @default-props))
-      ;(is (= "success" @should-update))
-      ;(is (= "success" @will-receive-props))
-      ;(is (= "success" @will-update))
-      ;(is (= "success" @did-update))
+                                        ;(is (= "success" @default-props))
+                                        ;(is (= "success" @should-update))
+                                        ;(is (= "success" @will-receive-props))
+                                        ;(is (= "success" @will-update))
+                                        ;(is (= "success" @did-update))
       ))
   (testing "checking for camel cased attributes"
     (let [comp (component "camel-case.html"
-                          {[:td] (content "test")})]
+                 {[:td] (content "test")})]
       (is (= "

test

" (render-dom comp))))))


Update and cleanup

Update and cleanup

--- clojure/profiles.clj
+++ clojure/profiles.clj
@@ -1,9 +1,3 @@
-{:user
- {:plugins [#_[lein-localrepo "0.5.4"] ;; https://github.com/kumarshantanu/lein-localrepo
-            #_[lein-nevam "0.1.2"]     ;; Convert pom.xml to project.clj
-            [lein-pprint "1.2.0"]]     ;; Pretty-print a representation of the project map
-  :dependencies [[alembic "0.3.2"]
-                 #_[pjstadig/humane-test-output "0.8.3"]]
-  #_:injections
-  #_[(require 'pjstadig.humane-test-output)
-     (pjstadig.humane-test-output/activate!)]}}
+;; https://github.com/technomancy/leiningen/blob/stable/doc/PROFILES.md
+{:user {:plugins [[lein-pprint "1.3.2"]]
+        :dependencies [[alembic "0.3.2"]]}}


Add generate-cljs-cache lumo script [skip ci]

--- scripts/lumo/generate_cljs_cache.cljs
+++ scripts/lumo/generate_cljs_cache.cljs
@@ -1,11 +1,7 @@
 (ns generate-cljs-cache
   (:require [clojure.string :as string]))

-(def nexeres (js/require "nexeres"))
-
-(def mkdirp (js/require "mkdirp"))
-
-(doseq [resource (filter #(re-matches #"cljs.*" %) (.keys nexeres))]
-  (let [filename (str "docs\\cache-cljs\\" (string/replace resource #"[/\\]" "_SLASH_"))]
-    (mkdirp (js/path.dirname filename)
-            #(js/fs.writeFile filename (js/zlib.inflateSync (.get nexeres resource)) (constantly true)))))
+(let [nexeres (js/require "nexeres")]
+  (doseq [resource (filter #(re-matches #"cljs.*" %) (.keys nexeres))]
+    (let [filename (str "docs/cache-cljs/" (string/replace resource #"[/\\]" "_SLASH_"))]
+      (js/fs.writeFile filename (js/zlib.inflateSync (.get nexeres resource)) (constantly true)))))


Logging for difference series.

Logging for difference series.

--- src/kixi/hecuba/controller/pipeline.clj
+++ src/kixi/hecuba/controller/pipeline.clj
@@ -82,9 +82,15 @@
                 range     (misc/start-end-dates :difference_series s where)
                 new-item  (assoc item :sensor s :range range)]
             (when (and range (= "CUMULATIVE" period))
-              (calculate/difference-series store new-item)
-              (misc/reset-date-range store s :difference_series (:start-date range) (:end-date range))))))
-      (log/info "Finished calculation of difference series."))
+              (log/debugf "Started calculating Difference Series for Sensor: %s:%s Start: %s End: %s" device_id type (:start-date range) (:end-date range))
+              (try
+                (calculate/difference-series store new-item)
+                (misc/reset-date-range store s :difference_series (:start-date range) (:end-date range))
+                (catch Throwable t
+                  (log/errorf t "FAILED to calculate Difference Series for Sensor: %s:%s Start: %s End: %s" device_id type (:start-date range) (:end-date range))
+                  (throw t)))
+              (log/debugf "COMPLETED calculating Difference Series for Sensor: %s:%s Start: %s End: %s" device_id type (:start-date range) (:end-date range))))))
+      (log/info "COMPLETED calculation of difference series."))

     (defnconsumer convert-to-co2-q [item]
       (log/info "Starting conversion from kWh to co2.")


Add auth and auth-query forms to the defcommand spec

Also change the order of defcommand forms a little bit and make sure
that we catch if one of the arbitrary forms has a naming collision
with reserved forms like auth, emit etc.

--- src/main/workflo/macros/specs/command.cljc
+++ src/main/workflo/macros/specs/command.cljc
@@ -18,6 +18,12 @@
 (s/def ::command-form-name
   (s/with-gen
     (s/and symbol?
+           #(not (some #{%} '[description
+                              spec
+                              query
+                              auth-query
+                              auth
+                              emit]))
            #(not (some #{\/} (str %))))
     #(s/gen '#{foo bar foo-bar})))

@@ -28,13 +34,21 @@
   (s/spec (s/cat :form-name ::command-form-name
                  :form-body ::command-form-body)))

+(s/def ::command-spec-form
+  (s/spec (s/cat :form-name #{'spec}
+                 :form-body ::command-spec)))
+
 (s/def ::command-query-form
   (s/spec (s/cat :form-name #{'query}
                  :form-body :workflo.macros.specs.query/query)))

-(s/def ::command-spec-form
-  (s/spec (s/cat :form-name #{'spec}
-                 :form-body ::command-spec)))
+(s/def ::command-auth-query-form
+  (s/spec (s/cat :form-name #{'auth-query}
+                 :form-body any?)))
+
+(s/def ::command-auth-form
+  (s/spec (s/cat :form-name #{'auth}
+                 :form-body ::command-form-body)))

 (s/def ::command-emit-form
   (s/spec (s/cat :form-name #{'emit}
@@ -44,8 +58,10 @@
   (s/cat :name ::command-name
          :forms
          (s/spec (s/cat :description (s/? ::command-description)
+                        :spec (s/? ::command-spec-form)
                         :query (s/? ::command-query-form)
-                        :spec (s/? ::command-spec-form)
+                        :auth-query (s/? ::command-auth-query-form)
+                        :auth (s/? ::command-auth-form)
                         :forms (s/* ::command-form)
                         :emit ::command-emit-form))
          :env (s/? any?)))


Remove deprecated ^

Remove deprecated ^

--- src/main/clojure/vimclojure/backend.clj
+++ src/main/clojure/vimclojure/backend.clj
@@ -168,7 +168,7 @@
                 (.getResourceAsStream (RT/baseLoader) fname))]
     (when strm
       (with-open [rdr (LineNumberReader. (InputStreamReader. strm))]
-        (dotimes [_ (dec (:line ^the-var))] (.readLine rdr))
+        (dotimes [_ (dec (:line (meta the-var)))] (.readLine rdr))
         (let [text (StringBuilder.)
               pbr (proxy [PushbackReader] [rdr]
                     (read [] (let [i (proxy-super read)]


all-acks-seen? should only return replica-version and epoch

--- src/onyx/messaging/immutable_messenger.clj
+++ src/onyx/messaging/immutable_messenger.clj
@@ -247,7 +247,8 @@
   (all-acks-seen?
     [messenger]
     (if (empty? (remove :barrier-ack (messenger->subscriptions messenger)))
-      (:barrier-ack (first (messenger->subscriptions messenger)))
+      (select-keys (:barrier-ack (first (messenger->subscriptions messenger)))
+                   [:replica-version :epoch])
       false))

   (receive-messages


No need for apply in =>'s definition.

No need for apply in =>'s definition.

--- src/overtunes/songs/canone_alla_quarta.clj
+++ src/overtunes/songs/canone_alla_quarta.clj
@@ -29,7 +29,7 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (defn sum-n [series n] (reduce + (take n series)))
-(defn => [value & fs] (reduce #(apply %2 [%1]) value fs))
+(defn => [value & fs] (reduce #(%2 %1) value fs))

 (defn scale [intervals]
   #(if-not (neg? %)


[#51] Prepared for fileName use

[#51] Prepared for fileName use

--- backend/src/org/akvo/dash/import.clj
+++ backend/src/org/akvo/dash/import.clj
@@ -50,11 +50,13 @@
      :file-extension (last (str/split url #"\."))}))

 (defmethod yank "DATA_FILE" [datasource]
-  (let [file-id (last (str/split (get-in datasource [:spec "url"])
-                                 #"\/"))
-        data (slurp (str "/tmp/akvo/dash/" "resumed/" file-id "/file"))]
-    {:data data
-     :digest (sha1 data)
+  (let [url       (get-in datasource [:spec "url"])
+        ;; file-name (get-in datasource [:spec "fileName"])
+        file-id   (last (str/split url
+                                   #"\/"))
+        data      (slurp (str "/tmp/akvo/dash/" "resumed/" file-id "/file"))]
+    {:data           data
+     :digest         (sha1 data)
      :file-extension (last (str/split (get-in datasource [:spec "fileName"])
                                       #"\."))}))


working on adding more leaves

working on adding more leaves

--- src/babel/english/lab.cljc
+++ src/babel/english/lab.cljc
@@ -96,17 +96,17 @@

 (def the-static-tree (create-the-static-tree))

+(def lexemes (flatten (vals (:lexicon model))))
+
 (defn basecamp []
   (let [tree the-static-tree]
-    (let [trees-with-see
-          (filter #(not (= :fail %))
-                  (map (fn [lexeme]
-                         (let [tree (u/copy tree)
-                               lexeme (u/copy lexeme)]
-                           (u/assoc-in! tree [:head :head] lexeme)))
-                       (first (take 1 (shuffle [(get (:lexicon model) "eat")
-                                                (get (:lexicon model) "see")])))))]
-      (first trees-with-see))))
+    (->> (-> lexemes
+             shuffle)
+         (map (fn [lexeme]
+                (let [tree (u/copy tree)
+                      lexeme (u/copy lexeme)]
+                  (u/assoc-in! tree [:head :head] lexeme))))
+         (filter #(not (= :fail %))))))

 (defn nextcamp []
   (let [parse (-> "the small dogs you see" parse first)]


Bring back error display in sync

Bring back error display in sync

--- src/braid/client/sync.cljs
+++ src/braid/client/sync.cljs
@@ -4,7 +4,8 @@
             [taoensso.timbre :as timbre :refer-macros [debugf]]
             [goog.string :as gstring]
             [braid.client.store :as store]
-            [goog.string.format]))
+            [goog.string.format]
+            [braid.client.dispatcher :refer [dispatch!]]))

 ; Change to :debug to get detailed info in dev
 (timbre/set-level! :info)
@@ -42,13 +43,12 @@
 (defmethod event-msg-handler :chsk/state
   [{:as ev-msg [old-state new-state] :?data}]
   (if (new-state :first-open?)
-      (debugf "Channel socket successfully established!")
-      (do
-        (debugf "Channel socket state change: %s" new-state)
-        ; FIXME should use dispatch!, but issue w/ circular dependency
-        #_(if (not (:open? new-state))
-            (store/display-error! :disconnected "Disconnected" :warn)
-            (store/clear-error! :disconnected))))
+    (debugf "Channel socket successfully established!")
+    (do
+      (debugf "Channel socket state change: %s" new-state)
+      (if (not (:open? new-state))
+        (dispatch! :disconnected ["Disconnected" :warn])
+        (dispatch! :clear-error [:disconnected]))))
   (event-handler [:socket/connected new-state]))

 (defmethod event-msg-handler :chsk/recv


use clostache instead of string/replace

use clostache instead of string/replace

--- src/chat/server/routes.clj
+++ src/chat/server/routes.clj
@@ -4,6 +4,7 @@
     [clojure.edn :as edn]
     [compojure.core :refer [GET POST defroutes context]]
     [compojure.route :refer [resources]]
+    [clostache.parser :as clostache]
     [chat.shared.util :refer [valid-nickname?]]
     [chat.server.digest :as digest]
     [chat.server.db :as db]
@@ -22,13 +23,11 @@
    :body (pr-str clj-body)})

 (defn- get-html [client]
-  (let [replacements {"{{algo}}" "sha256"
-                      "{{js}}" (str (digest/from-file (str "/js/" client "/out/braid.js")))
-                      "{{api_domain}}" (or (:api-domain env) (str "localhost:" @api-port))}
-        html (-> (str "public/" client ".html")
-                 clojure.java.io/resource
-                 slurp)]
-    (string/replace html #"\{\{\w*\}\}" replacements)))
+  (clostache/render-resource
+    (str "public/" client ".html")
+    {:algo "sha256"
+     :js (str (digest/from-file (str "/js/" client "/out/braid.js")))
+     :api_domain (or (:api-domain env) (str "localhost:" @api-port))}))

 (defroutes desktop-client-routes
   (GET "/*" []


Fix language

Fix language

--- demo/reagentdemo/news/news060.cljs
+++ demo/reagentdemo/news/news060.cljs
@@ -264,8 +264,9 @@
        [:p "The same thing could of course be achieved with React
        lifecycle methods, but that would be a lot more verbose."]

-       [:p [:code "with-let"] " can also be combined with " [:code "track"] ". For
-       example, the component above could also be written as: "]
+       [:p [:code "with-let"]" can also be combined
+       with "[:code "track"]" (and other reactive contexts). For
+       example, the component above could be written as: "]

        [demo-component {:comp tracked-pos
                         :src (s/src-of [:mouse-pos
@@ -313,7 +314,7 @@
         [:p "The actual event handling is done
         in "[:code "event-handler"]", which takes state and event as
         parameters, and returns a new state (events are represented by
-        vectors, with an event name in the first position)."]
+        vectors here, with an event name in the first position)."]

         [:p "All the UI components have to do is then just to return
         some markup, and set up routing of events through the dispatch
@@ -336,8 +337,8 @@
         itself dispatches a new event (that would result in lost
         events, and much confusion)."]

-        [:p "For a more structured version of this approach, see the
-        excellent "[:a
+        [:p "For a more structured version of a similar approach, see
+        the excellent "[:a
         {:href "https://github.com/Day8/re-frame"} "re-frame"]"
         framework."]]


Made net->dot ignore large networks

Made net->dot ignore large networks

--- src/clj/asols/graphics.clj
+++ src/clj/asols/graphics.clj
@@ -29,7 +29,7 @@
      (for [node-i (range nodes-count)]
        [(node->name layer-i node-i)])]))

-(defn net->dot
+(defn- net->dot*
   [{:keys [layers] :as net}]
   (let [graph-opts [def-graph-opts]
         layers-count (inc (count layers))
@@ -59,6 +59,15 @@
         (dot/digraph)
         (dot/dot))))

+(defn net->dot
+  [{:keys [layers] :as net}]
+  (let [in-counts (for [layer layers]
+                    (first (network/get-layer-shape layer)))
+        should-render? (< (apply max in-counts) 10)]
+    (if should-render?
+      (net->dot* net)
+      "")))
+
 (defn render-network
   "Render given network, return result as string"
   [net & {:keys [format] :or {format :svg}}]


rf: extracted -set-position helper

rf: extracted -set-position helper

--- src/clj_fakes/context.cljc
+++ src/clj_fakes/context.cljc
@@ -191,14 +191,26 @@
   {:pre [ctx (fn? f)]}
   (swap! ctx update-in [:unused-fakes] #(remove #{f} %)))

+(defn ^:no-doc -set-position
+  "Saves a position for the specified fake. It can be later used for debugging."
+  [ctx f position]
+  {:pre [ctx f]}
+  (swap! ctx assoc-in [:positions f] position))
+
+(defn ^:no-doc -position
+  "Returns a position of the specified fake."
+  [ctx f]
+  {:pre [ctx f]}
+  (get (:positions @ctx) f))
+
 (defn ^:no-doc -required
   [ctx position f]
   {:pre [ctx position (fn? f)]}
   (letfn [(wrapper [& args]
             (-mark-used ctx wrapper)
             (apply f args))]
-    (swap! ctx assoc-in [:positions wrapper] position)
     (swap! ctx update-in [:unused-fakes] conj wrapper)
+    (-set-position ctx wrapper position)
     wrapper))

 (defn ^:no-doc -fake
@@ -223,8 +235,8 @@
                                                 :return-value return-value})
               return-value))]
     (swap! ctx update-in [:recorded-fakes] conj (or k wrapper))
-    (swap! ctx assoc-in [:positions (or k wrapper)] position)
     (swap! ctx update-in [:unchecked-fakes] conj (or k wrapper))
+    (-set-position ctx (or k wrapper) position)
     wrapper))

 (defn ^:no-doc -recorded
@@ -258,12 +270,6 @@
 (alter-meta! #'->FakeReturnValue assoc :no-doc true)

 ;;;;;;;;;;;;;;;;;;;;;;;; Fakes - API
-(defn ^:no-doc -position
-  "Returns a position of the specified fake. Does not yet work for optional fakes."
-  [ctx f]
-  {:pre [ctx f]}
-  (get (:positions @ctx) f))
-
 (def default-fake-config
   "With this config fake will return a new `FakeReturnValue` type instance for any combination of args."
   [any? (fn [& _] (FakeReturnValue.))])
@@ -479,6 +485,7 @@
                              method-full-sym
                              (str method-sym)))
            config (-add-any-first-arg-into-matchers config)]
+       ; Descriptions are not set for :optional-fake and :-nice-fake because there's no need yet.
        (condp = fake-type
          :optional-fake
          (if config


removed legazy codez

removed legazy codez

--- src/cljs/lokate/point.cljs
+++ src/cljs/lokate/point.cljs
@@ -51,11 +51,3 @@
               (dom/span #js {:className "img icon-pin status"
                              :style #js {:color (status-color "green")}})
               (dom/span #js {:className "location-lat-lng"} (display-pos (:pos point))))))))))
-
-(defn notes-save []
-  (dom/div #js {:id "notes-editable"
-                :className "notes editable"
-                :onClick #(.log js/console "yo")
-                :data-ph "Notes..."
-                :dangerouslySetInnerHTML #js {:__html (:notes ;point
-                                                       )}}))


remove unnecessary imports

remove unnecessary imports

--- src/clojure/flambo/sql.clj
+++ src/clojure/flambo/sql.clj
@@ -11,17 +11,7 @@
            [org.apache.spark.sql SQLContext Row Dataset Column]
            [org.apache.spark.sql.hive HiveContext]
            [org.apache.spark.sql.expressions Window]
-
-           ;;[org.apache.spark.sql.types DataType DataTypes StructField StructType
-            ;;Metadata MetadataBuilder]
-
-           [org.apache.spark.sql.types DataTypes]
-
-           ;;[org.apache.spark.sql.types ArrayType BinaryType BooleanType
-            ;;ByteType CalendarIntervalType DateType Decimal DecimalType
-            ;;DoubleType FloatType IntegerType LongType  MapType  NullType
-           ;;NumericType ShortType StringType TimestampType UserDefinedType]
-    ))
+           [org.apache.spark.sql.types DataTypes]))

 ;; ## SQLContext


requested changes; table name fix

requested changes; table name fix

--- src/clojure/flambo/sql.clj
+++ src/clojure/flambo/sql.clj
@@ -287,18 +287,15 @@

 (defn query
   "Query a parquet file at **url** with **sql** statement creating temporary
-  table key **table** (default to `tmp`).
+  table key **table** (default to `schema-tmp`).

   See [[setup-temporary-view]] for `:type` key."
   [url sql & {:keys [table partitions] :as m
-              :or {table "tmp"}}]
+              :or {table "schema-tmp"}}]
   (apply setup-temporary-view url table (apply concat m))
-  (-> (.getOrCreate (SparkSession/builder))
-      (.sql sql)
-      ((fn [df]
-         (if partitions
-           (.repartition df partitions)
-           df)))))
+  (cond-> (.getOrCreate (SparkSession/builder))
+    true (.sql sql)
+    partitions (.repartition partitions)))

 (defn schema-from-url
   "Return a schema as a map from a parquet table at **url**.


fix errors in QP for Postgres timestamp fields

--- src/metabase/driver/query_processor.clj
+++ src/metabase/driver/query_processor.clj
@@ -428,9 +428,11 @@
                      (= col-kw :count)                       {:base_type    :IntegerField
                                                               :special_type :number}
                      ;; Otherwise something went wrong !
-                     :else                                   (throw (Exception. (format "Annotation failed: don't know what to do with Field '%s'.\nExpected these Fields:\n%s"
-                                                                                col-kw
-                                                                                (u/pprint-to-str field-kw->field))))))))
+                     :else                                   (do (log/error (u/format-color 'red "Annotation failed: don't know what to do with Field '%s'.\nExpected these Fields:\n%s"
+                                                                                col-kw
+                                                                                (u/pprint-to-str field-kw->field)))
+                                                                 {:base_type    :UnknownField
+                                                                  :special_type nil})))))
          ;; Add FK info the the resulting Fields
          add-fields-extra-info)))


[Issue #117] Quoted fact inappropriately being given :position k/v pair

--- test/midje/t_sweet.clj
+++ test/midje/t_sweet.clj
@@ -320,3 +320,5 @@
     (a) =streams=> [(throw (Exception.))]))

+(future-fact "Issue #117 - quoted facts not being ignore as we'd like"
+  '(fact foo => bar) => '(fact foo => bar))


Fixed bug in AB test

Fixed bug in AB test

--- src/webapp/client/components/usermain.cljs
+++ src/webapp/client/components/usermain.cljs
@@ -53,12 +53,16 @@

             (= (-> app :ui :tab) "browser")
-            (if (= (-> app :ui :graph-ab-test) "text")
-              (dom/div {} "Text")
-              (om/build  graph
-                         {
-                          :data    (:data    app)
-                          }))
+            (cond
+
+             (= (-> app :ui :graph-ab-test) "text")
+             (dom/div {} "Text")
+
+             (= (-> app :ui :graph-ab-test) "SVG")
+             (om/build  graph
+                        {
+                         :data    (:data    app)
+                         }))

             )


Revert "(PDB-3053) Create unique index on certnames.latest_report_id"

--- src/puppetlabs/puppetdb/scf/migrate.clj
+++ src/puppetlabs/puppetdb/scf/migrate.clj
@@ -1036,12 +1036,6 @@
   []
   (jdbc/do-commands
     "CREATE INDEX idx_certnames_latest_report_id on certnames(latest_report_id)"))
-
-(defn index-certnames-unique-latest-report-id
-  []
-  (jdbc/do-commands
-    "DROP INDEX IF EXISTS idx_certnames_latest_report_id"
-    "CREATE UNIQUE INDEX idx_certnames_latest_report_id on certnames(latest_report_id)"))

 (defn add-producer-to-reports-catalogs-and-factsets
   []
@@ -1204,8 +1198,8 @@
    50 remove-historical-catalogs
    51 fact-values-value-to-jsonb
    52 resource-params-cache-parameters-to-jsonb
-   53 add-corrective-change-index
-   54 index-certnames-unique-latest-report-id})
+   53 add-corrective-change-index})
+

 (def desired-schema-version (apply max (keys migrations)))


reintroducing deprecated function for legacy use

--- sidecar/src/figwheel_sidecar/repl.clj
+++ sidecar/src/figwheel_sidecar/repl.clj
@@ -164,3 +164,6 @@
                     :default)]
      (start-cljs-repl protocol figwheel-repl-env repl-opts))))

+;; deprecated
+(defn get-project-cljs-builds []
+  (:all-builds (config/fetch-config)))


Use p/extract instead of direct attr access on validation ns.

--- src/cats/applicative/validation.cljc
+++ src/cats/applicative/validation.cljc
@@ -154,7 +154,7 @@
     p/Functor
     (fmap [_ f s]
       (if (ok? s)
-        (ok (f (.-v s)))
+        (ok (f (p/extract s)))
         s))

     p/Foldable


fix plugin load

fix plugin load

--- src/clojure/zensols/cisql/plugin.clj
+++ src/clojure/zensols/cisql/plugin.clj
@@ -56,7 +56,7 @@

 (defn load-plugins [path]
   (if (.isFile path)
-    [(load-plugin (.getAbsolutePath path))]
+    (load-plugin (.getAbsolutePath path))
     (do (log/infof "scanning directory %s for plugins" path)
         (->> (file-seq (io/file path))
              (filter #(.isFile %))


Ideas

Ideas

--- src/clj/algorithms_clj/derivative.clj
+++ src/clj/algorithms_clj/derivative.clj
@@ -14,6 +14,8 @@
     ))

 ;; ---------------------------------------------------------------
+
+;; TODO - Represent the data with keyword? At least translate it (offer helpers)

 (defn prod?
   [expr]


Fix layout on montior-enter / exit docstrings

--- src/clj/clojuredocs/search/static.clj
+++ src/clj/clojuredocs/search/static.clj
@@ -109,10 +109,12 @@
 Clojure. See http://clojure.org/special_forms for more information."}
         {:name 'monitor-enter
          :ns "clojure.core"
-         :doc "A synchronization primitive that should be avoided in user code. Use the locking macro. See http://clojure.org/special_forms for more information."}
+         :doc "A synchronization primitive that should be avoided in user code. Use the
+locking macro. See http://clojure.org/special_forms for more information."}
         {:name 'monitor-exit
          :ns "clojure.core"
-         :doc "A synchronization primitive that should be avoided in user code. Use the locking macro. See http://clojure.org/special_forms for more information."}]
+         :doc "A synchronization primitive that should be avoided in user code. Use the
+locking macro. See http://clojure.org/special_forms for more information."}]
        (map #(assoc % :type "special-form"))))

 (def concept-pages