Add a note parameter to the notification trigger.

--- src/oc/storage/async/notification.clj
+++ src/oc/storage/async/notification.clj
@@ -101,12 +101,14 @@
 ;; ----- Notification triggering -----

 (defn ->trigger
-  ([notification-type content user] (->trigger notification-type nil nil content user))
-  ([notification-type org content user] (->trigger notification-type org nil content user))
-  ([notification-type org board content user]
+  ([notification-type content user] (->trigger notification-type nil nil content nil user))
+  ([notification-type org content user] (->trigger notification-type org nil content nil user))
+  ([notification-type org content note user] (->trigger notification-type org nil content nil user))
+  ([notification-type org board content note user]
   (let [notice {:notification-type notification-type
                 :resource-type (resource-type (or (:old content) (:new content)))
                 :content content
+                :note note
                 :user user
                 :notification-at (oc-time/current-timestamp)}
         org-notice (if org (assoc notice :org org) notice)


Fix whitespacing

Fix whitespacing

--- src-cljs/frontend/components/account.cljs
+++ src-cljs/frontend/components/account.cljs
@@ -212,16 +212,15 @@
                                              [:h1 "Beta Terms"]
                                              [:p
                                               "Our beta program is a way to engage with our most
-               thoughtful and dedicated users. We want to build the
-               best features with your help. To that end, in joining
-               the beta program you should be comfortable with these
-               expectations:"]
+                                               thoughtful and dedicated users. We want to build the
+                                               best features with your help. To that end, in joining
+                                               the beta program you should be comfortable with these
+                                               expectations:"]
                                              [:ul
                                               [:li "You’ll find out about new features through e-mail and in-app messages"]
                                               [:li "Please give us feedback about new features when we release them"]
                                               [:li "Keep the private beta, private. Please no tweets, blogs, or other public
-                    posting, but we do encourage you to talk with your
-                    coworkers!"]]]))
+                                                    posting, but we do encourage you to talk with your coworkers!"]]]))
                             :actions [(button/button {:on-click close-fn} "Cancel")
                                       (button/button
                                        {:on-click #(do
@@ -440,8 +439,6 @@
                   :when (= [(keyword (:vcs_type project)) (keyword (:username project))] selected-org)]
               (om/build project/email-pref {:project project :user user} {:react-key (:reponame project)}))]]])))))

-
-
 (defn notifications [app owner]
   (reify
     om/IRender


Allow lifecycles to have multiple structures in info model.

--- src/onyx/kafka/information_model.cljc
+++ src/onyx/kafka/information_model.cljc
@@ -98,11 +98,11 @@
    :lifecycle-entry
    {:kafka/read-messages
     {:model
-     {:lifecycle/calls :onyx.plugin.kafka/read-messages-calls}}
+     [{:lifecycle/calls :onyx.plugin.kafka/read-messages-calls}]}

     :kafka/write-messages
     {:model
-     {:lifecycle/calls :onyx.plugin.kafka/write-messages-calls}}}
+     [{:lifecycle/calls :onyx.plugin.kafka/write-messages-calls}]}}

    :display-order
    {:kafka/read-messages


makes eastwood happy

makes eastwood happy

--- src/open_company/resources/common.clj
+++ src/open_company/resources/common.clj
@@ -3,7 +3,6 @@
   (:require [clj-time.format :as format]
             [clj-time.core :as time]
             [rethinkdb.query :as r]
-            [open-company.config :as c]
             [open-company.db.pool :as pool]))

 ;; ----- RethinkDB metadata -----


Add blacklisted symbol

Add blacklisted symbol

--- src/nightmod/sandbox.clj
+++ src/nightmod/sandbox.clj
@@ -16,7 +16,7 @@
    (jail-test/blacklist-symbols
     '#{alter-var-root eval catch
        load-string load-reader addMethod ns-resolve resolve find-var
-       *read-eval* ns-publics ns-unmap ns-map ns-interns the-ns
+       *read-eval* ns ns-publics ns-unmap ns-map ns-interns the-ns
        in-ns System/out System/in System/err
        with-redefs-fn Class/forName})
    (jail-test/blacklist-nses '[clojure.main])


email permission for slave roles

email permission for slave roles

--- src/terraboot/cluster.clj
+++ src/terraboot/cluster.clj
@@ -141,6 +141,9 @@
                      "EC2:DescribeTags"]
            "Condition" {"Bool" {"aws:SecureTransport" "true"}}}))

