refactored a bit

refactored a bit

--- src/webdriver/api.clj
+++ src/webdriver/api.clj
@@ -1,5 +1,4 @@
 (ns webdriver.api
-
   "
   Documentation? Read the code, Luke!

@@ -12,7 +11,6 @@
   Phantom.js (Ghostdriver)
   https://github.com/detro/ghostdriver/tree/873c9d660a80a3faa743e4f352571ce4559fe691/src/request_handlers
   "
-
   (:require [webdriver.client :as client]
             [clojure.java.io :as io]
             [clojure.data.codec.base64 :as b64]
@@ -97,12 +95,12 @@
 (defn get-timeout [server session]
   "https://www.w3.org/TR/webdriver/#dfn-get-timeout"
   (client/call server :get
-               [:session (session-id session) :timeouts]))
+               [:session session :timeouts]))

 (defn set-timeout [server session type msec]
   "https://www.w3.org/TR/webdriver/#dfn-set-timeouts"
   (client/call server :post
-               [:session (session-id session) :timeouts]
+               [:session session :timeouts]
                {:type type :ms msec}))

 (defn go [server session url]
@@ -110,7 +108,7 @@
   (let [meth :post
         path [:session session :url]
         body {:url url}
-        resp (client/call meth path body)]
+        resp (client/call server meth path body)]
     (-> resp :value)))

 (defn get-current-url
@@ -123,108 +121,121 @@
         resp (client/call server meth path)]
     (-> resp :value)))

-(defn back [server session]
+(defn back
   "https://www.w3.org/TR/webdriver/#dfn-back"
-  (client/call server
-               :post
-               [:session (session-id session) :back]))
-
-(defn forward [server session]
+  [server session]
+  {:pre [(map? server) (string? session)]}
+  (let [meth :post
+        path [:session session :back]
+        resp (client/call server meth path)]
+    (-> resp :value)))
+
+(defn forward
   "https://www.w3.org/TR/webdriver/#dfn-forward"
-  (client/call server
-               :post
-               [:session (session-id session) :forward]))
-
-(defn refresh [server session]
+  [server session]
+  {:pre [(map? server) (string? session)]}
+  (let [meth :post
+        path [:session session :forward]
+        resp (client/call server meth path)]
+    (-> resp :value)))
+
+(defn refresh
   "https://www.w3.org/TR/webdriver/#dfn-refresh"
-  (client/call server
-               :post
-               [:session (session-id session) :refresh]))
-
-(defn get-title [server session]
+  [server session]
+  {:pre [(map? server) (string? session)]}
+  (let [meth :post
+        path [:session session :refresh]
+        resp (client/call server meth path)]
+    (-> resp :value)))
+
+(defn get-title
   "https://www.w3.org/TR/webdriver/#dfn-get-title"
-  (-> server
-      (client/call :get [:session (session-id session) :title])
-      :value))
+  [server session]
+  {:pre [(map? server) (string? session)]
+   :post [(string? %)]}
+  (let [meth :get
+        path [:session session :title]
+        resp (client/call server meth path)]
+    (-> resp :value)))

 (defn get-window-handle [server session]
   "https://www.w3.org/TR/webdriver/#dfn-get-window-handle"
   (-> server
-      (client/call :get [:session (session-id session) :window])
+      (client/call :get [:session session :window])
       :value))

 (defn close-window [server session]
   "https://www.w3.org/TR/webdriver/#dfn-get-window-handle"
-  (client/call server :delete [:session (session-id session) :window]))
+  (client/call server :delete [:session session :window]))

 (defn switch-to-window [server session handle]
   "https://www.w3.org/TR/webdriver/#dfn-switch-to-window"
   (client/call server :post
-               [:session (session-id session) :window]
+               [:session session :window]
                {:handle handle}))

 (defn get-window-handles [server session]
   "https://www.w3.org/TR/webdriver/#dfn-get-window-handles"
   (-> server
-      (client/call :get [:session (session-id session) :window :handles])
+      (client/call :get [:session session :window :handles])
       :value))

 (defn switch-to-frame [server session frame]
   "https://www.w3.org/TR/webdriver/#dfn-switch-to-frame"
   (-> server
       (client/call
-       :post [:session (session-id session) :frame]
+       :post [:session session :frame]
        {:id frame})))

 (defn switch-to-parent-frame [server session]
   "https://www.w3.org/TR/webdriver/#dfn-switch-to-parent-frame"
   (-> server
       (client/call
-       :post [:session (session-id session) :frame :parent])))
+       :post [:session session :frame :parent])))

 (defn get-window-size [server session]
   (-> server
-      (client/call :get [:session (session-id session) :window :size])))
+      (client/call :get [:session session :window :size])))

 (defn set-window-size [server session width height]
   (-> server
-      (client/call :post [:session (session-id session) :window :size]
+      (client/call :post [:session session :window :size]
                    {:width width :height height})))

 (defn set-window-position [server session x y]
   (-> server
-      (client/call :post [:session (session-id session) :window :position]
+      (client/call :post [:session session :window :position]
                    {:x x :y y})))

 (defn ^:not-implemented
   get-window-rect [server session]
   "https://www.w3.org/TR/webdriver/#dfn-get-window-rect"
   (-> server
-      (client/call :get [:session (session-id session) :window :rect])))
+      (client/call :get [:session session :window :rect])))

 (defn ^:not-implemented
   set-window-rect [server session x y width height]
   "https://www.w3.org/TR/webdriver/#dfn-set-window-rect"
   (client/call :post
-               [:session (session-id session) :window :rect]
+               [:session session :window :rect]
                {:x x :y y :width width :height height}))

 (defn maximize-window [server session]
   "https://www.w3.org/TR/webdriver/#dfn-maximize-window"
   (client/call server :post
-               [:session (session-id session) :window :maximize]))
+               [:session session :window :maximize]))

 (defn ^:not-implemented
   fullscreen-window [server session]
   "https://www.w3.org/TR/webdriver/#dfn-fullscreen-window"
   (client/call server :post
-               [:session (session-id session) :window :fullscreen]))
+               [:session session :window :fullscreen]))

 ;; ff only
 (defn get-active-element [server session]
   "https://www.w3.org/TR/webdriver/#dfn-get-active-element"
   (-> (client/call server :get
-                   [:session (session-id session) :element :active])
+                   [:session session :element :active])
       :value
       parse-element))

@@ -232,7 +243,7 @@
   "https://www.w3.org/TR/webdriver/#dfn-find-element"
   (-> server
       (client/call :post
-                   [:session (session-id session) :element]
+                   [:session session :element]
                    {:using locator :value term})
       :value
       parse-element))
@@ -241,7 +252,7 @@
   "https://www.w3.org/TR/webdriver/#dfn-find-elements"
   (-> server
       (client/call :post
-                   [:session (session-id session) :elements]
+                   [:session session :elements]
                    {:using locator :value term})
       :value
       (->> (mapv parse-element))))
@@ -250,7 +261,7 @@
   "https://www.w3.org/TR/webdriver/#dfn-find-element-from-element"
   (-> server
       (client/call :post
-                   [:session (session-id session) :element element :element]
+                   [:session session :element element :element]
                    {:using locator :value term})
       :value
       parse-element))
@@ -259,7 +270,7 @@
   "https://www.w3.org/TR/webdriver/#dfn-find-elements-from-element"
   (-> server
       (client/call :post
-                   [:session (session-id session) :element element :elements]
+                   [:session session :element element :elements]
                    {:using locator :value term})
       :value
       (->> (mapv parse-element))))
@@ -268,49 +279,49 @@
   "https://www.w3.org/TR/webdriver/#dfn-is-element-selected"
   (-> server
       (client/call :get
-                   [:session (session-id session) :element element :displayed])
+                   [:session session :element element :displayed])
       :value))

 (defn is-element-selected [server session element]
   "https://www.w3.org/TR/webdriver/#dfn-is-element-selected"
   (-> server
       (client/call :get
-                   [:session (session-id session) :element element :selected])
+                   [:session session :element element :selected])
       :value))

 (defn get-element-attribute [server session element attribute]
   "https://www.w3.org/TR/webdriver/#dfn-get-element-attribute"
   (-> server
       (client/call :get
-                   [:session (session-id session) :element element :attribute attribute])
+                   [:session session :element element :attribute attribute])
       :value))

 (defn get-element-property [server session element property]
   "https://www.w3.org/TR/webdriver/#dfn-get-element-property"
   (-> server
       (client/call :get
-                   [:session (session-id session) :element element :property property])
+                   [:session session :element element :property property])
       :value))

 (defn get-element-css-value [server session element property]
   "https://www.w3.org/TR/webdriver/#dfn-get-element-css-value"
   (-> server
       (client/call :get
-                   [:session (session-id session) :element element :css property])
+                   [:session session :element element :css property])
       :value))

 (defn get-element-text [server session element]
   "https://www.w3.org/TR/webdriver/#dfn-get-element-text"
   (-> server
       (client/call :get
-                   [:session (session-id session) :element element :text])
+                   [:session session :element element :text])
       :value))

 (defn get-element-tag-name [server session element]
   "https://www.w3.org/TR/webdriver/#dfn-get-element-tag-name"
   (-> server
       (client/call :get
-                   [:session (session-id session) :element element :name])
+                   [:session session :element element :name])
       :value))

 (defn
@@ -319,20 +330,20 @@
   "https://www.w3.org/TR/webdriver/#dfn-get-element-rect"
   (-> server
       (client/call :get
-                   [:session (session-id session) :element element :rect])))
+                   [:session session :element element :rect])))

 (defn is-element-enabled [server session element]
   "https://www.w3.org/TR/webdriver/#dfn-is-element-enabled"
   (-> server
       (client/call :get
-                   [:session (session-id session) :element element :enabled])
+                   [:session session :element element :enabled])
       :value))

 (defn element-click [server session element]
   "https://www.w3.org/TR/webdriver/#dfn-is-element-enabled"
   (-> server
       (client/call :post
-                   [:session (session-id session) :element element :click])
+                   [:session session :element element :click])
       :value))

 (defn ^{:chrome false}
@@ -340,19 +351,19 @@
   "https://www.w3.org/TR/webdriver/#dfn-is-element-enabled"
   (-> server
       (client/call :post
-                   [:session (session-id session) :element element :tap])))
+                   [:session session :element element :tap])))

 (defn element-clear [server session element]
   "https://www.w3.org/TR/webdriver/#dfn-element-clear"
   (-> server
       (client/call :post
-                   [:session (session-id session) :element element :clear])))
+                   [:session session :element element :clear])))

 (defn element-send-keys [server session element text]
   "https://www.w3.org/TR/webdriver/#dfn-element-send-keys"
   (-> server
       (client/call :post
-                   [:session (session-id session) :element element :value]
+                   [:session session :element element :value]
                    {:value (text-to-array text)})
       :value))

