Implement grid options copy tooltip.

Implement grid options copy tooltip.

--- src/uxbox/main/ui/dashboard/icons.cljs
+++ src/uxbox/main/ui/dashboard/icons.cljs
@@ -209,14 +209,38 @@
        :type "file"
        :on-change on-file-selected}]]))

-(mx/defc grid-options
-  [{:keys [type] :as coll}]
+(mx/defc grid-options-copy
+  {:mixins [mx/reactive mx/static]}
+  [colls]
+  (let [colls (mx/react collections-ref)
+        colls (->> (vals colls)
+                   (filter #(= :own (:type %)))
+                   (sort-by :name colls))
+        on-select (fn [event id]
+                    (dom/prevent-default event)
+                    (rs/emit! (di/copy-selected id)))]
+    [:ul.move-list
+     [:li.title "Copy to library"]
+     [:li [:a {:href "#" :on-click (partial on-select nil)} "Storage"]]
+     (for [coll colls
+           :let [id (:id coll)
+                 name (:name coll)]]
+       [:li {:key (str id)}
+        [:a {:on-click #(on-select % id)} name]])]))
+
+(mx/defcs grid-options
+  {:mixins [(mx/local) mx/static]}
+  [own {:keys [type] :as coll}]
   (let [editable? (or (= type :own)
-                      (nil? coll))]
+                      (nil? coll))
+        local (:rum/local own)]
     (letfn [(delete []
               (rs/emit! (di/delete-selected)))
             (on-delete [event]
-              (udl/open! :confirm {:on-accept delete}))]
+              (udl/open! :confirm {:on-accept delete}))
+            (on-toggle [event]
+              (swap! local update :show-copy-tooltip not)
+              (println "on-toggle"))]
       ;; MULTISELECT OPTIONS BAR
       [:div.multiselect-bar
        (if editable?
@@ -230,7 +254,9 @@
            i/trash]]
          [:div.multiselect-nav
           [:span.move-item.tooltip.tooltip-top
-           {:alt "Copy to"}
+           {:on-click on-toggle}
+           (when (:show-copy-tooltip @local)
+             (grid-options-copy))
            i/organize]])])))

 (mx/defc grid-item


clean up a little

clean up a little

--- src/promdash_annotation_server/handler.clj
+++ src/promdash_annotation_server/handler.clj
@@ -54,9 +54,11 @@
                       until (read-string (get-in request [:params :until] (str (current-timestamp))))]
                      (generate-string (annotation-list-response tags mrange until))))
            (POST "/annotations/tags/:tag" request
-                (let [tag (get-in request [:params :tag])
-                      body (parse-string (slurp (get request :body)) true)]
-                  (put-annotation tag (:created_at body) (:message body)))
+                 (let [tag (get-in request [:params :tag])
+                       body (parse-string (slurp (get request :body)) true)
+                       timestamp (:created_at body)
+                       message (:message body)]
+                   (put-annotation tag timestamp message))
                  "ok")
            (route/not-found "Not Found"))


lhs-delete now remembers joins

lhs-delete now remembers joins


(QENG-2013) Fix broken manifest generation in ezbake.

--- src/puppetlabs/ezbake/dependency_utils.clj
+++ src/puppetlabs/ezbake/dependency_utils.clj
@@ -169,7 +169,8 @@
           (:dependencies lein-project)
           (aether/resolve-dependencies
             :coordinates (:dependencies lein-project)
-            :repositories (:repositories lein-project)))
+            :repositories (:repositories lein-project)
+            :local-repo (:local-repo lein-project)))
         (add-dep-hierarchy-to-string! sb 0))
     (.toString sb)))


check for unknown options

check for unknown options

--- src/leiningen/sync.clj
+++ src/leiningen/sync.clj
@@ -4,7 +4,8 @@
             [leiningen.utils :as u]
             [leiningen.namespaces :as ns]
             [clojure.string :as str]
