Add `!` suffix to `add-module-lesson-group` function

Due to it causing side effects

Signed-off-by: Pang Yan Han <22594c345857f664c61cd411f607c4d40a9d4af9@gmail.com>

--- src/cljs/cljs_nusmods/timetable.cljs
+++ src/cljs/cljs_nusmods/timetable.cljs
@@ -591,7 +591,7 @@
   Lessons-Created-By-Draggable nil)

 ; Forward declaration
-(declare add-module-lesson-group)
+(declare add-module-lesson-group!)
 (declare timetable-prune-empty-rows)
 (declare add-missing-td-elements-replacing-lesson)
 (declare remove-lesson-group-html)
@@ -626,9 +626,9 @@
           (doall
             (flatten
               (map (fn [unselectedLessonGroup]
-                     (add-module-lesson-group moduleCode lessonType
-                                              unselectedLessonGroup
-                                              bgColorCssClass false))
+                     (add-module-lesson-group! moduleCode lessonType
+                                               unselectedLessonGroup
+                                               bgColorCssClass false))
                    unselectedLessonGroups)))]
       (set! Lessons-Created-By-Draggable augmentedTTLessonInfoSeq))))

@@ -685,8 +685,8 @@
             (update-ModulesSelected-for-affected-days affectedDaysSet)

             ; add the newly selected lesson group
-            (add-module-lesson-group moduleCode lessonType destLessonGroup
-                                     bgColorCssClass true)
+            (add-module-lesson-group! moduleCode lessonType destLessonGroup
+                                      bgColorCssClass true)

             (update-document-location-hash-with-changed-lesson-group!
               moduleCode lessonType destLessonGroup))))))
@@ -738,7 +738,7 @@
                           LESSON-GROUP-CHANGE-KEY
                           (:lessonGroup augModuleSelectedLessonInfo)))))))))

-(defn- add-module-lesson-group
+(defn- add-module-lesson-group!
   "Adds a lesson group of a module to the timetable.

    The `isActuallySelected?` param is used to indicate if the current lesson
@@ -825,11 +825,11 @@
                     lessonsMap)]

         (doseq [moduleInfo newModInfoSeq]
-          (add-module-lesson-group (:moduleCode moduleInfo)
-                                   (:lessonType moduleInfo)
-                                   (:lessonGroup moduleInfo)
-                                   bgColorCssClass
-                                   true))
+          (add-module-lesson-group! (:moduleCode moduleInfo)
+                                    (:lessonType moduleInfo)
+                                    (:lessonGroup moduleInfo)
+                                    bgColorCssClass
+                                    true))

         ; Update URL hash with newly added module
         (update-document-location-hash-with-new-module!
@@ -982,11 +982,11 @@
     (doseq [modInfo moduleInfoFinal]
       (let [moduleCode      (:moduleCode modInfo)
             bgColorCssClass (get moduleToColorsMap moduleCode)]
-        (add-module-lesson-group moduleCode
-                                 (:lessonType modInfo)
-                                 (:lessonGroup modInfo)
-                                 bgColorCssClass
-                                 true)))
+        (add-module-lesson-group! moduleCode
+                                  (:lessonType modInfo)
+                                  (:lessonGroup modInfo)
+                                  bgColorCssClass
+                                  true)))

     ; Update url hash
     (set-document-location-hash-based-on-modules-order!)))


conference list is now home | fs / sg | #4

--- src/cljs/conference_rating/core.cljs
+++ src/cljs/conference_rating/core.cljs
@@ -22,9 +22,6 @@
 (secretary/set-config! :prefix "#")

 (secretary/defroute "/" []
-  (session/put! :current-page #'home-page))
-
-(secretary/defroute "/conferences" []
                     (conference/load-conferences)
                     (session/put! :current-page #'conference/conferences-page))


Query tweaking

Query tweaking

--- src/cljs/gointermod/utils/comms.cljs
+++ src/cljs/gointermod/utils/comms.cljs
@@ -11,10 +11,11 @@
 (clj->js service)))

 (defn make-base-query [identifier organism evidence-codes]
-  (str "<query model=\"genomic\" view=\"Gene.id Gene.symbol Gene.secondaryIdentifier Gene.primaryIdentifier Gene.organism.shortName Gene.organism.taxonId Gene.homologues.homologue.id Gene.homologues.homologue.primaryIdentifier Gene.homologues.homologue.secondaryIdentifier Gene.homologues.homologue.symbol Gene.homologues.homologue.organism.shortName Gene.homologues.homologue.organism.taxonId Gene.homologues.dataSets.name Gene.homologues.dataSets.url Gene.goAnnotation.evidence.code.code Gene.goAnnotation.evidence.publications.pubMedId Gene.goAnnotation.evidence.publications.title Gene.goAnnotation.ontologyTerm.identifier Gene.goAnnotation.ontologyTerm.name Gene.goAnnotation.ontologyTerm.namespace\" sortOrder=\"Gene.symbol ASC\" constraintLogic=\"B and C and A and E\" name=\"intermod_go\" >
+  (str "<query model=\"genomic\" view=\"Gene.id Gene.symbol Gene.secondaryIdentifier Gene.primaryIdentifier Gene.organism.shortName Gene.organism.taxonId Gene.homologues.homologue.id Gene.homologues.homologue.primaryIdentifier Gene.homologues.homologue.secondaryIdentifier Gene.homologues.homologue.symbol Gene.homologues.homologue.organism.shortName Gene.homologues.homologue.organism.taxonId Gene.homologues.dataSets.name Gene.homologues.dataSets.url Gene.goAnnotation.evidence.code.code Gene.goAnnotation.evidence.publications.pubMedId Gene.goAnnotation.evidence.publications.title Gene.goAnnotation.ontologyTerm.identifier Gene.goAnnotation.ontologyTerm.name Gene.goAnnotation.ontologyTerm.namespace\" sortOrder=\"Gene.symbol ASC\" constraintLogic=\"A and B and C and D and E\" name=\"intermod_go\" >
     <constraint path=\"Gene.goAnnotation.qualifier\" op=\"IS NULL\" code=\"B\" />
     <constraint path=\"Gene.goAnnotation.ontologyTerm.obsolete\" op=\"=\" value=\"false\" code=\"C\" />
-    <constraint path=\"Gene.homologues.homologue\" code=\"A\" op=\"LOOKUP\" value=\"" identifier "\" extraValue=\"" (utils/get-abbrev organism) "\"/>
+    <constraint path=\"Gene.homologues.homologue\" code=\"A\" op=\"LOOKUP\" value=\"" identifier "\" extraValue=\"H. sapiens\"/>
+    <constraint path=\"Gene.organism.shortName\" code=\"D\" op=\"=\" value=\"" (utils/get-abbrev organism) "\"/>
     <constraint path=\"Gene.goAnnotation.evidence.code.code\" op=\"ONE OF\" code=\"E\">" evidence-codes "</constraint>
 </query>"))


Add productions with POST

Add productions with POST

--- src/cljs/mdr2/productions/vubis.cljs
+++ src/cljs/mdr2/productions/vubis.cljs
@@ -52,7 +52,7 @@
       {:db (notifications/set-button-state db id :vubis)
        :http-xhrio
        (as-transit
-        {:method          :put
+        {:method          :post
          :headers         (auth/auth-header db)
          :uri             "/api/productions"
          :params          cleaned


Fix badge upload: accept also svg-files

Fix badge upload: accept also svg-files

--- src/cljs/salava/badge/ui/upload.cljs
+++ src/cljs/salava/badge/ui/upload.cljs
@@ -65,7 +65,7 @@
     [:input {:type "file"
              :name "file"
              :on-change #(send-file)
-             :accept "image/png"}]]])
+             :accept "image/png, image/svg+xml"}]]])

 (defn init-data []
       (ajax/GET "/obpv1/user/test" {}))


relaxing validation of passed keys: by allowing a key options to be passed in it's now possible to specify cluster-wide variables

--- src/control/core.clj
+++ src/control/core.clj
@@ -155,7 +155,7 @@
                           ssh-options
                           [(ssh-client host user) cmd]))))

-(defn rsync
+(defn rsync
   "Rsync local files to remote machine's files,for example:
      (deftask :deploy \"scp files to remote machines\" []
     (rsync \"src/\" \":/home/login\"))
@@ -348,8 +348,8 @@
                    debug (:debug cluster)
                    log (or (:log cluster) true)
                    clients (if (nil? cluster) (create-clients (first args)) clients)]
-               (check-valid-options cluster :user :clients :addresses :parallel :includes :debug :log :ssh-options :scp-options :rsync-options :name)
-               ;;if task is nil,exit
+               (check-valid-options cluster :user :clients :addresses :parallel :includes :debug :log :ssh-options :scp-options :rsync-options :name :options)
+               ;;if task is nil,exit
                (when-exit (nil? task)
                           (str "No task named " (name task-name)))
                (when-exit (and (empty? addresses)
@@ -387,4 +387,3 @@

 (defn begin []
   (do-begin *command-line-args*))
-


Reimplement pbkdf2 hasher for using bouncycastle pbkdf2 algorithm implementation.

--- src/clojure/buddy/hashers/pbkdf2.clj
+++ src/clojure/buddy/hashers/pbkdf2.clj
@@ -15,13 +15,23 @@
 (ns buddy.hashers.pbkdf2
   (:require [buddy.core.codecs :refer :all]
             [buddy.core.util :refer :all]
-            [clojure.string :refer [split]]))
+            [clojure.string :refer [split]])
+  (:import javax.crypto.spec.PBEKeySpec
+           javax.crypto.SecretKeyFactory))
+
+(java.security.Security/addProvider
+ (org.bouncycastle.jce.provider.BouncyCastleProvider.))

 (defn make-pbkdf2
   [password salt iterations]
-  (let [bpasswd (->byte-array password)
-        bsalt   (->byte-array salt)]
-    (-> (buddy.impl.pbkdf2.Pbkdf2/deriveKey "HmacSHA256" bpasswd bsalt iterations 32)
+  (let [skf   (SecretKeyFactory/getInstance "PBKDF2WithHmacSHA1" "BC")
+        dkl   256
+        spec  (PBEKeySpec. (.toCharArray password)
+                           (->byte-array salt)
+                           iterations
+                           dkl)
+        key   (.generateSecret skf spec)]
+    (-> (.getEncoded key)
         (bytes->hex))))

 (defn make-password


Use transparent instead of black background

--- src/clojure/warreq/kea/calc/util.clj
+++ src/clojure/warreq/kea/calc/util.clj
@@ -21,7 +21,7 @@
     [:button {:layout-width 0
               :layout-height :fill
               :layout-weight 1
-              :background-color Color/BLACK
+              :background-color Color/TRANSPARENT
               :typeface Typeface/MONOSPACE
               :text (str value)
               :on-click (fn [_] (vibrate! d) (handler value))}]))
@@ -72,7 +72,7 @@
    :layout-width :fill
    :layout-height 0
    :layout-weight 1
-   :background-color Color/BLACK})
+   :background-color Color/TRANSPARENT})

 (defelement :edit-text
   :classname android.widget.EditText


Thought I had fspec sorted out for async loop

At least for the reader/writer functions.

But it's having issues resolving updated specs from cljeromq.

--- src/com/frereth/common/async_zmq.clj
+++ src/com/frereth/common/async_zmq.clj
@@ -26,22 +26,17 @@

 (s/def ::ex-chan :com.frereth.common.async-component/async-channel)
 (s/def ::ex-sock :com.frereth.common.zmq-socket/socket-description)
-(s/def ::external-reader #_(s/fspec :args (s/cat :sock :cljeromq.common/socket)
-                                    :ret :cljeromq.common/byte-array-seq)
-  any?)
-(s/def ::external-writer #_(s/fspec :args (s/cat :sock :cljeromq.common/socket
-                                                 :frames :cljeromq.common/byte-array-seq))
-  any?)
+;; run-async-loop! can't resolve testable-read-socket.
+;; What gives?
+;; Note that the problem isn't from the alias.
+;; It started with the fully-qualified name.
+;; Theory: I haven't restarted this REPL in quite a while.
+;; Lots have changed in cljeromq since then.
+(s/def ::external-reader (s/fspec :args (s/cat :sock :mq-cmn/testable-read-socket)
+                                  :ret bytes?))
+(s/def ::external-writer (s/fspec :args (s/cat :sock :mq-cmn/testable-write-socket
+                                               :frames :mq-cmn/byte-array-seq)))
 (s/def ::in-chan :com.frereth.common.async-component/async-channel)