@@ -360,80 +371,90 @@
   "https://www.w3.org/TR/webdriver/#dfn-get-page-source"
   (-> server
       (client/call :get
-                   [:session (session-id session) :source])
-      :value))
-
-(defn ^{:chrome false}
-  execute-script [{:keys [browser] :as server} session script & args]
+                   [:session session :source])
+      :value))
+
+(defn execute-script
   "https://www.w3.org/TR/webdriver/#dfn-execute-script"
-  (let [method :get
-        url [:session session :execute (case (:browser server)
-                                         :firefox :sync
-                                         :chrome :execute
-                                         :phantom :execute
-                                         :sync)]
-        data {:script script :args args}
+  [server session script & args]
+  {:pre [(map? server) (string? session) (string? script)]}
+  (let [cmd (case (:browser server)
+              (:chrome :phantom) :execute
+              :sync)
+        method :post
+        url [:session session cmd]
+        data {:script script :args (vec args)}
         resp (client/call server method url data)]
-    (case (:browser server)
-      :chrome (-> resp :value)
-      (-> resp :value first second)
-      )
-
-    ))
+    (-> resp :value)))

 (defn execute-async-script [server session script & args]
   "https://www.w3.org/TR/webdriver/#dfn-execute-async-script"
   (-> server
       (client/call :post
-                   [:session (session-id session) :execute :async]
+                   [:session session :execute :async]
                    {:script script :args args})))

-(defn get-all-cookies [server session]
+(defn get-all-cookies
   "https://www.w3.org/TR/webdriver/#dfn-get-all-cookies"
-  (-> server
-      (client/call :get
-                   [:session (session-id session) :cookie])
-      :value))
-
-(defn get-named-cookie [server session name]
+  [server session]
+  {:pre [(map? server) (string? session)]
+   :post [(vector? %)]}
+  (let [method :get
+        url [:session session :cookie]
+        resp (client/call server method url)]
+    (-> resp :value)))
+
+(defn get-named-cookie
   "https://www.w3.org/TR/webdriver/#dfn-get-named-cookie"
-  (-> server
-      (client/call :get
-                   [:session (session-id session) :cookie name])
-      :value
-      first))
+  [server session name]
+  {:pre [(map? server) (string? session) (string? name)]
+   :post [(vector? %)]}
+
+  (case (:browser server)
+
+    (:chrome :phantom)
+    (throw+ {:type :webdriver/not-implemented})
+    ;; (as->
+    ;;   (get-all-cookies server session) $
+    ;;   (filter #(-> % :name (= name)) $)
+    ;;   (vec $))
+
+    (let [method :get
+          url [:session session :cookie name]
+          resp (client/call server method url)]
+      (-> resp :value))))

 (defn add-cookie [server session cookie]
   "https://www.w3.org/TR/webdriver/#dfn-add-cookie"
   (-> server
       (client/call :post
-                   [:session (session-id session) :cookie]
+                   [:session session :cookie]
                    {:cookie cookie})))

 (defn delete-cookie [server session name]
   "https://www.w3.org/TR/webdriver/#dfn-delete-cookie"
   (-> server
       (client/call :delete
-                   [:session (session-id session) :cookie name])))
+                   [:session session :cookie name])))

 (defn delete-all-cookies [server session]
   "https://www.w3.org/TR/webdriver/#dfn-delete-all-cookies"
   (-> server
       (client/call :delete
-                   [:session (session-id session) :cookie])))
+                   [:session session :cookie])))

 (defn perform-actions [server session actions]
   "https://www.w3.org/TR/webdriver/#dfn-perform-implementation-specific-action-dispatch-steps"
   (-> server
       (client/call :post
-                   [:session (session-id session) :actions]
+                   [:session session :actions]
                    actions)))

 (defn release-actions [server session]
   "https://www.w3.org/TR/webdriver/#dfn-release-actions"
   (-> server
       (client/call :delete
-                   [:session (session-id session) :actions])))
+                   [:session session :actions])))

 (defn
   ^{:firefox false}
@@ -441,7 +462,7 @@
   "https://www.w3.org/TR/webdriver/#dfn-dismiss-alert"
   (-> server
       (client/call :post
-                   [:session (session-id session) :alert :dismiss])))
+                   [:session session :alert :dismiss])))

 (defn
   ^{:firefox false}
@@ -449,27 +470,27 @@
   "https://www.w3.org/TR/webdriver/#dfn-accept-alert"
   (-> server
       (client/call :post
-                   [:session (session-id session) :alert :accept])))
+                   [:session session :alert :accept])))

 (defn get-alert-text [server session]
   "https://www.w3.org/TR/webdriver/#dfn-get-alert-text"
   (-> server
       (client/call :get
-                   [:session (session-id session) :alert :text])
+                   [:session session :alert :text])
       :value))

 (defn send-alert-text [server session text]
   "https://www.w3.org/TR/webdriver/#dfn-send-alert-text"
   (-> server
       (client/call :post
-                   [:session (session-id session) :alert :text]
+                   [:session session :alert :text]
                    {:value (text-to-array text)})))

 (defn take-screenshot [server session filename]
   "https://www.w3.org/TR/webdriver/#dfn-take-screenshot"
   (-> server
       (client/call :get
-                   [:session (session-id session) :screenshot])
+                   [:session session :screenshot])
       :value
       (check-screenshot {:server server
                          :filename filename})
@@ -479,9 +500,21 @@
   "https://www.w3.org/TR/webdriver/#dfn-take-element-screenshot"
   (-> server
       (client/call :get
-                   [:session (session-id session) :element element :screenshot])
+                   [:session session :element element :screenshot])
       :value
       (check-screenshot {:server server
                          :element element
                          :filename filename})
       (b64-to-file filename)))
+
+(defn mouse-move-to
+  "Moves virtual mouse."
+  [server session & {:keys [element xoffset yoffset] :as payload}]
+  {:pre [(map? server) (string? session)]}
+  (case (:browser server)
+    :firefox (throw+ {:type :webdriver/not-implemented})
+    (let [meth :post
+          path [:session session :moveto]
+          body payload
+          resp (client/call server meth path body)]
+      (-> resp :value))))


refactored; form api added

refactored; form api added

--- src/webdriver/dsl.clj
+++ src/webdriver/dsl.clj
@@ -49,6 +49,30 @@
      ~@body))

 ;;
+;; find elements
+;;
+
+(defmacro with-el [term el & body]
+  `(let [~el (api/find-element *server* *session* *locator* ~term)]
+     ~@body))
+
+(defmacro with-els [term el & body]
+  `(doseq [~el (api/find-elements *server* *session* *locator* ~term)]
+     ~@body))
+
+(defmacro with-el-from [parent term el & body]
+  `(let [~el (api/find-element-from-element *server* *session* ~parent *locator* ~term)]
+     ~@body))
+
+(defmacro with-els-from [el-parent term el & body]
+  `(doseq [~el (api/find-elements-from-element *server* *session* ~el-parent *locator* ~term)]
+     ~@body))
+
+(defn with-el-active [el & body]
+  `(let [~el (api/get-active-element *server* *session*)]
+     ~@body))
+
+;;
 ;; locators
 ;;

@@ -192,30 +216,6 @@
        ~@body)))

 ;;
-;; find elements
-;;
-
-(defmacro with-el [term el & body]
-  `(let [~el (api/find-element *server* *session* *locator* ~term)]
-     ~@body))
-
-(defmacro with-els [term el & body]
-  `(for [~el (api/find-elements *server* *session* *locator* ~term)]
-     ~@body))
-
-(defmacro with-el-from [parent term el & body]
-  `(let [~el (api/find-element-from-element *server* *session* ~parent *locator* ~term)]
-     ~@body))
-
-(defmacro with-els-from [el-parent term el & body]
-  `(for [~el (api/find-elements-from-element *server* *session* ~el-parent *locator* ~term)]
-     ~@body))
-
-(defn with-el-active [el & body]
-  `(let [~el (api/get-active-element *server* *session*)]
-     ~@body))
-
-;;
 ;; name and text
 ;;

@@ -262,8 +262,8 @@
 ;; session
 ;;

