Permalink
Browse files

Generalize with-user into if-user, to make it more flexible.

Fixes #149.
  • Loading branch information...
1 parent a569d75 commit bc124ae6c5553395668846ddbdd9fde0fbcd1477 @amalloy amalloy committed Oct 16, 2011
Showing with 48 additions and 40 deletions.
  1. +1 −1 src/foreclojure/login.clj
  2. +13 −17 src/foreclojure/problems.clj
  3. +13 −18 src/foreclojure/users.clj
  4. +21 −4 src/foreclojure/utils.clj
View
2 src/foreclojure/login.clj
@@ -3,7 +3,7 @@
[ring.util.response :as response])
(:import [org.jasypt.util.password StrongPasswordEncryptor])
(:use [hiccup.form-helpers :only [form-to label text-field password-field check-box]]
- [foreclojure.utils :only [from-mongo flash-error flash-msg with-user form-row assuming send-email login-url]]
+ [foreclojure.utils :only [from-mongo flash-error flash-msg form-row assuming send-email login-url]]
[foreclojure.template :only [def-page content-page]]
[compojure.core :only [defroutes GET POST]]
[useful.map :only [keyed]]
View
30 src/foreclojure/problems.clj
@@ -5,7 +5,7 @@
[ring.util.response :as response]
[cheshire.core :as json])
(:import [org.apache.commons.mail EmailException])
- (:use [foreclojure.utils :only [from-mongo get-user get-solved login-link flash-msg flash-error row-class approver? can-submit? send-email image-builder with-user as-int maybe-update escape-html]]
+ (:use [foreclojure.utils :only [from-mongo get-user get-solved login-link flash-msg flash-error row-class approver? can-submit? send-email image-builder if-user with-user as-int maybe-update escape-html]]
[foreclojure.ring-utils :only [*url*]]
[foreclojure.template :only [def-page content-page]]
[foreclojure.social :only [tweet-link gist!]]
@@ -256,15 +256,13 @@ Return a map, {:message, :error, :url, :num-tests-passed}."
:golfChart (html (render-golf-chart))})))
(defn wants-no-javascript-codebox? []
- (when (session/session-get :user)
- (with-user [{:keys [user] :as user-obj}]
- (disable-codebox? user-obj))))
+ (if-user [{:keys [user] :as user-obj}]
+ (disable-codebox? user-obj)))
(def-page code-box [id]
(let [{:keys [_id title difficulty tags description
restricted tests approved user]}
(get-problem (Integer. id)),
- session-user (session/session-get :user)
title (str (when-not approved
"Unapproved: ")
title)]
@@ -273,12 +271,11 @@ Return a map, {:message, :error, :url, :num-tests-passed}."
:content
[:div
[:div#prob-title title]
- (if session-user
- (with-user [{:keys [solved]}]
- (if (some #{(Integer. id)} solved)
- (link-to (str "/problem/solutions/" id)
- [:button#solutions-link {:type "submit"} "Solutions"])
- [:div {:style "clear: right; margin-bottom: 15px;"} " "]))
+ (if-user [{:keys [solved]}]
+ (if (some #{(Integer. id)} solved)
+ (link-to (str "/problem/solutions/" id)
+ [:button#solutions-link {:type "submit"} "Solutions"])
+ [:div {:style "clear: right; margin-bottom: 15px;"} " "])
[:div {:style "clear: right; margin-bottom: 15px;"} " "])
[:hr]
[:table#tags
@@ -365,12 +362,11 @@ Return a map, {:message, :error, :url, :num-tests-passed}."
(defn show-solutions [id]
(let [problem-id (Integer. id)
user (session/session-get :user)]
- (if user
- (with-user [{:keys [solved]}]
- (if (some #{problem-id} solved)
- (show-solutions-page problem-id)
- (flash-error (str "/problem/" problem-id)
- "You must solve this problem before you can see others' solutions!")))
+ (if-user [{:keys [solved]}]
+ (if (some #{problem-id} solved)
+ (show-solutions-page problem-id)
+ (flash-error (str "/problem/" problem-id)
+ "You must solve this problem before you can see others' solutions!"))
(do
(session/session-put! :login-to *url*)
(flash-error "/login" "You must log in to see solutions!")))))
View
31 src/foreclojure/users.clj
@@ -3,7 +3,7 @@
[clojure.string :as string]
[sandbar.stateful-session :as session]
[cheshire.core :as json])
- (:use [foreclojure.utils :only [from-mongo row-class rank-class get-user with-user]]
+ (:use [foreclojure.utils :only [from-mongo row-class rank-class get-user if-user with-user]]
[foreclojure.template :only [def-page content-page]]
[foreclojure.ring-utils :only [*http-scheme* static-url]]
[foreclojure.config :only [config repo-url]]
@@ -111,10 +111,8 @@
[:span.following "me"]))
(defn generate-user-list [user-set table-name]
- (let [[user-id following]
- (when (session/session-get :user)
- (with-user [{:keys [_id following]}]
- [_id (set following)]))]
+ (let [[user-id following] (if-user [{:keys [_id following]}]
+ [_id (set following)])]
(list
[:br]
[:table.my-table {:id table-name}
@@ -135,10 +133,8 @@
user-set)])))
(defn generate-datatable-users-list [user-set]
- (let [[user-id following]
- (when (session/session-get :user)
- (with-user [{:keys [_id following]}]
- [_id (set following)]))]
+ (let [[user-id following] (if-user [{:keys [_id following]}]
+ [_id (set following)])]
(map-indexed
(fn [rownum {:keys [_id email position rank user contributor solved]}]
[rank
@@ -204,15 +200,14 @@
:class "user-profile-img"
:default "images/gus-of-disapproval.png"})]
[:div.user-profile-name page-title]
- (if (session/session-get :user)
- (with-user [{:keys [_id following]}]
- (if (not= _id user-id)
- (let [[url label] (if (some #{user-id} following)
- ["unfollow" "Unfollow"]
- ["follow" "Follow"])]
- (form-to [:post (str "/user/" url "/" username)]
- [:button.user-follow-button {:type "submit"} label]))
- [:div {:style "clear: right; margin-bottom: 10px;"} " "]))
+ (if-user [{:keys [_id following]}]
+ (if (not= _id user-id)
+ (let [[url label] (if (some #{user-id} following)
+ ["unfollow" "Unfollow"]
+ ["follow" "Follow"])]
+ (form-to [:post (str "/user/" url "/" username)]
+ [:button.user-follow-button {:type "submit"} label]))
+ [:div {:style "clear: right; margin-bottom: 10px;"} " "])
[:div {:style "clear: right; margin-bottom: 10px;"} " "])
[:hr]
[:table
View
25 src/foreclojure/utils.clj
@@ -122,10 +122,27 @@
(from-mongo
(fetch-one :users :where {:user username})))
-(defmacro with-user [[user-binding] & body]
- `(if-let [username# (session/session-get :user)]
- (let [~user-binding (get-user username#)]
- ~@body)
+(defmacro if-user
+ "Look for a user with the given username in the database, let-ing it
+ to the supplied binding and executing the then clause. If no such user
+ can be found, evaluate the else clause.
+
+ username defaults to the current value of (session-get :user) if not
+ specified. Callers need not verify that username is non-nil: that is
+ done for you before consulting the database."
+ ([[user-binding username] then]
+ `(if-user ~[user-binding username] ~then nil))
+ ([[user-binding username] then else]
+ (let [userexpr (or username `(session/session-get :user))]
+ `(let [username# ~userexpr]
+ (if-let [~user-binding (and username#
+ (get-user username#))]
+ ~then
+ ~else)))))
+
+(defmacro with-user [[binding expr] & body]
+ `(if-user [~binding ~expr]
+ (do ~@body)
[:span.error "You must " (login-link) " to do this."]))
(defn flash-fn [type]

0 comments on commit bc124ae

Please sign in to comment.