+(def send-email-policy
+  (policy {"Action" ["ses:SendEmail"]}))
+
 (defn cluster-aws-instance [name spec]
   (let [default-vpc-sgs [(remote-output-of "vpc" "sg-allow-ssh")
                          (remote-output-of "vpc" "sg-all-servers")]]
@@ -344,8 +347,9 @@
                                                     "cloudwatch:ListMetrics",
                                                     "cloudwatch:PutMetricData",
                                                     "EC2:DescribeTags" ]
-                                         "Condition" {"Bool" { "aws:SecureTransport" "true"}}
-                                         })})
+                                         "Condition" {"Bool" { "aws:SecureTransport" "true"}}})}
+                       {:name "slave-email-policy"
+                        :policy send-email-policy})

              (cluster-resource "template_file" "master-user-data"


Finish connection timeout support.

Finish connection timeout support.

--- src/onyx/messaging/netty_tcp.clj
+++ src/onyx/messaging/netty_tcp.clj
@@ -230,17 +230,14 @@
             (.group client-group)
             (.channel channel)
             (.handler (client-channel-initializer (new-client-handler))))
-        ch-fut ^ChannelFuture (.awaitUninterruptibly ^ChannelFuture (.connect ^Bootstrap b ^String host ^Integer port)
-                                                     ;; TODO, add connection timeout
-                                                     ;(:onyx.messaging.netty/connect-timeout-millis defaults)
-                                                     ;TimeUnit/MILLISECONDS
-                                                     )
-        ch (.channel ch-fut)]
-    (if (and (.isSuccess ^ChannelFuture ch-fut)
-             (established? ch))
-      ch
-      (do (.close ch)
-          nil))))
+        ch-fut ^ChannelFuture (.connect ^Bootstrap b ^String host ^Integer port)]
+    (if (.awaitUninterruptibly ch-fut (:onyx.messaging.netty/connect-timeout-millis defaults))
+      (let [ch (.channel ch-fut)]
+        (if (and (.isSuccess ch-fut)
+                 (established? ch))
+          ch
+          (do (.close ch)
+              nil))))))

 (defrecord NettyTcpSockets [peer-group]
   component/Lifecycle


Fix compression on Netty.

Fix compression on Netty.

--- src/onyx/messaging/netty_tcp.clj
+++ src/onyx/messaging/netty_tcp.clj
@@ -31,11 +31,11 @@

 (defn leak-detector-level! [level]
   (ResourceLeakDetector/setLevel
-    (case level
-      :disabled ResourceLeakDetector$Level/DISABLED
-      :simple ResourceLeakDetector$Level/SIMPLE
-      :advanced ResourceLeakDetector$Level/ADVANCED
-      :paranoid ResourceLeakDetector$Level/PARANOID)))
+   (case level
+     :disabled ResourceLeakDetector$Level/DISABLED
+     :simple ResourceLeakDetector$Level/SIMPLE
+     :advanced ResourceLeakDetector$Level/ADVANCED
+     :paranoid ResourceLeakDetector$Level/PARANOID)))

 (defn event-executor
   "Creates a new netty execution handler for processing events.
@@ -66,24 +66,24 @@
                          (NioEventLoopGroup. thread-count client-thread-factory))
           boss-thread-factory (DefaultThreadFactory. boss-event-thread-pool-name true)
           boss-group (if (epoll?)
-                         (EpollEventLoopGroup. thread-count boss-thread-factory)
-                         (NioEventLoopGroup. thread-count boss-thread-factory))
+                       (EpollEventLoopGroup. thread-count boss-thread-factory)
+                       (NioEventLoopGroup. thread-count boss-thread-factory))
           worker-thread-factory (DefaultThreadFactory. worker-event-thread-pool-name true)
           worker-group (if (epoll?)
-                       (EpollEventLoopGroup. thread-count worker-thread-factory)
-                       (NioEventLoopGroup. thread-count worker-thread-factory))]
+                         (EpollEventLoopGroup. thread-count worker-thread-factory)
+                         (NioEventLoopGroup. thread-count worker-thread-factory))]

       (timbre/info "Starting Netty peer group")
