Skip to content

Commit

Permalink
Merge branch 'release/1.3.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
amalloy committed Sep 24, 2011
2 parents 4a2cef0 + ff75fc3 commit 08aa61f
Show file tree
Hide file tree
Showing 15 changed files with 414 additions and 316 deletions.
1 change: 1 addition & 0 deletions config.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
:db-host "localhost"
:db-user nil
:db-pwd nil
:jetty-port 8080
:host "smtp.googlemail.com"
:user "team@4clojure.com"
:problem-submission true
Expand Down
2 changes: 1 addition & 1 deletion project.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(defproject foreclojure "1.3.1.2"
(defproject foreclojure "1.3.2"
:description "4clojure - a website for lisp beginners"
:dependencies [[clojure "1.2.1"]
[clojure-contrib "1.2.0"]
Expand Down
35 changes: 35 additions & 0 deletions resources/public/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,41 @@ div.message {
float: left;
}

div#heading {
font-weight: bold;
font-size: 25px;
float: left;
display: block;
clear: left;
margin-bottom: 10px;
}
div#heading-note {
font-weight: bold;
font-size: 13px;
display: block;
float: left;
clear: right;
margin: 11px 0 0 13px;
}

div#sub-heading {
font-size: 13px;
font-weight: normal;
display: block;
float: left;
clear: both;
margin-bottom: 10px;
}

div#main {
display: block;
float: left;
clear: both;
}

div.message #flash-text {}
div.message #error-text {}

div#prob-title {
font-size: 15pt;
font-family: sans-serif;
Expand Down
12 changes: 7 additions & 5 deletions src/foreclojure/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,13 @@
(int (/ (. r (maxMemory)) 1e6))))))
period)))

(defn run []
(prepare-mongo)
(register-heartbeat)
(run-jetty (var app) {:join? *block-server* :port 8080}))
(let [default-jetty-port 8080]
(defn run []
(prepare-mongo)
(register-heartbeat)
(run-jetty (var app) {:join? *block-server*
:port (get config :jetty-port default-jetty-port)})))

(defn -main [& args]
(binding [*block-server* true]
(run)))
(run)))
41 changes: 27 additions & 14 deletions src/foreclojure/golf.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,41 @@
[sandbar.stateful-session :as session])
(:use [hiccup.form-helpers :only [form-to check-box]]
[hiccup.page-helpers :only [link-to]]
[foreclojure.utils :only [def-page with-user]]
[foreclojure.utils :only [with-user]]
[foreclojure.template :only [def-page content-page]]
[foreclojure.users :only [golfer?]]
[compojure.core :only [defroutes POST GET]]
[somnium.congomongo :only [update!]]))

(def-page golfer-page []
"Your preferences have been saved.")

(defn golf-opt-in-box [user-obj]
(list
[:table
(form-to [:post "/golf/opt-in"]
[:tr
[:td
(check-box :opt-in
(golfer? user-obj))
[:label {:for "opt-in"}
"I want to join the golf league and compete to find the shortest solutions"]]]
[:tr [:td [:button {:type "submit"} "Update"]]])]))

(def-page opt-in-page []
(with-user [user-obj]
[:div
[:h2 "League sign-up"]
[:div#explain "While the primary purpose of 4clojure.com is to teach Clojure \"by doing\", you may also choose to compete for the shortest solution. This is affectionately known as " (link-to "http://lbrandy.com/blog/2008/09/what-code-golf-taught-me-about-python/" "code golf") ": the lower your score the better, get it? If you choose to participate, we'll score your correct solutions based on the number of non-whitespace characters (and some more metrics in the future). We'll also provide a chart showing how you stack up compared to everyone else on the site."]
[:table
(form-to [:post "/golf/opt-in"]
[:tr
[:td
(check-box :opt-in
(golfer? user-obj))
[:label {:for "opt-in"}
"I want to join the golf league and compete to find the shortest solutions"]]]
[:tr [:td [:button {:type "submit"} "Update"]]])]]))
(with-user [{:keys [user] :as user-obj}]
{:title "Account Settings"
:content
(content-page
{:heading "League sign-up"
:sub-heading (list "While the primary purpose of 4clojure.com is to teach Clojure \"by doing\", you may "
"also choose to compete for the shortest solution. This is affectionately known as "
(link-to "http://lbrandy.com/blog/2008/09/what-code-golf-taught-me-about-python/" "code golf")
": the lower your score the better, get it? If you choose to participate, we'll score "
"your correct solutions based on the number of non-whitespace characters (and some more "
"metrics in the future). We'll also provide a chart showing how you stack up compared "
"to everyone else on the site.")
:main (golf-opt-in-box user-obj)})}))