-            [clojure.tools.cli :as cli]))
+            [clojure.tools.cli :as cli]
+            [leiningen.core.main :as m]))

 (def sync-commands {:default ns/update-and-test!
                     :notest  ns/update-projects!
@@ -55,9 +56,12 @@
        (str/join \newline)))

 (defn sync [project-desc & args]
-  (let [{:keys [options arguments summary]} (cli/parse-opts args cli-options)]
+  (let [{:keys [options arguments summary errors]} (cli/parse-opts args cli-options)]
     (cond
-      (= 1 (count arguments))
-      (execute-program (u/split (first arguments)) project-desc options)
+      (not-empty errors) (m/info errors)
+      (= 1 (count arguments)) (execute-program
+                               (u/split (first arguments))
+                               project-desc
+                               options)
       :else (main/abort (usage summary)))
     (main/exit)))


better way to control :dimmer

better way to control :dimmer

--- src/lights/my_show.clj
+++ src/lights/my_show.clj
@@ -118,11 +118,8 @@
 (core/start-web-server 16000 true)
 (show/start!)     ; Start sending its DMX frames.

-; Dim all PARs to maximum
-(show/add-effect! :max-dimmer
-  (afterglow.effects.channel/channel-effect "Max dimmer" 189
-    (afterglow.channels/extract-channels
-      (show/fixtures-named "rgbw") #(= (:type %) :control))))
+; Reset dimmers to full brightness
+(show/add-effect! :dimmers (global-dimmer-effect 255))

 ; Variable to control lightness level on all PARs
 (show/set-variable! :lightness-level 30)


Play around with some protocol ideas.

Play around with some protocol ideas.

--- src/merkle_db/core.clj
+++ src/merkle_db/core.clj
@@ -1,37 +1,165 @@
 (ns merkle-db.core)

-;; ## Data Types
+(defprotocol IConnection
+  "Protocol for interacting with backing connection resources to work with one
+  or more databases."
+
+  (list-dbs
+    [conn]
+    "List information about the available databases.")
+
+  (create-db!
+    [conn db-name root-id]
+    "Initialize a new database. An initial `:root-id` may be provided, which
+    will 'clone' the database at that state.")
+
+  (open-db
+    [conn db-name at-inst]
+    "Open a database for use. An optional instant argument may be provided,
+    which will return the last committed database version occurring before that
+    time.")
+
+  (drop-db!
+    [conn db-name]
+    "Drop a database reference. Note that this will not remove block data, as
+    it may be shared."))
+
+
+(defprotocol IDatabase
+  "Protocol for interacting with a database at a specific version."
+
+  (describe
+    [db]
+    "Retrieve descriptive information about a database, including any user-set
+    metadata.")
+
+  (alter-db-meta
+    [db f]
+    "Update the user metadata attached to a database. The function `f` will be
+    called with the current value of the metadata, and the result will be used
+    as the new metadata.")
+
+  (commit!
+    [db]
+    "Ensure all data has been written to the backing block store and update the
+    database's root value in the ref manager.")
+
+  ; TODO: lock/unlock?
+  #_
+  (lock!
+    [db client-id]
+    [db client-id lock-key]
+    "...")
+
+  #_
+  (unlock!
+    [db client-id lock-key]
+    "..."))
+
+
+(defprotocol ITables
+  "..."
+
+  (create-table
+    [db table-name opts]
+    "...")
+
+  (describe-table
+    [db table-name]
+    "...")
+
+  (alter-table-meta
+    [db table-name f]
+    "...")
+
+  (alter-families
+    [db table-name new-families]
+    "...")
+
+  (drop-table
+    [db table-name]
+    "...."))
+
+
+(defprotocol IRecords
+  "..."
+
+  (scan
+    [db table-name opts]
+    "...")
+
+  (get-records
+    [db table-name primary-keys fields]
+    "...")
+
+  (write
+    [db table-name records]
+    "...")
+
+  (delete
+    [db table-name primary-keys]
+    "..."))
+
+
+(defprotocol IPartitions
+  "..."
+
+  (list-partitions
+    [db table-name]
+    "...")
+
+  (read-partition
+    [db partition-id fields]
+    "...")
+
+  (build-table
+    [db table-name partition-ids]
+    "..."))
+
+
+
+;; ## Connections

 ; TODO: should probably use deftypes here
 (defrecord Connection
   [block-store
    ref-tracker
    key-codec
-   data-codec])
+   data-codec]
+
+  IConnection
+
+  (list-dbs
+    [this]
+    ,,,)
+
+
+  (create-db!
+    [this db-name root-id]
+    ,,,)
+
+
+  (open-db
+    [this db-name at-inst]
+    ,,,)
+
+
+  (drop-db!
+    [this db-name]
+    ,,,))

 (alter-meta! #'->Connection assoc :private true)
 (alter-meta! #'map->Connection assoc :private true)

-(defrecord Database
-  [connection
-   ,,,])
-
-
-(alter-meta! #'->Database assoc :private true)
-(alter-meta! #'map->Database assoc :private true)
-
-
-
-;; ## Connections
-
 (defn connect
   [& {:as opts}]
   (map->Connection opts))

+#_
 (defn create-db!
   "Initialize a new database. An initial `:root` value may be provided,
   allowing for cheap database copy-on-write cloning."
@@ -39,12 +167,14 @@
   (throw (UnsupportedOperationException. "NYI")))

+#_
 (defn open-db
   "Open a database for use."
   [conn db-name]
   (throw (UnsupportedOperationException. "NYI")))

+#_
 (defn drop-db!
   "Drop a database from the backing tracker. Note that this will not remove the
   block data, as it may be shared."
@@ -55,4 +185,10 @@

 ;; ## Databases

-,,,
+(defrecord Database
+  [connection
+   ,,,])
+
+
+(alter-meta! #'->Database assoc :private true)
+(alter-meta! #'map->Database assoc :private true)


make filters task match servlets task

make filters task match servlets task

* filters task will create edn file if needed

--- src/migae/boot_gae.clj
+++ src/migae/boot_gae.clj
@@ -770,84 +770,118 @@
         (target-handler fileset)))))

-(boot/deftask filters
-  "generate filters class files"
-
-  [k keep bool "keep intermediate .clj files"
-   n gen-filters-ns NS str "namespace to generate and aot; default: 'filters"
-   w web-inf WEB-INF str "WEB-INF dir, default: WEB-INF"
-   v verbose bool "Print trace messages."]
-  (let [edn-tmp-dir (boot/tmp-dir!)
-        prev-pre (atom nil)
-        ;; config-sym (if config-sym config-sym 'filters/config)
-        ;; config-ns (symbol (namespace config-sym))
-        web-inf (if web-inf web-inf web-inf-dir)
-        filters-edn "filters.edn"
-        gen-filters-tmp-dir (boot/tmp-dir!)
-        gen-filters-ns (if gen-filters-ns (symbol gen-filters-ns) (gensym "filtersgen"))
-        gen-filters-path (str gen-filters-ns ".clj")]
-    (comp
-     (boot/with-pre-wrap [fileset]
-       (let [boot-config-edn-files (->> (boot/fileset-diff @prev-pre fileset)
-                                    boot/input-files
-                                    (boot/by-re [(re-pattern (str boot-config-edn "$"))]))]
-                    ;; (boot/by-name [boot-config-edn]))]
-         (if (> (count boot-config-edn-files) 1)
-           (throw (Exception. "only one _boot_config.edn file allowed")))
-         (if (= (count boot-config-edn-files) 0)
-           (throw (Exception. "cannot find _boot_config.edn")))
-
-         (let [boot-config-edn-f (first boot-config-edn-files)
-               boot-config-edn-map (-> (boot/tmp-file boot-config-edn-f) slurp read-string)]
-           (if (:filters boot-config-edn-map)
-             fileset
-             (do
-               ;; step 0: read the edn files
-               (let [filters-edn-files (->> (boot/input-files fileset)
-                                            (boot/by-name [filters-edn]))]
-                 (if (> (count filters-edn-files) 1)
-                   (throw (Exception. "only one filters.edn file allowed")))
-                 (if (= (count filters-edn-files) 0)
-                   (throw (Exception. "cannot find filters.edn")))
-                 (let [edn-filters-f (first filters-edn-files)
-                       filter-configs (-> (boot/tmp-file edn-filters-f) slurp read-string)
-                       smap (-> boot-config-edn-map (assoc-in [:filters]
-                                                        (:filters filter-configs)))
-                       boot-config-edn-s (with-out-str (pp/pprint smap))]
-                   ;; step 1:  inject filter config stanza to _boot_config.edn
-                   (let [path     (boot/tmp-path boot-config-edn-f)
-                         boot-config-edn-in-file  (boot/tmp-file boot-config-edn-f)
-                         boot-config-edn-out-file (io/file edn-tmp-dir path)]
-                     (io/make-parents boot-config-edn-out-file)
-                     (spit boot-config-edn-out-file boot-config-edn-s))
-
-                   ;; step 2: gen filters
-                   (let [gen-filters-content (stencil/render-file "migae/boot_gae/gen-filters.mustache"
-                                                                   (assoc filter-configs
-                                                                          :gen-filters-ns
-                                                                          gen-filters-ns))
-                         gen-filters-out-file (doto
-                                                   (io/file gen-filters-tmp-dir gen-filters-path)
-                                                 io/make-parents)]
-                     (spit gen-filters-out-file gen-filters-content))))))))
-       (util/info "Configuring filters...\n")
-
-       ;; step 3: commit files to fileset
-       (reset! prev-pre
-               (-> fileset
-                   (boot/add-source edn-tmp-dir)
-                   (boot/add-source gen-filters-tmp-dir)
-                   boot/commit!)))
-     (builtin/aot :namespace #{gen-filters-ns}) ;; :dir (str web-inf "/classes"))
-     (if keep identity
-       (builtin/sift :include #{(re-pattern (str gen-filters-ns ".*.class"))}
-                     :invert true))
-     (if keep
-       (comp
-        (builtin/sift :to-resource #{(re-pattern boot-config-edn)})
-        (builtin/sift :to-asset #{(re-pattern gen-filters-path)}))
-       identity)
-     )))
+(defn- normalize-filter-configs
+  [configs]
+  {:filters
+   (vec (flatten (for [config (:filters configs)]
+          (let [urls (into [] (for [url (:urls config)]
+                                {:path (str url)}))
+                ns (if (:ns config) (:ns config) (:class config)) ]
+            (merge config {:urls urls
+                           :filter {:ns ns}})))))})
+
+;; (boot/deftask filters
+;;   "generate filters class files"
+
+;;   [k keep bool "keep intermediate .clj files"
+;;    n gen-filters-ns NS str "namespace to generate and aot; default: 'filters"
+;;    w web-inf WEB-INF str "WEB-INF dir, default: WEB-INF"
+;;    v verbose bool "Print trace messages."]
+;;   (let [edn-tmp-dir (boot/tmp-dir!)
+;;         prev-pre (atom nil)
+;;         ;; config-sym (if config-sym config-sym 'filters/config)
+;;         ;; config-ns (symbol (namespace config-sym))
+;;         web-inf (if web-inf web-inf web-inf-dir)
+;;         filters-edn "filters.edn"
+;;         gen-filters-tmp-dir (boot/tmp-dir!)
+;;         gen-filters-ns (if gen-filters-ns (symbol gen-filters-ns) (gensym "filtersgen"))
+;;         gen-filters-path (str gen-filters-ns ".clj")]
+;;     (comp
+;;      (boot/with-pre-wrap [fileset]
+;;        (let [boot-config-edn-files (->> (boot/fileset-diff @prev-pre fileset)
+;;                                     boot/input-files
+;;                                     (boot/by-re [(re-pattern (str boot-config-edn "$"))]))
+;;              boot-config-edn-f (condp = (count boot-config-edn-files)
+;;                              0 (do (if verbose (util/info (str "Creating " boot-config-edn "\n")))
+;;                                    (io/file boot-config-edn)) ;; this creates a java.io.File
+;;                              1 (first boot-config-edn-files)  ;; this is a boot.tmpdir.TmpFile
+;;                              (throw (Exception.
+;;                                      (str "only one " boot-config-edn " file allowed; found "
+;;                                           (count boot-config-edn-files)))))
+;;              boot-config-edn-map (if (instance? boot.tmpdir.TmpFile boot-config-edn-f)
+;;                                    (-> (boot/tmp-file boot-config-edn-f) slurp read-string)
+;;                                    {})]
+
+;;          ;; (if (> (count boot-config-edn-files) 1)
+;;          ;;   (throw (Exception. "only one _boot_config.edn file allowed")))
+;;          ;; (if (= (count boot-config-edn-files) 0)
+;;          ;;   (throw (Exception. "cannot find _boot_config.edn")))
+
+;;          ;; (let [boot-config-edn-f (first boot-config-edn-files)
+;;          ;;       boot-config-edn-map (-> (boot/tmp-file boot-config-edn-f) slurp read-string)]
+;;            (if (:filters boot-config-edn-map)
+;;              fileset
+;;              (do
+;;                ;; step 0: read the edn files
+;;                (let [filters-edn-files (->> (boot/input-files fileset)
+;;                                              (boot/by-name [filters-edn]))
+;;                      filters-edn-f (condp = (count filters-edn-files)
+;;                                         0 (throw (Exception. (str "Cannot find " filters-edn " file.")))
+;;                                         1 (first filters-edn-files)
+;;                                         ;; > 1
+;;                                         (throw (Exception.
+;;                                                 (str "Only one " filters-edn "file allowed; found "
+;;                                                      (count filters-edn-files)))))
+;;                      filters-edn-map (-> (boot/tmp-file filters-edn-f) slurp read-string)
+;;                      filters-config-map (normalize-filter-configs filters-edn-map)
+;;                      filters-config-map {:filters (filter #(nil? (:class %))
+;;                                                             (:filters filters-config-map))}
+
+;;                ;; (let [filters-edn-files (->> (boot/input-files fileset)
+;;                ;;                              (boot/by-name [filters-edn]))]
+;;                ;;   (if (> (count filters-edn-files) 1)
+;;                ;;     (throw (Exception. "only one filters.edn file allowed")))
+;;                  ;; (if (= (count filters-edn-files) 0)
+;;                  ;;   (throw (Exception. "cannot find filters.edn")))
+;;                  (let [edn-filters-f (first filters-edn-files)
+;;                        filter-configs (-> (boot/tmp-file edn-filters-f) slurp read-string)
+;;                        smap (-> boot-config-edn-map (assoc-in [:filters]
+;;                                                         (:filters filter-configs)))
+;;                        boot-config-edn-s (with-out-str (pp/pprint smap))]
+;;                    ;; step 1:  inject filter config stanza to _boot_config.edn
+;;                    (let [path     (boot/tmp-path boot-config-edn-f)
+;;                          boot-config-edn-in-file  (boot/tmp-file boot-config-edn-f)
+;;                          boot-config-edn-out-file (io/file edn-tmp-dir path)]
+;;                      (io/make-parents boot-config-edn-out-file)
+;;                      (spit boot-config-edn-out-file boot-config-edn-s))
+
+;;                    ;; step 2: gen filters
+;;                    (let [gen-filters-content (stencil/render-file "migae/boot_gae/gen-filters.mustache"
+;;                                                                    (assoc filter-configs
+;;                                                                           :gen-filters-ns
+;;                                                                           gen-filters-ns))
+;;                          gen-filters-out-file (doto
+;;                                                    (io/file gen-filters-tmp-dir gen-filters-path)
+;;                                                  io/make-parents)]
+;;                      (spit gen-filters-out-file gen-filters-content))))))) ;;)
+;;        (util/info "Configuring filters...\n")
+
+;;        ;; step 3: commit files to fileset
+;;        (reset! prev-pre
+;;                (-> fileset
+;;                    (boot/add-source edn-tmp-dir)
+;;                    (boot/add-source gen-filters-tmp-dir)
+;;                    boot/commit!)))
+;;      (builtin/aot :namespace #{gen-filters-ns}) ;; :dir (str web-inf "/classes"))
+;;      (if keep identity
+;;        (builtin/sift :include #{(re-pattern (str gen-filters-ns ".*.class"))}
+;;                      :invert true))
+;;      (if keep
+;;        (comp
+;;         (builtin/sift :to-resource #{(re-pattern boot-config-edn)})
+;;         (builtin/sift :to-asset #{(re-pattern gen-filters-path)}))
+;;        identity)
+;;      )))

 (defn- install-jarfile-internal
   [jarname]
@@ -1453,6 +1487,101 @@
        identity)
      )))

+(boot/deftask filters
+  "generate filters class files"
+  [k keep bool "keep intermediate .clj files"
+   ;; d odir DIR str "output dir for generated class files"
+   ;; c config-sym SYM sym "namespaced symbol bound to meta-config data"
+   n gen-filters-ns NS str "namespace to generate and aot; default: 'filters"
+   w web-inf WEB-INF str "WEB-INF dir, default: WEB-INF"
+   v verbose bool "Print trace messages."]
+  (let [workspace (boot/tmp-dir!)
+        prev-pre (atom nil)
+        ;; config-sym (if config-sym config-sym 'filters/config)
+        ;; config-ns (symbol (namespace config-sym))
+        web-inf (if web-inf web-inf web-inf-dir)
+        filters-edn "filters.edn"
+        gen-filters-tmp-dir (boot/tmp-dir!)
+        gen-filters-ns (if gen-filters-ns (symbol gen-filters-ns) (gensym "filtersgen"))
+        gen-filters-path (str gen-filters-ns ".clj")]
+    (comp
+     (boot/with-pre-wrap [fileset]
+       (let [boot-config-edn-files (->> (boot/fileset-diff @prev-pre fileset)
+                                    boot/input-files
+                                    (boot/by-re [(re-pattern (str boot-config-edn "$"))]))
+             boot-config-edn-f (condp = (count boot-config-edn-files)
+                             0 (do (if verbose (util/info (str "Creating " boot-config-edn "\n")))
+                                   (io/file boot-config-edn)) ;; this creates a java.io.File
+                             1 (first boot-config-edn-files)  ;; this is a boot.tmpdir.TmpFile
+                             (throw (Exception.
+                                     (str "only one " boot-config-edn " file allowed; found "
+                                          (count boot-config-edn-files)))))
+             boot-config-edn-map (if (instance? boot.tmpdir.TmpFile boot-config-edn-f)
+                                   (-> (boot/tmp-file boot-config-edn-f) slurp read-string)
+                                   {})]
+         ;; (println "boot-config-edn-map: " boot-config-edn-map)
+
+         (if (:filters boot-config-edn-map)
+             fileset
+             (do
+               ;; step 1: read the edn config file and construct map
+               (let [filters-edn-files (->> (boot/input-files fileset)
+                                             (boot/by-name [filters-edn]))
+                     filters-edn-f (condp = (count filters-edn-files)
+                                        0 (throw (Exception. (str "Cannot find " filters-edn " file.")))
+                                        1 (first filters-edn-files)
+                                        ;; > 1
+                                        (throw (Exception.
+                                                (str "Only one " filters-edn "file allowed; found "
+                                                     (count filters-edn-files)))))
+                     filters-edn-map (-> (boot/tmp-file filters-edn-f) slurp read-string)
+                     filters-config-map (normalize-filter-configs filters-edn-map)
+                     filters-config-map {:filters (filter #(nil? (:class %))
+                                                            (:filters filters-config-map))}
+
+                     ;; step 2: inject filters config map into master config map
+                     master-config (-> boot-config-edn-map (assoc-in [:filters]
+                                                                     (:filters filters-config-map)))
+                     master-config (with-out-str (pp/pprint master-config))
+                     ;; step 3: create new master config file
+                     boot-config-edn-out-file (io/file workspace
+                                                       (if (instance? boot.tmpdir.TmpFile boot-config-edn-f)
+                                                         (boot/tmp-path boot-config-edn-f)
+                                                         boot-config-edn-f))
+                     ;; step 4: create filter generator
+                     gen-filters-content (stencil/render-file "migae/boot_gae/gen-filters.mustache"
+                                                               (assoc filters-config-map
+                                                                      :gen-filters-ns
+                                                                      gen-filters-ns))
+                     gen-filters-out-file (doto (io/file gen-filters-tmp-dir gen-filters-path)
+                                             io/make-parents)]
+                 ;; step 5: write new files
+                 (io/make-parents boot-config-edn-out-file)
+                 (spit boot-config-edn-out-file master-config)
+                 (spit gen-filters-out-file gen-filters-content)))))
+
+       (if verbose (util/info "Configuring filters...\n"))
+
+       ;; step 6: commit files to fileset
+       (reset! prev-pre
+               (-> fileset
+                   (boot/add-source workspace)
+                   (boot/add-source gen-filters-tmp-dir)
+                   boot/commit!)))
+
+     (builtin/aot :namespace #{gen-filters-ns})
+
+     (if keep
+       identity
+       (builtin/sift :include #{(re-pattern (str gen-filters-ns ".*.class"))}
+                     :invert true))
+     (if keep
+       (comp
+        (builtin/sift :to-resource #{(re-pattern boot-config-edn)})
+        (builtin/sift :to-asset #{(re-pattern gen-filters-path)}))
+       identity)
+     )))
+
 (boot/deftask target
   "target, using module name"
   [C no-clean bool "Don't clean target before writing project files"


Organize utility functions.

Organize utility functions.

--- src/multihash/core.clj
+++ src/multihash/core.clj
@@ -23,6 +23,50 @@
   (< 0 code 0x10))

+
+;; ## Utilities
+
+(defn- zero-pad
+  "Pads a string with leading zeroes up to the given width."
+  [width value]
+  (let [string (str value)]
+    (if (<= width (count string))
+      string
+      (-> width
+          (- (count string))
+          (repeat "0")
+          str/join
+          (str string)))))
+
+
+(defn- bytes->hex
+  "Converts a byte array into a lowercase hexadecimal string."
+  [^bytes value]
+  (let [width (* 2 (count value))
+        hex (-> (BigInteger. 1 value)
+                (.toString 16)
+                str/lower-case)]
+    (zero-pad width hex)))
+
+
+(defn- hex->bytes
+  "Parses a hexadecimal string into a byte array. Ensures that the resulting
+  array is zero-padded to match the hex string length."
+  ^bytes
+  [^String value]
+  (when (odd? (count value))
+    (throw (IllegalArgumentException.
+             (str "Input string '" value "' is not valid hex: number of "
+                  "characters (" (count value) ") is odd"))))
+  (let [width (/ (count value) 2)
+        data (.toByteArray (BigInteger. value 16))]
+    (if (= width (count data))
+      data
+      (let [data' (byte-array width)]
+        (System/arraycopy data 0 data' 0 (count data))
+        data'))))
+
+
 (defn- lookup-algo
   "Look up algorithm details by code number."
   [code]
@@ -42,8 +86,11 @@

 ;; ## Multihash Type

-;; Multihash identifiers have an `:algorithm` keyword and a `:digest` string giving
-;; the hexadecimal output on some byte content.
+;; Multihash identifiers have two properties:
+;;
+;; - `:code` is a numeric code for an algorithm entry in `digest-algorithms` or
+;;   an application-specific algorithm code.
+;; - `:digest` is a string holding the hex-encoded algorithm output.
 (deftype Multihash
   [^long code ^String digest _meta]

@@ -56,8 +103,8 @@
     (cond
       (identical? this that) true
       (instance? Multihash that)
-        (and (= code (:code that))
-             (= digest (:digest that)))
+        (and (= code   (.code   ^Multihash that))
+             (= digest (.digest ^Multihash that)))
       :else false))

   (hashCode [this]
@@ -82,6 +129,7 @@
       :algorithm (code->name code)
       :length (/ (count digest) 2)
       :digest digest
+      :bytes (hex->bytes digest)
       not-found))

   (valAt [this k]
@@ -103,29 +151,8 @@
 ; TODO: encode
 ; TODO: decode

-(defn- zero-pad
-  "Pads a string with leading zeroes up to the given width."
-  [width value]
-  (let [string (str value)]
-    (if (<= width (count string))
-      string
-      (-> width
-          (- (count string))
-          (repeat "0")
-          str/join
-          (str string)))))

-
-(defn hex-str
-  "Converts a byte array into a lowercase hexadecimal string."
-  [^bytes value]
-  (let [width (* 2 (count value))
-        hex (-> (BigInteger. 1 value)
-                (.toString 16)
-                str/lower-case)]
-    (zero-pad width hex)))
-
-
+; TODO: multimethod?
 (defn hash
   "Calculates the digest of the given byte array and returns a `Multihash`."
   [algorithm ^bytes content]
@@ -133,5 +160,5 @@
   (let [hex-digest (-> (digest-algorithms algorithm)
                        MessageDigest/getInstance
                        (.digest content)
-                       hex-str)]
+                       bytes->hex)]
     (Multihash. algorithm hex-digest nil)))


error cleared just by not showing the chart on mount but only on update.

--- statspop/src/statspop/charts/core.cljs
+++ statspop/src/statspop/charts/core.cljs
@@ -20,8 +20,6 @@
 ;; core functions to retain.

 (def chart-datom (atom nil))
-;; this throws an error on initial render because there isn't a chart-type to call. I'm ok with that.  It doesn't crash.  though maybe I can try it with bogus data?  or just catch the error.
-

 (defn show-chart
   [chart-data]
@@ -31,8 +29,9 @@
 (defn chart-component
   [chart-datom]
   (create-class
-   {:component-did-mount #(show-chart @chart-datom)
-    :component-did-update #(show-chart @chart-datom)
+   {:component-did-update #(show-chart @chart-datom)
     :display-name        "chart-component"
     :reagent-render      (fn [chart-datom]
                            [:div {:class (:class @chart-datom)}])}))
+
+;; this is going to throw an error whenever the chart is taken down unless I find some way to replace it with a blank chart or blank component.  Or just not have an option to take it down?  because why bother, it'll be reset for any new page or table anyway.


Pass package name as compile-time parameter

--- src/leiningen/droid/compile.clj
+++ src/leiningen/droid/compile.clj
@@ -6,6 +6,7 @@
             [leiningen.core.eval :as eval])
   (:use [leiningen.droid.utils :only [get-sdk-android-jar
                                       ensure-paths sh dev-build?]]
+        [leiningen.droid.manifest :only [get-package-name]]
         [leiningen.core
          [main :only [debug info abort]]
          [classpath :only [get-classpath]]]
@@ -50,7 +51,8 @@
   Uses neko to set compilation flags. Some neko macros and
   subsequently project code depends on them to eliminate
   debug-specific code when building the release."
-  [{{:keys [enable-dynamic-compilation start-nrepl-server]} :android,
+  [{{:keys [enable-dynamic-compilation start-nrepl-server
+            manifest-path]} :android,
     :keys [aot aot-exclude-ns] :as project}]
   (info "Compiling Clojure files...")
   (debug "Project classpath:" (get-classpath project))
@@ -73,7 +75,8 @@
     (let [form `(neko.init/with-properties
                   [:android-dynamic-compilation ~enable-dynamic-compilation
                    :android-start-nrepl-server ~start-nrepl-server
-                   :android-release-build ~(not dev-build)]
+                   :android-release-build ~(not dev-build)
+                   :android-package-name ~(get-package-name manifest-path)]
                   (doseq [namespace# '~nses]
                     (println "Compiling" namespace#)
                     (clojure.core/compile namespace#)))


New test: attempt to create job with improper name

--- test/emender_jenkins/rest_api_test.clj
+++ test/emender_jenkins/rest_api_test.clj
@@ -479,6 +479,12 @@
 (def create-job-postdata
     "{\"name\":\"test-Test_Product-1.0-Test_Book-en-US (preview)\", \"ssh_url_to_repo\":\"https://url-to-repo.git\", \"branch\":\"master\"}")

+(def create-job-postdata-bad-job-name-1
+    "{\"name\":\"xxx-Test_Product-1.0-Test_Book-en-US (preview)\", \"ssh_url_to_repo\":\"https://url-to-repo.git\", \"branch\":\"master\"}")
+
+(def create-job-postdata-bad-job-name-2
+    "{\"name\":\"test-Test_Product-1.0-Test_Book-en-US\", \"ssh_url_to_repo\":\"https://url-to-repo.git\", \"branch\":\"master\"}")
+
 (def default-request
     {:configuration
         {:jobs
@@ -497,7 +503,21 @@
                       read-request-body      (fn [request] create-job-postdata)
                       reload-job-list        (fn [response request] response)
                       send-response          (fn [response request] response)]
-                      (is (= (create-job default-request) {:status "ok"
+                      (is (= (create-job default-request) {:status  "ok"
                                                            :jobName "test-Test_Product-1.0-Test_Book-en-US (preview)"
-                                                           :command "create_job"}))
-)))
+                                                           :command "create_job"})))))
+
+(deftest test-create-job-bad-job-name-1
+    "Check the function emender-jenkins.rest-api/create-job."
+    (testing "the function emender-jenkins.rest-api/create-job."
+        (with-redefs [jenkins-api/create-job (fn [jenkins-url jenkins-auth include-jenkins-reply? job-name git-repo branch credentials-id metadata-directory metadata]
+                                                 (jenkins-api/ok-response-structure job-name "create_job" include-jenkins-reply? "created"))
+                      jenkins-api/start-job  (fn [jenkins-url jenkins-auth include-jenkins-reply? job-name]
+                                                 (jenkins-api/ok-response-structure job-name "build" include-jenkins-reply? "added to queue"))
+                      read-request-body      (fn [request] create-job-postdata-bad-job-name-1)
+                      reload-job-list        (fn [response request] response)
+                      send-response          (fn [response request] response)]
+                      (is (= (create-job default-request) {:status  400
+                                                           :headers {"Content-Type" "application/json"}
+                                                           :body "{\"status\":\"error\",\"jobName\":\"xxx-Test_Product-1.0-Test_Book-en-US (preview)\",\"command\":\"create_job\",\"message\":\"The name of job is wrong\"}"})))))
+


implemented inverted inxed in more functional way, and using transient collections for getting more speed to the building of the index

--- src/ontrail/search.clj
+++ src/ontrail/search.clj
@@ -7,7 +7,7 @@
             [clojure.string :as string])
   (:import [org.bson.types ObjectId]))

-(def minimum-term-length 3)
+(def minimum-term-length 2)
 (def search-limit 100)
 (def not-too-short-term? #(>= (count %) minimum-term-length))

@@ -19,44 +19,52 @@
 (defn kms[d]
   (str "km:" (quot d 1000)))

+(def re-term #"[a-zåäö#0-9\-]+")
+
+(defn to-term-seq [^String words]
+  (if words
+    (re-seq re-term (.toLowerCase (strip-html words)))
+    []))
+
+(defn to-bare-term-list [exercise]
+  (concat
+   (to-term-seq (:user exercise))
+   (to-term-seq (:body exercise))
+   (to-term-seq (:title exercise))
+   (to-term-seq (:sport exercise))
+   (to-term-seq (reduce (fn [a b]
+                          (if (and b (:body b))
+                            (str a " " (:body b))
+                            a))
+                        "" (:comments exercise)))
+                     ))
+
 (defn get-ex-terms [exercise]
-  (let [part (partial get exercise)
-        ex-date (:creationDate exercise)
+  (let [ex-date (:creationDate exercise)
         ex-distance (:distance exercise)
-        words (.toLowerCase (str (part :user) " " (part :sport) " "
-                                 (part :body) " " (part :title) " "
-                                 (tags-to-string (part :tags))))
-        clean-words (string/replace (strip-html words) #"[^a-zåäö#0-9]+" " ")
-        bare-term-list (string/split clean-words #" +")
-        term-list (filter not-too-short-term? bare-term-list)
-        extra-terms (conj term-list
-                          (str "d:" (:distance exercise))
-                          (str "y:" (time/year ex-date))
-                          (str "m:" (time/month ex-date)))]
-    (if (number? ex-distance)
-      (conj extra-terms (kms ex-distance))
-      extra-terms)))
-
+        bare-term-list (to-bare-term-list exercise)
+        term-list (filter not-too-short-term? bare-term-list)]
+    term-list))

 (def inverted-index (atom {}))

-(defn fst [x y] x)
+(defn insert-term [assoc-fn index ex-id term]
+  (if-let [postings (index term)]
+    (assoc-fn index term #{ex-id})
+    (let [new-val (conj (index term) ex-id)]
+      (assoc-fn index term new-val))))

-(defn insert-term [ex-id term]
-  (let [index @inverted-index]
-    (if (not (contains? index term))
-      (fst 1 (swap! inverted-index assoc term #{ex-id}))
-      (fst 0 (let [new-val (clojure.set/union (get index term) #{ex-id})]
-        (swap! inverted-index assoc term new-val))))))
-
-(defn insert-exercise-inmem-index [ex]
+(defn insert-exercise-to-index [assoc-fn index ex]
   (let [terms (get-ex-terms ex)
         ex-id (str (:_id ex))]
-    (reduce + (map (partial insert-term ex-id) terms))))
+    (reduce (partial insert-term assoc-fn index) terms)))

+(def insert-exercise-inmem-index
+  (partial insert-exercise-to-index assoc @inverted-index))
+
 (defn rebuild-index []
-  (do (reset! inverted-index {})
-      (apply + (map insert-exercise-inmem-index (mc/find-maps EXERCISE {})))))
+  (let [new-index (transient {})]
+    (count (do (reset! inverted-index (persistent! (reduce (partial insert-exercise-to-index assoc!) new-index (mc/find-maps EXERCISE {}))))))))

 (defn search-ids [& terms]
   (let [filtered-terms (filter not-too-short-term? terms)]
@@ -73,4 +81,4 @@
   (let [query-string (:q query)]
     (if (nil? query-string)
       '()
-      (apply search (string/split query-string #" +")))))
+      (apply search (re-seq re-term (.toLowerCase query-string))))))


update and format event docstrings

update and format event docstrings

--- src/overtone/event.clj
+++ src/overtone/event.clj
@@ -28,11 +28,14 @@
      true)))

 (defn on-event
-  "Takes an event-type (name of the event) a key (to refer back to this handler
-  in the future) and a handler fn. Runs handler whenever events of type event-
-  type are fired.  The handler can optionally accept a single event argument,
-  which is a map containing the :event-type property and any other properties
-  specified when it was fired.
+  "Runs handler whenever events of event-type are fired asynchronously. This
+  asynchronous behaviour can be overridden if required - see sync-event for
+  more information. Events may be triggered with the fns event and sync-event.
+
+  Takes an event-type (name of the event), a handler fn and a key (to refer
+  back to this handler in the future). The handler can optionally accept a
+  single event argument, which is a map containing the :event-type property
+  and any other properties specified when it was fired.

   (on-event \"/tr\" handler ::status-check )
   (on-event :midi-note-down (fn [event]
@@ -44,18 +47,29 @@
   (on-event* event-handlers* event-type key handler))

 (defn on-sync-event
-  "Synchronously runs handler whenever events of type event-type are fired.
-  The handler can optionally accept a single event argument, which is a map
-  containing the :event-type property and any other properties specified when it
-  was fired. If handler returns :done it will automatically be removed and will
-  therefore no longer respond to future matching events."
+  "Runs handler whenever events of type event-type are fired synchronously on
+  the event handling thread i.e. causes the event handling thread to block until
+  all sync events have been handled. Events may be triggered with the fns event
+  and sync-event.
+
+  Takes an event-type (name of the event), a handler fn and a key (to refer
+  back to this handler in the future). The handler can optionally accept a
+  single event argument, which is a map containing the :event-type property
+  and any other properties specified when it was fired.
+
+  (on-event \"/tr\" handler ::status-check )
+  (on-event :midi-note-down (fn [event]
+                              (funky-bass (:note event)))
+                            ::midi-note-down-hdlr)
+
+  Handlers can return :done to be removed from the handler list after execution."
   [event-type handler key]
   (on-event* sync-event-handlers* event-type key handler))

 (defn remove-handler
   "Remove an event handler previously registered to handle events of event-type.
-   Removes both sync and async handlers with a given key for a particular event
-  type
+  Removes both sync and async handlers with a given key for a particular event
+  type.

   (defn my-foo-handler [event] (do-stuff (:val event))

@@ -63,8 +77,7 @@
   (event :foo :val 200) ; my-foo-handler gets called with:
                         ; {:event-type :foo :val 200}
   (remove-handler :foo ::bar-key)
-  (event :foo :val 200) ; my-foo-handler no longer called
-  "
+  (event :foo :val 200) ; my-foo-handler no longer called"
   [event-type key]
   (dosync
     (doseq [handler-ref* [event-handlers* sync-event-handlers*]]
@@ -72,7 +85,7 @@
         (alter handler-ref* assoc event-type (dissoc handlers key))))))

 (defn clear-handlers
-  "Remove all handlers for events of type event-type."
+  "Remove all handlers (both sync and async) for events of type event-type."
   [event-type]
   (dosync
     (alter event-handlers* dissoc event-type)
@@ -80,9 +93,10 @@
   nil)

 (defn- run-handler-with-known-arity [[f arity] & args]
-  "Expects a tuple of fn with arity and applies fn to the first  arity number of args. If arity
-   is -1 it assumes that the fn is a var and so calculates arity on the fly allowing for the
-   potential rebinding of the fn with a different arity."
+  "Expects a tuple of fn with arity and applies fn to the first  arity number of
+  args. If arity is -1 it assumes that the fn is a var and so calculates arity
+  on the fly allowing for the potential rebinding of the fn with a different
+  arity."
   (let [arity (if (= arity -1) (arg-count @f) arity)]
     (try
       (apply f (take arity args))
@@ -91,7 +105,8 @@
                    (with-out-str (.printStackTrace e)))))))

 (defn- handle-event
-  "Runs the event handlers for the given event, and removes any handler that returns :done."
+  "Runs the event handlers for the given event, and removes any handler that
+  returns :done."
   [handlers* event]
   (log/debug "handling event: " event)
   (let [event-type (:event-type event)
@@ -107,6 +122,7 @@

 (defn event
   "Fire an event of type event-type with any number of additional properties.
+
   NOTE: an event requires key/value pairs, and everything gets wrapped into an
   event map.  It will not work if you just pass values.

@@ -122,9 +138,10 @@
       (.execute thread-pool #(handle-event event-handlers* event)))))

 (defn sync-event
-  "Runs all event handlers synchronously regardless of whether they were declared as async or not.
-   If handlers create new threads which generate events, these will revert back to the default
-   behaviour of event (i.e. not forced sync). See event."
+  "Runs all event handlers synchronously regardless of whether they were
+  declared as async or not. If handlers create new threads which generate
+  events, these will revert back to the default behaviour of event (i.e. not
+  forced sync). See event."
   [& args]
   (binding [FORCE-SYNC? true]
     (apply event args)))


add matchbrackets addon

add matchbrackets addon

--- src/parinfer/core.cljs
+++ src/parinfer/core.cljs
@@ -5,10 +5,14 @@
     [om.core :as om :include-macros true]
     [om.dom :as dom :include-macros true]
     [sablono.core :refer-macros [html]]
+
     [cljsjs.codemirror]
     [cljsjs.codemirror.mode.clojure]
     [cljsjs.codemirror.keymap.vim]
+    [cljsjs.codemirror.addon.edit.matchbrackets]
+
     [parinfer.formatter :refer [format-text]]
+
     ))

 (enable-console-print!)
@@ -95,9 +99,10 @@
   (reset! frame-updated? false))

 (def editor-opts
-  {:lineNumbers "true"
+  {:lineNumbers true
    :mode "clojure"
    :keyMap "vim"
+   :matchBrackets true
    })

 (defn setup-editor


Implement "src" and "artifact" modes in doc

--- src/grimoire/doc.clj
+++ src/grimoire/doc.clj
@@ -12,7 +12,9 @@
             [detritus.var :refer [var->ns var->sym macro?]]
             [detritus.update :refer [update]]))

-(defn var->type [v]
+(defn var->type
+
+  [v]
   {:pre [(var? v)]}
   (let [m (meta v)]
     (cond (:macro m)                            :macro
@@ -24,19 +26,34 @@
 (defn var->thing

   [{:keys [groupid artifactid version]} var]
-  ;; FIXME: get the ns, name out of the var & make a :def thing
+  {:pre [(string? groupid)
+         (string? artifactid)
+         (string? version)
+         (var? var)]}
   (t/->Def groupid
            artifactid
            version
            (name (var->ns var))
            (name (var->sym var))))

+(defn ns->thing
+
+  [{:keys [groupid artifactid version]} ns-symbol]
+  {:pre [(symbol? ns-symbol)
+         (string? groupid)
+         (string? artifactid)
+         (string? version)]}
+  (t/->Ns groupid
+          artifactid
+          version
+          (name ns-symbol)))
+
 (defn var->src
   "Adapted from clojure.repl/source-fn. Returns a string of the source code for
   the given var, if it can find it. Returns nil if it can't find the source.

   Example: (var->src #'clojure.core/filter)"
-
+
   [v]
   {:pre [(var? v)]}
   (when-let [filepath (:file (meta v))]
@@ -55,13 +72,27 @@
             (read (java.io.PushbackReader. pbr)))
           (str text))))))

-(defn ns-stringifier [x]
+(defn ns-stringifier
+
+  [x]
   (cond (instance? clojure.lang.Namespace x)
-        ,,(ns-name x)
-
+        ,,(name (ns-name x))
         (string? x)
         ,,x
+        (symbol? x)
+        ,,(name x)
+        :else
+        ,,(throw
+           (Exception.
+            (str "Don't know how to stringify " x)))))

+(defn name-stringifier
+
+  [x]
+  (cond (symbol? x)
+        ,,(name x)
+        (string? x)
+        ,,x
         :else
         ,,(throw
            (Exception.
@@ -73,7 +104,7 @@
   (let [docs (-> (meta var)
                  (assoc  :src  (var->src var)
                          :type (var->type var))
-                 (update :name name)
+                 (update :name name-stringifier)
                  (update :ns   ns-stringifier))]
     (api/write-meta config
                     (var->thing config var)
@@ -100,6 +131,7 @@
   #{#'clojure.data/Diff})

 (defn write-docs-for-ns
+
   [config ns]
   (let [ns-vars (->> (ns-publics ns) vals (remove var-blacklist))
         macros  (filter macro? ns-vars)
@@ -107,6 +139,10 @@
                               (not (macro? %1)))
                         ns-vars)
         vars    (filter #(not (fn? @%1)) ns-vars)]
+
+    (let [meta  (-> ns the-ns meta)
+          thing (ns->thing config ns)]
+      (api/write-meta config thing meta))

     ;; write per symbol docs
     (doseq [var ns-vars]
@@ -121,14 +157,26 @@

 (defn -main

-  [groupid artifactid version pattern target]
-  (let [pattern (re-pattern pattern)
-        config  {:groupid    groupid
+  [groupid artifactid version target files-thing]
+  (let [config  {:groupid    groupid
                  :artifactid artifactid
                  :version    version
                  :datastore  {:docs target}}]
-    (doseq [ns (tns.f/find-namespaces
-                (cp/classpath))]
-      (when (re-matches pattern (name ns))
+    (if (= :classpath files-thing)
+      ;; classpath searching case
+      (let [pattern (format ".*?/%s/%s/%s.*"
+                            (string/replace groupid "." "/") artifactid version)
+            pattern (re-pattern pattern)]
+        (doseq [e (cp/classpath)]
+          (when (re-matches pattern (str e))
+            (doseq [ns (tns.f/find-namespaces [e])]
+              (when-not (= ns 'clojure.parallel) ;; FIXME: get out nobody likes you
+                (require ns)
+                (write-docs-for-ns config ns))))))
+
+      ;; source dirs vector case
+      (doseq [ns (->> files-thing
+                      (map io/file)
+                      (tns.f/find-namespaces))]
         (require ns)
         (write-docs-for-ns config ns)))))


Rework var->thing for the platform structure

--- src/grimoire/doc.clj
+++ src/grimoire/doc.clj
@@ -38,17 +38,20 @@
           ,,:var)))

 (defn var->thing
-
-  [{:keys [groupid artifactid version]} var]
+  "Function from a groupid, artifactid, version, platform and a var to the Def
+  Thing representing the given var in the described Artifact."
+  [{:keys [groupid artifactid version platform]} var]
   {:pre [(string? groupid)
          (string? artifactid)
          (string? version)
+         (string? platform)
          (var? var)]}
-  (t/->Def groupid
-           artifactid
-           version
-           (name (var->ns var))
-           (name (var->sym var))))
+  (-> (t/->Group    groupid)
+      (t/->Artifact artifactid)
+      (t/->Version  version)
+      (t/->Platform platform)
+      (t/->Ns       (name (var->ns var)))
+      (t/->Def      (name (var->sym var)))))

 (defn ns->thing


Fressian codec cleanup.

Fressian codec cleanup.

--- core/src/immutant/codecs/fressian.clj
+++ core/src/immutant/codecs/fressian.clj
@@ -24,13 +24,9 @@
   (:import java.nio.ByteBuffer))

 (defn ^:internal ^:no-doc fressian-codec
-  [& options]
-  (let [{:keys [name content-type read-handlers write-handlers]
-         :or {name :fressian content-type "application/fressian"}}
-        (-> options
-          kwargs-or-map->raw-map
-          (validate-options fressian-codec))
-        fressian-write (try-resolve-throw `clojure.data.fressian/write
+  [{:keys [name content-type read-handlers write-handlers]
+    :or {name :fressian content-type "application/fressian"}}]
+  (let [fressian-write (try-resolve-throw `clojure.data.fressian/write
                          "add org.clojure/data.fressian to your dependencies.")
         fressian-read (try-resolve 'clojure.data.fressian/read)]
     (make-codec
@@ -50,9 +46,6 @@
                   (catch Throwable e
                     (throw (decode-error :fressian data e))))))))

-(set-valid-options! fressian-codec #{:name :content-type :type
-                                     :read-handlers :write-handlers})
-
 (defn register-fressian-codec
   "Creates and registers a codec that can be used to encode to/decode from Fressian.

@@ -65,6 +58,8 @@
    *not* merged with the default handlers - you are responsible for
    that (as shown in the linked example).

+   You must add `org.clojure/data.fressian` as a dependency.
+
    options can be a map or kwargs, with these valid keys [default]:

    * :name - the name of the encoding [:fressian]
@@ -74,4 +69,11 @@
    * :read-handlers the full set of handlers to use for reading. If not
      provided, the built-in Fressian defaults are used [nil]"
   [& options]
-  (register-codec (apply fressian-codec options)))
+  (-> options
+    kwargs-or-map->raw-map
+    (validate-options register-fressian-codec)
+    fressian-codec
+    register-codec))
+
+(set-valid-options! register-fressian-codec #{:name :content-type :type
+                                              :read-handlers :write-handlers})


Added a few meta tags for the front page (#98)

* Update pages.clj

--- src/pronouns/pages.clj
+++ src/pronouns/pages.clj
@@ -159,11 +159,16 @@
 (defn front []
   (let [abbreviations (take 6 (u/abbreviate @pronouns-table))
         links (map make-link abbreviations)
-        title "Pronoun Island"]
-    (html
-     [:html
-      [:head
-       [:title title]
+        title "Pronoun Island"
+        description "Pronoun.is is a website for personal pronoun usage examples."]
+    (html
+     [:html
+      [:head
+       [:title title]
+       [:meta {:name "description" :content description}]
+       [:meta {:name "twitter:card" :content "summary"}]
+       [:meta {:name "twitter:title" :content title}]
+       [:meta {:name "twitter:description" :content description}]
        [:meta {:name "viewport" :content "width=device-width"}]
        [:meta {:charset "utf-8"}]
        [:link {:rel "stylesheet" :href "/pronouns.css"}]]


catching 500 as well

catching 500 as well

--- src/proxmox/remote.clj
+++ src/proxmox/remote.clj
@@ -41,7 +41,7 @@
   (try+
     (let [res (call- client/post "/access/ticket" {:form-params login-creds})]
       (select-keys res [:CSRFPreventionToken :ticket]))
-    (catch [:status 401 ] e
+    (catch #(#{401 500} (:status %)) e
       (throw (ExceptionInfo. "Failed to login" config)))))

 (def auth-headers
@@ -51,6 +51,7 @@
         (assoc
           (assoc {} "Cookie" (str "PVEAuthCookie=" ticket)) "CSRFPreventionToken" CSRFPreventionToken)))))

+(auth-headers)
 (defn prox-post
   "A post against a proxmox instance with provided params"
   ([api] (prox-post api nil))


Fix typo

Fix typo

--- satori-rules/rules/infra/mesos.clj
+++ satori-rules/rules/infra/mesos.clj
@@ -35,7 +35,7 @@
       (by :host
         (set-state (< 120)
           (changed :state
-            (shoud-alarm-every 60
+            (should-alarm-every 60
               (! {:note "Mesos Master 重启了"
                   :level 1
                   :expected 300


Updating name of a config variable.

Updating name of a config variable.

--- test/cmr/system_int_test/search/granule_search_index_name_test.clj
+++ test/cmr/system_int_test/search/granule_search_index_name_test.clj
@@ -18,7 +18,7 @@
     ;; When this test is run in CI the set variable will not influence the cmr-search-app
     ;; or cmr-indexer-app which are running in a separate process.
     ;; The CI script must set this environment variable to make those work.
-    (config/set-config-value! :separate-coll-index "C1-SEP_PROV1,C2-SEP_PROV1")
+    (config/set-config-value! :colls-with-separate-indexes "C1-SEP_PROV1,C2-SEP_PROV1")
     (ingest/reset)
     (ingest/create-provider "SEP_PROV1")
     (f)


Resource Most Recent Snapshot Fails on Empty Database

Closes #1

--- src/lens/handler.clj
+++ src/lens/handler.clj
@@ -758,17 +758,24 @@
     (resource-defaults)

     :exists? false
-    :existed? true
+
+    :existed?
+    (fnk [db]
+      (some->> (api/all-snapshots db)
+               (into [])
+               (sort-by :db/txInstant)
+               (last)
+               (hash-map :snapshot)))
+
     :moved-temporarily? true

     :handle-moved-temporarily
-    (fnk [db]
-      (->> (api/all-snapshots db)
-           (into [])
-           (sort-by :db/txInstant)
-           (last)
-           (snapshot-path path-for)
-           (to-location)))))
+    (fnk [snapshot]
+      (-> (snapshot-path path-for snapshot)
+          (to-location)))
+
+    :handle-not-found
+    (error-body path-for "No snapshot found.")))

 ;; ---- Query -----------------------------------------------------------------


Use let, not def. Fix docs

Use let, not def. Fix docs

--- src/riemann/keenio.clj
+++ src/riemann/keenio.clj
@@ -10,8 +10,8 @@
   "POST to Keen IO."
   [collection project-id write-key request]

-  (def final-event-url
-    (str event-url project-id "/events/" collection))
+  (let [final-event-url
+    (str event-url project-id "/events/" collection)]

   (client/post final-event-url
                {:body (json/generate-string request)
@@ -20,7 +20,7 @@
                 :conn-timeout 5000
                 :content-type :json
                 :accept :json
-                :throw-entire-message? true}))
+                :throw-entire-message? true})))

 (defn keenio
   "Creates a keen adapter. Takes your Keen project id and write key, and
@@ -28,7 +28,7 @@
   event will be sent.

 (streams
-  (let [kio (keenio \"COLLECTION_NAME\", \"PROJECT_ID\" \"WRITE_KEY\")]
+  (let [kio (keenio \"COLLECTION_NAME\" \"PROJECT_ID\" \"WRITE_KEY\")]
     (where (state \"error\") kio)))"

   [collection project-id, write-key]


Minor refactoring

Minor refactoring

--- src/ring_curl/core.clj
+++ src/ring_curl/core.clj
@@ -17,8 +17,8 @@
   (if-not (blank? s) (str " " s)))

 (defn method [request]
-  (let [request-method (:request-method request)]
-    (str "-X " (upper-case (if (nil? request-method) "get" (name request-method))) (if (= :head request-method) " --head"))))
+  (let [request-method (or (:request-method request) :get)]
+    (str "-X " (upper-case (name request-method)) (if (= :head request-method) " --head"))))

 (defn- scheme [request]
   (let [s (:scheme request)]


Fix dev tools borked by c1de64b

Fix dev tools borked by c1de64b

--- src/lt/objs/dev.cljs
+++ src/lt/objs/dev.cljs
@@ -4,12 +4,13 @@
             [lt.objs.cache :as cache]
             [lt.objs.notifos :as notifos]
             [lt.objs.command :as cmd]
+            [lt.util.ipc :as ipc]
             [lt.objs.app :as app]))

 (cmd/command {:command :dev-inspector
               :desc "Dev: Open Developer Tools"
               :exec (fn []
-                      (.send app/ipc "toggleDevTools" (app/window-number)))})
+                      (ipc/send "toggleDevTools" (app/window-number)))})

 (cmd/command {:command :toggle-edge
               :desc "Toggle edge"


hadny debugging fn

hadny debugging fn

--- src/merlion/core.clj
+++ src/merlion/core.clj
@@ -16,6 +16,8 @@
     watcher
     (do (if watcher (close! watcher))
         (etcd/watch-prefix new-prefix))))
+(defn spy [a] (pprint a) a)
+

 (defn proxy-handler1 [backends-ch req]
   (println [:req req :ch backends-ch] )


Allow creating textures from pixmaps

Allow creating textures from pixmaps

--- src/play_clj/g2d.clj
+++ src/play_clj/g2d.clj
@@ -1,6 +1,6 @@
 (ns play-clj.g2d
   (:require [play-clj.utils :as u])
-  (:import [com.badlogic.gdx.graphics Texture]
+  (:import [com.badlogic.gdx.graphics Pixmap Texture]
            [com.badlogic.gdx.graphics.g2d Animation BitmapFont NinePatch
             ParticleEffect TextureAtlas TextureRegion]
            [play_clj.entities TextureEntity NinePatchEntity
@@ -22,6 +22,8 @@
     (cond
       (string? arg)
       (-> ^String arg Texture. TextureRegion.)
+      (isa? (type arg) Pixmap)
+      (-> ^Pixmap arg Texture. TextureRegion.)
       (:object arg)
       (TextureRegion. ^TextureRegion (:object arg))
       :else
@@ -31,10 +33,10 @@
   "Returns an entity based on [TextureRegion](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/TextureRegion.html).

     (texture \"image.png\")
-    (texture \"image.png\" :flip true false)
     (texture \"image.png\"
              :flip true false
-             :set-region 0 0 100 100)"
+             :set-region 0 0 100 100)
+    (texture (texture \"image.png\"))"
   [arg & options]
   `(let [entity# (texture* ~arg)]
      (u/calls! ^TextureRegion (u/get-obj entity# :object) ~@options)


- use more standard col-span instead of colSpan

--- src/re_com/date.cljs
+++ src/re_com/date.cljs
@@ -18,7 +18,7 @@
      [:tr
       [:th {:class "prev available"}
        [:i {:class "fa fa-arrow-left icon-arrow-left glyphicon glyphicon-arrow-left"}]]
-      [:th {:class "month" :colSpan "5"} "Aug 2014"]
+      [:th {:class "month" :col-span "5"} "Aug 2014"]
       [:th {:class "next available"}
        [:i {:class "fa fa-arrow-right icon-arrow-right glyphicon glyphicon-arrow-right"}]]]
      [:tr [:th "Su"][:th "Mo"][:th "Tu"][:th "We"][:th "Th"][:th "Fr"][:th "Sa"]]


Improved version of `deref-or-value-peek` because the derefable Reagent data types have different ways of retrieving the value without causing capture

--- src/re_com/util.cljs
+++ src/re_com/util.cljs
@@ -1,6 +1,7 @@
 (ns re-com.util
   (:require
     [clojure.set :refer [superset?]]
+    [reagent.ratom :refer [RAtom Reaction RCursor Track Wrapper]]
     [goog.date.DateTime]
     [goog.date.UtcDateTime]))

@@ -21,23 +22,38 @@
 (defn deref-or-value
   "Takes a value or an atom
   If it's a value, returns it
-  If it's an atom, returns the value inside it by derefing
+  If it's a Reagent object that supports IDeref, returns the value inside it by derefing
   "
   [val-or-atom]
-  (if (satisfies? IDeref val-or-atom) @val-or-atom val-or-atom))
+  (if (satisfies? IDeref val-or-atom)
+    @val-or-atom
+    val-or-atom))

 (defn deref-or-value-peek
   "Takes a value or an atom
   If it's a value, returns it
-  If it's an atom, returns the value inside it, but WITHOUT derefing
-  The arg validation code uses this as calling deref-or-value can cause different behaviour between dev (where we validate)
-  and prod (where we don't).
-  This was experienced in popover-content-wrapper with the position-injected atom which is not derefed there, however
-  the dev-only validation caused it to be derefed, modifying its render behaviour
+  If it's a Reagent object that supports IDeref, returns the value inside it, but WITHOUT derefing
+
+  The arg validation code uses this, since calling deref-or-value adds this arg to the watched ratom list for the component
+  in question, which in turn can cause different rendering behaviour between dev (where we validate) and prod (where we don't).
+
+  This was experienced in popover-content-wrapper with the position-injected atom which was not derefed there, however
+  the dev-only validation caused it to be derefed, modifying its render behaviour and causing mayhem and madness for the developer.
+
+  See below that different Reagent types have different ways of retrieving the value without causing capture, although in the case of
+  Track, we just deref it as there is no peek or state, so hopefully this won't cause issues (surely this is used very rarely).
   "
   [val-or-atom]
-  (if (satisfies? IDeref val-or-atom) val-or-atom.state val-or-atom))
+  (if (satisfies? IDeref val-or-atom)
+    (cond
+      (instance? RAtom    val-or-atom) val-or-atom.state
+      (instance? Reaction val-or-atom) (._peek-at val-or-atom)
+      (instance? RCursor  val-or-atom) (._peek val-or-atom)
+      (instance? Track    val-or-atom) @val-or-atom
+      (instance? Wrapper  val-or-atom) val-or-atom.state
+      :else                            (throw (js/Error. "Unknown reactive data type")))
+    val-or-atom))

 (defn get-element-by-id


Add datetime column to export data

Add datetime column to export data

--- src/polismath/darwin/export.clj
+++ src/polismath/darwin/export.clj
@@ -57,6 +57,10 @@
 ;; cid, author, aggrees, disagrees, mod, text

+(defn datetime [timestamp]
+  (str (java.util.Date. timestamp)))
+
+
 (defn full-path [darwin filename]
   (str (or (-> darwin :config :export :temp-dir) "/tmp/")
        filename))
@@ -103,9 +107,11 @@

 (defn get-conversation-votes
   [darwin & args]
-  ;; Flip the signs on the votes XXX (remove when we switch)
-  (map #(update-in % [:vote] (partial * -1))
-       (apply get-conversation-votes* darwin args)))
+  (->> (apply get-conversation-votes* darwin args)
+       ;; Flip the signs on the votes XXX (remove when we switch)
+       (map #(update-in % [:vote] (partial * -1)))
+       (map #(assoc % :datetime (datetime (:created %))))))
+

 (defn get-conversation-data
   "Return a map with :topic and :description keys"
@@ -117,7 +123,7 @@
         (ko/where {:zid zid})))
     first))

-(defn get-participation-data
+(defn get-participation-data*
   ([darwin zid]
    (kdb/with-db (db-spec darwin)
      (ko/select "participants"
@@ -128,6 +134,12 @@
      (ko/select "participants"
        (ko/fields :zid :pid :vote_count :created)
        (ko/where {:zid zid :created [<= final-timestamp]})))))
+
+(defn get-participation-data
+  [& args]
+  (->> (apply get-participation-data* args)
+       (map (fn [data]
+              (assoc data :datetime (datetime (:created data)))))))

 (defn get-comments-data
@@ -320,7 +332,10 @@
             ;; keep an eye on it for now... XXX
             aggrees (filter #(= 1 (:vote %)) comment-votes)
             disagrees (filter #(= -1 (:vote %)) comment-votes)]
-        (assoc comment-data :aggrees (count aggrees) :disagrees (count disagrees))))
+        (assoc comment-data
+               :aggrees (count aggrees)
+               :disagrees (count disagrees)
+               :datetime (datetime (:created comment-data)))))
     comments))

@@ -413,14 +428,16 @@
       (update-in [:stats-history]
                  (partial scsv/vectorize {:header [:n-votes :n-comments :n-visitors :n-voters :n-commenters]}))
       (update-in [:votes]
-                 (partial scsv/vectorize {:header [:created :tid :pid :vote]
+                 (partial scsv/vectorize {:header [:created :datetime :tid :pid :vote]
                                           :format-header {:created   "timestamp"
+                                                          :datetime  "datetime"
                                                           :tid       "comment-id"
                                                           :pid       "voter-id"
                                                           :vote      "vote"}}))
       (update-in [:comments]
-                 (partial scsv/vectorize {:header [:created :tid :pid :aggrees :disagrees :mod :txt]
+                 (partial scsv/vectorize {:header [:created :datetime :tid :pid :aggrees :disagrees :mod :txt]
                                           :format-header {:created   "timestamp"
+                                                          :datetime  "datetime"
                                                           :tid       "comment-id"
                                                           :pid       "author-id"
                                                           :aggrees   "agrees"
@@ -580,7 +597,9 @@
 (comment
   (require '[polismath.runner :as runner])
   (def darwin (:darwin runner/system))
-  (export-conversation {;;:zid 310273
+  runner/system
+  (export-conversation runner/system
+                       {;;:zid 310273
                         :zinvite "7scufp"
                         :format :csv
                         :filename "cljwebdev.zip"


bug in :boolean instruction bindings

bug in :boolean instruction bindings

--- src/push/types/type/boolean.clj
+++ src/push/types/type/boolean.clj
@@ -27,6 +27,17 @@
     :tags #{:boolean :conversion}
     (d/consume-top-of :scalar :as :value)
     (d/calculate [:value] #(exotics/scalar-to-truth-table %1 2) :as :table)
+    (d/push-onto :booleans :table)))
+
+
+
+(def boolean-3bittable
+  (core/build-instruction
+    boolean-3bittable
+    "`:boolean-3bittable` pops the top `:scalar` item and pushes the result of applying `(exotics/scalar-to-truth-table i 3)` to :booleans"
+    :tags #{:boolean :conversion}
+    (d/consume-top-of :scalar :as :value)
+    (d/calculate [:value] #(exotics/scalar-to-truth-table %1 3) :as :table)
     (d/push-onto :booleans :table)))


add optional blogid to image api

add optional blogid to image api

--- src/smallblog/core.clj
+++ src/smallblog/core.clj
@@ -105,14 +105,21 @@
     [blogid request page pagination]
     (data/get-posts blogid pagination (* page pagination)))

+(defn -get-page-from-req [request]
+    (let [req-params (:params request)]
+        (if (contains? req-params "page")
+            (Integer/parseInt (get req-params "page"))
+            0)))
+
+(defn -get-pagination-from-req [request]
+    (let [req-params (:params request)]
+        (if (contains? req-params "pagination")
+            (Integer/parseInt (get req-params "pagination"))
+            10)))
+
 (defn render-html-posts-helper [blogid request]
-    (let [req-params (:params request)
-          page (if (contains? req-params "page")
-                   (Integer/parseInt (get req-params "page"))
-                   0)
-          pagination (if (contains? req-params "pagination")
-                         (Integer/parseInt (get req-params "pagination"))
-                         10)]
+    (let [page (-get-page-from-req request)
+          pagination (-get-pagination-from-req request)]
         (render-html-posts
             (-get-posts-with-pagination blogid request page pagination)
             (util/uri-from-request request)
@@ -257,10 +264,11 @@
                (let [userid (:id (data/get-current-user))]
                    (json-response (render-blog-json
                                       (data/make-blog userid title)))))
-           (GET "/api/blog/:bid/post/" [bid]
-               (let [bid (Integer/parseInt bid)]
-                   ; XXX need to paginate the API
-                   (json-response (doall (for [post (data/get-posts bid 10 0)]
+           (GET "/api/blog/:bid/post/" [bid :as request]
+               (let [bid (Integer/parseInt bid)
+                     page (-get-page-from-req request)
+                     pagination (-get-pagination-from-req request)]
+                   (json-response (doall (for [post (data/get-posts bid pagination page)]
                                              (render-post-json post))))))
            (POST "/api/blog/:bid/post/" [bid title content]
                (if (not (allow-access? #{(keyword (str data/owner-blog-prefix bid))}
@@ -268,10 +276,16 @@
                    (redirect templates/*permission-denied-uri*)
                    (json-response (render-post-json
                                       (data/make-post (Integer/parseInt bid) title content)))))
-           (GET "/api/images/" []
-               (let [userid (:id (data/get-current-user))]
+           (GET "/api/images/" [:as request]
+                (let [req-params (:params request)
+                      blog (if (contains? req-params "blog")
+                               (Integer/parseInt (get req-params "blog"))
+                               nil)
+                      page (-get-page-from-req request)
+                      pagination (-get-pagination-from-req request)
+                      userid (:id (data/get-current-user))]
                    (json-response (render-json-images
-                                      (data/get-images userid 10 0)))))
+                                      (data/get-images userid blog pagination page)))))
            ; (GET "/api/post/:id" [id]
            ; 	(json-response (data/get-post id)))
            ; (PUT "/api/post/:id" [id]


Disable some routing for now

Disable some routing for now

--- src/trak/routes.cljs
+++ src/trak/routes.cljs
@@ -10,11 +10,13 @@
 ;; -------------------------
 ;; Bidi routes

-(def routes ["/" {""        :index
-                  "cities/" {[:id] :city}
-                  "venues/" {[:id] {""                :venue
-                                    ["/" :venue-name] :venue}
-                             }}])
+(def routes ["/" {"" :index
+                  ;"cities/" {[:id] :city}
+                  ;"venues/" {[:id] {""                :venue
+                  ;                  ["/" :venue-name] :venue}
+                  ;           }
+                  }
+             ])

 ;; -------------------------
 ;; History
@@ -62,4 +64,5 @@

 (defmethod handler :index [path route-params]
   (utils/info ["Handled path " path route-params])
-  (pubsub/publish :actions {:action :find-albums}))
+  ;(pubsub/publish :actions {:action :find-albums})
+  )


Set default fetch size to 100 on lazy queries.

--- src/suricatta/impl.clj
+++ src/suricatta/impl.clj
@@ -201,13 +201,13 @@
     (let [^DSLContext context (proto/get-context ctx)
           ^ResultQuery query (->> (into-array Object (rest sqlvec))
                                   (.resultQuery context (first sqlvec)))]
-      (.fetchSize query (get opts :fetch-size 60))
+      (.fetchSize query (get opts :fetch-size 100))
       (.fetchLazy context query)))

   org.jooq.ResultQuery
   (fetch-lazy [^ResultQuery query ^Context ctx opts]
     (let [^DSLContext context (proto/get-context ctx)]
-      (.fetchSize query (get opts :fetch-size 60))
+      (.fetchSize query (get opts :fetch-size 100))
       (.fetchLazy context query)))

   suricatta.types.Deferred


Crawl data

Crawl data

--- src/whitman/core.clj
+++ src/whitman/core.clj
@@ -1,5 +1,7 @@
 (ns whitman.core
-  (:require [whitman.config :as config])
+  (:require [whitman.config :as config]
+            [whitman.crawler :as crawler]
+            [whitman.db :as db])
   (:gen-class))

 (defn exit [code msg]
@@ -7,9 +9,14 @@
     (do (println msg)
         (System/exit code))))

+(defn do-crawl [cfg]
+  (let [users (crawler/records cfg)
+        docs (map #(crawler/sample-docs cfg %) users)]
+    (doseq [d docs] (db/insert cfg (:query d) (:insert d)))))
+
 (defn -main [& args]
   (if (< (count args) 1)
       (exit 1 "No configuration file specified")
       (-> (nth args 0)
           config/read-config
-          println)))
+          do-crawl)))


Send :error to client instead of failing silently

Both `find-symbol` and `find-debug-fns-reply` were failing silently
instead of returning an error to the client

--- src/refactor_nrepl/refactor.clj
+++ src/refactor_nrepl/refactor.clj
@@ -73,11 +73,15 @@
     (find-nodes ast (partial contains-var-or-const? name (alias-info ast)))))

 (defn- find-debug-fns-reply [{:keys [transport ns-string debug-fns] :as msg}]
-  (let [ast (ns-ast ns-string)
-        result (find-invokes ast debug-fns)]
-    (transport/send transport
-                    (response-for msg :value (when (not-empty result) result)
-                                  :status :done))))
+  (try
+    (let [ast (ns-ast ns-string)
+             result (find-invokes ast debug-fns)]
+         (transport/send transport
+                         (response-for msg :value (when (not-empty result) result)
+                                       :status :done)))
+    (catch Exception e
+      (transport/send transport
+                      (response-for msg :error (.getMessage e) :status :done)))))

 (defn- match [file-content line end-line]
   (let [line-index (dec line)
@@ -145,12 +149,16 @@
              (map #(conj (vec (take 4 %)) var-name (.getCanonicalPath (java.io.File. file)) (match ns-string (first %) (second %)))))))))

 (defn- find-symbol-reply [{:keys [transport file ns name clj-dir loc-line loc-column] :as msg}]
-  (let [syms (or (when file (not-empty (find-local-symbol file name loc-line loc-column)))
-                 (find-global-symbol-reply file ns name clj-dir))]
-    (doseq [found-sym syms]
-      (transport/send transport (response-for msg :occurrence found-sym)))
-    (transport/send transport (response-for msg :syms-count (count syms)
-                                            :status :done))))
+  (try
+    (let [syms (or (when file (not-empty (find-local-symbol file name loc-line loc-column)))
+                      (find-global-symbol-reply file ns name clj-dir))]
+         (doseq [found-sym syms]
+           (transport/send transport (response-for msg :occurrence found-sym)))
+         (transport/send transport (response-for msg :syms-count (count syms)
+                                                 :status :done)))
+    (catch Exception e
+      (transport/send transport
+                      (response-for msg :error (.getMessage e) :status :done)))))

 (defn wrap-refactor
   "Ensures that refactor only triggered with the right operation and


WIP - Version du code en Clojure pour le contest CG "Mean Max - Buggy Road" en "Wood League 1" - Utilisation de multiméthodes


Add "update-page-metadata" endpoint and rename all front methods with more consistent naming.

--- src/uxbox/frontend/projects.clj
+++ src/uxbox/frontend/projects.clj
@@ -17,13 +17,13 @@
 ;; Handlers
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

-(defn project-list
+(defn list-projects
   [{user :identity}]
   (let [params {:user user :type :project/list}]
     (-> (sv/query params)
         (p/then #(http/ok (ufc/rsp %))))))

-(defn project-create
+(defn create-project
   [{user :identity params :data}]
   (p/alet [params (assoc params
                          :type :project/create
@@ -32,7 +32,7 @@
            loc (str "/api/projects/" (:id result))]
     (http/created loc (ufc/rsp result))))

-(defn project-update
+(defn update-project
   [{user :identity params :route-params data :data}]
   (let [params (merge data
                       {:id (UUID/fromString (:id params))
@@ -41,7 +41,7 @@
     (-> (sv/novelty params)
         (p/then #(http/ok (ufc/rsp %))))))

-(defn project-delete
+(defn delete-project
   [{user :identity params :route-params}]
   (let [params {:id (UUID/fromString (:id params))
                 :type :project/delete
@@ -49,13 +49,13 @@
     (-> (sv/novelty params)
         (p/then (fn [v] (http/no-content))))))

-(defn page-list
+(defn list-pages
   [{user :identity}]
   (let [params {:user user :type :page/list}]
     (-> (sv/query params)
         (p/then #(http/ok (ufc/rsp %))))))

-(defn page-list-by-project
+(defn list-pages-by-project
   [{user :identity params :route-params}]
   (let [params {:user user
                 :project (UUID/fromString (:id params))
@@ -63,7 +63,7 @@
     (-> (sv/query params)
         (p/then #(http/ok (ufc/rsp %))))))

-(defn page-create
+(defn create-page
   [{user :identity params :data}]
   (p/alet [params (assoc params
                          :type :page/create
@@ -72,7 +72,7 @@
            loc (str "/api/pages/" (:id result))]
     (http/created loc (ufc/rsp result))))

-(defn page-update
+(defn update-page
   [{user :identity params :route-params data :data}]
   (let [params (merge data
                       {:id (UUID/fromString (:id params))
@@ -81,7 +81,17 @@
     (-> (sv/novelty params)
         (p/then #(http/ok (ufc/rsp %))))))

-(defn page-delete
+
+(defn update-page-metadata
+  [{user :identity params :route-params data :data}]
+  (let [params (merge data
+                      {:id (UUID/fromString (:id params))
+                       :type :page/update-metadata
+                       :user user})]
+    (-> (sv/novelty params)
+        (p/then #(http/ok (ufc/rsp %))))))
+
+(defn delete-page
   [{user :identity params :route-params}]
   (let [params {:id (UUID/fromString (:id params))
                 :type :page/delete


Don't use deref outside the box namespace


Improve update check

Improve update check

--- desktop/src/nightweb_desktop/utils.clj
+++ desktop/src/nightweb_desktop/utils.clj
@@ -56,12 +56,12 @@
 (defn check-update-periodically
   []
   (future
-    (when-let [version (get-version)]
+    (let [version (or (get-version) "beta")]
       (while true
         (when-let [url (try (slurp "https://nightweb.net/desktop.txt")
                          (catch Exception e nil))]
           (reset! update-url (if (< (.indexOf version url) 0) url nil)))
-        (Thread/sleep (* 24 60 60 1000))))))
+        (Thread/sleep (* 6 60 60 1000))))))

 (defn pic-to-data-uri
   "Converts the pic from the given pic hash to a data url."


:before doesn't work on "replaced" elements in FF

Fixes #2662

--- frontend/components/build_invites.cljs
+++ frontend/components/build_invites.cljs
@@ -39,11 +39,15 @@
            [:label {:for (str login "-email")}
             [:i.fa.fa-exclamation-circle]
             " Fix Email"]]
-          [:label.invite-select {:id (str login "-checkbox")}
+          [:label.invite-select {:id (str login "-label")
+                                 :for (str login "-checkbox")}
            [:input {:type "checkbox"
+                    :id (str login "-checkbox")
                     :checked (boolean (:checked user))
                     :on-change #(utils/toggle-input
-                                 controls-ch (conj (state/build-github-user-path index) :checked) %)}]]])))))
+                                 controls-ch (conj (state/build-github-user-path index) :checked) %)}]
+           [:div.checked \uf046]
+           [:div.unchecked \uf096]]])))))

 (defn build-invites [invite-data owner opts]
   (reify


remove vpc id

remove vpc id

--- resources/default.clj
+++ resources/default.clj
@@ -15,7 +15,6 @@
  :LoadBalancer {:LoadBalancerName $app-name
                 :Listeners [elb-8080->8080]
                 :SecurityGroups [$sg-http-8080]
-                :VpcId $vpc-id
                 :Subnets $elb-subnets-be
                 :Scheme "internal"
                 :HealthCheck elb-healthcheck-ping}


Launch workers with id and port properties

--- storm-core/src/clj/backtype/storm/daemon/supervisor.clj
+++ storm-core/src/clj/backtype/storm/daemon/supervisor.clj
@@ -418,6 +418,9 @@
                        " -Dlogfile.name=" logfilename
                        " -Dstorm.home=" storm-home
                        " -Dlogback.configurationFile=" storm-home "/logback/cluster.xml"
+                       " -Dstorm.id=" storm-id
+                       " -Dworker.id=" worker-id
+                       " -Dworker.port=" port
                        " -cp " classpath " backtype.storm.daemon.worker "
                        (java.net.URLEncoder/encode storm-id) " " (:assignment-id supervisor)
                        " " port " " worker-id)]


added retrying infos to the messages on inconsistent assignments.

--- storm-core/src/clj/backtype/storm/daemon/supervisor.clj
+++ storm-core/src/clj/backtype/storm/daemon/supervisor.clj
@@ -78,7 +78,7 @@
             assignments)
           (catch RuntimeException e
             (if (> @retries 2) (throw e) (swap! retries inc))
-            (log-warn (.getMessage e))
+            (log-warn (.getMessage e) ": retrying " @retries " of 3")
             existing-assignment))))

 (defn- read-storm-code-locations


test local-size limit with put requests

test local-size limit with put requests

--- test/bzzz/core_handler_test.clj
+++ test/bzzz/core_handler_test.clj
@@ -34,6 +34,11 @@
    :enforce-limits enforce-limit
    :facets {:name {:size 7}}})

+(defn send-put-request [enforce-limit size]
+  (http-client/put host {:accept :json
+                         :as :json
+                         :body (json/write-str (put-request enforce-limit size))}))
+
 (defn send-delete-request []
   (http-client/delete host {:accept :json
                             :as :json
@@ -61,10 +66,12 @@

   (testing "put"
     (refresh-search-managers)
-    (let [r (:body (http-client/put host {:accept :json
-                                          :as :json
-                                          :body (json/write-str (put-request false 1000))}))
-          cnt (* 2 (count (flatten hosts)))]
+    (let [r (:body (send-put-request false 1000))
+          r1 (:body (send-put-request false 1))
+          hcnt (count (flatten hosts))
+          cnt (* 2 hcnt)]
+      (is (= cnt (:total r1)))
+      (is (= hcnt (count (:hits r1))))
       (is (= cnt (:total r)))
       (is (= cnt (count (:hits r))))))

@@ -72,9 +79,7 @@
     (refresh-search-managers)
     (dotimes [n (* 2 (count (flatten hosts)))]
       (let [should-be (+ 1 n)
-            r (:body (http-client/put host {:accept :json
-                                            :as :json
-                                            :body (json/write-str (put-request true should-be))}))
+            r (:body (send-put-request true should-be))
             cnt (* 2 (count (flatten hosts)))]
         (is (= cnt (:total r)))
         (is (= should-be (count (:hits r)))))))
@@ -83,9 +88,7 @@
     (is (= (:body (send-delete-request)
                   {test-index-name "name:doe"})))
     (refresh-search-managers)
-    (let [r (:body (http-client/put host {:accept :json
-                                          :as :json
-                                          :body (json/write-str (put-request false 10))}))]
+    (let [r (:body (send-put-request false 10))]
       (is (= 0 (:total r)))))

   (testing "stop"


Add a test cases for checking the last bases of twobit writer.

--- test/cljam/io/sequence_test.clj
+++ test/cljam/io/sequence_test.clj
@@ -267,4 +267,13 @@
       (with-open [r (cseq/twobit-reader test-twobit-n-file)
                   w (cseq/twobit-writer f)]
         (cseq/write-sequences w (cseq/read-all-sequences r {:mask? true})))
-      (is (same-file? f test-twobit-n-file)))))
+      (is (same-file? f test-twobit-n-file)))
+
+    (let [f (str temp-dir "/test-2.2bit")
+          s [{:name "SEQ1" :sequence "AAAA"}
+             {:name "SEQ2" :sequence "AAAAG"}
+             {:name "SEQ3" :sequence "AAAAGC"}
+             {:name "SEQ4" :sequence "AAAAGCT"}
+             {:name "SEQ5" :sequence "AAAAGCTA"}]]
+      (with-open [w (cseq/writer f)] (cseq/write-sequences w s))
+      (with-open [r (cseq/reader f)] (is (= (cseq/read-all-sequences r) s))))))


remove bad ns style from import_test.cljs

--- test/cljs/cljs/import_test.cljs
+++ test/cljs/cljs/import_test.cljs
@@ -6,7 +6,7 @@
 (defn test-import []
   (assert (fn? Long))
   (assert (.equals (Long. 4 6) (.add (Long. 1 2) (Long. 3 4))))
-  (assert (= "12" (str (Long/fromInt 12))))
+  (assert (= "12" (str (Long.fromInt 12))))
   (assert (not (nil? (Vec2. 1 2))))
   (assert (not (nil? (Vec3. 1 2 3))))
   (assert (.equals (Integer.fromString "10") (goog.math.Integer.fromString "10"))))


Add more tests for Riley

Add more tests for Riley

--- test/cljx/revue/riley_test.cljx
+++ test/cljx/revue/riley_test.cljx
@@ -162,16 +162,23 @@
   (test-gen 'OP ['println 0] {:name 'println :n-args 0})
   (test-gen 'OP ['println 3] {:name 'println :n-args 3}))

-(defn add-unknown-source-info [inst]
-  (assoc inst :function :%unknown-function :source nil))
+(defn add-source-info [inst & {:keys [function source]
+                                       :or {function :%unknown-function
+                                            source nil}}]
+  (let [inst1 (if (:function inst)
+                inst
+                (assoc inst :function function))]
+    (if (:source inst1)
+      inst1
+      (assoc inst1 :source source))))

 (deftest gen-seq
   (is (= (riley/gen-seq) []))
   (is (= (riley/gen-seq (riley/gen 'LVAR 0 1 'x) (riley/gen 'GSET 'foo))
-         (map add-unknown-source-info
+         (map add-source-info
               [(vm/->LVAR 0 1 'x) (vm/->GSET 'foo)])))
     (is (= (riley/gen-seq [] (riley/gen 'LVAR 0 1 'y) [] (riley/gen 'GSET 'foo) [])
-         (map add-unknown-source-info
+         (map add-source-info
               [(vm/->LVAR 0 1 'y) (vm/->GSET 'foo)]))))

 (deftest gen-label
@@ -223,21 +230,21 @@

 (deftest gen-args-1
   (is (= (riley/gen-args 'foo [])
-         [(add-unknown-source-info (vm/->ARGS 0 'foo))]))
+         [(add-source-info (vm/->ARGS 0 'foo))]))
   (is (= (riley/gen-args 'foo '[a])
-         [(add-unknown-source-info (vm/->ARGS 1 'foo))]))
+         [(add-source-info (vm/->ARGS 1 'foo))]))
   (is (= (riley/gen-args 'foo '[a b])
-         [(add-unknown-source-info (vm/->ARGS 2 'foo))]))
+         [(add-source-info (vm/->ARGS 2 'foo))]))
   (is (= (riley/gen-args 'foo '[a b c])
-         [(add-unknown-source-info (vm/->ARGS 3 'foo))]))
+         [(add-source-info (vm/->ARGS 3 'foo))]))
   (is (= (riley/gen-args 'foo '[& a])
-         [(add-unknown-source-info (vm/->ARGS* 0 'foo))]))
+         [(add-source-info (vm/->ARGS* 0 'foo))]))
   (is (= (riley/gen-args 'foo '[a & b])
-         [(add-unknown-source-info (vm/->ARGS* 1 'foo))]))
+         [(add-source-info (vm/->ARGS* 1 'foo))]))
   (is (= (riley/gen-args 'foo '[a b & c])
-         [(add-unknown-source-info (vm/->ARGS* 2 'foo))]))
+         [(add-source-info (vm/->ARGS* 2 'foo))]))
   (is (= (riley/gen-args 'foo '[a b c & c])
-         [(add-unknown-source-info (vm/->ARGS* 3 'foo))])))
+         [(add-source-info (vm/->ARGS* 3 'foo))])))

 (deftest gen-args-2
   (is (thrown? #+clj java.lang.IllegalArgumentException #+cljs js/Error
@@ -249,6 +256,77 @@
   (is (thrown? #+clj java.lang.AssertionError #+cljs js/Error
                (riley/gen-args 'foo '[a & 1]))))

+(deftest gen-return
+  (binding [riley/*current-function* 'my-fun]
+    (is (= (riley/gen-return))
+        [(add-source-info (vm/->RETURN 'my-fun))])))
+
+(deftest comp-const
+  (binding [riley/*current-function* 'foo]
+    (is (= (riley/comp-const 1 false false) []))
+    (is (= (riley/comp-const 1 false true) []))
+    (is (= (riley/comp-const 1 true false)
+           (map #(assoc %1 :source nil :function 'foo)
+                [(vm/->CONST 1) (vm/->RETURN 'foo)])))
+    (is (= (riley/comp-const 1 true true)
+           [(assoc (vm/->CONST 1) :source nil :function 'foo)]))))
+
+(deftest comp-sequence
+  (is (= (riley/comp-sequence [] (util/env) false false) []))
+  (is (= (riley/comp-sequence [] (util/env) false true) []))
+  (is (= (riley/comp-sequence [] (util/env) true false)
+         (map add-source-info
+              [(vm/->CONST nil) (vm/->RETURN :%unknown-function)])))
+  (is (= (riley/comp-sequence [] (util/env) true true)
+         [(add-source-info (vm/->CONST nil))]))
+  (is (= (riley/comp-sequence [1] (util/env) false false) []))
+  (is (= (riley/comp-sequence [1] (util/env) false true) []))
+  (is (= (riley/comp-sequence [1] (util/env) true false)
+         (map add-source-info
+              [(vm/->CONST 1) (vm/->RETURN :%unknown-function)])))
+  (is (= (riley/comp-sequence [1] (util/env) true true)
+         [(add-source-info (vm/->CONST 1))]))
+  (reset! riley/label-counter 0)
+  (let [label (vm/->Label 'K1)]
+    (is (= (riley/comp-sequence ['(f) 2 3] (util/env) false false)
+           (concat (map (fn [inst] (add-source-info inst :source '(f)))
+                        [(vm/->SAVE label) (assoc (vm/->GVAR 'f) :source 'f)
+                         (vm/->CALLJ 0)])
+                   [label]
+                   (map (fn [inst] (add-source-info inst :source '(f)))
+                        [(vm/->POP)])))))
+  (reset! riley/label-counter 0)
+  (let [label (vm/->Label 'K1)]
+    (is (= (riley/comp-sequence ['(f) 2 3] (util/env) false true)
+           (concat (map (fn [inst] (add-source-info inst :source '(f)))
+                        [(vm/->SAVE label) (assoc (vm/->GVAR 'f) :source 'f)
+                         (vm/->CALLJ 0)])
+                   [label]
+                   (map (fn [inst] (add-source-info inst :source '(f)))
+                        [(vm/->POP)])))))
+  (reset! riley/label-counter 0)
+  (let [label (vm/->Label 'K1)]
+    (is (= (riley/comp-sequence ['(f) 2 3] (util/env) true false)
+           (concat (map (fn [inst] (add-source-info inst :source '(f)))
+                        [(vm/->SAVE label) (assoc (vm/->GVAR 'f) :source 'f)
+                         (vm/->CALLJ 0)])
+                   [label]
+                   (map (fn [inst] (add-source-info inst :source '(f)))
+                        [(vm/->POP) ])
+                   (map add-source-info
+                        [(vm/->CONST 3) (vm/->RETURN :%unknown-function)])))))
+  (reset! riley/label-counter 0)
+  (let [label (vm/->Label 'K1)]
+    (is (= (riley/comp-sequence ['(f) 2 3] (util/env) true true)
+           (concat (map (fn [inst] (add-source-info inst :source '(f)))
+                        [(vm/->SAVE label) (assoc (vm/->GVAR 'f) :source 'f)
+                         (vm/->CALLJ 0)])
+                   [label]
+                   (map (fn [inst] (add-source-info inst :source '(f)))
+                        [(vm/->POP)])
+                   (map add-source-info
+                        [(vm/->CONST 3)]))))))
+
 ;;; Evaluate this (e.g., with C-x C-e in Cider) to run the tests for
 ;;; this namespace:
 ;;; (t/run-tests 'revue.riley-test)


Use 'map' instead of 'for' in problem63.clj

--- euler_clojure/src/euler/problem63.clj
+++ euler_clojure/src/euler/problem63.clj
@@ -16,5 +16,5 @@
 (defn problem63 []
   ;; Retrieve results from find-powers until the empty list indicates no more
   ;; results. Find the length of all items of every resulting list.
-  (let [results (take-while not-empty (for [i (iterate inc 1)] (find-powers i)))]
-    (apply + (for [xs results] (count xs)))))
+  (let [results (take-while not-empty (map find-powers (iterate inc 1)))]
+    (apply + (map count results))))


Added check for day-night flag as UMM granules in format other than ECHO10 could have a nil day-night flag value.

--- umm-lib/src/cmr/umm/echo10/granule.clj
+++ umm-lib/src/cmr/umm/echo10/granule.clj
@@ -39,7 +39,8 @@
     (let [{:keys [producer-gran-id
                   day-night
                   production-date-time
-                  size]} data-granule]
+                  size]} data-granule
+          day-night (if day-night day-night "UNSPECIFIED")]
       (x/element :DataGranule {}
                  (when size
                    (x/element :SizeMBDataGranule {} size))


Bump to nrepl v0.2.10

Bump to nrepl v0.2.10

--- lein/profiles.clj
+++ lein/profiles.clj
@@ -1,2 +1,2 @@
 {:user {:plugins [[cider/cider-nrepl "0.9.0-SNAPSHOT"]]
-        :dependencies [[org.clojure/tools.nrepl "0.2.7"]]}}
+        :dependencies [[org.clojure/tools.nrepl "0.2.10"]]}}


More merging

More merging

--- lein/profiles.clj
+++ lein/profiles.clj
@@ -4,10 +4,10 @@
 {:user {:aliases {"slamhound" ["run" "-m" "slam.hound"]}
         :dependencies [[alembic "0.3.2"]
                        #_[clj-ns-browser "1.3.1" :exclusions [hiccup]]
+                       ;; We inherit this next through vinyasa.
+                       ;; Shouldn't need to declare it
                        [im.chit/hara "2.1.11"]
-                       ;; TODO: figure out how to exclude plexus-utils
-                       ;; The obvious approach doesn't work
-                       [im.chit/vinyasa "0.3.4"]  ; :exclusions [org.codehaus.plexus/plexus-utils]
+                       [im.chit/vinyasa "0.3.4" :exclusions [org.codehaus.plexus/plexus-utils]]
                        [io.aviso/pretty "0.1.16"]
                        [leiningen #= (leiningen.core.main/leiningen-version)  :exclusions [cheshire
                                                                                com.fasterxml.jackson.core/jackson-core
@@ -25,22 +25,31 @@
                                                                                org.jsoup/jsoup
                                                                                potemkin]]
                        [nrepl-inspect "0.3.0"]
+                       [org.codehaus.plexus/plexus-utils "3.0"]
+                       [org.clojure/tools.namespace "0.2.10"]
                        [pjstadig/humane-test-output "0.7.0"]
                        ;; Q: Is there any point to this next one?
                        [ritz/ritz-nrepl-middleware "0.7.0"]
                        [slamhound "1.5.5"]
                        [spyscope "0.1.5"]]
-        :injections [(require '[vinyasa.inject :as inject])
-                     (require 'spyscope.core)
+        :injections [(require 'spyscope.core)
+                     (require '[vinyasa.inject :as inject])
+                     ;; TODO: call install-pretty-exception
+                     (require 'io.aviso.repl)
                      (inject/in
+                      ;; Default injection ns is .
                       [vinyasa.inject :refer [inject [in inject-in]]]
                       #_[vinyasa.lein :exclude [*project*]]
                       #_[vinyasa.pull :all]
                       [alembic.still [distill pull]]
                       [cemerick.pomegranate add-classpath add-dependencies get-classpath resources]

-                      clojure.core [vinyasa.reflection .& .> .? .* .% .%>]
+
+                      ;; Inject into clojure.core
+                      clojure.core
+                      [vinyasa.reflection .> .? .* .% .%> .& .>ns .>var]

+                      ;; Inject into clojure.core, with prefix
                       clojure.core >
                       [clojure.pprint pprint]
                       [clojure.java.shell sh]


Pollaus elasticin käynnistykselle

Pollaus elasticin käynnistykselle

--- clj-test-utils/src/clj_test_utils/elasticsearch_mock_utils.clj
+++ clj-test-utils/src/clj_test_utils/elasticsearch_mock_utils.clj
@@ -48,20 +48,29 @@
           result)))
     (add-hook #'clojure.test/run-tests #'run-all-test-hook))

-(defn stop-docker-elastic []
+(defn- stop-docker-elastic []
   (sh "docker" "kill" "kouta-elastic"))

-(defn init-docker-elastic []
+(defn- elastic-has-started? [elastic-ip]
+  (let [response (sh "curl" (str elastic-ip "/_cluster/health"))
+        result-code (:exit response)]
+    (= result-code 0)))
+
+(defn- wait-elastic-to-start [elastic-ip]
+  (loop [tries 30]
+    (when (and (> tries 1)
+               (not (elastic-has-started? elastic-ip)))
+      (Thread/sleep 1000)
+      (recur (- tries 1)))))
+
+(defn- init-docker-elastic []
   (let [port (find-free-local-port)
         elastic-ip (str "http://127.0.0.1:" port)
         elastic-docker-ip (str "127.0.0.1:" port ":9200")]
     (intern 'clj-elasticsearch.elastic-utils 'elastic-host elastic-ip)
-    ;(println (sh "curl" (str elastic-ip "/_cluster/health")))
-    (println (sh "docker" "run" "--rm" "-d" "--name" "kouta-elastic" "--env" "\"discovery.type=single-node\"" "-p" elastic-docker-ip "docker.elastic.co/elasticsearch/elasticsearch:6.8.13"))
+    (sh "docker" "run" "--rm" "-d" "--name" "kouta-elastic" "--env" "\"discovery.type=single-node\"" "-p" elastic-docker-ip "docker.elastic.co/elasticsearch/elasticsearch:6.8.13")
     (println "Starting elasticsearch container")
-    (Thread/sleep 16000) ;TODO toteuta pollaus milloin elastic on käynnistynyt
-    ;(println (sh "curl" (str elastic-ip "/_cluster/health")))
-    ))
+    (wait-elastic-to-start elastic-ip)))

 (defn global-docker-elastic-fixture
   []


State the goal

State the goal

--- test/workshop/jobs/test_3_3.clj
+++ test/workshop/jobs/test_3_3.clj
@@ -11,6 +11,10 @@
 ;; changing the catalog entry. Now let's use what we learned to
 ;; write a catalog entry and parameterized function from scratch.
 ;; There are two sections of the source file for you to work on.
+;;
+;; The goal is to prepend a ~ and append a ? to every :name value
+;; in your segment. By parameterizing the function, you can dynamically
+;; parameterize your functions at runtime.
 ;;
 ;; Try it with:
 ;;