-      (assoc component
-             :shared-event-executor shared-event-executor
-             :client-group client-group
-             :worker-group worker-group
-             :boss-group boss-group)))
+      (assoc component
+        :shared-event-executor shared-event-executor
+        :client-group client-group
+        :worker-group worker-group
+        :boss-group boss-group)))

   (stop [component]
     (assoc component
-           :shared-event-executor nil :client-group nil
-           :worker-group nil :boss-group nil)))
+      :shared-event-executor nil :client-group nil
+      :worker-group nil :boss-group nil)))

 (defn netty-peer-group [opts]
   (map->NettyPeerGroup {:opts opts}))
@@ -92,9 +92,9 @@
   [config peer-site peer-sites]
   (let [used-ports (->> (vals peer-sites)
                         (filter
-                          (fn [s]
-                            (= (:netty/external-addr peer-site)
-                               (:netty/external-addr s))))
+                         (fn [s]
+                           (= (:netty/external-addr peer-site)
+                              (:netty/external-addr s))))
                         (map :netty/port)
                         set)
         port (first (remove used-ports
@@ -104,7 +104,7 @@

 (defn int32-frame-decoder
   []
-  ; Offset 0, 4 byte header, skip those 4 bytes.
+                                        ; Offset 0, 4 byte header, skip those 4 bytes.
   (LengthFieldBasedFrameDecoder. Integer/MAX_VALUE, 0, 4, 0, 4))

 (defn int32-frame-encoder
@@ -153,11 +153,11 @@
                   EpollServerSocketChannel
                   NioServerSocketChannel)
         channel-group (DefaultChannelGroup. (str "tcp-server " host ":" port)
-                                            (ImmediateEventExecutor/INSTANCE))
+                        (ImmediateEventExecutor/INSTANCE))
         initializer (channel-initializer-done
-                      (gen-tcp-handler channel-group
-                                       (create-server-handler buf-recvd-ch)))]
-    ; Configure bootstrap
+                     (gen-tcp-handler channel-group
+                                      (create-server-handler buf-recvd-ch)))]
+                                        ; Configure bootstrap
     (doto bootstrap
       (.group boss-group worker-group)
       (.channel channel)
@@ -167,7 +167,7 @@
       (.childOption ChannelOption/TCP_NODELAY true)
       (.childOption ChannelOption/SO_KEEPALIVE true)
       (.childHandler initializer))
-    ; Start bootstrap
+                                        ; Start bootstrap
     (let [ch (->> (InetSocketAddress. host port)
                   (.bind bootstrap)
                   (.sync)
@@ -184,7 +184,7 @@
     (handlerAdded [ctx]
       (timbre/info "Handler added"))
     (handlerRemoved [ctx]
-       (timbre/info "Handler removed"))
+      (timbre/info "Handler removed"))
     (exceptionCaught [context cause]
       (.printStackTrace cause)
       (.close context))))