-
-(comment
-  ;; This looks like a duplicate of ::interface, though the name is more
-  ;; meaningful
-  (s/def ::event-pair-interface (s/keys :req-un [::ex-chan
-                                                 ::ex-sock
-                                                 ::external-reader
-                                                 ::external-writer
-                                                 ::in-chan])))

 (s/def ::interface (s/keys :req-un [::ex-sock
                                     ::external-reader


Corrected the tapping of the multichan

Corrected the tapping of the multichan

--- src/ctia/logging.clj
+++ src/ctia/logging.clj
@@ -1,6 +1,6 @@
 (ns ctia.logging
   (:require [clojure.tools.logging :as log]
-            [clojure.core.async :as a :refer [go <!]]
+            [clojure.core.async :as a :refer [go <! chan]]
             [ctia.events :as e]
             [schema.core :as s])
   (:import [clojure.core.asyc.impl.protocols Channel]))
@@ -8,6 +8,8 @@
 (s/defn log-channel :- Channel
   "Logging an event channel indefinitely. Returns the channel for a go loop that never ends."
   [{m :mult :as ev} :- e/EventChannel]
-  (go (loop [ev (<! m)]
-        (log/info "event: " ev)
-        (recur (<! m)))))
+  (let [events (chan)]
+    (tap m events)
+    (go (loop [ev (<! events)]
+          (log/info "event: " ev)
+          (recur (<! events))))))


fixed a whoopsie

fixed a whoopsie

--- src/dartbot/core.clj
+++ src/dartbot/core.clj
@@ -5,7 +5,11 @@
             [cheshire.core :refer :all]))

 (defn parse-int [string]
-  (read-string (re-find #"\d+" string))
+  (cond
+    (number? string) string
+    (nil? string) 0
+    :else (read-string (re-find #"\d+" string))
+    )
   )

 (defn parse-message [string]
@@ -80,7 +84,7 @@

 (defn make-game [payload gid]
-  {gid {:timestamp (:timestamp payload)
+  {gid {:timestamp (parse-int (:timestamp payload))
         :currentplayer (first (:players payload))
         :currentthrows []
         :playerorder (:players payload)
@@ -293,10 +297,10 @@
   (ws/start response-handler)
   (println "Websocket up")
   (reset! world-atom (load-backup))
-  (loop [world (load-backup) line (read-line)]
+  (loop [ line (read-line)]
     (let [message (parse-message line)]
-      (if (valid? world message)
-        (recur (reset! world-atom (update-world world message)) (read-line))
-        (recur world (read-line))
+      (if (valid? @world-atom message)
+        (do (reset! world-atom (update-world @world-atom message)) (recur (read-line)))
+        (recur (read-line))
         )
       )))


Isolate two functiosn out of handle-playing

--- src/constraint/core.cljs
+++ src/constraint/core.cljs
@@ -98,11 +98,14 @@
     `(~vertex-id ~@vertex-data ~incoming-flow)))

+(defn print-state [world-state]
+  (let [textarea (dommy.core/sel1 :#data)
+        newlined-state (string/replace (str world-state) #", " ",\n")]
+    (dommy/set-text! textarea newlined-state)))
+
+
 (defn draw-world [world-state]
-  (dommy/set-text! (dommy.core/sel1 :#data)
-                              (string/replace (str world-state)
-                                              #", "
-                                              ", \n"))
+  (print-state world-state)
   (dommy/replace! (dommy.core/sel1 :#forsvg)
                   (crate/html [:div#forsvg
                                (make-svg (map-size world-state)
@@ -117,15 +120,20 @@
     [to from color]
     edge))

+(defn toggle-editing [world-state]
+  (update-in world-state [:editing?] not))
+
+(defn flip-update-edge [clicked-what world-state]
+  (let [clicked-edge [:edges clicked-what]
+        flip-it (partial flip-edge world-state)]
+    (update-in world-state clicked-edge flip-it)))

 (defn handle-playing [clicked-what world-state]
   (let [clicked-edit? (re-matches #"edit" clicked-what)
         clicked-edge? (re-matches #"edge.*" clicked-what)]
     (cond
-      clicked-edit? (update-in world-state [:editing?] not)
-      clicked-edge? (update-in world-state
-                               [:edges clicked-what]
-                               (partial flip-edge world-state))
+      clicked-edit? (toggle-editing world-state)
+      clicked-edge? (flip-update-edge clicked-what world-state)
       :else world-state)))


fetch an instance for tests

fetch an instance for tests

--- src/er_cassandra/model/util/test.clj
+++ src/er_cassandra/model/util/test.clj
@@ -91,6 +91,11 @@
   ([entity record opts]
    @(m/select-upsert *model-session* entity record (ts/past-timestamp-opt opts))))

+(defn fetch-instance
+  ([entity key key-value] (fetch-instance entity key key-value {}))
+  ([entity key key-value opts]
+   @(m/select-one *model-session* entity key key-value opts)))
+
 (defn record-stream
   ([table-name] (record-stream table-name {}))
   ([table-name opts]


paginate batches for measurements posts

paginate batches for measurements posts

--- src/kixi/hecuba/api/measurements.clj
+++ src/kixi/hecuba/api/measurements.clj
@@ -145,7 +145,7 @@
                                                (v/validate sensor))
                                           measurements)
               {:keys [min-date max-date]} (m/min-max-dates validated-measurements)]
-          (db/execute session (m/prepare-batch validated-measurements))
+          (m/insert-measurements store validated-measurements 100)
           (v/update-sensor-metadata store sensor min-date max-date)
           {:response {:status 202 :body "Accepted"}})
         {:response {:status 400 :body "Provide valid device_id and type."}}))))


Make time-range inclusive.

Make time-range inclusive.

--- src/kixi/hecuba/api/measurements.clj
+++ src/kixi/hecuba/api/measurements.clj
@@ -40,10 +40,8 @@
   [start end step]
   (let [start-date (t/first-day-of-the-month start)
         end-date   (t/last-day-of-the-month end)
-        inf-range  (tp/periodic-seq start step)
-        below-end? (fn [t] (t/within? (t/interval start-date end-date)
-                                         t))]
-    (take-while below-end? inf-range)))
+        in-range-inclusive? (complement (fn [t] (t/after? t end-date)))]
+    (take-while in-range-inclusive? (tp/periodic-seq start-date step))))

 (defn retrieve-measurements
   "Iterate over a sequence of months and concatanate measurements retrieved from the database."


Jenkins reply is send only if configured

--- src/emender_jenkins/jenkins_api.clj
+++ src/emender_jenkins/jenkins_api.clj
@@ -83,11 +83,15 @@
                  nil))))

 (defn ok-response-structure
-    [job-name command jenkins-response]
-    {:status   "ok"
-     :job-name job-name
-     :command  command
-     :jenkins-response jenkins-response})
+    [job-name command include-jenkins-reply? jenkins-response]
+    (if include-jenkins-reply?
+        {:status   "ok"
+         :job-name job-name
+         :command  command
+         :jenkins-response jenkins-response}
+        {:status   "ok"
+         :job-name job-name
+         :command  command}))

 (defn error-response-structure
     [job-name command exception]
@@ -98,10 +102,10 @@
     })

 (defn job-related-command
-    [jenkins-url jenkins-auth job-name command]
+    [jenkins-url jenkins-auth include-jenkins-reply? job-name command]
     (try
         (let [response (post-command jenkins-url jenkins-auth job-name command)]
-            (ok-response-structure job-name command response))
+            (ok-response-structure job-name command include-jenkins-reply? response))
         (catch Exception e
             (.printStackTrace e)
             (error-response-structure job-name command e))))
@@ -114,19 +118,19 @@

 (defn start-job
     [jenkins-url jenkins-auth include-jenkins-reply? job-name]
-    (job-related-command jenkins-url jenkins-auth job-name "build"))
+    (job-related-command jenkins-url jenkins-auth include-jenkins-reply? job-name "build"))

 (defn enable-job
     [jenkins-url jenkins-auth include-jenkins-reply? job-name]
-    (job-related-command jenkins-url jenkins-auth job-name "enable"))
+    (job-related-command jenkins-url jenkins-auth include-jenkins-reply? job-name "enable"))

 (defn disable-job
     [jenkins-url jenkins-auth include-jenkins-reply? job-name]
-    (job-related-command jenkins-url jenkins-auth job-name "disable"))
+    (job-related-command jenkins-url jenkins-auth include-jenkins-reply? job-name "disable"))

 (defn delete-job
     [jenkins-url jenkins-auth include-jenkins-reply? job-name]
-    (job-related-command jenkins-url jenkins-auth job-name "doDelete"))
+    (job-related-command jenkins-url jenkins-auth include-jenkins-reply? job-name "doDelete"))

 (defn log-operation
     [job-name git-repo branch operation]
@@ -146,7 +150,7 @@
         :trust-store-pass "changeit"}))

 (defn create-job
-    [jenkins-url jenkins-auth job-name include-jenkins-reply? git-repo branch]
+    [jenkins-url jenkins-auth include-jenkins-reply? job-name git-repo branch]
     (log-operation job-name git-repo branch "create")
     (let [template (slurp "data/template.xml")
           config   (update-template template git-repo branch)
@@ -154,7 +158,7 @@
           (println "URL to use: " url)
           (try
               (->> (send-configuration-xml-to-jenkins url config)
-                   (ok-response-structure job-name "create"))
+                   (ok-response-structure job-name "create" include-jenkins-reply?))
               (catch Exception e
                   (.printStackTrace e)
                   (error-response-structure job-name "create" e)))))
@@ -168,7 +172,7 @@
           (println "URL to use: " url)
           (try
               (->> (send-configuration-xml-to-jenkins url config)
-                   (ok-response-structure job-name "update"))
+                   (ok-response-structure job-name "update" include-jenkins-reply?))
               (catch Exception e
                   (.printStackTrace e)
                   (error-response-structure job-name "update" e)))))


don't be quite so verbose in our data migration.

--- src/metabase/db/migrations.clj
+++ src/metabase/db/migrations.clj
@@ -188,33 +188,34 @@
 ;; NOTE: we only handle active Tables/Fields and we skip any FK relationships (they can safely populate later)
 (defmigration create-raw-tables
   (when (= 0 (:cnt (first (k/select RawTable (k/aggregate (count :*) :cnt)))))
-    (doseq [{database-id :id, :keys [name engine]} (db/sel :many Database)]
-      (when-let [tables (not-empty (db/sel :many Table :db_id database-id, :active true))]
-        (log/info (format "Migrating schema information for %s database '%s'" engine name))
-        (doseq [{table-id :id, table-schema :schema, table-name :name} tables]
-          ;; create the RawTable
-          (let [{raw-table-id :id} (db/ins RawTable
-                                     :database_id  database-id
-                                     :schema       table-schema
-                                     :name         table-name
-                                     :details      {}
-                                     :active       true)]
-            ;; update the Table and link it with the RawTable
-            (k/update Table
-              (k/set-fields {:raw_table_id raw-table-id})
-              (k/where      {:id table-id}))
-            ;; migrate all Fields in the Table (skipping :dynamic-schema dbs)
-            (when-not (driver/driver-supports? (driver/engine->driver engine) :dynamic-schema)
-              (doseq [{field-id :id, column-name :name, :as field} (db/sel :many Field :table_id table-id, :visibility_type [not= "retired"])]
-                (let [{raw-column-id :id} (db/ins RawColumn
-                                            :raw_table_id  raw-table-id
-                                            :name          column-name
-                                            :base_type     (:base_type field)
-                                            :is_pk         (= :id (:special_type field))
-                                            :details       {}
-                                            :active        true)]
-                  ;; update the Field and link it with the RawColumn
-                  (k/update Field
-                    (k/set-fields {:raw_column_id raw-column-id
-                                   :last_analyzed (u/new-sql-timestamp)})
-                    (k/where      {:id field-id})))))))))))
+    (binding [db/*sel-disable-logging* true]
+      (doseq [{database-id :id, :keys [name engine]} (db/sel :many Database)]
+        (when-let [tables (not-empty (db/sel :many Table :db_id database-id, :active true))]
+          (log/info (format "Migrating raw schema information for %s database '%s'" engine name))
+          (doseq [{table-id :id, table-schema :schema, table-name :name} tables]
+            ;; create the RawTable
+            (let [{raw-table-id :id} (db/ins RawTable
+                                       :database_id  database-id
+                                       :schema       table-schema
+                                       :name         table-name
+                                       :details      {}
+                                       :active       true)]
+              ;; update the Table and link it with the RawTable
+              (k/update Table
+                (k/set-fields {:raw_table_id raw-table-id})
+                (k/where      {:id table-id}))
+              ;; migrate all Fields in the Table (skipping :dynamic-schema dbs)
+              (when-not (driver/driver-supports? (driver/engine->driver engine) :dynamic-schema)
+                (doseq [{field-id :id, column-name :name, :as field} (db/sel :many Field :table_id table-id, :visibility_type [not= "retired"])]
+                  (let [{raw-column-id :id} (db/ins RawColumn
+                                              :raw_table_id  raw-table-id
+                                              :name          column-name
+                                              :base_type     (:base_type field)
+                                              :is_pk         (= :id (:special_type field))
+                                              :details       {}
+                                              :active        true)]
+                    ;; update the Field and link it with the RawColumn
+                    (k/update Field
+                      (k/set-fields {:raw_column_id raw-column-id
+                                     :last_analyzed (u/new-sql-timestamp)})
+                      (k/where      {:id field-id}))))))))))))


Increase headroom for retry-ch. My intuition says that it should be set to max-pending setting.

--- src/onyx/plugin/core_async.clj
+++ src/onyx/plugin/core_async.clj
@@ -9,7 +9,7 @@
   (assert (:core.async/chan event) ":core.async/chan not found - add it using a :before-task-start lifecycle")
   {:core.async/pending-messages (atom {})
    :core.async/drained? (atom false)
-   :core.async/retry-ch (chan 1000)})
+   :core.async/retry-ch (chan 10000)})

 (defn inject-writer
   [event lifecycle]


Updated system integration tests so that the application ports are configurable.

--- test/cmr/system_int_test/utils/url_helper.clj
+++ test/cmr/system_int_test/utils/url_helper.clj
@@ -1,34 +1,58 @@
 (ns ^{:doc "helper to provide the urls to various service endpoints"}
   cmr.system-int-test.utils.url-helper
-  (:require [ring.util.codec :as codec]))
+  (:require [ring.util.codec :as codec]
+            [clojure.string :as str]))

-(def elastic_root "http://localhost:9210")
+(defn config-value
+  "Retrieves a configuration value which can be set as an environment variable on the command line
+  or default to a value"
+  [config-name default-value]
+  (let [env-name (str "CMR_" (-> config-name
+                                 name
+                                 (str/replace "-" "_")
+                                 str/upper-case))]
+    (or (System/getenv env-name)
+        default-value)))

-(def create-provider-url "http://localhost:3001/providers")
+(def elastic-port (config-value :elastic-port 9210))
+
+(def metadata-db-port (config-value :metadata-db-port 3001))
+
+(def ingest-port (config-value :ingest-port 3002))
+
+(def indexer-port (config-value :indexer-port 3004))
+
+(def search-port (config-value :search-port 3003))
+
+(def elastic_root (format "http://localhost:%s" elastic-port))
+
+(def create-provider-url (format "http://localhost:%s/providers" metadata-db-port))

 (defn delete-provider-url
   [provider-id]
-  (format "http://localhost:3001/providers/%s" provider-id))
+  (format "http://localhost:%s/providers/%s" metadata-db-port provider-id))

 (defn collection-ingest-url
   [provider-id native-id]
-  (format "http://localhost:3002/providers/%s/collections/%s"
+  (format "http://localhost:%s/providers/%s/collections/%s"
+          ingest-port
           provider-id
           native-id))

 (defn collection-search-url
   [params]
-  (str "http://localhost:3003/collections?" (codec/form-encode params)))
+  (format "http://localhost:%s/collections?%s" search-port (codec/form-encode params)))

 (defn granule-ingest-url
   [provider-id native-id]
-  (format "http://localhost:3002/providers/%s/granules/%s"
+  (format "http://localhost:%s/providers/%s/granules/%s"
+          ingest-port
           provider-id
           native-id))

 (defn granule-search-url
   [params]
-  (str "http://localhost:3003/granules?" (codec/form-encode params)))
+  (format "http://localhost:%s/granules?%s" search-port (codec/form-encode params)))

 (defn elastic-flush-url
   []
@@ -37,22 +61,25 @@
 (defn mdb-concept-url
   "URL to concept in mdb."
   [concept-id revision-id]
-  (format "http://localhost:3001/concepts/%s/%s" concept-id revision-id))
+  (format "http://localhost:%s/concepts/%s/%s" metadata-db-port concept-id revision-id))

 (defn mdb-reset-url
   "Force delete all concepts from mdb."
   []
-  (format "http://localhost:3001/reset"))
+  (format "http://localhost:%s/reset" metadata-db-port))

 (defn indexer-reset-url
   "Delete and re-create indexes in elastic. Only development team to use this functionality."
   []
-  (format "http://localhost:3004/reset"))
+  (format "http://localhost:%s/reset" indexer-port))

 ;; discard this once oracle impl is in place
 (defn mdb-concept-coll-id-url
   "URL to access a collection concept in mdb with given prov and native id."
   [provider-id native-id]
-  (format "http://localhost:3001/concept-id/collection/%s/%s" provider-id native-id))
+  (format "http://localhost:%s/concept-id/collection/%s/%s"
+          metadata-db-port
+          provider-id
+          native-id))


whitespace

whitespace

--- src/pc/delay.clj
+++ src/pc/delay.clj
@@ -12,7 +12,7 @@
   (.schedule thread-pool f delay-ms TimeUnit/MILLISECONDS))

 (defn repeat-fn [thread-pool delay-ms f]
-  (.scheduleAtFixedRate thread-pool f delay-ms delay-ms TimeUnit/MILLISECONDS ))
+  (.scheduleAtFixedRate thread-pool f delay-ms delay-ms TimeUnit/MILLISECONDS))

 (defn shutdown-pool! [pool]
   (.shutdown pool))


Bus: Add `subscribe-all' to receive *all* messages

--- src/pepa/bus.clj
+++ src/pepa/bus.clj
@@ -22,20 +22,32 @@
   ([bus topic]
    (notify! bus topic {})))

-(defrecord Bus [input output]
+(defn subscribe-all
+  "Returns a channel receiving all messages sent over the bus."
+  [bus & [buf]]
+  (let [ch (async/chan buf)]
+    (async/tap (:mult bus) ch)))
+
+(defrecord Bus [input mult output]
   component/Lifecycle
   (start [component]
     (println ";; Starting bus")
     (let [input (async/chan)
-          output (async/pub input ::topic)]
+          mult (async/mult input)
+          output-tap (async/chan)
+          output (async/pub output-tap ::topic)]
+      (async/tap mult output-tap)
       (assoc component
              :input input
+             :mult mult
              :output output)))

   (stop [component]
     (println ";; Stopping bus")
+    (async/close! (:input component))
     (assoc component
            :input nil
+           :mult nil
            :output nil)))

 (defn make-component []


Allow connections to the REPL from remote machines. Fixes #72.

--- src/app/cljs/one/sample/core.cljs
+++ src/app/cljs/one/sample/core.cljs
@@ -1,10 +1,18 @@
 (ns ^{:doc "Contains the entry point for the ClojureScript sample application."}
   one.sample.core
-  (:require [clojure.browser.repl :as repl]
+  (:require [goog.uri.utils :as uri]
+            [clojure.browser.repl :as repl]
             [one.dispatch :as dispatch]
             [one.sample.view :as view]))

 ;; **TODO:** Add marginalia comment to explain what `:export` is for.
+
+(defn- server
+  "Return a string which is the scheme and domain portion of the URL
+  for the server from which this code was served."
+  []
+  (let [location (.toString window.location ())]
+    (str (uri/getScheme location) "://" (uri/getDomain location))))

 (defn ^:export repl
   "Connects to a ClojureScript REPL running on localhost port 9000.
@@ -13,7 +21,7 @@
   browser for evaluation. This function should be called from a script
   in the development host HTML page."
   []
-  (repl/connect "http://localhost:9000/repl"))
+  (repl/connect (str (server) ":9000/repl")))

 (defn ^:export start
   "Start the application by firing a `:init` event which will cause the


Comment test code

Comment test code

--- src/atom_finder/location_dump.clj
+++ src/atom_finder/location_dump.clj
@@ -27,19 +27,13 @@
          )
     )
   )
-'(->> atom-finder.constants/big-root
-     find-all
-     (map #(update % :node write-node))
-     (map prn)
-     time
-     )

 (defn location-dump [filename]
   (map (partial merge {:file filename}) (->> filename parse-file find-all)))

 ;(->> "/Users/dgopstein/opt/src/gcc/contrib/paranoia.cc" location-dump (map prn))

-(->> gcc-path
+'(->> gcc-path
      (pmap-dir-files location-dump)
      (mapcat (partial map #(update % :node write-node)))
      (map #(merge %1 (if (:path %1) {:depth (count (:path %1))} {})))


don't add "s" after plural proper nouns

don't add "s" after plural proper nouns

--- src/babel/english/morphology.cljc
+++ src/babel/english/morphology.cljc
@@ -503,7 +503,8 @@
    (and (= (get-in word '(:agr :number)) :plur)
         (= (get-in word '(:cat)) :noun)
         (string? (get-in word '(:english)))
-        (not (= (get-in word [:pronoun]) true)))
+        (not (= (get-in word [:pronoun]) true))
+        (not (= (get-in word [:propernoun]) true)))
    (str (plural-en (get-in word '(:english)))
         (if (get-in word '(:note))
           (str (get-in word '(:note)))))
@@ -511,7 +512,8 @@
    (and (= (get-in word '(:agr :number)) :plur)
         (= (get-in word '(:cat)) :noun)
         (string? (get-in word '(:english :english)))
-        (not (= (get-in word [:pronoun]) true)))
+        (not (= (get-in word [:pronoun]) true))
+        (not (= (get-in word [:propernoun]) true)))
    (str (plural-en (get-in word '(:english :english)))
         (if (get-in word '(:english :note))
           (str (get-in word '(:english :note)))))


'tu' should not contract (e.g. "tu as" =/=> "t'as"

--- src/babel/francais/morphology.clj
+++ src/babel/francais/morphology.clj
@@ -29,10 +29,10 @@
         (and (not (nil? b))
              (let [a (get-string word)
                    b (get-string b)]
-               (and (re-find #"^(je|tu)$" a) ;;
+               (and (re-find #"^(je)$" a) ;;
                     (re-find #"^[aeéiou]" b))))
         (let [a (get-string word)]
-          (str (string/replace a #"^(j|t).*" (fn [[_ prefix]] (str prefix "'"))) (get-string b)))
+          (str (string/replace a #"^(j).*" (fn [[_ prefix]] (str prefix "'"))) (get-string b)))

         ;; (elle) la + est (amuseé) = (elle) l'est (amuseé)
         (and (not (nil? b))


components start/stop functions added

components start/stop functions added

--- src/clj/hellhound/system/core.clj
+++ src/clj/hellhound/system/core.clj
@@ -34,13 +34,33 @@
   [system component]
   ())

+
+(defn starting-context
+  [component]
+  {})
+
+(defn call-start
+  [component]
+  (when-not (started? component)
+    (start! component (starting-context component))))
+
+(defn component-dependencies
+  [system component]
+  (map #(get-component system %
+                       (dependencies component))))
+
 (defn start-component!
   [system component]
-  (let [dependencies (dependencies component)]
-    (map #(start-component)))
-  (start-dependencies systbem component)
-  (wire-component-io))
+  (let [components-map   (conj (component-dependencies system component)
+                               component)]

+    (update-system system
+                   :components
+                   (map call-start components-map))))
+
+
+(defn stop-component!
+  [system component])

 (defn start-system!
   [system]
@@ -59,6 +79,7 @@
   [system]
   (:components system))

+
 (extend-protocol protocols/System
   clojure.lang.PersistentArrayMap
   (start! [this]


listgen.clj output set to 'text'; csv2table commented out

--- src/clj/webapp/routes/listlpv.clj
+++ src/clj/webapp/routes/listlpv.clj
@@ -108,7 +108,7 @@
               reqvec (split (:body req) #"\n")
               header (first reqvec)
               lpvs (rest reqvec)
-              lpvtable (csv2table lpvs)
+              ;;lpvtable (csv2table lpvs)
               ]
           (log/info "sparql result status: " (:status req))
           [:div
@@ -116,7 +116,7 @@
            ;;[:p header]
            [:hr]
            ;;[:pre reqvec]
-           [:pre lpvtable]
+           ;;[:pre lpvtable]
           [:hr]
           [:h3#clickable "Query:"]
           [:pre query-sparql-pr]])


More helper functions

More helper functions

--- src/cljs/asciinema_player/vt.cljs
+++ src/cljs/asciinema_player/vt.cljs
@@ -104,6 +104,38 @@
 (defn switch-to-alternate-buffer [{:keys [width height char-attrs] :as vt}]
   (assoc vt :lines (empty-screen width height char-attrs)))

+(defn save-cursor [{{:keys [x y]} :cursor :keys [char-attrs origin-mode auto-wrap-mode] :as vt}]
+  (assoc vt :saved {:cursor {:x x :y y}
+                    :char-attrs char-attrs
+                    :origin-mode origin-mode
+                    :auto-wrap-mode auto-wrap-mode}))
+
+(defn restore-cursor [{{:keys [cursor char-attrs origin-mode auto-wrap-mode]} :saved :as vt}]
+  (-> vt
+      (assoc :char-attrs char-attrs
+             :origin-mode origin-mode
+             :auto-wrap-mode auto-wrap-mode)
+      (update-in [:cursor] merge cursor)))
+
+(defn set-mode [vt intermediate param]
+  (match [intermediate param]
+         [nil 4] (assoc vt :insert-mode true)
+         [0x3f 6] (-> vt (assoc :origin-mode true) move-cursor-to-home)
+         [0x3f 7] (assoc vt :auto-wrap-mode true)
+         [0x3f 25] (show-cursor vt)
+         [0x3f 1047] (switch-to-alternate-buffer vt)
+         [0x3f 1048] (save-cursor vt)
+         :else vt))
+
+(defn reset-mode [vt intermediate param]
+  (match [intermediate param]
+         [nil 4] (assoc vt :insert-mode false)
+         [0x3f 6] (-> vt (assoc :origin-mode false) move-cursor-to-home)
+         [0x3f 7] (assoc vt :auto-wrap-mode false)
+         [0x3f 25] (show-cursor vt false)
+         [0x3f 1048] (restore-cursor vt)
+         :else vt))
+
 ;; control functions

 (defn scroll-down [{:keys [width top-margin bottom-margin char-attrs] :as vt}]
@@ -159,22 +191,11 @@
 (defn execute-decaln [{:keys [width height] :as vt}]
   (assoc vt :lines (vec (repeat height (vec (repeat width [0x45 {}]))))))

-(defn execute-sc
-  "http://www.vt100.net/docs/vt510-rm/DECSC"
-  [{{:keys [x y]} :cursor :keys [char-attrs origin-mode auto-wrap-mode] :as vt}]
-  (assoc vt :saved {:cursor {:x x :y y}
-                    :char-attrs char-attrs
-                    :origin-mode origin-mode
-                    :auto-wrap-mode auto-wrap-mode}))
-
-(defn execute-rc
-  "http://www.vt100.net/docs/vt510-rm/DECRC"
-  [{{:keys [cursor char-attrs origin-mode auto-wrap-mode]} :saved :as vt}]
-  (-> vt
-      (assoc :char-attrs char-attrs
-             :origin-mode origin-mode
-             :auto-wrap-mode auto-wrap-mode)
-      (update-in [:cursor] merge cursor)))
+(defn execute-sc [vt]
+  (save-cursor vt))
+
+(defn execute-rc [vt]
+  (restore-cursor vt))

 (defn split-coll [elem coll]
   (loop [coll coll
@@ -385,28 +406,9 @@
       3 (update-in vt [:tabs] empty)
       vt)))

-(defn set-mode [vt intermediate param]
-  (match [intermediate param]
-         [nil 4] (assoc vt :insert-mode true)
-         [0x3f 6] (-> vt (assoc :origin-mode true) move-cursor-to-home)
-         [0x3f 7] (assoc vt :auto-wrap-mode true)
-         [0x3f 25] (show-cursor vt)
-         [0x3f 1047] (switch-to-alternate-buffer vt)
-         [0x3f 1048] (execute-sc vt)
-         :else vt))
-
 (defn execute-sm [vt]
   (let [intermediate (get-intermediate vt 0)]
     (reduce #(set-mode %1 intermediate %2) vt (get-params vt))))
-
-(defn reset-mode [vt intermediate param]
-  (match [intermediate param]
-         [nil 4] (assoc vt :insert-mode false)
-         [0x3f 6] (-> vt (assoc :origin-mode false) move-cursor-to-home)
-         [0x3f 7] (assoc vt :auto-wrap-mode false)
-         [0x3f 25] (show-cursor vt false)
-         [0x3f 1048] (execute-rc vt)
-         :else vt))

 (defn execute-rm [vt]
   (let [intermediate (get-intermediate vt 0)]


Payments renews token after use so user doesn't have to input info again.

--- src/cljs/elevent_client/core.cljs
+++ src/cljs/elevent_client/core.cljs
@@ -324,7 +324,7 @@
           :error-handler   #(add-message! :negative "Sign in failed")})))

 (defn sign-out! []
-  (swap! session dissoc :token :user :stripe-token)
+  (swap! session dissoc :token :user :stripe-token :payment-info)
   (refresh!)
   (set! js/window.location (home-route)))

@@ -667,8 +667,8 @@
                                   (format-of   :number   :format #"^[0-9]{16}$")
                                   (format-of   :cvc      :format #"^[0-9]{3}$")
                                   (format-of   :exp-date :format #"^[0-1][0-9]/20[1-9][0-9]$"))
+        editing? (atom false)
         stripe-error (atom nil)
-        stripe-success (atom nil)
         button-loading? (atom false)]
     (fn []
       (Stripe.setPublishableKey "pk_test_7ntI7D72loXtuO2F15gV0nR0")
@@ -681,13 +681,15 @@
               (prn response)
               (if response.error
                 (do
-                  (reset! stripe-error response.error.message)
-                  (reset! stripe-success nil))
-                (do
+                  (reset! stripe-error response.error.message))
+                (let [[month year] (clojure.string/split (:exp-date @form) #"/" 2)]
                   (reset! stripe-error nil)
-                  (reset! stripe-success "Success!")
+                  (reset! editing? false)
                   (swap! session assoc :stripe-token response.id)
-                  (swap! session assoc :cc-last      (subs (:number @form) 12)))))
+                  (swap! session assoc :payment-info (dissoc (assoc @form
+                                                               :exp-month (int month)
+                                                               :exp-year (int year))
+                                                             :exp-date)))))

             create-token
             (fn [e form]
@@ -706,18 +708,28 @@
                                        :exp-year (int year))
                                      :exp-date))
                     response-handler))))]
-        (if (nil? (:stripe-token @session))
+        #_(when (:payment-info @session)
+          (swap! form assoc
+                 :number   (str "************" (subs (get-in @session [:payment-info :number]) 12))
+                 :cvc      (get-in @session [:payment-info :cvc])
+                 :exp-date (str (get-in @session [:payment-info :exp-month])
+                                "/"
+                                (get-in @session [:payment-info :exp-year]))))
+        (if (or (nil? (:payment-info @session))
+                @editing?)
           [:div.ui.vertical.segment
            [:h2.ui.dividing.header
             "Payment Info"]
            [:div.two.fields
             [:div.required.field {:class (when (and number (:number errors))
-                                           "error")}
+                                           "error")
+                                  :on-change #(swap! session dissoc :payment-info)}
              [:label "Card Number"]
              [input-atom :text
               (r/wrap number swap! form assoc :number)]]
             [:div.required.field {:class (when (and cvc (:cvc errors))
-                                           "error")}
+                                           "error")
+                                  :on-change #(swap! session dissoc :payment-info)}
              [:label "CVC"]
              [:div.two.fields
               [:div.field
@@ -726,8 +738,9 @@
               [:div.field]]]]
            [:div.two.fields
             [:div.required.field {:class (when (and exp-date (:exp-date errors))
-                                           "error")}
-             [:label "Expiration Date"]
+                                           "error")
+                                  :on-change #(swap! session dissoc :payment-info)}
+             [:label "Expiration Date (MM/YYYY)"]
              [input-atom :text ; TODO placeholder
               (r/wrap exp-date swap! form assoc :exp-date)]]
             [:div.field]]
@@ -740,16 +753,30 @@
               "Confirm")]
            [:span.ui.red.compact.message
             {:class (when (nil? @stripe-error) "hidden")}
-            @stripe-error]
-           [:span.ui.green.compact.message
-            {:class (when (nil? @stripe-success) "hidden")}
-            @stripe-success]]
+            @stripe-error]]
           [:div.inline.fields
-           [:div.field (str "Charging card ending in " (:cc-last @session) ".")]
-           [:a.field {:on-click #(swap! session dissoc :stripe-token :cc-last)
+           [:div.field (str "Charging card ending in "
+                            (subs (get-in @session [:payment-info :number]) 12)
+                            ".")]
+           [:a.field {:on-click #(swap! session dissoc :payment-info)
                       :style {:cursor "pointer"}}
             "Charge different card"
             [:i.right.chevron.icon]]])))))
+
+
+;; Helpers
+;; =============================================================================
+
+(defn renew-stripe-token! [callback]
+  (let [response-handler
+        (fn [status response]
+          (when (not response.error)
+            (do
+              (swap! session assoc :stripe-token response.id)
+              (callback))))]
+    (Stripe.card.createToken
+      (clj->js (:payment-info @session))
+      response-handler)))

 ;; Pages
@@ -1614,13 +1641,21 @@
             register
             (fn [form]
               (when (empty? errors)
-                (attendees-endpoint :create
-                                    {:UserId (get-in @session [:user :UserId])
-                                     :EventId event-id
-                                     :Token (when (:RequiresPayment event) (:stripe-token @session))
-                                     ; TODO: maybe this logic is wrong?MIght want to buy ticket even if not required
-                                     :Amount (when (:RequiresPayment event) (:TicketPrice event))}
-                                    #(js/location.replace (events-route)))))]
+                ; TODO: maybe this logic is wrong?MIght want to buy ticket even if not required
+                (if (:RequiresPayment event)
+                  (renew-stripe-token!
+                    (fn [] (attendees-endpoint :create
+                                               {:UserId (get-in @session [:user :UserId])
+                                                :EventId event-id
+                                                :Token (:stripe-token @session)
+                                                :Amount (:TicketPrice event)}
+                                               #(do
+                                                  (swap! session dissoc :stripe-token)
+                                                  (js/location.replace (events-route))))))
+                  (attendees-endpoint :create
+                                      {:UserId (get-in @session [:user :UserId])
+                                       :EventId event-id}
+                                      #(js/location.replace (events-route))))))]
         (when (seq event)
           [:div.ui.stackable.page.grid
            [:div.sixteen.wide.column
@@ -1668,7 +1703,7 @@
                {:type :submit
                 :class (when (or (seq errors)
                                  (and (:RequiresPayment event)
-                                      (nil? (:stripe-token @session))))
+                                      (nil? (:payment-info @session))))
                          "disabled")
                 :on-click #(register @form)}
                "Register"]]]]])))))
@@ -1732,11 +1767,12 @@
            (let [activities (into [] (map (fn [[activity-id]]
                                             activity-id)
                                           @cart-activities))]
-             (schedules-endpoint :bulk
-                                 {:UserId      user-id
-                                  :Token       (:stripe-token @session)
-                                  :ActivityIds activities}
-                                 #(reset! cart-activities #{}))))]
+             (renew-stripe-token!
+               (fn [] (schedules-endpoint :bulk
+                                          {:UserId      user-id
+                                           :Token       (:stripe-token @session)
+                                           :ActivityIds activities}
+                                          #(reset! cart-activities #{}))))))]
         (when (seq event)
           [:div.sixteen.wide.column
            [:div.ui.segment
@@ -1860,7 +1896,7 @@
                 [:div.ui.divider]
                 [:button.ui.primary.button
                  {:type :submit
-                  :class (when (nil? (:stripe-token @session))
+                  :class (when (nil? (:payment-info @session))
                            "disabled")
                   :on-click #(add-cart-activities! % (get-in @session [:user :UserId]) cart-activities)}
                  "Confirm Payment and Add Activities"]]]])])))))
@@ -1957,7 +1993,8 @@
       (let [{:keys [Name]} @form
             errors (validator @form)
             create-organization
-            (fn [form]
+            (fn [e form]
+              (.preventDefault e)
               (organizations-endpoint :create
                                       form
                                       #(set! js/window.location
@@ -1976,7 +2013,7 @@
             [:button.ui.primary.button
              {:type :submit
               :class (when (seq errors) "disabled")
-              :on-click #(create-organization @form)}
+              :on-click #(create-organization % @form)}
              "Add"]]]]]))))

 (defn calendar-page []


Convert   in Clojure into spaces code as preprocess

--- src/clojournal/routes/article.clj
+++ src/clojournal/routes/article.clj
@@ -21,7 +21,8 @@
                               (str/replace "\n" "")
                               (str/replace "
" "
\n
"))]]
            (if code
-             (format "%s
\n
%s
\n
" text code)
+             (let [code (str/replace code " " " ")]
+               (format "%s
\n
%s
\n
" text code))
              text))
          str/join
          (format "
%s
")


Run init-parinfer! at the right time

Run init-parinfer! at the right time

--- src/clojure/nightcode/editors.clj
+++ src/clojure/nightcode/editors.clj
@@ -542,6 +542,8 @@
       ; add watchers
       (add-watchers! path extension text-area completer)
       (add-button-watchers! path editor-pane)
+      ; initialize parinfer
+      (init-parinfer! text-area extension edit-history)
       ; enable/disable buttons while typing
       (.addDocumentListener (.getDocument text-area)
         (reify DocumentListener
@@ -551,7 +553,6 @@
             (update-buttons! editor-pane text-area))
           (removeUpdate [this e]
             (update-buttons! editor-pane text-area))))
-      (init-parinfer! text-area extension edit-history)
       ; return a map describing the editor
       {:view editor-pane
        :text-area text-area


added html dumping

added html dumping

--- src/clueweb_disqus/read_stats.clj
+++ src/clueweb_disqus/read_stats.clj
@@ -2,7 +2,8 @@
   "Read stats + make a graph"
   (:gen-class :main true)
   (:require [clj-time.core :as t]
-            [clj-time.coerce :as c])
+            [clj-time.coerce :as c]
+            [clojure.java.io :as io])
   (:use [incanter core stats charts io]))

 (defn compute-downloaded-records
@@ -17,6 +18,32 @@
      0
      stats-files)))

+(defn generate-samples
+  []
+  (let [data-files (filter
+                     (fn [f]
+                       (re-find #".clj$" (.getAbsolutePath f)))
+                     (file-seq (java.io.File. ".")))]
+    (str
+     ""
+     ""
+     "
"
+     (clojure.string/join
+      "\n"
+      (map
+       (fn [a-data-file]
+         (let [rdr (-> a-data-file io/reader java.io.PushbackReader.)
+               stream (take-while
+                       identity
+                       (repeatedly
+                        (fn [] (try (read rdr)
+                                   (catch Exception e nil)))))]
+           (last stream)))
+       data-files))
+     "
"
+     ""
+     "")))
+
 (defn -main
   [& args]
   (spit "disqus_stats.csv"
@@ -26,8 +53,9 @@
              (compute-downloaded-records)
              "\n")
         :append true)
-  (let [data (read-dataset "disqus_stats.csv")
-        dates (sel data :cols 0)
-        cnt (sel data :cols 1)]
-    (save (time-series-plot dates cnt :y-label "Threads List Downloaded")
-          "/bos/www/htdocs/spalakod/disqus/disqus_thread_list.png")))
+  (do (let [data (read-dataset "disqus_stats.csv")
+            dates (sel data :cols 0)
+            cnt (sel data :cols 1)]
+        (save (time-series-plot dates cnt :y-label "Threads List Downloaded")
+              "/bos/www/htdocs/spalakod/disqus/disqus_thread_list.png"))
+      (spit "disqus_samples.html" (generate-samples))))


fix typo in duffel.tree.meta

fix typo in duffel.tree.meta

--- src/duffel/tree/meta.clj
+++ src/duffel/tree/meta.clj
@@ -76,7 +76,7 @@
     (fn [dt]
       (let [[meta-file dt-rest] (pluck-meta dt)]
         (if (nil? meta-file) dt
-          (meta-onto-files dt-rest
+          (meta-onto-branch dt-rest
             (read-meta-file meta-file)))))
     dtree))


add draw-line-spec

add draw-line-spec

--- tests/battlebots/arena_spec.clj
+++ tests/battlebots/arena_spec.clj
@@ -87,3 +87,7 @@
   (is (= [2 2] (adjust-coords [2 2] 7 [4 4] 8)) "move left eight spaces")
   (is (= [2 2] (adjust-coords [2 2] 8 [4 4]))   "passing an invalid direction will return the same coords")
   (is (= [2 2] (adjust-coords [2 2] 0 [4 4] 0)) "passing 0 for steps will return the same coords"))
+
+(deftest draw-line-spec
+  (is (= [[0 0] [1 1] [2 2] [3 3]] (draw-line 0 0 3 3)) "from (0 0) to (3 3)")
+  #_(is (= [[2 2] [2 3] [2 4] [2 5]] (draw-line 2 2 2 5)) "from (2 2) to (2 5)"))


require more ns in user ns

require more ns in user ns

--- dev/user.clj
+++ dev/user.clj
@@ -4,7 +4,6 @@
   ;(:require
   ; [clojure.java.io :as io]
   ; [clojure.java.javadoc :refer [javadoc]]
-  ; [clojure.pprint :refer [pprint]]
   ; [clojure.reflect :refer [reflect]]
   ; [clojure.repl :refer [apropos dir doc find-doc pst source]]
   ; [clojure.set :as set]
@@ -15,9 +14,13 @@
   (:require [com.stuartsierra.component :as component]
             [clojure.tools.logging :as log]
             [clojure.tools.namespace.repl :refer [refresh refresh-all]]
+            [clojure.pprint :refer [pprint] :rename {pprint pp}]
             [clojento.logback :as logback]
             [clojento.core :as app]
             [clojento.magento :as mage]
+            [clojento.magento.db :as mage-db]
+            [clojento.magento.db.products :as mage-db-products]
+            [clojento.magento.t_db :as mage-db-test]
             [ragtime.jdbc]
             [ragtime.repl]
             [midje.repl :refer [autotest]]))


Got overtone.live loading without name conflicts etc.

--- src/overtunes/pitch/chords.clj
+++ src/overtunes/pitch/chords.clj
@@ -1,6 +1,7 @@
 (ns overtunes.pitch.chords
-  (:use [overtone.inst.sampled-piano :only [sampled-piano]]
-        [overtone.live :only []]))
+  (:use
+    [overtone.live :exclude [scale octave sharp flat sixth]]
+    [overtone.inst.sampled-piano :only [sampled-piano]]))

 (def note! sampled-piano)
 (def chord! #(map note! %))
@@ -15,28 +16,29 @@

 (def semitone 1)
 (def tone (* semitone 2))
-(def octave1 (* 12 semitone))
+(def octave (* 12 semitone))

-(def sharp1 #(+ % semitone))
-(def flat1 #(- % semitone))
-(def raise #(+ % octave1))
+(def sharp #(+ % semitone))
+(def flat #(- % semitone))
+(def raise #(+ % octave))

-(defn scale1
+(defn scale
+  "Define a scale as a cumulative sum of intervals."
   ([] '(0))
   ([interval & intervals]
-   (cons 0 (map #(+ interval %) (apply scale1 intervals)))))
+   (cons 0 (map #(+ interval %) (apply scale intervals)))))

 (def major-scale (zipmap
                    [:i :ii :iii :iv :v :vi :vii :viii]
-                   (scale1 tone tone semitone tone tone tone semitone)))
+                   (scale tone tone semitone tone tone tone semitone)))

 (defn grounding [offset]
   "Takes an offset from root and produces a function for rendering chords."
   (fn
     ([octave-number]
-     (+ offset (* octave-number octave1)))
+     (+ offset (* octave-number octave)))
     ([octave-number chord]
-     (map #(+ offset % (* octave-number octave1)) (vals chord)))))
+     (map #(+ offset % (* octave-number octave)) (vals chord)))))

 ; Name notes
 (defall [C D E F G A B]
@@ -46,17 +48,17 @@

 ; Qualities
 (def major (select-keys major-scale [:i :iii :v]))
-(def minor (update-in major [:iii] flat1))
+(def minor (update-in major [:iii] flat))
 (def power (select-keys major-scale [:i :v :viii]))

 ; Modifications
-(def augmented #(update-in % [:v] sharp1))
-(def diminished #(update-in % [:v] flat1))
+(def augmented #(update-in % [:v] sharp))
+(def diminished #(update-in % [:v] flat))
 (def suspended-second #(assoc % :iii (:ii major-scale)))
 (def suspended-fourth #(assoc % :iii (:iv major-scale)))
-(def sixth1 #(assoc % :vi (:vi major-scale)))
+(def sixth #(assoc % :vi (:vi major-scale)))
 (def seventh #(assoc % :vii (+ (:v %) (:iii %))))
-(def dominant-seventh #(assoc % :vii (flat1 (:vii major-scale))))
+(def dominant-seventh #(assoc % :vii (flat (:vii major-scale))))
 (def ninth #(assoc (seventh %) :ix (raise (:ii major-scale))))
 (def eleventh #(assoc (ninth %) :xi (raise (:iv major-scale))))
 (def thirteenth #(assoc (eleventh %) :xi (raise (:vi major-scale))))


more coherent documentation

more coherent documentation

--- src/engine/data/rope.clj
+++ src/engine/data/rope.clj
@@ -10,7 +10,8 @@
 (def *leaf-cutoff-length* 64) ; This value has been determined optimal for split operations through benchmarking. TODO make constant in clojure 1.3

 (defprotocol Measurable
-  "Trivial protocol for things measurable.
+  "Trivial protocol for things measurable
+
 Default implementations are provided for nil and String; nil measures as 0
 characters, 0 lines. Strings get analyzed accordingly."
   (measure [object] "Measure object"))
@@ -31,7 +32,9 @@
   (print-simple (format "#<CharSequenceMeasurement %d/%d>" (:length weight) (:lines weight)) writer))

 (defn measurement
-  "CharSequenceMeasurement from length and lines; (measurement) is 0/0"
+  "CharSequenceMeasurement from length and lines
+
+(measurement) is 0/0"
   ([] (CharSequenceMeasurement. 0 0))
   ([length lines] (CharSequenceMeasurement. length lines)))

@@ -55,7 +58,8 @@

 (defprotocol Treeish-2-3
-  "Protocol describing 2-3-Trees, such as Ropes.
+  "Protocol describing 2-3-Trees, such as Ropes
+
 Default implementations for nil and String exist."
   (split [tree pred] "Split tree by pred")
   (conc [tree1 tree2] "Concatenate tree1 and tree2")
@@ -104,6 +108,7 @@

 (defn weigh
   "The accumulated measurement of all children to the right
+
 Provided that Treeish-2-3 is implemented for seq.
 In other words: What a new Treeish-2-3 node would weigh with seq as its left child."
   [seq]
@@ -151,7 +156,9 @@
   (apply str (->> (rope-seq root) (filter string?))))

 (defn rebalance
-  "Create rebalanced copy of the Rope, using the algorithm described in \"Ropes: an Alternative to Strings\".
+  "Rebalanced copy of the Rope provided
+
+Using the algorithm described in \"Ropes: an Alternative to Strings\".
 The implementation does not resemble the one from the paper, but is instead
 idiomatic Clojure and optimized for functional languages in general."  [root]
   (let [fold (fn [coll] (reduce rope (reverse coll)))
@@ -173,7 +180,8 @@
       (rebalance new-rope))))

 (defn string->rope [string]
-  "Create a fresh Rope from flat string.
+  "Fresh Rope from flat string
+
 The resulting leafes will carry at most *leaf-cutoff-length* characters of the
 input string."
   (letfn [(build [acc]


Erm, seems as if #{...} does not allow multiple keys anymore

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

--- src/conexp/tests/fca/contexts.clj
+++ src/conexp/tests/fca/contexts.clj
@@ -204,8 +204,8 @@
 			    (incidence ctx))
 			 (= base-set (objects ctx) (attributes ctx))))
        #{}
-       #{1 2 3 2 1 282 392 2 1 23}
-       #{nil 4 '4 * -}))
+       #{1 2 3 282 392 23}
+       #{nil 4 * -}))

 (deftest test-context-sum
   'to-be-done)


Clean up draw-entity! functions

Clean up draw-entity! functions

--- src/play_clj/core_graphics.clj
+++ src/play_clj/core_graphics.clj
@@ -169,12 +169,12 @@

 ; rendering

-(defmulti draw-entity! #(-> % second :type))
-
-(defmethod draw-entity! nil [_])
+(defmulti draw-entity! (fn [_ entity] (:type entity)))
+
+(defmethod draw-entity! nil [_ _])

 (defmethod draw-entity! :actor
-  [[^SpriteBatch batch {:keys [^Actor object] :as entity}]]
+  [^SpriteBatch batch {:keys [^Actor object] :as entity}]
   (assert object)
   (doseq [[k v] entity]
     (case k
@@ -186,8 +186,8 @@
   (.draw object batch 1))

 (defmethod draw-entity! :texture
-  [[^SpriteBatch batch {:keys [^TextureRegion object x y width height]
-                        :or {x 0 y 0 width 0 height 0}}]]
+  [^SpriteBatch batch {:keys [^TextureRegion object x y width height]
+                       :or {x 0 y 0 width 0 height 0}}]
   (assert object)
   (.draw batch object (float x) (float y) (float width) (float height)))

@@ -196,7 +196,7 @@
   (let [^SpriteBatch batch (batch screen)]
     (.begin batch)
     (doseq [entity entities]
-      (draw-entity! [batch entity]))
+      (draw-entity! batch entity))
     (.end batch))
   entities)


Allow setting the camera z position

Allow setting the camera z position

--- src/play_clj/core_graphics.clj
+++ src/play_clj/core_graphics.clj
@@ -252,16 +252,25 @@
 (defn x!
   [{:keys [^Camera camera]} x]
   (assert camera)
-  (when x (set! (. (. camera position) x) x))
+  (set! (. (. camera position) x) x)
   (.update camera))

 (defn y!
   [{:keys [^Camera camera]} y]
   (assert camera)
-  (when y (set! (. (. camera position) y) y))
+  (set! (. (. camera position) y) y)
   (.update camera))

+(defn z!
+  [{:keys [^Camera camera]} z]
+  (assert camera)
+  (set! (. (. camera position) z) z)
+  (.update camera))
+
 (defn position!
-  [screen x y]
-  (x! screen x)
-  (y! screen y))
+  ([screen x y]
+    (position! screen x y nil))
+  ([screen x y z]
+    (when x (x! screen x))
+    (when y (y! screen y))
+    (when z (z! screen z))))


Actually hooked up base-clusters-weights to group-clusterings in conv-update graph

--- src/polismath/conversation.clj
+++ src/polismath/conversation.clj
@@ -207,9 +207,17 @@
             (plmb/fnk [base-clusters-proj]
               (named-dist-matrix base-clusters-proj))

+      :base-clusters-weights
+            (plmb/fnk [base-clusters]
+              (into {}
+                    (map
+                      (fn [clst]
+                        [(:id clst) (count (:members clst))])
+                      base-clusters)))
+
       ; Compute group-clusters for multiple k values
       :group-clusterings
-            (plmb/fnk [conv base-clusters-proj opts']
+            (plmb/fnk [conv base-clusters-weights base-clusters-proj opts']
               (into {}
                 ; XXX - should test pmap out
                 (map
@@ -223,7 +231,8 @@
                               (if last-clusterings
                                 (last-clusterings k)
                                 last-clusterings))
-                          :cluster-iters (:group-iters opts')))])
+                          :cluster-iters (:group-iters opts')
+                          :weights base-clusters-weights))])
                   (range 2 (inc (max-k-fn base-clusters-proj (:max-k opts')))))))

       ; Compute silhouette values for the various clusterings


handle errors from futures in different thread

tika sometimes gives me memory errors and I haven't been able to catch
them from the thread itself and call cleanup code. The result has been
an idle java process as RabbitMQ didn't send more messages since from
RabbitMQ's POV the java process was still working on those messages.

we now periodically collect failed futures and call 'nack' for failed
messages.

--- src/fscrawler_tika_convert/core.clj
+++ src/fscrawler_tika_convert/core.clj
@@ -12,7 +12,52 @@
   (:require [clojure.stacktrace :as trace])
   (:require [tika])
   (:import java.io.File)
+  (:import [java.util.concurrent TimeUnit ScheduledThreadPoolExecutor Callable])
   (:gen-class))
+
+
+(def es (ScheduledThreadPoolExecutor. 4))
+
+
+(defn periodically
+  "periodically run function f with a fixed delay of n milliseconds"
+
+  [n f]
+  (.scheduleWithFixedDelay es ^Runnable f 0 n TimeUnit/MILLISECONDS))
+
+
+(def future-map (atom {}))
+
+(defn register-future
+  [a-future nackfn]
+  (swap! future-map assoc a-future nackfn))
+
+(defn unregister-future
+  [a-future]
+  (swap! future-map dissoc a-future))
+
+
+(defn deref-exception
+  [a-future]
+  (try
+    (do (deref a-future)
+        nil)
+    (catch Throwable err
+      err)))
+
+
+(defn reap-futures
+  []
+  (try
+    (doseq [[a-future val] @future-map]
+      (when (realized? a-future)
+        (if-let [error (deref-exception a-future)]
+          (do
+            (println "************* error in future" (str a-future) error val)
+            ((:cleanup-on-error val))))
+        (swap! future-map dissoc a-future)))
+    (catch Throwable err
+      (println "error" err))))

 (defn map-from-routing-key-string
@@ -67,27 +112,31 @@
         relpath (:relpath (:entry body))
         delivery-tag (:delivery-tag metadata)
         fp (string/join File/separator [directory relpath])
+        nack-this-message #(lb/nack ch delivery-tag false false)
         ;; converted (tika/parse fp)
         ]
         ;;
-    (future
-      (try
-        (let [converted (convert fp)]
-          ;; (println "before ack" (Thread/currentThread) (:delivery-tag metadata))
+    (register-future
+     (future
+       (try
+         (let [converted (convert fp)]
+           ;; (println "before ack" (Thread/currentThread) (:delivery-tag metadata))

-          (lb/publish ch
-                      exchange
-                      (routing-key-string-with-command routing-key "import_file")
-                      (json/write-str (assoc body "tika-content" converted)))
-          (lb/ack ch delivery-tag)
-          (println "done" fp " ****" ))
-        (catch Throwable err
+           (lb/publish ch
+                       exchange
+                       (routing-key-string-with-command routing-key "import_file")
+                       (json/write-str (assoc body "tika-content" converted)))
+           (lb/ack ch delivery-tag))
+         (catch Exception err
+           (println "got exception while handling" fp err)
+           (trace/print-stack-trace err)
+           (lb/nack ch delivery-tag false false))))
+     {:cleanup-on-error nack-this-message
+      :fp fp})

-          (println "got exception while handling" fp err)
-          (trace/print-stack-trace err)
-          (lb/nack ch delivery-tag false false))))

-    (println "scheduled" fp " ****" )))
+    ;; (println "scheduled" fp " ****" )
+    ))

     ;; (println "dir" fp " ****" (:content-type converted))))

@@ -122,6 +171,7 @@
   (alter-var-root #'*read-eval* (constantly false))

+
   (let [[options args banner]
         (cli/cli args
                  ["--ampqp-url" "amqp url to connect to"]
@@ -129,6 +179,9 @@
                  ["--root" "Root directory of web server" :default "public"])]
     (println "port:" (:port options))
     (println "root:" (:root options)))
+
+  (periodically 250 reap-futures)
+
   (while true
     (try
       (run-with-connection)


Exclude the `/repl` endpoint from the OAuth2 redirect.

--- src/regarde/authentication.clj
+++ src/regarde/authentication.clj
@@ -26,7 +26,7 @@
    :put-target oauth2-ring/put-target-in-session
    :get-oauth2-data oauth2-ring/get-oauth2-data-from-session
    :put-oauth2-data oauth2-ring/put-oauth2-data-in-session
-   :exclude #".*/sign-in.*"})
+   :exclude #"(.*/sign-in.*)|(.*/repl.*)"})

 (defn- google-user-info [token-data]
   (let [response (oauth2/get "https://www.googleapis.com/oauth2/v1/userinfo" token-data)]


pass driver instead of gl

pass driver instead of gl

--- src/gamma_driver/drivers/basic.cljs
+++ src/gamma_driver/drivers/basic.cljs
@@ -139,10 +139,10 @@
       input))

   gdp/IDraw
-  (draw-arrays [this program spec] (draw-arrays* gl program spec))
-  (draw-arrays [this program spec target] (draw-arrays* gl program spec target))
-  (draw-elements [this program spec] (draw-elements* gl program spec))
-  (draw-elements [this program spec target] (draw-elements* gl program spec target)))
+  (draw-arrays [this program spec] (draw-arrays* this program spec))
+  (draw-arrays [this program spec target] (draw-arrays* this program spec target))
+  (draw-elements [this program spec] (draw-elements* this program spec))
+  (draw-elements [this program spec target] (draw-elements* this program spec target)))

 (defn basic-driver [gl]


Made level 1.

Made level 1.

--- src/divergence/entity/levels.cljs
+++ src/divergence/entity/levels.cljs
@@ -41,26 +41,23 @@
 (defn level-1 [stage]
   [(e/timestream)
    (e/some-text stage)
-   (e/goal 1450 200 stage)
-   (e/groundTileC -100 560 :t1 stage)
+   (e/goal 1360 200 stage)
+   (e/groundTileC -100 530 :g1 stage)
    ;(e/box :box -100 260 stage)
-   (e/groundTileB 0 560 :t2 stage)
-   (e/groundTileA 100 560 :t3 stage)
-   (e/groundTileB 200 520 :t4 stage)
-   (e/groundTileC 300 480 :t5 stage)
-   (e/groundTileB 400 440 :t6 stage)
-   (e/groundTileC 500 440 :t7 stage)
-   (e/groundTileA 600 440 :t8 stage)
-   (e/groundTileB 700 440 :t9 stage)
-   (e/groundTileA 600 340 :t10 stage)
+   (e/groundTileB 0 530 :g2 stage)
+   (e/groundTileA 100 530 :g3 stage)
+   (e/groundTileB 200 530 :g4 stage)
+   (e/groundTileC 300 530 :g5 stage)
+   (e/groundTileB 400 530 :g6 stage)
+   (e/groundTileC 500 530 :g7 stage)
+   (e/groundTileA 600 530 :g8 stage)
+   (e/groundTileB 700 530 :g9 stage)
    ;(e/box :box 600 140 stage)
-   (e/groundTileA 800 260 :t11 stage)
    ;(e/rope-block 750 0 stage)
-   (e/groundTileB 900 440 :t12 stage)
-   (e/groundTileC 1000 500 :t13 stage)
-   (e/groundTileA 1100 440 :t14 stage)
-   (e/groundTileB 1200 440 :t15 stage)
-   (e/groundTileA 1400 440 :t16 stage)
+   (e/groundTileC 1000 530 :g10 stage)
+   (e/groundTileA 1100 450 :g11 stage)
+   (e/groundTileB 1200 370 :g12 stage)
+   (e/groundTileA 1300 290 :g13 stage)

    ;(e/vertical-full-block 0 -40 :b1 stage)
    ;(e/horizontal-full-block 0 560 :b3 stage)


Clean up/reduce duplication in template-parser.

--- src/selmer/template_parser.clj
+++ src/selmer/template_parser.clj
@@ -26,6 +26,8 @@
 (defn split-include-tag [^String tag-str]
   (seq (.split ^String (get-tag-params #"[^/]include" (.replace tag-str "\\" "/")) " ")))

+(defn string->reader [string]
+  (reader (StringReader. string)))

 (defn insert-includes
   "parse any included templates and splice them in replacing the include tags"
@@ -140,39 +142,45 @@
         (.append ^StringBuilder buf block-tag)
         (consume-block rdr buf blocks)))))

-(defn set-default-value [tag-str defaults]
-  (let [tag-name (-> tag-str
-                   (clojure.string/replace *filter-open-pattern* "")
-                   (clojure.string/replace *filter-close-pattern* ""))]
-    (if-let [value (get defaults tag-name)]
-      (str *tag-open* *filter-open* tag-name "|default:\"" value "\"" *filter-close* *tag-close*)
-      tag-str)))
-
-(defn add-default [identifier default]
-  (str identifier "|default:" \" default \"))
-
-(defn trim-ends [string n-left n-right]
-  (.substring ^String string n-left (- (.length ^String string) n-right)))
-
-(defn string->reader [string]
-  (reader (StringReader. string)))
-
 (defn wrap-in-expression-tag [string]
   (str *tag-open* *tag-second* \space string \space *tag-second* *tag-close*))
+
+(defn wrap-in-variable-tag [string]
+  (str *tag-open* *filter-open* \space string \space *filter-close* *tag-close*))
+
+(defn trim-regex [string & regexes]
+  (reduce #(clojure.string/replace %1 %2 "") string regexes))
+
+(defn trim-variable-tag [string]
+  (trim-regex string *filter-open-pattern* *filter-close-pattern*))
+
+(defn trim-expression-tag [string]
+  (trim-regex string *tag-open-pattern* *tag-close-pattern*))

 (defn to-expression-string [tag-name args]
   (let [tag-name' (name tag-name)
         args' (clojure.string/join \space args)]
     (wrap-in-expression-tag (str tag-name' \space args'))))

-(defn add-defaults-to-tag [tag-str defaults]
-  (let [try-add-default #(if-let [default (get defaults %)]
-                           (add-default % default)
-                           %)
-        tag-str' (trim-ends tag-str 1 2)
-        {:keys [tag-name args]} (read-tag-info (string->reader tag-str'))
-        args' (map try-add-default args)]
-    (to-expression-string tag-name args')))
+(defn add-default [identifier default]
+  (str identifier "|default:" \" default \"))
+
+(defn try-add-default [identifier defaults]
+  (if-let [default (get defaults identifier)]
+    (add-default identifier default)
+    identifier))
+
+(defn add-defaults-to-variable-tag [tag-str defaults]
+  (let [tag-name (trim-variable-tag tag-str)]
+    (wrap-in-variable-tag (try-add-default tag-name defaults))))
+
+(defn add-defaults-to-expression-tag [tag-str defaults]
+  (let [tag-str' (->> (trim-expression-tag tag-str)
+                      ;; NOTE: we add a character here since read-tag-info
+                      ;; consumes the first character before parsing.
+                      (str *tag-second*))
+        {:keys [tag-name args]} (read-tag-info (string->reader tag-str')) ]
+    (to-expression-string tag-name (map #(try-add-default % defaults) args))))

 (defn get-template-path [template]
   (resource-path template))
@@ -199,12 +207,12 @@
                  (cond
                   (and defaults
                        (re-matches *filter-pattern* tag-str))
-                  (do (.append buf (set-default-value tag-str defaults))
+                  (do (.append buf (add-defaults-to-variable-tag tag-str defaults))
                       (recur blocks (read-char rdr) parent))

                   (and defaults
                        (re-matches *tag-pattern* tag-str))
-                  (do (.append buf (add-defaults-to-tag tag-str defaults))
+                  (do (.append buf (add-defaults-to-expression-tag tag-str defaults))
                       (recur blocks (read-char rdr) parent))

                   ;;if the template extends another it's not the root


For CSV output, do no wrap strings in quotation marks.

--- src/dsbdp/data_processing_dsl.clj
+++ src/dsbdp/data_processing_dsl.clj
@@ -82,11 +82,8 @@
   [input rules]
   (let [extracted-strings (reduce
                             (fn [v rule]
-                              (let [data-proc-sub-fn (create-proc-sub-fn (second rule) input)
-                                    data-proc-sub-fn-ret-type (get-proc-sub-fn-ret-type (eval `(fn [~input] ~data-proc-sub-fn)))]
-                                (conj v (if (= java.lang.String data-proc-sub-fn-ret-type)
-                                          `(str "\"" ~data-proc-sub-fn "\"")
-                                          data-proc-sub-fn))))
+                              (let [data-proc-sub-fn (create-proc-sub-fn (second rule) input)]
+                                (conj v data-proc-sub-fn)))
                             '[str] rules)
         commas (reduce into [] ["." (repeat (- (count rules) 1) ",") "."])]
     (vec (filter #(not= \. %) (interleave extracted-strings commas)))))


Reduce duplicate code.

Reduce duplicate code.

--- src/dsbdp/data_processing_dsl.clj
+++ src/dsbdp/data_processing_dsl.clj
@@ -49,14 +49,18 @@
         ret (data-proc-sub-fn dummy-ba)]
     (type ret)))

+(defmacro java-map-out-reduce-fn
+  []
+  `(fn [v# rule#]
+    (conj v# `(.put
+              ~(name (first rule#))
+              ~(create-proc-sub-fn (second rule#) ~'input)))))
+
 (defn create-proc-fn-body-java-map-out
   "Create a data processing function body for emitting data into a Java map."
   [input rules]
   (reduce
-    (fn [v rule]
-      (conj v `(.put
-                ~(name (first rule))
-                ~(create-proc-sub-fn (second rule) input))))
+    (java-map-out-reduce-fn)
     '[doto (java.util.HashMap.)] rules))

 (defn create-proc-fn-body-clj-map-out
@@ -132,10 +136,7 @@
   "Create a data processing function body for incrementally emitting data into a Java map."
   [input output rules]
   (reduce
-    (fn [v rule]
-      (conj v `(.put
-                ~(name (first rule))
-                ~(create-proc-sub-fn (second rule) input))))
+    (java-map-out-reduce-fn)
     '[doto ^java.util.Map output] rules))

 (defn create-incremental-proc-fn-body-clj-map-out
@@ -167,7 +168,7 @@
                           (create-incremental-proc-fn-body-java-map-out input-sym output-sym rules))))
 ;        _ (println "Created data processing function vector from DSL:" fn-body-vec)
         fn-body (reverse (into '() fn-body-vec))
-;        _ (println "Created data processing function body:" fn-body)
+java-map-out-reduce-fn;        _ (println "Created data processing function body:" fn-body)
         data-processing-fn (eval `(fn [~input-sym ~output-sym] ~fn-body))]
     data-processing-fn))


in bootstrapped context, *unchecked-if* already defined in cljs.core and a simple dynamic boolean var, not an atom

--- src/main/clojure/cljs/analyzer.cljc
+++ src/main/clojure/cljs/analyzer.cljc
@@ -796,7 +796,8 @@
         else-expr (allowing-redef (analyze env else))]
     {:env env :op :if :form form
      :test test-expr :then then-expr :else else-expr
-     :unchecked @*unchecked-if*
+     :unchecked #?(:clj  @*unchecked-if*
+                   :cljs *unchecked-if*)
      :children [test-expr then-expr else-expr]}))

 (defmethod parse 'case*
@@ -1300,7 +1301,8 @@
                        ;; TODO: proper resolve
                        (= target '*unchecked-if*)
                        (do
-                         (reset! *unchecked-if* val)
+                         #?(:clj  (reset! *unchecked-if* val)
+                            :cljs (set! *unchecked-if* val))
                          ::set-unchecked-if)

                        (symbol? target)


Display what characters are allowed when user edits a method configuration name

--- src/cljs/main/broadfcui/page/workspace/method_configs/method_config_editor.cljs
+++ src/cljs/main/broadfcui/page/workspace/method_configs/method_config_editor.cljs
@@ -16,6 +16,7 @@
    [broadfcui.page.workspace.method-configs.synchronize :as mc-sync]
    [broadfcui.page.workspace.workspace-common :as ws-common]
    [broadfcui.utils :as utils]
+   [broadfcui.common.input :as input]
    ))

 (defn- filter-empty [coll]
@@ -201,11 +202,11 @@
         (create-section
          (if editing?
            [:div {}
-            (style/create-text-field {:ref "confname" :style {:width 500}
+            (style/create-text-field {:ref "confname" :style {:maxWidth 500}
                                       :data-test-id "edit-method-config-name-input"
                                       :defaultValue (:name config)
                                       :onKeyDown (common/create-key-handler [:space] #(.preventDefault %))})
-            (style/create-textfield-hint "foo")]
+            (style/create-textfield-hint input/hint-alphanumeric_-period)]
            [:div {:style {:padding "0.5em 0 1em 0"}
                   :data-test-id "method-config-name"} (:name config)]))
         (create-section-header "Referenced Method")


Remove old manifest flags

Remove old manifest flags

--- src-cljs/frontend/models/feature.cljs
+++ src-cljs/frontend/models/feature.cljs
@@ -10,8 +10,7 @@
   In an ideal world, when a feature launches to 100%, the code will be updated
   and old behavior branches and conditionals get removed.  This manifest intends
   to be a stop-gap until it's removed"
-  {"ui-v2" true
-   "ui-v2-opt-in-banner" false})
+  {})

 (defn- feature-flag-value-true? [value]
   (= value "true"))


Read request body in request-info handler (#52)

* Slurp request body in request-info

* Remove unnecessary null check

* if->when

--- kitchen/src/kitchen/core.clj
+++ kitchen/src/kitchen/core.clj
@@ -290,7 +290,9 @@

 (defn- request-info-handler
   "Returns the info received in the request."
-  [{:keys [headers] :as request}]
+  [{:keys [body headers] :as request}]
+  (when (instance? InputStream body)
+    (slurp body))
   {:status 200
    :headers {"Content-Type" "application/json"}
    :body (json/write-str {:headers headers})})


Added support for incoming mail.

Added support for incoming mail.

--- src/appengine_magic/services/mail.clj
+++ src/appengine_magic/services/mail.clj
@@ -1,6 +1,6 @@
 (ns appengine-magic.services.mail
   (:refer-clojure :exclude (send))
-  (:use [appengine-magic.utils :only [record]])
+  (:use [appengine-magic.utils :only [record copy-stream]])
   (:import [com.google.appengine.api.mail MailServiceFactory
             MailService$Message MailService$Attachment]))

@@ -20,7 +20,9 @@

 (defn make-attachment [filename data]
-  (MailService$Attachment. filename data))
+  (MailService$Attachment. filename (if (instance? (class (.getBytes "")) data)
+                                        data
+                                        (.getBytes data))))

 (defn make-message [& {:keys [from to subject text-body html-body
@@ -71,6 +73,34 @@
   (.sendToAdmins (get-mail-service) (make-mail-service-message msg)))

+(defrecord #^{:private true} MessageAlternativeParts [parts])
+(defrecord #^{:private true} MessagePart [filename content-type data])
+
+
+(defn- deconstruct-message [#^MimeMessage message]
+  (let [all-subparts (fn [part]
+                       (map #(.getBodyPart part %) (range (.getCount part))))
+        subparts (fn subparts [part]
+                   (let [content-type (.toLowerCase (.getContentType part))]
+                     (cond
+                      ;; multiple attachments
+                      (re-matches #"multipart\/mixed.*" content-type)
+                      (doall (map subparts (all-subparts (.getContent part))))
+                      ;; probably message text
+                      (re-matches #"multipart\/alternative.*" content-type)
+                      (MessageAlternativeParts.
+                       (doall (map subparts (all-subparts (.getContent part)))))
+                      ;; a specific attachment
+                      :else (let [content (.getContent part)]
+                              (if (string? content)
+                                  (MessagePart. (.getFileName part) content-type content)
+                                  (with-open [tempout (java.io.ByteArrayOutputStream.)]
+                                    (copy-stream (.getInputStream part) tempout)
+                                    (MessagePart. (.getFileName part) content-type
+                                                  (.toByteArray tempout))))))))]
+    (flatten [(subparts message)])))
+
+
 (defn parse-message [request]
   (let [session (javax.mail.Session/getDefaultInstance (java.util.Properties.) nil)
         raw-msg (javax.mail.internet.MimeMessage. session (.getInputStream (:request request)))
@@ -81,7 +111,30 @@
         to (map #(.toString %) (.getRecipients raw-msg javax.mail.Message$RecipientType/TO))
         cc (map #(.toString %) (.getRecipients raw-msg javax.mail.Message$RecipientType/CC))
         reply-to (first (map #(.toString %) (.getReplyTo raw-msg)))
-        message-id (.getMessageID raw-msg)]
+        message-id (.getMessageID raw-msg)
+        msg-raw-parts (deconstruct-message raw-msg)
+        msg-parts (reduce (fn breakdown [acc raw-part]
+                            (cond
+                             ;; alternatives
+                             (instance? MessageAlternativeParts raw-part)
+                             (reduce breakdown acc (:parts raw-part))
+                             ;; has a valid filename, must be an attachment
+                             (not (nil? (:filename raw-part)))
+                             (assoc acc :attachments
+                                    (conj (:attachments acc)
+                                          (make-attachment (:filename raw-part)
+                                                           (:data raw-part))))
+                             ;; text part
+                             (re-matches #"text\/plain.*" (:content-type raw-part))
+                             (assoc acc :text-body (:data raw-part))
+                             ;; HTML part
+                             (re-matches #"text\/html.*" (:content-type raw-part))
+                             (assoc acc :html-body (:data raw-part))))
+                          {:attachments []}
+                          msg-raw-parts)]
     (record MailMessage
             :from from :to to :subject subject
-            :reply-to reply-to :cc cc)))
+            :reply-to reply-to :cc cc
+            :text-body (:text-body msg-parts) :html-body (:html-body msg-parts)
+            :attachments (:attachments msg-parts)
+            :message-id message-id)))


Don't scroll thread to bottom if scrolled up

Makes it easier to be following active threads

--- src/braid/client/ui/views/thread.cljs
+++ src/braid/client/ui/views/thread.cljs
@@ -80,10 +80,26 @@
         kill-chan (chan)
         embed-update-chan (chan)

+        messages-node (atom nil)
+        ref-cb (fn [node] (reset! messages-node node))
+
+        at-bottom? (atom true)
+
+        check-at-bottom
+        (fn []
+          (let [node @messages-node]
+            (reset! at-bottom?
+                    (> 2
+                       (- (.-scrollHeight node)
+                          (.-scrollTop node)
+                          (.-clientHeight node))))))
+
         scroll-to-bottom!
         (fn [component]
-          (when-let [messages (r/dom-node component)]
-            (set! (.-scrollTop messages) (.-scrollHeight messages))))]
+          (when-let [node @messages-node]
+            (when @at-bottom?
+              (set! (.-scrollTop node) (.-scrollHeight node)))))]
+
     (r/create-class
       {:display-name "thread"

@@ -101,9 +117,12 @@

        :component-did-update scroll-to-bottom!

+       :component-will-update check-at-bottom
+
        :reagent-render
        (fn [thread]
          [:div.messages
+          {:ref ref-cb}
           (let [sorted-messages
                 (->> @messages
                      (sort-by :created-at)


tracing hooks

tracing hooks

--- src/celestial/persistency/systems.clj
+++ src/celestial/persistency/systems.clj
@@ -54,6 +54,7 @@
       (throw+ {:type ::persmission-env-violation} (<< "~{username} attempted to access system ~{system} in env ~{env}"))))))

 (defn hookless-get [id]
+  (trace "hooks on get-system" (:robert.hooke/hooks (meta get-system)))
   (h/with-hooks-disabled get-system (get-system id)))

 (defn is-system? [s]


non valid system

non valid system

--- src/celestial/persistency/systems.clj
+++ src/celestial/persistency/systems.clj
@@ -135,7 +135,7 @@

 (defn validate-system
   [system]
-  (validate! system system-base :error ::non-valid-machine-type)
+  (validate! system system-base :error ::non-valid-system)
   ((hyp-to-v (figure-virt system)) system))

 (defn clone-system
@@ -185,5 +185,13 @@
   )

+(declare validate-template)

+(entity {:version 1} template :indices [type])

+(def template-base {:type #{:required :type-exists}})
+
+(defn validate-template
+  [template]
+  (validate! template template-base :error ::non-valid-template)
+  ((hyp-to-v (figure-virt template)) template))


refactor update-balances -> calculate-balances-and-indexes

--- src/clj_money/models/transactions.clj
+++ src/clj_money/models/transactions.clj
@@ -107,8 +107,19 @@
     (find-transaction-item-preceding-date storage
                                           (:account-id item)
                                           transaction-date)))
-
-(defn- update-balances
+(defn- add-item-balance-and-index
+  [storage transaction-date item]
+  (let [previous-item (get-previous-item storage item transaction-date)
+        previous-balance (or (get previous-item :balance)
+                             (bigdec 0))
+        next-index (+ 1 (or (get previous-item :index) -1))
+        polarized-amount (accounts/polarize-amount storage item)]
+    (-> item
+        (assoc :balance (+ previous-balance
+                           polarized-amount)
+               :index next-index))))
+
+(defn- calculate-balances-and-indexes
   "Updates transaction item and account balances resulting from the
   specified transaction.

@@ -122,16 +133,10 @@
   [storage transaction]
   (update-in transaction
              [:items]
-             #(map (fn [item]
-                     (let [previous-item (get-previous-item storage item (:transaction-date transaction))
-                           previous-balance (or (get previous-item :balance)
-                                                (bigdec 0))
-                           next-index (+ 1 (or (get previous-item :index) -1))
-                           polarized-amount (accounts/polarize-amount storage item)]
-                       (-> item
-                           (assoc :balance (+ previous-balance
-                                              polarized-amount)
-                                  :index next-index)))) %)))
+             #(map (partial add-item-balance-and-index
+                            storage
+                            (:transaction-date transaction))
+                   %)))

 (defn- subsequent-items
   "Returns items in the same account with an equal or greater
@@ -180,7 +185,7 @@
     (if (validation/has-error? validated)
       validated
       (let [storage (storage storage-spec)
-            with-balances (update-balances storage validated)
+            with-balances (calculate-balances-and-indexes storage validated)
             _ (update-affected-balances storage-spec (:items with-balances))
             result (create-transaction storage (before-save with-balances))
             items (into [] (map #(->> (assoc % :transaction-id (:id result))


use correct caches

use correct caches

--- src/cljc/commos/delta/compscribe.cljc
+++ src/cljc/commos/delta/compscribe.cljc
@@ -459,11 +459,24 @@
                              (update (or cache [:is]) 1
                                      delta/add v))}))

+(defn- sum-cache
+  "Caches on endpoints.  Sends the current sum to a new subscriber,
+  continues with sums."
+  [service]
+  (cached-service service {:accumulate
+                           (fn [cache v]
+                             #_(println ["Sum cache processing"
+                                         [cache v]])
+                             (update (or cache [:is]) 1
+                                     delta/add v))
+                           :mode :cache}))
+
 (defn compscriber
   [service]
   (let [service (-> service
+                    (hybrid-cache)
                     (compscribe-service)
-                    (hybrid-cache))
+                    (sum-cache))
         compile-spec (memoize compile-spec)]
     (reify
       IStream


Extend protocols to google maps classes

Extend protocols to google maps classes

--- src/cljs/gtfve/utils/google_maps.cljs
+++ src/cljs/gtfve/utils/google_maps.cljs
@@ -12,6 +12,24 @@
                                     :lng 121.032520}
                            :mapTypeId (:ROADMAP map-types)
                            :zoom 15})
+(extend-type Maps.LatLng
+  ILookup
+  (-lookup [this key] (get (js->clj this) key))
+  (-lookup [this key not-found] (or (get (js->clj this) key) not-found))
+  ISeqable
+  (-seq [this] (list (.lat this) (.lng this)))
+  IEncodeClojure
+  (-js->clj [this options] {:lat (.lat this) :lng (.lng this)}))
+
+(extend-type Data.Point
+  ILookup
+  (-lookup [this key] (get (js->clj this) key))
+  (-lookup [this key not-found] (or (get (js->clj this) key) not-found))
+  ISeqable
+  (-seq [this] (seq (.get this)))
+  IEncodeClojure
+  (-js->clj [this options] (apply js->clj (.get this) options)))
+

 (defn data-listen
   ([data type]


pending badge alert

pending badge alert

--- src/cljs/salava/social/ui/stream.cljs
+++ src/cljs/salava/social/ui/stream.cljs
@@ -91,6 +91,14 @@
                               (update-status id "declined" state)
                               (.preventDefault %))}
         (t :badge/Declinebadge)]]]]]])
+
+(defn badge-alert [state]
+  (if (:badge-alert @state)
+    [:div {:class "alert alert-success"}
+     (case (:badge-alert @state)
+       "accepted"  [:div (str (t :badge/Youhaveaccepted) " " (:badge-name @state)". ") (t :badge/Youcanfind)]
+       "declined" (t :badge/Badgedeclined)
+       "")]))

 (defn badge-pending [badge state]
   [:div.row {:key (:id badge)}
@@ -413,6 +421,7 @@
     [:div {:class "my-badges pages"}

      [m/modal-window]
+     [badge-alert state]
      [pending-connections reload-fn]
      [badges-pending state]
      (if (not-activated?)
@@ -442,7 +451,8 @@
                      :pending-badges []
                      :tips {:profile-picture-tip false
                             :welcome-tip false
-                            :not-verified-emails []}})]
+                            :not-verified-emails []}
+                     :badge-alert nil})]

     (init-data state)
     (fn []


Corrected last eastwood warning

Corrected last eastwood warning

--- src/clojure_rest/dao/document_dao.clj
+++ src/clojure_rest/dao/document_dao.clj
@@ -1,5 +1,5 @@
 (ns clojure-rest.dao.document-dao
-  (:use [korma.core :only [select insert update values delete where set-fields]])
+  (:use [korma.core :only [select insert values delete where set-fields]])
   (:require [clojure.java.jdbc :as jdbc]
             [clojure.tools.logging :as log]
             [clojure-rest.model.document :as document-model]
@@ -29,7 +29,7 @@
 (defn update-document
   "Updates an existing document on the database"
   [id-document-to-update document-to-update]
-  (update document-model/document
+  (korma.core/update document-model/document
           (set-fields document-to-update)
           (where {:id_document id-document-to-update})))


Add follow-up schema and compound index creation.

--- src/oc/storage/resources/common.clj
+++ src/oc/storage/resources/common.clj
@@ -87,6 +87,16 @@

 (def Status (schema/pred #(#{:draft :published} (keyword %))))

+(def FollowUp
+  "A follow-up item."
+  {
+  :uuid lib-schema/UniqueID
+  :created-at lib-schema/ISO8601
+  :assignee lib-schema/Author
+  :author lib-schema/Author
+  :completed? schema/Bool
+  :completed-at lib-schema/ISO8601})
+
 (def Entry
   "An entry on a board."
   {
@@ -124,7 +134,10 @@
   (schema/optional-key :video-error) (schema/maybe schema/Bool)
   :revision-id schema/Int
   :created-at lib-schema/ISO8601
-  :updated-at lib-schema/ISO8601})
+  :updated-at lib-schema/ISO8601
+
+  ;; FollowUps
+  (schema/optional-key :follow-ups) [FollowUp]})

 (def NewBoard
   "A new board for creation, can have new or existing entries already."


hide loading output after repl is ready

hide loading output after repl is ready

--- src/replme/cljs/loading_mesage.cljs
+++ src/replme/cljs/loading_mesage.cljs
@@ -1,7 +1,7 @@
 (ns replme.cljs.loading-message
   (:require [cljs.core.async :refer [<! >! chan sub]]
             [replme.cljs.websocket :as ws])
-  (:use [jayq.core :only [$ fade-out append prop anim height]])
+  (:use [jayq.core :only [$ fade-out append slide-up prop anim]])
   (:require-macros [cljs.core.async.macros :refer [go-loop]]))

 (enable-console-print!)
@@ -22,7 +22,9 @@

     (go-loop [msg (<! command-out-sub)]
              (if (= (:message msg) "REPL OK")
-               (fade-out loading-spinner 500))
+               (do
+                 (slide-up loading-message 500)
+                 (fade-out loading-spinner 500)))
              (recur (<! command-out-sub)))

     (go-loop [msg (<! console-out-sub)]