Permalink
Browse files

Merge branch 'release/1.5.2'

  • Loading branch information...
2 parents 3387ff9 + b828be3 commit 065a9b1cdb95aaf2b0c1c77c4da77e252ccf12a2 @amalloy amalloy committed Oct 20, 2011
View
@@ -1,4 +1,4 @@
-(defproject foreclojure "1.5.1.1"
+(defproject foreclojure "1.5.2"
:description "4clojure - a website for learning Clojure"
:dependencies [[clojure "1.2.1"]
[clojure-contrib "1.2.0"]
@@ -41,9 +41,9 @@ $(document).ready(function() {
$("#all-users-link").html("[show <a href=\"/users/all\">all</a>]");
- $("#user-table").addClass("js-enabled");
+ $("#user-table,#server-user-table").addClass("js-enabled");
- $("#user-table input.following").live("click", function(e) {
+ $("#user-table,#server-user-table input.following").live("click", function(e) {
e.preventDefault();
var $checkbox = $(this)
var $form = $checkbox.parents("form")
@@ -59,6 +59,7 @@ $(document).ready(function() {
});
return false;
});
+
});
var difficulty = {
@@ -94,6 +95,19 @@ jQuery.fn.dataTableExt.afnSortData['user-name'] = function(oSettings, iColumn)
return aData;
}
+// See comments for above function to make sense of this mess
+jQuery.fn.dataTableExt.afnSortData['following'] = function(oSettings, iColumn)
+{
+ var aData = [];
+ $('td:eq('+iColumn+') span.following', oSettings.oApi._fnGetTrNodes(oSettings)).each(function () {
+ var followingText = $(this).text();
+ if (!followingText || followingText == "") { followingText = "no" }
+ aData.push(followingText);
+ });
+ return aData;
+}
+
+
function configureDataTables(){
$('#problem-table').dataTable( {
@@ -127,13 +141,19 @@ function configureDataTables(){
{"sType": "numeric"},
{"sSortDataType": "user-name"},
{"sType": "numeric"},
- {"sType": "string"}
+ {"sSortDataType": "following"}
]
} );
$('#server-user-table').dataTable( {
- "iDisplayLength":10,
+ "aoColumns": [
+ null,
+ null,
+ null,
+ {"bSortable": false}
+ ],
+ "iDisplayLength":100,
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": "/datatable/users"
View
@@ -3,14 +3,16 @@
[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]]
[clojail.core :only [thunk-timeout]]
[clojure.stacktrace :only [print-cause-trace]]
[somnium.congomongo :only [update! fetch-one]]))
+(def password-reset-url "https://www.4clojure.com/settings")
+
(def login-box
(form-to [:post "/login"]
[:table
@@ -85,7 +87,7 @@
:text
(str "The password for your 4clojure.com account "
name " has been reset to " pw ". Make sure to change it"
- " soon at https://4clojure.com/login/update - pick"
+ " soon at " password-reset-url " - pick"
" something you'll remember!")})
{:success true})
10 :sec)
@@ -103,8 +105,8 @@
:only [:_id :user])]
(let [{:keys [success] :as diagnostics} (try-to-email email name id)]
(if success
- (do (session/session-put! :login-to "/login/update")
- (flash-msg (login-url "/login/update")
+ (do (session/session-put! :login-to password-reset-url)
+ (flash-msg (login-url password-reset-url)
"Your password has been reset! You should receive an email soon."))
(do (spit (str name ".pwd") diagnostics)
(flash-error "/login/reset"
@@ -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;"} "&nbsp;"]))
+ (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;"} "&nbsp;"])
[:div {:style "clear: right; margin-bottom: 15px;"} "&nbsp;"])
[:hr]
[:table#tags
@@ -306,7 +303,7 @@ Return a map, {:message, :error, :url, :num-tests-passed}."
[:br]
[:br]
[:p#instruct "Code which fills in the blank: "]
- (when (wants-no-javascript-codebox?) [:span#disable-javascript-codebox])
+ (when (wants-no-javascript-codebox?) [:span#disable-javascript-codebox])
(text-area {:id "code-box"
:spellcheck "false"}
:code (escape-html
@@ -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
@@ -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]]
@@ -103,17 +103,16 @@
(str "/user/" (if follow? "follow" "unfollow") "/" username))
(defn following-checkbox [current-user-id following user-id user]
- (when (and current-user-id (not= current-user-id user-id))
+ (if (and current-user-id (not= current-user-id user-id))
(let [following? (contains? following user-id)]
(form-to [:post (follow-url user (not following?))]
[:input.following {:type "checkbox" :checked following?}]
- [:span.following (when following? "yes")]))))
+ [:span.following (when following? "yes")]))
+ [: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}
@@ -134,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
@@ -203,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;"} "&nbsp;"]))
+ (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;"} "&nbsp;"])
[:div {:style "clear: right; margin-bottom: 10px;"} "&nbsp;"])
[:hr]
[:table
View
@@ -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 065a9b1

Please sign in to comment.