-(defmacro with-session [capabilities & body]
-  `(binding [*session* (api/new-session *server* ~capabilities)]
+(defmacro with-session [cap-desired cap-required & body]
+  `(binding [*session* (api/new-session *server* ~cap-desired ~cap-required)]
      (try
        ~@body
        (finally
@@ -385,6 +385,12 @@
     (get-alert-text)
     true))

+(defn has-text [text]
+  (with-xpath
+    (with-404
+      (with-el (format "//*[contains(text(),'%s')]" text) el
+        true))))
+
 ;;
 ;; wait functions
 ;;
@@ -393,12 +399,14 @@
   (Thread/sleep (* sec 1000)))

 (defn wait-for-predicate
-  [predicate & {:keys [timeout poll]
+  [predicate & {:keys [timeout poll message]
                 :or {timeout 10 poll 0.5}}]
   (loop [times 0
          time-rest timeout]
     (when (< time-rest 0)
+      (is false message)
       (throw+ {:type :webdriver/timeout
+               :message message
                :timeout timeout
                :poll poll
                :times times
@@ -431,6 +439,44 @@

 (defn wait-running [& args]
   (apply wait-for-predicate running args))
+
+(defn wait-has-text [text & args]
+  (apply wait-for-predicate #(has-text text) args))
+
+;;
+;; element properties
+;;
+
+(defn prop-el [el name]
+  (api/get-element-property *server* *session* el name))
+
+(defn prop [term name]
+  (with-el term el
+    (prop-el el name)))
+
+(defmacro with-prop-el [el name & body]
+  `(let [~name (prop-el ~el ~(str name))]
+     ~@body))
+
+(defmacro with-prop [term name & body]
+  `(with-el ~term el#
+     (with-prop-el el# ~name
+       ~@body)))
+
+(defmacro with-props-el [el names & body]
+  (let [func (fn [name] `(prop-el ~el ~(str name)))
+        forms (map func names)
+        binds (-> names
+                  (interleave forms)
+                  vec
+                  vector)]
+    `(let ~@binds
+       ~@body)))
+
+(defmacro with-props [term names & body]
+  `(with-el ~term el#
+     (with-props-el el# ~names
+       ~@body)))

 ;;
 ;; keys and input
@@ -470,12 +516,32 @@
 (defn fill-form-el [el-form form]
   (doseq [[field value] form]
     (let [term (format "//input[@name='%s']" (name field))]
-      (with-el-from el-form term el-input
-        (fill-el el-input (str value))))))
+      (with-xpath
+        (with-el-from el-form term el-input
+          (fill-el el-input (str value)))))))

 (defn fill-form [term form]
   (with-el term el-form
     (fill-form-el el-form form)))
+
+(defn submit-form-el [el-form form]
+  (fill-form-el el-form form)
+  (with-xpath
+    (with-el-from el-form "//submit | //button[@type='submit']" el-submit
+      (click-el el-submit))))
+
+(defn submit-form [term form]
+  (with-el term el-form
+    (submit-form-el el-form form)))
+
+(defn clear-form-el [el-form]
+  (with-xpath
+    (with-els-from el-form "//input[not(@type='hidden')]" el-input
+      (clear-el el-input))))
+
+(defn clear-form [term]
+  (with-el term el-form
+    (clear-form-el el-form)))

 (defn get-form-el [el-form]
   (let [term "//input"
@@ -541,59 +607,24 @@
        ~@body)))

 ;;
-;; element properties
-;;
-
-(defn prop-el [el name]
-  (api/get-element-property *server* *session* el name))
-
-(defn prop [term name]
-  (with-el term el
-    (prop-el el name)))
-
-(defmacro with-prop-el [el name & body]
-  `(let [~name (prop-el ~el ~(str name))]
-     ~@body))
-
-(defmacro with-prop [term name & body]
-  `(with-el ~term el#
-     (with-prop-el el# ~name
-       ~@body)))
-
-(defmacro with-props-el [el names & body]
-  (let [func (fn [name] `(prop-el ~el ~(str name)))
-        forms (map func names)
-        binds (-> names
-                  (interleave forms)
-                  vec
-                  vector)]
-    `(let ~@binds
-       ~@body)))
-
-(defmacro with-props [term names & body]
-  `(with-el ~term el#
-     (with-props-el el# ~names
-       ~@body)))
-
-;;
 ;; tests
 ;;

 (deftest simple-test
   (let [host "127.0.0.1"
-        port (random-port) ;; 4444 ;; 8910
+        port (random-port)
         args ["geckodriver" "--host" host "--port" port]
-        capabilities {}
         html "<input class=\"input__control input__input\" tabindex=\"2\" autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" aria-autocomplete=\"list\" aria-label=\"Запрос\" id=\"text\" maxlength=\"400\" name=\"text\">"
         input "//input[@id='text']"]

     ;; with-start host port
     (proc/with-proc p [args]
       (with-server host port
-        (wait-running)
-        (with-session capabilities
+        (wait-running :message "The server did not start.")
+        (with-session {} {}
           (client/with-pool {}
             (go-url "http://ya.ru")
+            (wait-has-text "Найти" :message "Найти was not found on the page")
             (js-set-hash "fooooo")
             ;; (with-url url
             ;;   (is (= url 1)))
@@ -633,4 +664,7 @@
                 (is (= height 46.0)))))
           (screenshot "page.png")
           (screenshot input "element.png")
+          (clear-form "//form")
+          ;; (submit-form "//form" {:text "sdfsdfsdfsdfs"})
+          ;; (wait 5)
           )))))


Элемент ввода времени

Элемент ввода времени

--- radiolamp-6P3S/src/ixinfestor/omut.cljs
+++ radiolamp-6P3S/src/ixinfestor/omut.cljs
@@ -1045,6 +1045,50 @@
   (when-not (str-to-date v)
     (om/transact! app #(assoc % :has-warning? true :text-warning "Неправильная дата")))
   true)
+
+
+
+
+(def input-datetime--date-str-format "yyyy-MM-ddTHH:mmZ")
+
+(defn input-datetime-form-group--set-date! [app d]
+  (assoc app :value (format-date input-datetime--date-str-format d)))
+
+(defn input-datetime-form-group--date [app]
+  (str-to-date (@app :value)))
+
+
+
+(defn input-datetime-form-group  [app owner {:keys [label
+                                                    type
+                                                    label-class+
+                                                    input-class+
+                                                    spec-input]
+                                             :or   {label        "Метка"
+                                                    label-class+ "col-xs-12 col-sm-4 col-md-4 col-lg-4"
+                                                    input-class+ "col-xs-12 col-sm-8 col-md-8 col-lg-8"
+                                                    spec-input   {}}}]
+  (reify
+    om/IRender
+    (render [this]
+      (dom/div #js {:className (str "form-group " (input-css-string-has? app))}
+               (dom/label #js {:className (str "control-label " label-class+) } label)
+               (dom/div #js {:className input-class+ :style #js {}}
+                        (dom/b nil "введено: "
+                               (date-com-format-datetime (str-to-date (@app :value))))
+                        (om/build
+                         input app
+                         {:opts (assoc spec-input
+                                       :type                "datetime"
+                                       :placeholder         input-datetime--date-str-format
+                                       :onChange-valid?-fn  input-vldfn-not-empty-date)})
+                        (om/build helper-p app {})
+                        )))))
+
+
+
+
+

 ;; END input


use :stable meta in UI code

use :stable meta in UI code

--- src/main/shadow/cljs/ui/components/inspect.cljs
+++ src/main/shadow/cljs/ui/components/inspect.cljs
@@ -185,11 +185,7 @@
        label]))

 (defc ui-object-panel
-  {:supports?
-   (fn [prev-args next-args]
-     (= (first prev-args) (first next-args)))}
-
-  [ident panel-idx active?]
+  [^:stable ident panel-idx active?]
   (bind object
     (sg/query-ident ident
       [:db/ident
@@ -392,11 +388,7 @@
          ])))

 (defc ui-explore-object-panel
-  {:supports?
-   (fn [prev-args next-args]
-     (= (first prev-args) (first next-args)))}
-
-  [ident panel-idx active?]
+  [^:stable ident panel-idx active?]
   (bind object
     (sg/query-ident ident
       [:db/ident


Remove symbol declaration

Remove symbol declaration

--- dungeon-crawler/desktop/src-common/dungeon_crawler/core.clj
+++ dungeon-crawler/desktop/src-common/dungeon_crawler/core.clj
@@ -6,7 +6,7 @@
             [play-clj.g2d :refer :all]
             [play-clj.ui :refer :all]))

-(declare dungeon-crawler main-screen npc-health-screen overlay-screen)
+(declare dungeon-crawler main-screen overlay-screen)

 (defonce manager (asset-manager))
 (set-asset-manager! manager)


terminology comment before i forget

terminology comment before i forget

--- src/seathree/handler.clj
+++ src/seathree/handler.clj
@@ -8,6 +8,9 @@
            [clojure.tools.nrepl.server :as nrsv   ]
            [seathree.config            :as cfg    ]
            [seathree.twitter           :as twitter]))
+
+;; Update: getting tweets from twitter, storing
+;; Sync: request from client for a username

 (comment TODO gzipping)
 (comment TODO re-architect to work with status ids instead of update timestamps!)


refactor: extract function create-pages

refactor: extract function create-pages

--- examples/lesson-carousel-starter-kit/src/carousel/core.cljs
+++ examples/lesson-carousel-starter-kit/src/carousel/core.cljs
@@ -80,10 +80,8 @@
         (setMountPoint .5, 1, 0))
     root-dot))

-(defn create-pager [root-node]
-  (let [simulation (PhysicsEngine.)
-        pager-node (.. root-node addChild)
-        url-base "http://demo.famo.us.s3.amazonaws.com/hub/apps/carousel/Museo_del_Prado_-_Goya_-_Caprichos_-_No._"
+(defn create-pages [root-node]
+  (let [url-base "http://demo.famo.us.s3.amazonaws.com/hub/apps/carousel/Museo_del_Prado_-_Goya_-_Caprichos_-_No._"
         image-names ["01_-_Autorretrato._Francisco_Goya_y_Lucientes2C_pintor_thumb.jpg"
                      "02_-_El_si_pronuncian_y_la_mano_alargan_al_primero_que_llega_thumb.jpg"
                      "03_-_Que_viene_el_Coco_thumb.jpg"
@@ -116,7 +114,7 @@
                            (setProperty "backgroundImage" image-url)
                            (setProperty "background-repeat" "no-repeat")
                            (setProperty "background-size" "cover"))
-                       (.. simulation (add box spring rotational-spring))
+
                        {:node image-node
                         :el el
                         :box box
@@ -124,13 +122,22 @@
                         :quaternion quaternion
                         :rotationalSpring rotational-spring
                         :anchor anchor}))
-                   image-names)
+                   image-names)]
+    pages))
+
+(defn create-pager [root-node]
+  (let [simulation (PhysicsEngine.)
+        pager-node (.. root-node addChild)
+        pages (create-pages root-node)
         pager {:node     pager-node
                :currentIndex (atom 0)
                :pages pages
                :pageWidth (atom 0)}
        ]

+    (doseq [ {:keys [box spring rotationalSpring]} pages]
+      (.. simulation (add box spring rotationalSpring)))
+
     (.. pager-node (addComponent (clj->js {:onSizeChange (fn [^Float32Array size]
                                                            (reset! (:pageWidth pager) size))})))


refactor pull out :pages :currentIndex from pager

--- examples/lesson-carousel-starter-kit/src/carousel/core.cljs
+++ examples/lesson-carousel-starter-kit/src/carousel/core.cljs
@@ -130,7 +130,6 @@
         pager-node (.. root-node addChild)
         pages (create-pages root-node)
         pager {:node     pager-node
-               :currentIndex (atom 0)
                :pages pages
                :pageWidth (atom 0)}
        ]
@@ -158,17 +157,7 @@
                                                                    (.. FamousEngine (requestUpdateOnNextTick this)))
                                                           )})))

-    (add-watch (:currentIndex pager) :watcher (fn [key atom old-index new-index]
-                                                (let [pages (:pages pager)
-                                                      old-page (nth pages old-index)
-                                                      new-page (nth pages new-index)]
-                                                  (.. (:anchor old-page) (set 1 0 0))
-                                                  (.. (:quaternion old-page) (fromEuler 0 (/ (.. js/Math -PI) -2) 0))
-                                                  (.. (:anchor new-page) (set 0 0 0))
-                                                  (.. (:quaternion new-page) (set 1 0 0 0))
-                                                  )
-
-                                                ))
+

     pager))

@@ -184,6 +173,8 @@

         dots-node (create-dots root-node)
         pager (create-pager root-node)
+        pages (:pages pager)
+        current-index (atom 0)

         back (decorate-arrow-node back-node "<")
         next (decorate-arrow-node next-node ">")
@@ -197,15 +188,24 @@
         (setAlign 1 0.5 0)
         (setPosition -40 0 0)
         (setMountPoint 1 0.5 0))
+
+    (add-watch current-index :watcher (fn [key atom old-index new-index]
+                                        (let [old-page (nth pages old-index)
+                                              new-page (nth pages new-index)]
+                                          (.. (:anchor old-page) (set 1 0 0))
+                                          (.. (:quaternion old-page) (fromEuler 0 (/ (.. js/Math -PI) -2) 0))
+                                          (.. (:anchor new-page) (set 0 0 0))
+                                          (.. (:quaternion new-page) (set 1 0 0 0)))))
+
     (go
       (while true
         (let [[v channel] (alts! [back-clicks next-clicks])]
           (cond
-            (= channel back-clicks) (let [current-index (:currentIndex pager)]
+            (= channel back-clicks) (do
                                       (println "back" @current-index)
                                       (swap! current-index dec)
                                       )
-            (= channel next-clicks) (let [current-index (:currentIndex pager)]
+            (= channel next-clicks) (do
                                       (println "next" @current-index)
                                       (swap! current-index inc)
                                       )))))))


Set activity add form start/end times on load.

