Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'release/0.2.1'

  • Loading branch information...
commit 465eed62131400f424728eb984f0e661e7da5655 2 parents 24cc9e6 + 709bdc9
@amalloy amalloy authored
View
2  project.clj
@@ -1,4 +1,4 @@
-(defproject foreclojure "0.2.0"
+(defproject foreclojure "0.2.1"
:description "4clojure - a website for lisp beginners"
:dependencies [[org.clojure/clojure "1.2.1"]
[org.clojure/clojure-contrib "1.2.0"]
View
2  resources/public/css/style.css
@@ -113,7 +113,7 @@ a.novisited {color: #00e;}
}
#welcome{
- width: 90%;
+ width: 100%;
float: left;
}
View
16 src/foreclojure/core.clj
@@ -1,9 +1,10 @@
(ns foreclojure.core
(:use compojure.core
[foreclojure static problems login register
- users config social version db-utils]
+ users config social version db-utils utils]
ring.adapter.jetty
somnium.congomongo
+ ring.middleware.stacktrace
[ring.middleware.reload :only [wrap-reload]])
(:require [compojure [route :as route] [handler :as handler]]
[sandbar.stateful-session :as session]
@@ -36,12 +37,13 @@
(route/resources "/")
(route/not-found "Page not found"))
-(def app
- (handler/site
- (session/wrap-stateful-session
- (if (:wrap-reload config)
- (wrap-reload #'main-routes '(foreclojure.core))
- #'main-routes))))
+(def app (-> #'main-routes
+ ((if (:wrap-reload config)
+ #(wrap-reload % '(foreclojure.core))
+ identity))
+ session/wrap-stateful-session
+ handler/site
+ wrap-uri-binding))
(defn run []
(run-jetty (var app) {:join? false :port 8080}))
View
31 src/foreclojure/data_set.clj
@@ -706,9 +706,38 @@ number of prime numbers."
:tests ["(= (__ 2) [2 3])"
"(= (__ 5) [2 3 5 7 11])"
"(= (last (__ 100)) 541)"]})
+
+ (insert! :problems
+ {:_id 68
+ :title "Recurring Theme"
+ :times-solved 0
+ :description "Clojure only has one non-stack-consuming looping construct: recur. Either a function or a loop can be used as the recursion point. Either way, recur rebinds the bindings of the recursion point to the values it is passed. Recur must be called from the tail-position, and calling it elsewhere will result in an error."
+ :tags ["elementary" "recursion"]
+ :tests ["(= __\n (loop [x 5\n result []]\n (if (> x 0)\n (recur (dec x) (conj result (+ 2 x)))\n result)))"]})
+
+ (insert! :problems
+ {:_id 69
+ :title "Merge with a Function"
+ :times-solved 0
+ :restricted ["merge-with"]
+ :description "Write a function which takes a function f and a variable number of maps. Your function should return a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) should be combined with the mapping in the result by calling (f val-in-result val-in-latter)"
+ :tags ["medium" "core-functions"]
+ :tests ["(= (__ * {:a 2, :b 3, :c 4} {:a 2} {:b 2} {:c 5})\n {:a 4, :b 6, :c 20})"
+ "(= (__ - {1 10, 2 20} {1 3, 2 10, 3 15})\n {1 7, 2 10, 3 15})"
+ "(= (__ concat {:a [3], :b [6]} {:a [4 5], :c [8 9]} {:b [7]})\n {:a [3 4 5], :b [6 7], :c [8 9]})"]})
+
+ (insert! :problems
+ {:_id 70
+ :title "Word Sorting"
+ :times-solved 0
+ :description "Write a function which splits a sentence up into a sorted list of words. Capitalization should not affect sort order and punctuation should be ignored."
+ :tags ["medium" "sorting"]
+ :tests ["(= (__ \"Have a nice day.\")\n [\"a\" \"day\" \"Have\" \"nice\"])"
+ "(= (__ \"Clojure is a fun language!\")\n [\"a\" \"Clojure\" \"fun\" \"is\" \"language\"])"
+ "(= (__ \"Fools fall for foolish follies.\")\n [\"fall\" \"follies\" \"foolish\" \"Fools\" \"for\"])"]})
(insert! :problems
- {:_id 68
+ {:_id 71
:title "Power Set"
:times-solved 0
:description "A power set is the set of all subsets of a given set. Given a list, produce a set of sublists while preserving the order of elements."
View
12 src/foreclojure/login.clj
@@ -8,10 +8,12 @@
somnium.congomongo)
(:require [sandbar.stateful-session :as session]
[ring.util.response :as response])
- (:import java.net.URLEncoder
- org.apache.commons.mail.SimpleEmail))
+ (:import org.apache.commons.mail.SimpleEmail))
-(def-page my-login-page []
+(def-page my-login-page [location]
+ (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)]
@@ -121,12 +123,12 @@
" something you'll remember!")})
(session/session-put! :login-to "/login/update")
(flash-msg "Your password has been reset! You should receive an email soon"
- "/login"))
+ (login-url "/login/update")))
(flash-error "We don't know anyone with that email address!"
"/login/reset")))
(defroutes login-routes
- (GET "/login" [] (my-login-page))
+ (GET "/login" [location] (my-login-page location))
(POST "/login" {{:strs [user pwd]} :form-params}
(do-login user pwd))
View
11 src/foreclojure/problems.clj
@@ -68,7 +68,8 @@
(send total-solved inc))
(str "Congratulations, you've solved the problem!"
"<br />" (next-problem-link id)))
- "You've solved the problem! If you log in we can track your progress.")]
+ (str "You've solved the problem! If you "
+ (login-link "log in") " we can track your progress."))]
(session/session-put! :code [id code])
(flash-msg (str message " " gist-link) (str "/problem/" id))))
@@ -130,7 +131,7 @@
[:div
[:div.message (session/flash-get :message)]
[:b "Code which fills in the blank:" [:br]]]
- (form-to [:post "/run-code"]
+ (form-to [:post *url*]
(text-area {:id "code-box"
:spellcheck "false"}
:code (session/flash-get :code))
@@ -168,11 +169,11 @@
(defroutes problems-routes
(GET "/problems" [] (problem-page))
(GET "/problem/:id" [id] (code-box id))
+ (POST "/problem/:id" [id code]
+ (run-code (Integer. id) code))
(GET "/problems/rss" [] (create-feed
"4Clojure: Recent Problems"
"http://4clojure.com/problems"
"Recent problems at 4Clojure.com"
"http://4clojure.com/problems/rss"
- (problem-feed 20)))
- (POST "/run-code" {{:strs [id code]} :form-params}
- (run-code (Integer. id) code)))
+ (problem-feed 20))))
View
27 src/foreclojure/utils.clj
@@ -7,7 +7,15 @@
somnium.congomongo)
(:require [sandbar.stateful-session :as session]
(ring.util [response :as response])
- [clojure.walk :as walk]))
+ [clojure.walk :as walk])
+ (:import java.net.URLEncoder))
+
+(def ^{:dynamic true} *url* nil)
+
+(defn wrap-uri-binding [handler]
+ (fn [req]
+ (binding [*url* (:uri req)]
+ (handler req))))
(defmacro dbg [x]
`(let [x# ~x] (println '~x "=" x#) x#))
@@ -27,6 +35,19 @@
~fail-expr
~body))
+(defn login-url
+ ([] (login-url *url*))
+ ([location]
+ (str "/login?location=" (URLEncoder/encode location))))
+
+(defn login-link
+ ([] (login-link "Log in" *url*))
+ ([text] (login-link text *url*))
+ ([text location]
+ (html
+ (link-to (login-url location)
+ text))))
+
(defn flash-fn [type]
(fn [msg url]
(session/flash-put! type msg)
@@ -52,7 +73,7 @@
`(if-let [username# (session/session-get :user)]
(let [~user-binding (get-user username#)]
~@body)
- [:span.error "You must " (link-to "/login" "Log in") " to do this."]))
+ [:span.error "You must " (login-link) " to do this."]))
(defn form-row [[type name info]]
[:tr
@@ -101,7 +122,7 @@
[:span#username (str "Logged in as " user )]
[:a#logout {:href "/logout"} "Logout"]]
[:div
- [:a#login {:href "/login"} "Login"]
+ [:a#login {:href (login-url)} "Login"]
[:a#register {:href "/register"} "Register"]])]]
[:div#content_body body]
[:div#footer
Please sign in to comment.
Something went wrong with that request. Please try again.