@@ -215,43 +215,43 @@
         (.channel ^ChannelFuture (.connect b host port))))))

 (defn app [daemon parsed-ch inbound-ch release-ch retry-ch]
-    (go-loop []
-             (try (let [msg (<!! parsed-ch)
-                        t ^byte (:type msg)]
-                    (cond (= t protocol/messages-type-id)
-                          (doseq [message (:messages msg)]
-                            (>!! inbound-ch message))
-
-                          (= t protocol/ack-type-id)
-                          (acker/ack-message daemon
-                                             (:id msg)
-                                             (:completion-id msg)
-                                             (:ack-val msg))
-
-                          (= t protocol/completion-type-id)
-                          (>!! release-ch (:id msg))
-
-                          (= t protocol/retry-type-id)
-                          (>!! retry-ch (:id msg))
-
-                          :else
-                          (throw (ex-info "Unexpected message received from Netty" {:message msg}))))
-                  (catch Exception e
-                    (taoensso.timbre/error e)
-                    (throw e)))
-             (recur)))
-
-(defn buf-recv-loop [buf-recv-ch parsed-ch]
+  (go-loop []
+           (try (let [msg (<!! parsed-ch)
+                      t ^byte (:type msg)]
+                  (cond (= t protocol/messages-type-id)
+                        (doseq [message (:messages msg)]
+                          (>!! inbound-ch message))
+
+                        (= t protocol/ack-type-id)
+                        (acker/ack-message daemon
+                                           (:id msg)
+                                           (:completion-id msg)
+                                           (:ack-val msg))
+
+                        (= t protocol/completion-type-id)
+                        (>!! release-ch (:id msg))
+
+                        (= t protocol/retry-type-id)
+                        (>!! retry-ch (:id msg))
+
+                        :else
+                        (throw (ex-info "Unexpected message received from Netty" {:message msg}))))
+                (catch Exception e
+                  (taoensso.timbre/error e)
+                  (throw e)))
+           (recur)))
+
+(defn buf-recv-loop [messenger buf-recv-ch parsed-ch]
   (go-loop []
            (let [buf (<!! buf-recv-ch)]
              (try
-               (let [decompressed (protocol/read-buf buf)]
+               (let [decompressed (protocol/read-buf (:decompress-f messenger) buf)]
                  (>!! parsed-ch decompressed)
-                 ; undo retain added in server handler
+                 ;; undo retain added in server handler
                  (.release ^ByteBuf buf))
                (catch Throwable t
                  (timbre/fatal t "Exception in recv loop.")))
-                 (recur))))
+             (recur))))

 (defrecord NettyTcpSockets [peer-group]
   component/Lifecycle
@@ -265,15 +265,17 @@
           bind-addr (bind-addr config)
           external-addr (external-addr config)
           ports (allowable-ports config)]
-      (assoc component
-             :bind-addr bind-addr
-             :external-addr external-addr
-             :boss-group boss-group
-             :client-group client-group
-             :worker-group worker-group
-             :ports ports
-             :resources (atom nil)
-             :release-ch release-ch)))
+      (assoc component
+        :bind-addr bind-addr
+        :external-addr external-addr
+        :boss-group boss-group
+        :client-group client-group
+        :worker-group worker-group
+        :ports ports
+        :resources (atom nil)
+        :release-ch release-ch
+        :decompress-f (or (:onyx.messaging/decompress-fn (:config peer-group)) decompress)
+        :compress-f (or (:onyx.messaging/compress-fn (:config peer-group)) compress))))

   (stop [{:keys [resources release-ch] :as component}]
     (taoensso.timbre/info "Stopping Netty TCP Sockets")
@@ -311,7 +313,7 @@
                                         (:bind-addr messenger)
                                         (:netty/port assigned)
                                         buf-recv-ch)