--- src/cljs/elevent_client/pages/events/id/activities/id/edit.cljs
+++ src/cljs/elevent_client/pages/events/id/activities/id/edit.cljs
@@ -95,6 +95,12 @@
                        (callback)
                        (when-not activity-id (reset-form!)))))))]
         (when (seq event)
+          ; Add start/end times to form state
+          (swap! form assoc
+                 :StartTime (or (:StartTime @form)
+                                (:StartDate event))
+                 :EndTime   (or (:EndTime @form)
+                                (:StartDate event)))
           [:div.sixteen.wide.column
            [:div.ui.segment
             [:div.ui.vertical.segment


Clean upload component

Clean upload component

--- src/airhead_frontend/components.cljs
+++ src/airhead_frontend/components.cljs
@@ -87,7 +87,6 @@
 (defn upload-section []
   (let [form-ref         (r/atom nil)
         file-input-ref   (r/atom nil)
-        upload-input-ref (r/atom nil)

         state (r/atom {:response nil
                        :percentage 0})]
@@ -95,14 +94,10 @@
       [:section#upload
        [:h2 "Upload"]

-       [:form.hidden
-        {:ref #(reset! form-ref %)}
+       [:form.hidden {:ref #(reset! form-ref %)}
+
         [:input {:type "file" :name "track"
-                 :ref #(reset! file-input-ref %)}]
-        [:input {:type "button"
-                 :ref #(reset! upload-input-ref %)
-                 :on-click #(when-let [form @form-ref]
-                              (req/upload! form state))}]]
+                 :ref #(reset! file-input-ref %)}]]

        [:div.controller-box
         [:div.pure-button-group
@@ -115,7 +110,8 @@
          [:div.pure-button.pure-button.pure-u-1-2
           {:title "Upload"
            :on-click #(when @file-input-ref
-                        (.click @upload-input-ref))}
+                        (when-let [form @form-ref]
+                          (req/upload! form state)))}
           [:i.fa.fa-upload]]]

         [:div


done with adjudicators and cleaning of UI

--- src/tango/cljs/main.cljs
+++ src/tango/cljs/main.cljs
@@ -74,27 +74,18 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; UI utils

-(defn- to-number [s]
-  {:pre [(string? s)]}
-  (let [prepared-string (clojure.string/replace s #" " "")]
-    (cond (re-seq #"^[-+]?\d*[\.,]\d*$" prepared-string)
-          (js/parseDouble (clojure.string/replace prepared-string #"," "."))
-          (re-seq #"^[-+]?\d+$" prepared-string)
-          (js/parseInt (clojure.string/replace prepared-string #"\+" ""))
-          :else s)))
-
-(defn number-string? [s]
-  (if s
-    (re-seq #"\d+" s)))
+;; (defn- to-number [s]
+;;   {:pre [(string? s)]}
+;;   (let [prepared-string (clojure.string/replace s #" " "")]
+;;     (cond (re-seq #"^[-+]?\d*[\.,]\d*$" prepared-string)
+;;           (js/parseDouble (clojure.string/replace prepared-string #"," "."))
+;;           (re-seq #"^[-+]?\d+$" prepared-string)
+;;           (js/parseInt (clojure.string/replace prepared-string #"\+" ""))
+;;           :else s)))

 (defn make-dance-type-presentation [dances]
   ;; Dances are presented as a list of the first letters of each dance
   (clojure.string/join (map #(first (:dance/name %)) dances)))
-
-(defn make-event-time-presentation [time status]
-  (str time
-       (when (= status 1)
-         "*")))

 (def round-map
   {:none ""
@@ -113,157 +104,11 @@
 (defn make-event-round-presentation [event-round]
   (get round-map event-round))

-(defn make-round-presentation [round-status round-count]
-  (str
-   round-count " - "
-   (if round-status
-     (if (number-string? round-status)
-       (str "Round " round-status)
-       (condp = round-status
-         "S" (str "Semifinal" )
-         "E" "2nd Try"
-         "F" "Final"
-         "O" "Retry"
-         (str "Unknown status : " round-status)))
-     "Not Started")))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Components
-
-(defn count-class-recalled [class]
-  (let [results (:result/results (last (:class/results class)))
-        started (count (:class/competitors class))]
-    (if (empty? results)
-      started
-      (reduce
-       (fn [x y]
-         (if (contains?
-              #{:r :x}
-              (:competitor/recalled y))
-           (inc x)
-           x))
-       0
-       results))))
-
-(defn count-result-recalled [class-result]
-  (reduce
-   (fn [x y]
-     (if (contains?
-          #{:r :x}
-          (:competitor/recalled y))
-       (inc x)
-       x))
-   0
-   class-result))
-
-;; (def new-adj-data
-;;   {:competition/name "TurboMegatävling"
-;;    :competition/date "2014 11 22"
-;;    :competition/location "THUNDERDOME"
-;;    :competition/panels
-;;    [{:adjudicator-panel/name "1"
-;;      :adjudicator-panel/adjudicators
-;;      [{:adjudicator/name "Anders"
-;;        :adjudicator/id 1
-;;        :adjudicator/country "Sweden"}
-;;       {:adjudicator/name "Bertil"
-;;        :adjudicator/id 2
-;;        :adjudicator/country ""}]
-;;      :adjudicator-panel/id 4}
-;;     {:adjudicator-panel/name "2"
-;;      :adjudicator-panel/adjudicators
-;;      [{:adjudicator/name "Bertil"
-;;        :adjudicator/id 2
-;;        :adjudicator/country ""}
-;;       {:adjudicator/name "Cesar"
-;;        :adjudicator/id 3
-;;        :adjudicator/country ""}]
-;;      :adjudicator-panel/id 5}]
-;;    :competition/adjudicators
-;;    [{:adjudicator/name "Anders"
-;;      :adjudicator/id 1
-;;      :adjudicator/country "Sweden"}
-;;     {:adjudicator/name "Bertil"
-;;      :adjudicator/id 2
-;;      :adjudicator/country "Uganda"}
-;;     {:adjudicator/name "Cesar"
-;;      :adjudicator/id 3
-;;      :adjudicator/country "Tibet"}]
-;;    :competitor/activities []
-;;    :competition/classes []})
-
-(defn adjudictors-component []
-  [:div
-   [:h3 "Domare"]
-   [:table.table
-    [:thead
-     [:tr
-      ;[:th {:with "20"} "#"]
-      [:th {:with "200"} "Name"]
-      [:th {:with "20"} "Country"]]]
-    [:tbody
-     (for [adjudicator
-           (sort-by :adjudicator/name (:competition/adjudicators (:competition @app-state)))
-                                        ;(sort-by :adjudicator/id (:competition/adjudicators (:competition @app-state)))
-           ]
-       ^{:key adjudicator}
-       [:tr
-        ;[:td (:adjudicator/id adjudicator)]
-        [:td (:adjudicator/name adjudicator)]
-        [:td (:adjudicator/country adjudicator)]])]]])
-
-;; (defn adjudictors-component []
-;;   [:div
-;;    [:h3 "Domare"]
-;;    [:table.table
-;;     [:thead
-;;      [:tr
-;;       ;[:th {:with "20"} "#"]
-;;       [:th {:with "200"} "Name"]
-;;       [:th {:with "20"} "Country"]]]
-;;     [:tbody
-;;      (for [adjudicator (sort-by :adjudicator/id (:competition/adjudicators (:competition @app-state)))]
-;;        ^{:key adjudicator}
-;;        [:tr
-;;         ;[:td (:adjudicator/id adjudicator)]
-;;         [:td (:adjudicator/name adjudicator)]
-;;         [:td (:adjudicator/country adjudicator)]])]]])
-
-(defn new-adjudictor-panels-component []
-  [:div
-   [:h3 "Domarpaneler"]
-   [:table.table
-    [:thead
-     [:tr
-      [:th {:with "20"} "#"]
-      [:th {:with "200"} "Domare"]]]
-    [:tbody
-     (for [adjudicator-panel (sort-by :adjudicator-panel/id (:competition/panels (:competition @app-state)))]
-       ^{:key adjudicator-panel}
-       [:tr
-        [:td (:adjudicator-panel/id adjudicator-panel)]
-        [:td (clojure.string/join ", " (map :adjudicator/name (:adjudicator-panel/adjudicators adjudicator-panel)))]])]]])
-
-(defn adjudictor-panels-component []
-  [:div
-   [:h3 "Domarpaneler"]
-   [:table.table
-    [:thead
-     [:tr
-      [:th {:with "20"} "#"]
-      [:th {:with "200"} "Domare"]]]
-    [:tbody
-     (for [adjudicator-panel (sort-by :panel/id (:competition/adjudicator-panels (:competition @app-state)))]
-       ^{:key adjudicator-panel}
-       [:tr
-        [:td (:panel/id adjudicator-panel)]
-        [:td (clojure.string/join ", " (mapcat vals (:panel/adjudicators adjudicator-panel)))]])]]])
-
 (defn get-completed-rounds [rounds]
   (filter #(and (= (:round/status %) :completed)
                 (not= (:round/type %) :presentation)) rounds))

-(defn make-round-presentation-new [rounds]
+(defn make-round-presentation [rounds]
   ;; Only count rounds that are completed and that are not presentation rounds
   (let [completed-rounds (get-completed-rounds rounds)]
     (str
@@ -275,9 +120,49 @@
            (get round-map round-type)))
        "Not Started"))))

+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Components
+
+;; TODO - id is used as entity id and not as presentation, is name enough or should we keep
+;; a adj/number or adj/position ?
+(defn adjudictors-component []
+  [:div
+   [:h3 "Domare"]
+   [:table.table
+    [:thead
+     [:tr
+      ;[:th {:with "20"} "#"]
+      [:th {:with "200"} "Name"]
+      [:th {:with "20"} "Country"]]]
+    [:tbody
+     (for [adjudicator
+           (sort-by :adjudicator/name (:competition/adjudicators (:competition @app-state)))]
+       ^{:key adjudicator}
+       [:tr
+        ;[:td (:adjudicator/id adjudicator)]
+        [:td (:adjudicator/name adjudicator)]
+        [:td (:adjudicator/country adjudicator)]])]]])
+
+(defn adjudictor-panels-component []
+  [:div
+   [:h3 "Domarpaneler"]
+   [:table.table
+    [:thead
+     [:tr
+      [:th {:with "20"} "#"]
+      [:th {:with "200"} "Domare"]]]
+    [:tbody
+     (for [adjudicator-panel (sort-by :adjudicator-panel/name (:competition/panels (:competition @app-state)))]
+       ^{:key adjudicator-panel}
+       [:tr
+        [:td (:adjudicator-panel/name adjudicator-panel)]
+        [:td (clojure.string/join
+              ", "
+              (map :adjudicator/name (:adjudicator-panel/adjudicators adjudicator-panel)))]])]]])
+
 (defn classes-component []
   [:div
-   [:h3 "Klasser Nyyy"]
+   [:h3 "Klasser"]
    [:table.table
     [:thead
      [:tr
@@ -303,8 +188,7 @@
         ;; Present how far into the competition this class is.
         ;; The round status is given by the last completed round, if there are none
         ;;  the class is not started
-        [:td (make-round-presentation-new (:class/rounds class))
-         ]])]]])
+        [:td (make-round-presentation (:class/rounds class))]])]]])

 ;; TODO - make the on-click event run thoughe dispatch
 (defn import-component []
@@ -319,15 +203,10 @@
                             :on-click #(dispatch [:select-page :classes])}]
    [:input.btn.btn-default {:type "button" :value "Time Schedule"
                             :on-click #(dispatch [:select-page :events])}]
-   ;; [:input.btn.btn-default {:type "button" :value "NewAdjudicators"
-   ;;                          :on-click #(dispatch [:select-page :new-adjudicators])}]
-   [:input.btn.btn-default {:type "button" :value "NewAdjudicator panels"
-                            :on-click #(dispatch [:select-page :new-adjudicator-panels])}]
    [:input.btn.btn-default {:type "button" :value "Adjudicators"
                             :on-click #(dispatch [:select-page :adjudicators])}]
    [:input.btn.btn-default {:type "button" :value "Adjudicator panels"
-                            :on-click #(dispatch [:select-page :adjudicator-panels])}]
-   ])
+                            :on-click #(dispatch [:select-page :adjudicator-panels])}]])

 (defn time-schedule-activity-presenter [activity classes]
   (let [round (:activity/source activity)
@@ -404,12 +283,11 @@

      :type (if comment?
               ""
-              (make-dance-type-presentation (:round/dances round)))})
-  )
+              (make-dance-type-presentation (:round/dances round)))}))

 (defn events-component []
   [:div
-   [:h3 "Time Schedule Ny"]
+   [:h3 "Time Schedule"]
    [:table.table
     [:thead
      [:tr
@@ -448,9 +326,7 @@
      (condp = (:selected-page @app-state)
        :classes [classes-component]
        :events [events-component]
-       ;:adjudicators [adjudictors-component]
        :adjudicators [adjudictors-component]
-       :new-adjudicator-panels [new-adjudictor-panels-component]
        :adjudicator-panels [adjudictor-panels-component])]))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -459,35 +335,24 @@
 (defn ^:export run []
   (reagent/render-component [menu-component] (.-body js/document)))

-;; (defn handle-export []
-;;   (let [export-link (. js/document (getElementById "export-download-link"))]
-;;     (log "Exporting competition")
-;;     (.click export-link)))
-
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Socket handling
+
 (defn- event-handler [[id data :as ev] _]
   (log (str "Event: " id))
   (match [id data]
-    ;; TODO Match your events here <...>
-         ;; [:chsk/recv [:file/imported content]]
-         ;; (do
-         ;;   (swap! app-state #(merge % {:selected-page :classes
-         ;;                               :competition (:file/content content)}))
-         ;;   ;(swap! app-state #(hash-map :competitions (conj (:competitions %) content)))
-         ;;   (log (str @app-state))
-         ;;   )
+         ;; TODO Match your events here <...>
          [:chsk/recv [:file/imported content]]
          (do
            (swap! app-state #(merge % {:competition content}))
            (log (str @app-state)))
          ;; [:chsk/recv [:file/export content]]
          ;; (handle-export)
-    [:chsk/state [:first-open _]] (log "Channel socket successfully established!")
-    ;[:chsk/state new-state] (log (str "Chsk state change: " new-state))
-    ;[:chsk/recv payload] (log (str "Push event from server: " payload))
-    :else (log (str "Unmatched event: " ev)))
-  )
+         [:chsk/state [:first-open _]]
+         (log "Channel socket successfully established!")
+                                        ;[:chsk/state new-state] (log (str "Chsk state change: " new-state))
+                                        ;[:chsk/recv payload] (log (str "Push event from server: " payload))
+         :else (log (str "Unmatched event: " ev))))

 (defonce chsk-router
   (sente/start-chsk-router-loop! event-handler ch-chsk))
@@ -496,6 +361,12 @@
 ;; Purgatory

 ;; Exempel till "Export"
+
+;; (defn handle-export []
+;;   (let [export-link (. js/document (getElementById "export-download-link"))]
+;;     (log "Exporting competition")
+;;     (.click export-link)))
+
 ;;

 ;; (defn save-document []
@@ -507,104 +378,3 @@
 ;; (set! (.-href download-link) href-content)
 ;; (.click download-link)))

-
-;; TODO - Let the server return dancers in a UI-normalized way
-;; (defn get-dancers [competitions]
-;;   (into #{}
-;;         (map #(dissoc % :competitor/number)
-;;              (for [competition competitions
-;;                    classes (:competition/classes competition)
-;;                    competitors (:class/competitors classes)]
-;;                competitors))))
-
-;; (defonce component-state
-;;   (atom {:competitions-visible false}))
-
-;; (defn competitor-component [competitors include-number?]
-;;   [:div ""
-;;    [:ul
-;;     (for [competitor competitors]
-;;       ^{:key competitor}
-;;       [:li
-;;        (str (if include-number?
-;;               (str "Tävlande nummer : " (:competitor/number competitor) " - "))
-;;             (str (:competitor/name competitor)
-;;                  " från "
-;;                  (:competitor/club competitor)))])]])
-
-;; (defn class-component [classes]
-;;   [:h3 "Classes"]
-;;   [:div
-;;    (for [cls classes]
-;;      ^{:key cls}
-;;      [:div
-;;       (:class/name cls)
-;;       [competitor-component (:class/competitors cls) true]])])
-
-;; (defn competition-item []
-;;   (let [open (atom false)]
-;;     (fn [competition]
-;;       [:li
-;;        [:div.view
-;;         [:label {:on-click #(log "Klickz")} (str (:competition/name competition) " i "
-;;                       (:competition/location competition) " den "
-;;                       (:competition/date competition))
-;;          ]
-;;         [:input.btn.btn-default
-;;          {:type "button"
-;;           :value (if @open "Stäng" "Öppna")
-;;           :on-click #(swap! open not)}]]
-;;        (if @open
-;;          [:div
-;;           [:input.btn.btn-default
-;;            {:type "button"
-;;             :value "Exportera"
-;;             ;; TODO - send competition id when we got back-end storage
-;;             :on-click #(on-export-click % competition)}]
-;;           [:a {:id "export-download-link"
-;;                :href (str "/exported-files/" (:competition/name competition) ".xml")
-;;                :download (str (:competition/name competition) ".xml")}]
-;;           [:h4 "Klasser :"]
-;;           [class-component (:competition/classes competition)]])])))
-
-;; (defn competitors-component []
-;;   [:div
-;;    [:h2 "Tillgängliga dansare"]
-;;    [competitor-component (get-dancers (:competitions @app-state))]])
-
-;; (defn import-component []
-;;   [:div
-
-;;    [:h2 "Tillgängliga tävlingar"]
-;;    [:ul
-;;     (for [competition (:competitions @app-state)]
-;;       ^{:key competition} [competition-item competition])]
-;;    [:h2 "Importera en ny tävling : "]
-;;    [:input.btn.btn-default {:type "file" :value "Import file"
-;;                             :onChange ;#(dispatch [:file/import (.item (.. % -target -files) 0)])
-;;                             #(on-click-import-file %)
-;;                             }]])
-
-;; (defn menu-component []
-;;   (let [visible-component (atom :none)]
-;;     (fn []
-;;       [:div.container
-;;        [:div.header
-;;         [:h2 "Välkommen till Tango!"]
-;;         [:input.btn.btn-primary.btn-lg.navbar-btn
-;;          {:type "button" :value "Tävlingar" :on-click #(reset! visible-component :competitions)}]
-;;         [:input.btn.btn-primary.btn-lg
-;;          {:type "button" :value "Dansare" :on-click #(reset! visible-component :competitors)}]
-;;         [:input.btn.btn-primary.btn-lg
-;;          {:type "button" :value "Domare" :on-click #(reset! visible-component :adjudicators)}]
-
-;;         [:input.btn.btn-default
-;;          {:type "button" :value "Debug Button" :on-click #(chsk-send! [:debug/test {:test "Test"}])}]
-;;         ;[:h2 (str "visible-component " @visible-component)]
-;;         ]
-;;        (condp = @visible-component
-;;          :competitions [import-component]
-;;          :competitors [competitors-component]
-;;          :adjudicators [:div]
-;;          :none [:div])
-;;        ])))


Remove reflection on creds

Remove reflection on creds

Not a real problem since creds creation is memoized anyway, but this did
create noise in logs output, etc.

--- src/taoensso/faraday.clj
+++ src/taoensso/faraday.clj
@@ -95,14 +95,15 @@
         :as client-opts}]
      (if (empty? client-opts) (AmazonDynamoDBClient.) ; Default client
        (let [creds (or creds (:credentials client-opts)) ; Deprecated opt
-             _ (assert (or (nil? creds) (instance? AWSCredentials creds)))
+             _ (assert (or (nil? creds)    (instance? AWSCredentials         creds)))
              _ (assert (or (nil? provider) (instance? AWSCredentialsProvider provider)))
+             ^AWSCredentialsProvider provider provider
              ^AWSCredentials aws-creds
              (when-not provider
                (cond
-                creds      creds ; Given explicit AWSCredentials
-                access-key (BasicAWSCredentials. access-key secret-key)
-                :else      (DefaultAWSCredentialsProviderChain.)))
+                 creds      creds ; Given explicit AWSCredentials
+                 access-key (BasicAWSCredentials. access-key secret-key)
+                 :else      (DefaultAWSCredentialsProviderChain.)))
              client-config
              (doto-cond [g (ClientConfiguration.)]
                proxy-host      (.setProxyHost         g)
@@ -111,7 +112,9 @@
                max-conns       (.setMaxConnections    g)
                max-error-retry (.setMaxErrorRetry     g)
                socket-timeout  (.setSocketTimeout     g))]
-         (doto-cond [g (AmazonDynamoDBClient. (or provider aws-creds) client-config)]
+         (doto-cond [g (if provider
+                         (AmazonDynamoDBClient. provider  client-config)
+                         (AmazonDynamoDBClient. aws-creds client-config))]
            endpoint (.setEndpoint g)))))))

 (defn- db-client ^AmazonDynamoDBClient [client-opts] (db-client* client-opts))


Change db-client type hint to AmazonDynamoDB.

AmazonDynamoDBClient is too specific of a type and causes problems with
mocking, etc.

--- src/taoensso/faraday.clj
+++ src/taoensso/faraday.clj
@@ -76,6 +76,7 @@
             com.amazonaws.auth.BasicAWSCredentials
             com.amazonaws.auth.DefaultAWSCredentialsProviderChain
             com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient
+            com.amazonaws.services.dynamodbv2.AmazonDynamoDB
             java.nio.ByteBuffer))

 ;; TODO Add support for splitting data > 64KB over > 1 keys? This may be tough
@@ -118,7 +119,7 @@
                          (AmazonDynamoDBClient. aws-creds client-config))]
            endpoint (.setEndpoint g)))))))

-(defn- db-client ^AmazonDynamoDBClient [client-opts] (db-client* client-opts))
+(defn- db-client ^AmazonDynamoDB [client-opts] (db-client* client-opts))

 ;;;; Exceptions


remove unused `defui` static field

remove unused `defui` static field

--- src/main/om_css/core.clj
+++ src/main/om_css/core.clj
@@ -141,8 +141,7 @@
                   (garden/css component-style))
         this-arg {:ns-name ns-name
                   :component-name (str name)}
-        forms (reshape-defui forms this-arg)
-        forms (concat forms (list 'static 'field 'ns ns-name))]
+        forms (reshape-defui forms this-arg)]
     (when css-str
       (swap! css assoc [ns-name name] css-str))
     `(om.next/defui ~name ~@forms)))


Walk is tail-recursive

Walk is tail-recursive

--- src/micro_logic/core.clj
+++ src/micro_logic/core.clj
@@ -49,7 +49,7 @@
   ;; substitution map.  In this case, the variable itself is returned,
   ;; indicating that the variable is currently unbound.
   (walk [u s] (if-let [val (get s u)]
-                (walk val s)
+                (recur val s)
                 u))
   Object
   (walk [u s] u)


Address kibit suggestions.

Address kibit suggestions.

--- src/mvxcvi/directive.clj
+++ src/mvxcvi/directive.clj
@@ -69,7 +69,7 @@
     (when-not (every? list? more)
       (throw (IllegalArgumentException.
                (str "Non-list elements in '" cmd-name "' command definition: "
-                    (filter (complement list?) more)))))
+                    (remove list? more)))))
     (when (> (count init-elements) 1)
       (throw (IllegalArgumentException.
                (str "Multiple `init` elements in '" cmd-name
@@ -141,7 +141,7 @@
         (action opts args)

         :else
-        (do (when-not (empty? args)
+        (do (when (seq args)
               (println "Unrecognized arguments:" (string/join " " args) "\n"))
             (println usage)
             false)))


more card implementation

more card implementation

--- src/node/game/cards.cljs
+++ src/node/game/cards.cljs
@@ -600,18 +600,6 @@
                    (some #{:rd} (:successful-run runner-reg))
                    (some #{:archives} (:successful-run runner-reg))))
     :effect (effect (gain :agenda-point 1) (move (first (:play-area runner)) :scored))}
-
-   "Project Atlas"
-   {:effect (effect (set-prop card :counter (- (:advance-counter card) 3)))
-    :abilities [{:counter-cost 1 :prompt "Choose a card" :msg (msg "add " (:title target) " to HQ from R&D")
-                 :choices (req (:deck corp)) :effect (effect (move target :hand) (shuffle! :deck))}]}
-
-   "Project Vitruvius"
-   {:effect (effect (set-prop card :counter (- (:advance-counter card) 3)))
-    :abilities [{:counter-cost 1 :prompt "Choose a card"
-                 :msg (msg "add " (if (:seen target)
-                                    (:title target) "an unseen card ") " to HQ from Archives")
-                 :choices (req (:discard corp)) :effect (effect (move target :hand))}]}

    "Oracle May"
    {:abilities [{:cost [:click 1] :once :per-turn :prompt "Choose card type"
@@ -690,6 +678,18 @@
    {:abilities [{:req (req tagged) :cost [:click 1] :effect (effect (damage :meat 1))
                  :msg "do 1 meat damage"}]}

+   "Project Atlas"
+   {:effect (effect (set-prop card :counter (- (:advance-counter card) 3)))
+    :abilities [{:counter-cost 1 :prompt "Choose a card" :msg (msg "add " (:title target) " to HQ from R&D")
+                 :choices (req (:deck corp)) :effect (effect (move target :hand) (shuffle! :deck))}]}
+
+   "Project Vitruvius"
+   {:effect (effect (set-prop card :counter (- (:advance-counter card) 3)))
+    :abilities [{:counter-cost 1 :prompt "Choose a card"
+                 :msg (msg "add " (if (:seen target)
+                                    (:title target) "an unseen card ") " to HQ from Archives")
+                 :choices (req (:discard corp)) :effect (effect (move target :hand))}]}
+
    "Public Sympathy"
    {:effect (effect (gain :max-hand-size 2)) :leave-play (effect (lose :max-hand-size 2))}

@@ -1032,6 +1032,10 @@
    {:abilities [{:msg "break any number of AP subroutine" :effect (effect (trash card))}
                 {:msg "Prevent any number of net damage" :effect (effect (trash card))}]}

+   "Eater"
+   {:abilities [{:cost [:credit 1] :msg "Break ICE subroutine"}
+                {:cost [:credit 1] :msg "add 1 strength" :effect (effect (pump card 1))}]}
+
    "Faerie"
    {:abilities [{:msg "break any number of sentry subroutine" :effect (effect (trash card))}
                 {:cost [:credit 1] :msg "add 1 strength" :effect (effect (pump card 1))}]}
@@ -1101,6 +1105,14 @@
    "Refractor"
    {:abilities [{:cost [:credit 1] :msg "break 1 code gate subroutine"}
                 {:cost [:credit 1] :msg "add 3 strength" :effect (effect (pump card 3))}]}
+
+   "Sage"
+   {:abilities [{:cost [:credit 2] :msg "break 1 code gate or barrier subroutine"}]
+    :effect #(add-watch % (keyword (str "sage" (:cid %3)))
+                        (fn [k ref old new]
+                          (when (not= (get-in old [:runner :memory]) (get-in new [:runner :memory]))
+                            (set-prop ref %2 %3 :counter 0))))
+    :leave-play #(remove-watch % (keyword (str "sage" (:cid %3))))}

    "Snowball"
    {:abilities [{:cost [:credit 1] :msg "break 1 barrier subroutine"}
@@ -1188,6 +1200,10 @@
                  :effect (effect (lose :runner :click 1))}
                 {:msg "end the run" :effect (effect (end-run))}]}

+   "Errand Boy"
+   {:abilities [{:msg "gain 1 [Credits]" :effect (effect (gain :credit 1))}
+                {:msg "draw 1 card" :effect (effect (draw))}]}
+
    "Fenris"
    {:effect (effect (gain :bad-publicity 1) (system-msg "takes 1 bad publicity"))
     :abilities [{:msg "do 1 brain damage" :effect (effect (damage :brain 1))}
@@ -1278,6 +1294,11 @@
                  :counter-cost 1 :effect (effect (damage :net 1))}
                 {:msg "add 1 power counter" :effect (effect (add-prop card :counter 1))}]}

+   "Markus 1.0"
+   {:abilities [{:prompt "Choose a program to trash" :msg "Trash a program" :label "Trash a program"
+                 :choices (req (get-in runner [:rig :program])) :effect (effect (trash target))}
+                {:msg "end the run" :effect (effect (end-run))}]}
+
    "Mother Goddess"
    {:abilities [{:msg "end the run" :effect (effect (end-run))}]}

@@ -1294,8 +1315,8 @@
    {:abilities [{:msg "end the run" :effect (effect (end-run))}]}

    "Pop-up Window"
-   {:msg "gain 1 [Credits]" :effect (effect (gain :corp :credit 1))
-    :abilities [{:msg "end the run" :effect (effect (end-run))}]}
+   {:abilities [{:msg "gain 1 [Credits]" :effect (effect (gain :credit 1))}
+                {:msg "end the run" :effect (effect (end-run))}]}

    "Pup"
    {:abilities [{:msg "do 1 net damage" :effect (effect (damage :net 1))}]}


Function rename.

Function rename.

--- src/oc/email/content.clj
+++ src/oc/email/content.clj
@@ -216,7 +216,7 @@
               (repeat (spacer 25 "header"))))]]
       (spacer 60 "header")]))

-(defn- message [snapshot]
+(defn- note [snapshot]
   [:table {:class "note"}
     [:tr
       [:td
@@ -250,7 +250,7 @@
     [:table {:class "body"}
       [:tr
         [:td {:class "float-center", :align "center", :valign "top"}
-          (when-not (s/blank? (:note snapshot)) (message snapshot))
+          (when-not (s/blank? (:note snapshot)) (note snapshot))
           [:center
             [:table {:class "container"}
               [:tr


Use AP with user-settings parameter as notification settings url, remove old /profile that is not present anymore.

--- src/oc/email/content.clj
+++ src/oc/email/content.clj
@@ -25,7 +25,8 @@
 (def reminder-date-format (time-format/formatter "EEEE, MMMM d"))
 (def reminder-date-format-year (time-format/formatter "EEEE, MMMM d YYYY"))

-(def profile-url (str config/web-url "/profile/notifications"))
+(defn- profile-url [org-slug]
+  (str (s/join "/" [config/web-url org-slug "all-posts"]) "?user-settings=notifications"))

 (def doc-type "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">")

@@ -245,14 +246,14 @@

 (declare reminder-notification-settings-footer)

-(defn- email-footer [type]
+(defn- email-footer [data type]
   [:table {:class "row footer-table"
            :valign "middle"
            :align "center"}
     [:tr
       [:td {:class "small-12 large-12 columns" :valign "middle" :align "center"}
         (when (= type :reminder-notification)
-          reminder-notification-settings-footer)
+          (reminder-notification-settings-footer data))
         (vspacer 24 "footer-table" "footer-table")
         [:table {:class "row footer-table"}
           [:tr
@@ -557,7 +558,7 @@
 (defn reminder-alert-headline [data]
   (str "Hi " (first-name (:assignee (:reminder (:notification data)))) ", it's time to update your team"))

-(defn reminder-alert-settings-footer [frequency]
+(defn reminder-alert-settings-footer [org-slug frequency]
   [:table {:class "row reminders-footer"
          :valign "middle"
          :align "center"}
@@ -577,7 +578,7 @@
                 ;:else
                 "weekly")
               " reminder. You can adjust or turn off reminders in ")
-              [:a {:href profile-url}
+              [:a {:href (profile-url org-slug)}
                 "Carrot"]
               "."]]]]
       (vspacer 16 "" "settings-footer")]]])
@@ -616,7 +617,7 @@
                 {:href create-post-url}
                 "Ok, let's do it"]]]]
         (spacer 80)
-        (reminder-alert-settings-footer (:frequency reminder-data))]]))
+        (reminder-alert-settings-footer org-slug (:frequency reminder-data))]]))

 ;; Reminder notification

@@ -640,21 +641,22 @@
 (defn reminder-notification-subline [reminder-data]
   (str (frequency-string (:frequency reminder-data)) " starting " (reminder-due-date (:next-send reminder-data))))

-(def reminder-notification-settings-footer
-  [:table {:class "row reminders-footer"
-         :valign "middle"
-         :align "center"}
-  [:tr
-    [:td {:class "small-12 large-12 columns" :valign "middle" :align "center"}
-      (vspacer 32 "" "reminders-footer")
-      [:table {:class "row reminders-footer center-align"}
-        [:tr
-          [:th {:class "small-12 large-12"}
-            [:p {:class "reminders-footer reminders-footer-paragraph"}
-              "You can always adjust or turn off reminders in "
-              [:a {:href profile-url}
-                "Carrot"]]]]]
-      (vspacer 32 "footer-table reminders-bottom-footer" "reminders-footer")]]])
+(defn reminder-notification-settings-footer [data]
+  (let [org (:org data)]
+    [:table {:class "row reminders-footer"
+           :valign "middle"
+           :align "center"}
+    [:tr
+      [:td {:class "small-12 large-12 columns" :valign "middle" :align "center"}
+        (vspacer 32 "" "reminders-footer")
+        [:table {:class "row reminders-footer center-align"}
+          [:tr
+            [:th {:class "small-12 large-12"}
+              [:p {:class "reminders-footer reminders-footer-paragraph"}
+                "You can always adjust or turn off reminders in "
+                [:a {:href (profile-url (:slug org))}
+                  "Carrot"]]]]]
+        (vspacer 32 "footer-table reminders-bottom-footer" "reminders-footer")]]]))

 (defn- reminder-notification-content [reminder]
   (let [org (:org reminder)
@@ -986,7 +988,7 @@
                     :notify (notify-content data)
                     :reminder-notification (reminder-notification-content data)
                     :reminder-alert (reminder-alert-content data))]]
-              (email-footer type)]]]]]))
+              (email-footer data type)]]]]]))

 (defn- head [data]
   [:html {:xmlns "http://www.w3.org/1999/xhtml"}


Remove yeller support now that test-helper is user facing

--- src/onyx/test_helper.clj
+++ src/onyx/test_helper.clj
@@ -1,7 +1,6 @@
 (ns onyx.test-helper
   (:require [clojure.core.async :refer [chan >!! alts!! timeout <!! close! sliding-buffer]]
             [com.stuartsierra.component :as component]
-            [yeller.timbre-appender]
             [taoensso.timbre :refer  [info warn trace fatal error] :as timbre]
             [onyx.extensions :as extensions]
             [onyx.api]))
@@ -26,14 +25,8 @@
   ([]
      (load-config "test-config.edn"))
   ([filename]
-     (let [yeller-token (System/getenv "YELLER_TOKEN")
-           impl (System/getenv "TEST_TRANSPORT_IMPL")]
+     (let [impl (System/getenv "TEST_TRANSPORT_IMPL")]
        (cond-> (read-string (slurp (clojure.java.io/resource filename)))
-               (not-empty yeller-token)
-               (assoc-in [:peer-config :onyx.log/config :appenders :yeller]
-                         (yeller.timbre-appender/make-yeller-appender
-                          {:token yeller-token
-                           :environment "citests"}))
                (= impl "aeron")
                (assoc-in [:peer-config :onyx.messaging/impl] :aeron)))))


add issue list handler

add issue list handler

--- src/panpan/eina.clj
+++ src/panpan/eina.clj
@@ -1,11 +1,12 @@
 (ns panpan.eina
   (:require
-    [clojure.string     :as str]
-    [panpan.github.feed :as feed]
-    [jubot.adapter      :as ja]
-    [jubot.scheduler    :as js]
-    [jubot.handler      :as jh]
-    [jubot.brain        :as jb]))
+    [clojure.string       :as str]
+    [panpan.github.feed   :as feed]
+    [panpan.github.search :as search]
+    [jubot.adapter        :as ja]
+    [jubot.scheduler      :as js]
+    [jubot.handler        :as jh]
+    [jubot.brain          :as jb]))

 (def ^:const SCHEDULE "0 /1 * * * * *")
 (def ^:const NAME "エイナ")
@@ -39,7 +40,12 @@
    :close-issue
    ["ありがとう。助かったわ"
     "ミッション、本当にお疲れ様"
-    ]})
+    ]
+   :reply
+   ["はーい"
+    "ちょっと待ってね"
+    ]
+   })

 (def github-schedule
   (js/schedules
@@ -51,12 +57,21 @@
               out)))

 (defn eina-handler
-  "エイナ(さん)?.+github.+テスト - github rss 取得のテスト"
+  "エイナ(さん)?.*クエスト.*(教えて|おしえて) - github のクエスト一覧
+   エイナ(さん)?.*github.*テスト              - github rss 取得のテスト
+  "
   [{:keys [user] :as arg}]
   (jh/regexp arg
-    #"エイナ(さん)?.+github.*テスト"
+    #"エイナ(さん)?.*クエスト.*(教えて|おしえて)"
     (fn [& _]
-      (out "@" user " はーい")
+      (->> MESSAGES :reply rand-nth (out "@" user " "))
+      (->> (search/get-assigned-issues "liquidz" :state "open")
+           (map #(str " * <" (:url %) "|" (:title %) ">"))
+           (str/join "\n")
+           out))
+    #"エイナ(さん)?.*github.*テスト"
+    (fn [& _]
+      (->> MESSAGES :reply rand-nth (out "@" user " "))
       (jb/set feed/FEED_URL nil)
       (->> (feed/get-github-feeds)
            (map feed/github-respond)
@@ -66,3 +81,4 @@

       (jb/set feed/FEED_URL nil)
       ((first github-schedule)))))
+


Don't fetch profile and projects if authentication is failed.

--- src/uxbox/data/auth.cljs
+++ src/uxbox/data/auth.cljs
@@ -51,19 +51,15 @@

   rs/WatchEvent
   (-apply-watch [this state s]
-    (letfn [(on-error [{:keys [status payload]}]
-              (println status payload)
-              (uum/error (tr "errors.auth.unauthorized"))
-              (rx/empty))]
-      (let [params {:username username
-                    :password password
-                    :scope "webapp"}]
-        (->> (rp/req :fetch/token params)
-             (rx/catch rp/client-error? on-error)
-             (rx/map :payload)
-             (rx/mapcat #(rx/of (logged-in %)
-                                (dp/fetch-projects)
-                                (udu/fetch-profile))))))))
+    (let [params {:username username
+                  :password password
+                  :scope "webapp"}]
+      (->> (rp/req :fetch/token params)
+           (rx/map :payload)
+           (rx/mapcat #(rx/of (logged-in %)
+                              (udp/fetch-projects)
+                              (udu/fetch-profile)))
+           (rx/catch rp/client-error? #(udm/error (tr "errors.auth.unauthorized")))))))

 (defn login
   [params]


test cli-opts

test cli-opts

--- test/app/test/cli.clj
+++ test/app/test/cli.clj
@@ -1,4 +1,5 @@
 (ns app.test.cli
+  (:require [clojure.tools.cli :refer [parse-opts]])
   (:use [app.cli])
   (:use [app.core])
   (:use [app.model.protocols])
@@ -10,6 +11,77 @@
 (def javaparserCus (cus "test-resources/sample-codebases/javaparser/"))

 (deftest issue43
+  "mcp query fails when no threshold is specified"
   (let [op (:mcp operations)]
     (with-redefs [println (fn [_] 1)]
-      (printOperation op javaparserCus 0))))+      (printOperation op javaparserCus 0))))
+
+(deftest cli-opts-help
+  (let [args ["--help"]
+        res (parse-opts args cliOpts)]
+    (is (= [] (:arguments res)))
+    (is (= false (:linter (:options res))))
+    (is (= false (:interactive (:options res))))
+    (is (= true (:help (:options res))))
+    (is (= nil (:errors res)))))
+
+(deftest cli-opts-interactive-short
+  (let [args ["-i"]
+        res (parse-opts args cliOpts)]
+    (is (= [] (:arguments res)))
+    (is (= false (:linter (:options res))))
+    (is (= true (:interactive (:options res))))
+    (is (= false (:help (:options res))))
+    (is (= nil (:errors res)))))
+
+(deftest cli-opts-interactive-long
+  (let [args ["--interactive"]
+        res (parse-opts args cliOpts)]
+    (is (= [] (:arguments res)))
+    (is (= false (:linter (:options res))))
+    (is (= true (:interactive (:options res))))
+    (is (= false (:help (:options res))))
+    (is (= nil (:errors res)))))
+
+(deftest cli-opts-linter-short
+  (let [args ["-l"]
+        res (parse-opts args cliOpts)]
+    (is (= [] (:arguments res)))
+    (is (= true (:linter (:options res))))
+    (is (= false (:interactive (:options res))))
+    (is (= false (:help (:options res))))
+    (is (= nil (:errors res)))))
+
+(deftest cli-opts-linter-long
+  (let [args ["--linter"]
+        res (parse-opts args cliOpts)]
+    (is (= [] (:arguments res)))
+    (is (= true (:linter (:options res))))
+    (is (= false (:interactive (:options res))))
+    (is (= false (:help (:options res))))
+    (is (= nil (:errors res)))))
+
+(deftest cli-opts-unknown
+  (let [args ["--foo"]
+        res (parse-opts args cliOpts)]
+    (is (:errors res))))
+
+(deftest cli-opts-dir-short
+  (let [args ["-d" "FOO"]
+        res (parse-opts args cliOpts)]
+    (is (= [] (:arguments res)))
+    (is (= false (:linter (:options res))))
+    (is (= false (:interactive (:options res))))
+    (is (= false (:help (:options res))))
+    (is (= "FOO" (:dir (:options res))))
+    (is (= nil (:errors res)))))
+
+(deftest cli-opts-dir-long
+  (let [args ["--dir" "FOO"]
+        res (parse-opts args cliOpts)]
+    (is (= [] (:arguments res)))
+    (is (= false (:linter (:options res))))
+    (is (= false (:interactive (:options res))))
+    (is (= false (:help (:options res))))
+    (is (= "FOO" (:dir (:options res))))
+    (is (= nil (:errors res)))))


mark them interesting if they've recently had a new layer

--- src/pc/admin/db.clj
+++ src/pc/admin/db.clj
@@ -15,6 +15,7 @@
         latest-tx (.tx (last index-range))
         doc-ids (map first (d/q '{:find [?d] :in [$ ?earliest-tx ?latest-tx]
                                   :where [[?t :document/id ?d ?tx]
+                                          [?t :layer/name]
                                           [(< ?earliest-tx ?tx)]
                                           [(> ?latest-tx ?tx)]]}
                                 db (dec earliest-tx) (inc latest-tx)))]


mapped data update

mapped data update

--- src/prais2/map_data.cljs
+++ src/prais2/map_data.cljs
@@ -9,10 +9,11 @@
   [:.container
    [:.row
     [:section
-     [:h1 "Mapped Data"]
+     [:h1 "Mapped Data for 2011-2014"]
      [:p
       "There are fourteen hospitals in the UK and Ireland that perform heart surgery in children (here a child means someone under the age of 16)."]
-     [:p
+     [:p "This data is updated annually and covers the last three years. The survival data in this map is from 2011-14"]
+     #_[:p
       "We have marked these hospitals on the map. Click on a hospital's marker or menu item and a summary report will appear alongside or underneath. Mouse over or click on the bars and dot within the summary data chart for further explanation."]
      [:p "To see all hospitals together "
       [:button.btn.btn-link {:style {:padding 0}


Remove :target-obj since we can use (. applet frame) instead.

--- src/quil/applet.clj
+++ src/quil/applet.clj
@@ -22,7 +22,7 @@
   It means we can dispose frame, call on-close function and perform other
   clean ups."
   [applet]
-  (-> applet meta :target-obj deref .dispose)
+  (.dispose (. applet frame))
   ((:on-close (meta applet))))

 (defn applet-state
@@ -57,7 +57,6 @@
      (fn []
        (.setResizable frame true)
        (.setAlwaysOnTop frame keep-on-top?)))
-    (reset! (:target-obj (meta applet)) frame)
     applet))

@@ -332,13 +331,11 @@
         on-close-fn       (or (:on-close options) no-fn)

         state             (atom nil)
-        target-obj        (atom nil)
         looping?          (atom true)
         listeners         (into {} (for [name listeners]
                                      [name (or (options name) no-fn)]))
         applet-state      (merge options
                                  {:state state
-                                  :target-obj target-obj
                                   :target target
                                   :looping? looping?
                                   :on-close on-close-fn


Fix #110.

Fix #110.

--- src/quil/applet.clj
+++ src/quil/applet.clj
@@ -170,7 +170,8 @@
                     sketchFullScreen sketchFullScreenParent
                     exit exitParent})

-(defn -exit [this] (.dispose this))
+(defn -exit [this]
+  (applet-close this))

 (defn -sketchFullScreen [this] (:present (meta this)))


adding the gen-class to the namespace to be able to launch the app from a jar.

--- src/clj/baconator/server/handler.clj
+++ src/clj/baconator/server/handler.clj
@@ -1,4 +1,5 @@
 (ns baconator.server.handler
+  (:gen-class)
   (:use compojure.core
         ring.util.response
         org.httpkit.server
@@ -30,7 +31,6 @@
       (let [tweet (parse-string (str payload) true)
             lower (.toLowerCase (:text tweet))]
         (when (:coordinates tweet)
-          (println (:text tweet))
           (let [coordinates (:coordinates (:coordinates tweet))
                 user (:screen_name (:user tweet))]
             (send-checkin {:user user
@@ -42,9 +42,10 @@
    (fn [_resp excp]
       (.printStackTrace excp))))

-(api/statuses-filter :params {:track "bacon"}
+(defn track-word [word]
+  (api/statuses-filter :params {:track word}
                      :oauth-creds twitter-creds
-                     :callbacks *callback*)
+                     :callbacks *callback*))

 ;; Handle the checkins websocket

@@ -75,6 +76,5 @@

 (defn -main [& args]
   (let [port (Integer/parseInt (or (System/getenv "PORT") "8080"))]
-        (run-server application {:port port :join? false})))
-
-
+    (track-word "bacon")
+    (run-server application {:port port :join? false})))


Create special type for github repo name.

--- src/clj/hatnik/web/server/schema.clj
+++ src/clj/hatnik/web/server/schema.clj
@@ -40,6 +40,11 @@
           (s/pred #(re-matches #"(?i)^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$" %)
                   'email-format?)))

+(def GithubRepository
+  (s/both (s/pred #(re-matches #"(?i)^[A-Z0-9-_]+/[A-Z0-9-_]+$" %)
+                  'valid-github-repo?)
+          (string-of-length 1 128)))
+
 (def Project
   "Schema for project. Project has only 1 field - name in API."
   {:name (string-of-length 1 128)})
@@ -62,8 +67,7 @@
    :type (s/eq "github-issue")
    :title TemplateTitle
    :body TemplateBody
-   :repo (s/pred #(re-matches #"(?i)^[A-Z0-9-_]+/[A-Z0-9-_]+$" %)
-                  'valid-github-repo?)})
+   :repo GithubRepository})

 (def Action
   "Schema for action. Essentially it is the union of all actions."


Make little refactoring on podnapisi source

--- src/clj/subman/sources/podnapisi.clj
+++ src/clj/subman/sources/podnapisi.clj
@@ -1,5 +1,6 @@
 (ns subman.sources.podnapisi
-  (:require [net.cgrand.enlive-html :as html]
+  (:require [swiss.arrows :refer [-<>]]
+            [net.cgrand.enlive-html :as html]
             [subman.helpers :as helpers]
             [subman.const :as const]))

@@ -67,8 +68,7 @@

 (defn get-release-page-result
   "Get release page result"
-  [page] (map #(assoc % :source const/type-podnapisi)
-              (-> (get-release-page-url page)
-                  parse-list-page
-                  flatten)))
-
+  [page] (-<> (get-release-page-url page)
+              parse-list-page
+              flatten
+              (map #(assoc % :source const/type-podnapisi) <>)))


[TEMP COMMIT] Debugged. Woo!

[TEMP COMMIT] Debugged. Woo!

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

--- src/cljs/cljs_nusmods/timetable.cljs
+++ src/cljs/cljs_nusmods/timetable.cljs
@@ -1002,7 +1002,7 @@
             (set! ModulesSelected
                   (update-in
                     ModulesSelected
-                    [moduleCode lessonType lessonGroup :info]
+                    [moduleCode lessonType :info]
                     (fn [modSelLessonInfoSeq]
                       (conj
                         (filter (fn [modSelLessonInfo]
@@ -1058,6 +1058,7 @@
         ; Update `ModulesSelected`
         (update-ModulesSelected-for-affected-days affectedDaysSet)
         (.log js/console "Boo ya!")
+        (.log js/console (str "ModulesSelected:" (.stringify js/JSON (clj->js ModulesSelected))))

         ; Remove from `ModulesSelectedOrder`
         (set! ModulesSelectedOrder (remove #{moduleCode} ModulesSelectedOrder))


`add-module-lesson-group!` - correct indentation

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

--- src/cljs/cljs_nusmods/timetable.cljs
+++ src/cljs/cljs_nusmods/timetable.cljs
@@ -758,12 +758,10 @@

             augLessonInfoSeq
             (doall (map (fn [modulesMapLesson]
-                          (add-module-lesson! moduleCode moduleName
-                                                         lessonType
-                                                         lessonLabel
-                                                         modulesMapLesson
-                                                         bgColorCssClass
-                                                         isActuallySelected?))
+                          (add-module-lesson! moduleCode moduleName lessonType
+                                              lessonLabel modulesMapLesson
+                                              bgColorCssClass
+                                              isActuallySelected?))
                         modulesMapLessonSeq))

             lessonInfoSeq       (map #(dissoc %1 :divElem :moduleCode


Standardize the path to the upload file

Standardize the path to the upload file

--- src/cljs/mdr2/productions/vubis.cljs
+++ src/cljs/mdr2/productions/vubis.cljs
@@ -108,11 +108,11 @@

 (rf/reg-sub
  ::vubis-file
- (fn [db _] (-> db :vubis-file)))
+ (fn [db _] (get-in db [:upload :vubis])))

 (rf/reg-event-db
   ::set-vubis-file
-  (fn [db [_ file]] (assoc db :vubis-file file)))
+  (fn [db [_ file]] (assoc-in db [:upload :vubis] file)))

 (defn- file-input []
   (let [get-value (fn [e] (-> e .-target .-files (aget 0)))


Grid-like puzzle browser

Grid-like puzzle browser

--- src/cljs/nonojure/puzzlebrowser.cljs
+++ src/cljs/nonojure/puzzlebrowser.cljs
@@ -5,6 +5,8 @@
    [jayq.core :refer [ajax]])
   (:use-macros
    [dommy.macros :only [node sel sel1 deftemplate]]))
+
+(def num-cols 5)

 (defn ^:export showalert []
   (let [min-size (.-value (sel1 :#minSize))
@@ -24,17 +26,16 @@
      [:p (str width "x" height " - " rating)]
      #_(create-template width height)]))

-#_(defn create-thumbnails [nonos]
-  (doseq [nono nonos]
-    (dommy/append! (sel1 :body) (nono-thumbnail (js->clj nono)))))
-
 (defn create-thumbnails [nonos]
-  (dommy/append! (sel1 :body)
-                 [:ul
-                  (for [nono nonos]
-                    [:li (nono-thumbnail (js->clj nono))])]))
+  (let [cells (for [nono nonos]
+                [:td (nono-thumbnail (js->clj nono))])
+        padded-cells (concat cells (repeat (dec num-cols) [:td ""]))
+        rows (partition num-cols padded-cells)
+        contents (for [row rows] [:tr row])
+        table [:table#table.puzzle-browser{:id "puzzle-browser" :border 1} contents]]
+    (dommy/append! (sel1 :body) table)))

 (defn ^:export init []
-  (let [url "/api/nonograms?filter=size&value=1-10&sort=rating&order=asc"]
+  (let [url "/api/nonograms?filter=size&value=1-100&sort=rating&order=asc"]
     (ajax url {:success create-thumbnails
                :error #(js/alert "Error")})))


remove duplicated variable

remove duplicated variable

--- src/cljs/searchbot/input/labels.cljs
+++ src/cljs/searchbot/input/labels.cljs
@@ -17,8 +17,8 @@
 (defn- toggle-edit! [owner target] (om/set-state! owner :editing-labels? (not (checked? owner target))))

 (defn- update-labels! [owner input-value]
-  (let [new-labels (labelize input-value)]
-    (om/set-state! owner :labels new-labels)
+  (let [new-labelized (labelize input-value)]
+    (om/set-state! owner :labelized new-labelized)
     (om/set-state! owner :labels-string input-value)))

 (defn- style-trans
@@ -59,10 +59,10 @@

 (defcomponent labels [app owner {:keys [labels on-label-updated!]}]
   (init-state [_]
-              {:labels labels
+              {:labelized labels
                :labels-string (clojure.string/join " " (map :name labels))
                :editing-labels? false})
-  (render-state [_ {:keys [labels labels-string editing-labels?]}]
+  (render-state [_ {:keys [labelized labels-string editing-labels?]}]
                 (html
                  [:.card
                   [:.card-content {:ref "card"}
@@ -80,7 +80,7 @@
                                              ))}]
                      [:span.lever]
                      [(if editing-labels? :strong :span) "Edit"]]]
-                   (for [l labels]
+                   (for [l labelized]
                      [:a.teal.btn {:style {:cursor "default" :text-transform "none" :margin-right "5px" :margin-top "5px"}}
                       [:i.fa.fa-tag.left] (:name l)])
                    (make-labels-input {:owner owner :labels-string labels-string


Formatting.

Formatting.

--- src/cljs/town_client/components.cljs
+++ src/cljs/town_client/components.cljs
@@ -173,19 +173,6 @@
    [:.header-responders-count :.responders-count] (content (:respondent-count neighborhood))
    })

-(def foo (atom
-          {:agree_add_density 0
-           :agree_add_my_area_density_for_less_cars 0
-           :agree_bulevardisation 0
-           :agree_high_rise 0
-           :agree_suburbs_build_near_stations 0
-           :enjoy_culture_urban_meetings 0
-           :enjoy_metropolis_fascinating_possibilities 0
-           :enjoy_outdoors_large_woods 0
-           :my_area_could_be_built_more 0
-           :prefer_daily_shopping_near 0
-           :would_use_rail_transport_more 0
-           }))

 (deftemplate neighborhood-page "public/kaupunginosa.html" []
   {[:head]
@@ -226,7 +213,22 @@
                             (.getElementById js/document "content-wrap")))

+; ----- REPL testing -----
+
 #_(
+   (def foo (atom
+             {:agree_add_density 0
+              :agree_add_my_area_density_for_less_cars 0
+              :agree_bulevardisation 0
+              :agree_high_rise 0
+              :agree_suburbs_build_near_stations 0
+              :enjoy_culture_urban_meetings 0
+              :enjoy_metropolis_fascinating_possibilities 0
+              :enjoy_outdoors_large_woods 0
+              :my_area_could_be_built_more 0
+              :prefer_daily_shopping_near 0
+              :would_use_rail_transport_more 0
+              }))
    (reset! state/neighborhoods {1 {:name "foo" :id 1 :prev nil :next nil}})
    (reset! (:future-accommodation app-state) {:verylikely 0
          :quitelikely 0


Removed *read-eval* shenanigans since that seems to break uberjars.

--- src/clojure/bookmark_writer/core.clj
+++ src/clojure/bookmark_writer/core.clj
@@ -46,7 +46,4 @@
 (defn -main
   "Simple and dumb test case."
   [& args]
-  ;; work around dangerous default behaviour in Clojure
-  (alter-var-root #'*read-eval* (constantly false))
-
   (populate-bookmarks! (clojure.java.io/file test-filename) test-output-filename bookmark-map))


removing useless fn

removing useless fn

--- src/com/ig/swagger/search/parser.clj
+++ src/com/ig/swagger/search/parser.clj
@@ -49,19 +49,17 @@
       :field-names
       (fields schema))))

-(defn types-fields [param]
+(defn find-types [param]
   (let [schema (:schema param param)
+        param-type (:type schema)
         type (if (and (:$ref schema)
-                      (= "object" (:type schema)))
+                      (= "object" param-type))
                (stringify (last (ref->keyword-path (:$ref schema)))))]
     (cons type
           (cond
-            (= "object" (:type schema)) (vec (mapcat types-fields (vals (:properties schema))))
-            (= "array" (:type schema)) (types-fields (:items schema))
+            (= "object" param-type) (vec (mapcat find-types (vals (:properties schema))))
+            (= "array" param-type) (find-types (:items schema))
             :default nil))))
-
-(defn- find-types [param]
-  (types-fields param))

 (defn get-controller-data
   [global-params path [method operation]]