(defn set-golfer [opt-in]
(with-user [{:keys [_id]}]
Expand Down
156 changes: 82 additions & 74 deletions src/foreclojure/login.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,39 @@
[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 [def-page from-mongo flash-error flash-msg with-user form-row assuming send-email login-url]]
[foreclojure.utils :only [from-mongo flash-error flash-msg with-user form-row assuming send-email login-url]]
[foreclojure.template :only [def-page content-page]]
[foreclojure.users :only [disable-codebox? set-disable-codebox hide-solutions? set-hide-solutions]]
[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 login-box
(form-to [:post "/login"]
[:table
[:tr
[:td (label :user "Username")]
[:td (text-field :user)]]
[:tr
[:td (label :pwd "Password")]
[:td (password-field :pwd)]]
[:tr
[:td]
[:td [:button {:type "submit"} "Log In"]]]
[:tr
[:td]
[:td
[:a {:href "/login/reset"} "Forgot your password?"]]]]))

(def-page my-login-page [location]
{:title "4clojure - login"
:content
(list
(when location
(session/session-put! :login-to location)
nil) ;; don't include this in HTML output
[:div.error
(session/flash-get :error)
(session/flash-get :message)]
(form-to [:post "/login"]
[:table
[:tr
[:td (label :user "Username")]
[:td (text-field :user)]]
[:tr
[:td (label :pwd "Password")]
[:td (password-field :pwd)]]
[:tr
[:td]
[:td [:button {:type "submit"} "Log In"]]]
[:tr
[:td]
[:td
[:a {:href "/login/reset"} "Forgot your password?"]]]]))})
(do
(if location (session/session-put! :login-to location))
{:title "4clojure - login"
:content
(content-page
{:main login-box})}))

(defn do-login [user pwd]
(let [user (.toLowerCase user)
Expand All @@ -48,50 +48,58 @@
(session/session-put! :user user)
(session/session-delete-key! :login-to)
(response/redirect (or location "/problems")))
(flash-error "Error logging in." "/login"))))
(flash-error "/login" "Error logging in."))))

(defn account-settings-box [user]
[:table
(form-to [:post "/login/update"]
(map form-row
[[text-field :new-username "Username" user]
[password-field :old-pwd "Current password"]
[password-field :pwd "New password"]
[password-field :repeat-pwd "Repeat password"]])
[:tr
[:td [:button {:type "submit"} "Reset now"]]])])

(defn js-settings-box [user-obj]
(list
[:p "Selecting this will disable the JavaScript code entry box and just give you plain text entry"]
(form-to [:post "/users/set-disable-codebox"]
(check-box :disable-codebox
(disable-codebox? user-obj))
[:label {:for "disable-codebox"}
"Disable JavaScript in code entry box"]
[:br]
[:div#button-div
[:button {:type "submit"} "Submit"]])))

(defn hide-settings-box [user-obj]
(list
[:p "When you solve a problem, we allow any user who has solved a problem to view your solutions to that problem. Check this box to keep your solutions private."]
(form-to [:post "/users/set-hide-solutions"]
(check-box :hide-solutions
(hide-solutions? user-obj))
[:label {:for "hide-solutions"}
"Hide my solutions"]
[:br]
[:div#button-div
[:button {:type "submit"} "Submit"]])))