-        buf-loop (buf-recv-loop buf-recv-ch parsed-ch)
+        buf-loop (buf-recv-loop messenger buf-recv-ch parsed-ch)
         app-loop (app daemon parsed-ch inbound-ch release-ch retry-ch)]
     (reset! (:resources messenger)
             {:shutdown-fn shutdown-fn
@@ -339,7 +341,7 @@
 (defmethod extensions/send-messages NettyTcpSockets
   [messenger event ^Channel peer-link messages]
   (.writeAndFlush peer-link
-                  ^ByteBuf (protocol/build-messages-msg-buf messages)
+                  ^ByteBuf (protocol/build-messages-msg-buf (:compress-f messenger) messages)
                   (.voidPromise ^Channel peer-link)))

 (defmethod extensions/internal-ack-message NettyTcpSockets


Revert "Takes apart read-batch into different calls."

This reverts commit 42bf61e9406a5644b1644b13e9d89181923e9af7.

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -30,7 +30,7 @@
   (or (not-empty (:onyx.core/windows event))
       (not-empty (:onyx.core/triggers event))))

-(defn start-lifecycle? [event]
+(defn munge-start-lifecycle [event]
   (let [rets (lc/invoke-start-task event)]
     (when-not (:onyx.core/start-lifecycle? rets)
       (timbre/info (format "[%s] Peer chose not to start the task yet. Backing off and retrying..."
@@ -140,18 +140,19 @@
 (defn gen-lifecycle-id [event]
   (assoc event :onyx.core/lifecycle-id (uuid/random-uuid)))

-(defn read-batch [task-type replica peer-replica-view job-id pipeline event]
-  (if (and (= task-type :input)
-           (:backpressure? peer-replica-view))
-    (assoc event :onyx.core/batch (list))
-    (merge event (p-ext/read-batch pipeline event))))
-
-(defn back-off-after-read [event]
+(defn handle-backoff! [event]
   (let [batch (:onyx.core/batch event)]
     (when (and (= (count batch) 1)
                (= (:message (first batch)) :done))
-      (Thread/sleep (:onyx.core/drained-back-off event)))
-    event))
+      (Thread/sleep (:onyx.core/drained-back-off event)))))
+
+(defn read-batch [task-type replica peer-replica-view job-id pipeline event]
+  (if (and (= task-type :input) (:backpressure? peer-replica-view))
+    (assoc event :onyx.core/batch '())
+    (let [rets (merge event (p-ext/read-batch pipeline event))
+          rets (lc/invoke-after-read-batch rets)]
+      (handle-backoff! event)
+      rets)))

 (defn validate-ackable! [peers event]
   (when-not (seq peers)
@@ -407,8 +408,6 @@
              (gen-lifecycle-id)
              (lc/invoke-before-batch compiled-before-batch-fn pipeline)
              (read-batch task-type replica peer-replica-view job-id pipeline)
-             (lc/invoke-after-read-batch)
-             (back-off-after-read)
              (tag-messages task-type replica peer-replica-view id)
              (add-messages-to-timeout-pool task-type state)
              (process-sentinel task-type pipeline monitoring)
@@ -547,7 +546,7 @@
             restart-pred-fn (operation/resolve-restart-pred-fn task-map)
             ex-f (fn [e] (handle-exception log restart-pred-fn e restart-ch outbox-ch job-id))
             _ (while (and (first (alts!! [kill-ch task-kill-ch] :default true))
-                          (not (start-lifecycle? pipeline-data)))
+                          (not (munge-start-lifecycle pipeline-data)))
                 (Thread/sleep (arg-or-default :onyx.peer/peer-not-ready-back-off opts)))

             pipeline-data (-> pipeline-data


print message IDs

print message IDs

--- src/org/timmc/heim_logger/v2.clj
+++ src/org/timmc/heim_logger/v2.clj
@@ -118,10 +118,10 @@
       (send-packet session "ping-reply" {:time (:time data)})

       "send-event"
-      (let [{:keys [sender, content]} data
-            {nick :name, id :id} sender]
-        (println (format "RECV %s(%s) -> %s"
-                         nick id content)))
+      (let [{:keys [sender, content, parent], msg-id :id} data
+            {nick :name, user-id :id} sender]
+        (println (format "RECV %s/%s %s(%s) -> %s"
+                         parent msg-id nick user-id content)))

       "join-event"
       (println "JOIN" (:name data))


Report :num-control-busses in server-info

--- src/overtone/sc/info.clj
+++ src/overtone/sc/info.clj
@@ -58,6 +58,7 @@
                      :num-output-buses (long nob)
                      :num-input-buses (long nib)
                      :num-audio-buses (long nab)
+                     :num-control-buses (long ncb)
                      :num-buffers (long nb)
                      :num-running-synths (long nrs)})
             :overtone/remove-handler)))


Fix group-node-tree to take a group as an id in addition to a number.

--- src/overtone/sc/node.clj
+++ src/overtone/sc/node.clj
@@ -518,7 +518,8 @@
   ([] (group-node-tree* 0))
   ([id & [ctls?]]
      (ensure-connected!)
-     (let [ctls? (if (or (= 1 ctls?) (= true ctls?)) 1 0)]
+     (let [ctls? (if (or (= 1 ctls?) (= true ctls?)) 1 0)
+           id (to-synth-id id)]
        (let [reply-p (recv "/g_queryTree.reply")
              _ (snd "/g_queryTree" id ctls?)
              tree (:args (deref! reply-p))]


make webmaster tools happy with our analytics script

We're using output-wrapper now, so no worries about conflicts

--- src/pc/views/scripts.clj
+++ src/pc/views/scripts.clj
@@ -8,10 +8,10 @@
   (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
   (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
   m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
-  })(window,document,'script','//www.google-analytics.com/analytics.js','_google_analytics');
+  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

-  _google_analytics('create', 'UA-56552392-1', 'auto');
-  _google_analytics('send', 'pageview');
+  ga('create', 'UA-56552392-1', 'auto');
+  ga('send', 'pageview');

 </script>
 ")


fix #849

fix #849

--- src/status_im/protocol/listeners.cljs
+++ src/status_im/protocol/listeners.cljs
@@ -8,7 +8,11 @@

 (defn- parse-payload [payload]
   (debug :parse-payload)
-  (r/read-string (u/to-utf8 payload)))
+  (try
+    {:payload (r/read-string (u/to-utf8 payload))}
+    (catch :default err
+      (debug :parse-payload-error err)
+      {:error err})))

 (defn- decrypt [key content]
   (try
@@ -36,12 +40,14 @@
       (let [{:keys [from payload to] :as message}
             (js->clj js-message :keywordize-keys true)

-            {:keys [type ack?] :as payload'}
+            {{:keys [type ack?] :as payload'} :payload
+             payload-error                    :error}
             (parse-payload payload)]
-        (when (or (not= (i/normalize-hex identity)
-                        (i/normalize-hex from))
-                  ;; allow user to receive his own discoveries
-                  (= type :discover))
+        (when (and (not payload-error)
+                   (or (not= (i/normalize-hex identity)
+                             (i/normalize-hex from))
+                       ;; allow user to receive his own discoveries
+                       (= type :discover)))
           (let [{:keys [content error]} (parse-content (:private keypair)
                                                        payload'
                                                        (not= "0x0" to))]


if no spec is found its valid for path purposes

--- src/strictly_specking/strict_keys.clj
+++ src/strictly_specking/strict_keys.clj
@@ -81,7 +81,9 @@
 (defn score-suggestion [k->s map-x ky [suggested-key score]]
   (let [key-val  (get map-x ky)
         key-spec (k->s suggested-key)
-        valid    (s/valid? key-spec key-val)]
+        valid    (or (and (spec-from-registry key-spec)
+                          (s/valid? key-spec key-val))
+                     true)]
     [suggested-key
      (cond-> (/ score 10)
        ;; TODO: I don't think this is neccessary at all


Add test for behavior described in issue #35

--- src/test/clojure/clara/test_rules.clj
+++ src/test/clojure/clara/test_rules.clj
@@ -1119,4 +1119,37 @@
                     (fire-rules))]

     ;; Only one reduced temperature should be present.
-    (is (= [{:?t 9}] (query session temp-query)))))+    (is (= [{:?t 9}] (query session temp-query)))))
+
+
+;; Test behavior discussed in https://github.com/rbrush/clara-rules/issues/35
+(deftest test-identical-facts
+  (let [ident-query (mk-query [] [[?t1 <- Temperature (= ?loc location)]
+                                [?t2 <- Temperature (= ?loc location)]
+                                [:test (not (identical? ?t1 ?t2))]])
+
+        temp (->Temperature 15 "MCI")
+        temp2 (->Temperature 15 "MCI")
+
+        session (-> (mk-rulebase ident-query)
+                    (mk-session)
+                    (insert temp
+                            temp))
+
+        session-with-dups (-> (mk-rulebase ident-query)
+                              (mk-session)
+                              (insert temp
+                                      temp2))]
+
+    ;; The inserted facts are identical, so there cannot be a non-identicial match.
+    (is (empty? (query session ident-query)))
+
+
+    ;; Duplications should have two matches, since either fact can bind to either condition.
+    (is (= [{:?t1 #clara.rules.testfacts.Temperature{:temperature 15, :location "MCI"}
+             :?t2 #clara.rules.testfacts.Temperature{:temperature 15, :location "MCI"}
+             :?loc  "MCI"}
+            {:?t2 #clara.rules.testfacts.Temperature{:temperature 15, :location "MCI"}
+             :?t1 #clara.rules.testfacts.Temperature{:temperature 15, :location "MCI"}
+             :?loc "MCI"}]
+           (query session-with-dups ident-query)))))


Destructure the basic result data into a map

--- src/radicalzephyr/boot_junit.clj
+++ src/radicalzephyr/boot_junit.clj
@@ -4,7 +4,11 @@
   (:import org.junit.runner.JUnitCore))

 (defn destructure-results [result]
-  {})
+  {:successful? (.wasSuccessful result)
+   :run-time (.getRunTime result)
+   :run     (.getRunCount result)
+   :ignored (.getIgnoredCount result)
+   :failed  (.getFailureCount result)})

 (core/deftask junit
   "Run the jUnit test runner."


Improved coercion of SPARQL bindings to Clojure data structures

--- src/rdf_path_examples/sparql.clj
+++ src/rdf_path_examples/sparql.clj
@@ -16,13 +16,9 @@
   [literal]
   (.getBoolean literal))

-(defmethod literal->clj XSDDatatype/XSDduration
+(defmethod literal->clj :default
   [literal]
   (.getLexicalForm literal))
-
-(defmethod literal->clj :default
-  [literal]
-  (.getValue literal))

 ; ----- Protocols -----

@@ -33,7 +29,6 @@
 (extend-protocol IStringifiableNode
   Literal
   (node->clj [node] (literal->clj node))
-    ;(.getLexicalForm node))

   Resource
   (node->clj [node] (str node)))


Better filtering of numbers.

Better filtering of numbers.

--- src-cljs/kixi/hecuba/tabs/hierarchy/sensors.cljs
+++ src-cljs/kixi/hecuba/tabs/hierarchy/sensors.cljs
@@ -210,11 +210,14 @@
          (if (->> all-series first seq)
            [:div.col-md-12
             (for [[key series] all-series]
-              (let [values             (map :value series)
+              (let [values             (keep #(let [v (:value %)]
+                                                (cond (nil? v) nil
+                                                      (number? v) v
+                                                      (re-matches #"-?\+?\d+(\.\d+)?" v) (js/parseFloat v))) series)
                     measurements-min   (apply min values)
                     measurements-max   (apply max values)
                     measurements-sum   (reduce + values)
-                    measurements-count (count series)
+                    measurements-count (count values)
                     measurements-mean  (if (not= 0 measurements-count) (/ measurements-sum measurements-count) "NA")]
                 [:div.col-md-3
                  (bs/panel


GG & RS | 99 | Use keywords for valid and invalid classes

--- src-cljs/stonecutter/renderer/register_form.cljs
+++ src-cljs/stonecutter/renderer/register_form.cljs
@@ -8,8 +8,8 @@
 (def email-address-form-row-element-selector :.clj--registration-email)
 (def password-form-row-element-selector :.clj--registration-password)

-(def field-invalid-class "form-row--invalid")
-(def field-valid-class "form-row--valid")
+(def field-invalid-class :form-row--invalid)
+(def field-valid-class :form-row--valid)

 (defn add-or-remove-class! [element-selector css-class add?]
   (let [element (dm/sel1 element-selector)]


Add choose-bias game

Add choose-bias game

--- src/randometer/core.cljs
+++ src/randometer/core.cljs
@@ -87,6 +87,26 @@
                         :answertext (map #(str % " switch") (cons x xs))}
          boards keymap guess]))))

+(defn choose-bias [x xs]
+  (let [game-state (atom {})
+        init-game! (fn []
+                     (let [boards (map #(puzzle biased-generator %) (cons x xs))
+                           keymap (shuffle-boards boards)]
+                      (swap! game-state assoc
+                             :boards boards
+                             :keymap keymap
+                             :guess nil)))
+        guess! (fn [ix]
+                 (swap! game-state assoc :guess ix))]
+    (init-game!)
+    (fn []
+      (let [{:keys [boards keymap guess]} @game-state]
+        [board-chooser {:on-guess #(guess! %)
+                        :on-reset #(init-game!)
+                        :flavortext "Which is unbiased?"
+                        :answertext (map #(str % " ●") (cons x xs))}
+         boards keymap guess]))))
+
 (defn main-page []
   (let [app-state (atom {:game nil})]
     (fn []
@@ -103,6 +123,7 @@
          [:option {:value "decide-bias"} "Biased or unbiased"]]]
        (case (:game @app-state)
          "choose-corr" [choose-corr 0.5 [0.25 0.33 0.67 0.75]]
+         "choose-bias" [choose-bias 0.5 [0.25 0.33 0.67 0.75]]
          nil)])))

 (reagent/render-component [main-page]


tweak greetings build.boot

tweak greetings build.boot

--- examples/greetings/build.boot
+++ examples/greetings/build.boot
@@ -60,22 +60,24 @@
 (task-options!
  pom  {:project     +project+
        :version     +version+
-       :description "Example code, boot, miraj, GAE"
+       :description "Example code, boot, GAE"
        :license     {"EPL" "http://www.eclipse.org/legal/epl-v10.html"}})

 (def web-inf-dir "WEB-INF")
 (def classes-dir (str web-inf-dir "/classes"))

+;; same as gae/build:
 (deftask btest
-  "make a dev build - including reloader"
+  "assemble, configure, and build app"
   [k keep bool "keep intermediate .clj and .edn files"
+   p prod bool "production build, without reloader"
    v verbose bool "verbose"]
   (comp (gae/install-sdk :verbose verbose)
         (gae/libs :verbose verbose)
         (gae/logging :verbose verbose)
         (gae/appstats :verbose verbose)
         (builtin/javac) ;; :options ["-verbose"])
-        (gae/reloader :keep keep :verbose verbose)
+        (if prod identity (reloader :keep keep :verbose verbose))
         (gae/filters :keep keep :verbose verbose)
         (gae/servlets :keep keep :verbose verbose)
         (gae/webxml :verbose verbose)


fixed date test

fixed date test

--- test/selmer/core_test.clj
+++ test/selmer/core_test.clj
@@ -161,9 +161,10 @@
   (is (= "" (render-string "{{f|upper}}" {}))))

 (deftest filter-date
-  (is (= ;;"1970-01-01_00:00:00"
-         "1969-12-31_18:00:00"
-         (render-string "{{f|date:\"yyyy-MM-dd_HH:mm:ss\"}}" {:f (java.util.Date. (long 0))}))))
+  (let [date (java.util.Date.)]
+    (is (= ;;"1970-01-01_00:00:00"
+          (.format (java.text.SimpleDateFormat. "yyyy-MM-dd_HH:mm:ss") date)
+           (render-string "{{f|date:\"yyyy-MM-dd_HH:mm:ss\"}}" {:f date})))))

 (deftest filter-hash-md5
   (is (= "acbd18db4cc2f85cedef654fccc4a4d8"


Downgrade log in history to debug

Downgrade log in history to debug

--- src/yetibot/core/commands/history.clj
+++ src/yetibot/core/commands/history.clj
@@ -1,6 +1,6 @@
 (ns yetibot.core.commands.history
   (:require
-    [taoensso.timbre :refer [info]]
+    [taoensso.timbre :refer [debug info]]
     [yetibot.core.models.history :as h]
     [clojure.string :refer [blank? join split]]
     [yetibot.core.hooks :refer [cmd-hook]]))
@@ -67,6 +67,8 @@
                   ;; default to last 30 items if there were no filters
                   (take
                     30 (h/history-for-chat-source chat-source extra-where)))]
+
+    (debug "computed history" (pr-str history))
     ;; format
     (if (= (first next-commands) "count")
       ;; count doesn't need any formatting since it's just a raw number