;; TODO this page is getting hella gross. Need a real Settings page soon.
(def-page update-credentials-page []
{:title "Change password"
:content
(with-user [{:keys [user] :as user-obj}]
[:div#account-settings
[:div#update-pwd
[:h2 "Change password for " user]
[:span.error (session/flash-get :error)]
[:table
(form-to [:post "/login/update"]
(map form-row
[[text-field :new-username "Username" user]
[password-field :old-pwd "Current password"]
[password-field :pwd "New password"]
[password-field :repeat-pwd "Repeat password"]])
[:tr
[:td [:button {:type "submit"} "Reset now"]]])]
[:hr]
[:div#settings-codebox
(with-user [{:keys [user] :as user-obj}]
{:title "Change password"
:content
(content-page
{:main
(list
[:h2 "Change password for " user]
[:div#account-settings (account-settings-box user)]
[:hr]
[:h2 "Disable JavaScript Code Box"]
[:p "Selecting this will disable the JavaScript code entry box and just give you plain text entry"]
(form-to [:post "/users/set-disable-codebox"]
(check-box :disable-codebox
(disable-codebox? user-obj))
[:label {:for "disable-codebox"}
"Disable JavaScript in code entry box"]
[:br]
[:div#button-div
[:button {:type "submit"} "Submit"]])]
[:hr]
[:div#settings-follow
[:div#settings-codebox (js-settings-box user-obj)]
[:hr]
[:h2 "Hide My Solutions"]
[:p "When you solve a problem, we allow any user who has solved a problem to view your solutions to that problem. Check this box to keep your solutions private."]
(form-to [:post "/users/set-hide-solutions"]
(check-box :hide-solutions
(hide-solutions? user-obj))
[:label {:for "hide-solutions"}
"Hide my solutions"]
[:br]
[:div#button-div
[:button {:type "submit"} "Submit"]])]]])})
[:div#settings-follow (hide-settings-box user-obj)])})}))

(defn do-update-credentials! [new-username old-pwd new-pwd repeat-pwd]
(with-user [{:keys [user pwd]}]
Expand All @@ -116,9 +124,9 @@
{:$set {:pwd (if (not-empty new-pwd) new-pwd-hash pwd) :user new-lower-user}}
:upsert false)
(session/session-put! :user new-lower-user)
(flash-msg (str "Account for " new-lower-user " updated successfully")
"/problems"))
(flash-error why "/login/update")))))
(flash-msg "/problems"
(str "Account for " new-lower-user " updated successfully")))
(flash-error "/login/update" why)))))

(def-page reset-password-page []
{:title "Reset password"
Expand Down Expand Up @@ -175,13 +183,13 @@
(let [{:keys [success] :as diagnostics} (try-to-email email name id)]
(if success
(do (session/session-put! :login-to "/login/update")
(flash-msg "Your password has been reset! You should receive an email soon."
(login-url "/login/update")))
(flash-msg (login-url "/login/update")
"Your password has been reset! You should receive an email soon."))
(do (spit (str name ".pwd") diagnostics)
(flash-error (str "Something went wrong emailing your new password! Please contact <a href='mailto:team@4clojure.com?subject=Password Reset: " name "'>team@4clojure.com</a> - we'll reset it manually and look into the problem. When you do, please mention your username.")
"/login/reset"))))
(flash-error "We don't know anyone with that email address!"
"/login/reset")))
(flash-error "/login/reset"
(str "Something went wrong emailing your new password! Please contact <a href='mailto:team@4clojure.com?subject=Password Reset: " name "'>team@4clojure.com</a> - we'll reset it manually and look into the problem. When you do, please mention your username.")))))
(flash-error "/login/reset"
"We don't know anyone with that email address!")))

(defroutes login-routes
(GET "/login" [location] (my-login-page location))
Expand Down
Loading

0 comments on commit 08aa61f

Please sign in to comment.