Skip to content

Commit

Permalink
Merge branch 'release/1.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
amalloy committed Jul 16, 2011
2 parents 6f0b20c + 9edf1b4 commit ed1301e
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 18 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ vaguely like this:
* For the first time use, you will need to load the problem data. Run the script `load-data.sh`:

./load-data.sh
* Run `lein ring server` and the browser should open for you.
* Run `lein run` and then open the brower to http://localhost:8080/

lein ring server
lein run

## Contributors

Expand Down
5 changes: 3 additions & 2 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(defproject foreclojure "1.0.5"
(defproject foreclojure "1.1.0"
:description "4clojure - a website for lisp beginners"
:dependencies [[clojure "1.2.1"]
[clojure-contrib "1.2.0"]
Expand All @@ -17,6 +17,7 @@
[incanter/incanter-charts "1.2.3"]
[org.apache.commons/commons-email "1.2"]]
:dev-dependencies [[lein-ring "0.4.0"]
[swank-clojure "1.2.1"]]
[swank-clojure "1.2.1"]
[midje "1.1.1"]]
:main foreclojure.core
:ring {:handler foreclojure.core/app})
66 changes: 63 additions & 3 deletions resources/public/script/foreclojure.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,73 @@ function configureCodeBox(){

var ClojureMode = require("ace/mode/clojure").Mode;
var session = editor.getSession();

var clickHandler = function() {
var text = session.getValue(),
id = $('#id').attr("value"),
images = $(".testcases").find("img"),
cont = true,
high = false,
time = 800,

beforeSendCallback = function(data) {
$("#message-text").text("Executing unit tests...");
var anim = function() {
if(cont) {
images.animate({
opacity: high ? 1.0 : 0.1,
}, time);
high = !high;
setTimeout(anim,time);
}
};
anim();
},
successCallback = function(data) {
var failingTest = data.failingTest;
cont = false;

images.stop(true);
images.css({ opacity: 1.0, });
images.each( function(index,element) {
var color = "blue";
if (index < failingTest) {
color = "green";
} else if (index === failingTest) {
color = "red";
}
element.src = "/images/"+color+"light.png";
});

$("#message-text").html(data.message);
$("#golfgraph").html(data.golfChart);
$("#golfscore").html(data.golfScore);
configureGolf();
};

$.ajax({type: "POST",
url: "/rest/problem/"+id,
dataType: "json",
data: { id: id, code: text, },
timout: 20000, // default clojail timeout is 10000
beforeSend: beforeSendCallback,
success: successCallback,
error: function(data, str, error) {
$("#message-text").text("An Error occured: "+error);
},
});
return false;
};

$("#run-button").click(clickHandler);

session.setMode(new ClojureMode());
session.setUseSoftTabs(true);
session.setTabSize(2);

document.getElementById('editor').style.fontSize='13px';
$("#run-button").click(function(){
var text = editor.getSession().getValue();
var text = editor.getSession().getValue();
$('#code').val(text);
});
}
Expand All @@ -99,10 +159,10 @@ function configureGolf(){
var text = $('#graph-link').html();
if (text && text == 'View Chart'){
$('#graph-link').html("View Code");
}else{
} else {
$('#graph-link').html("View Chart");
}


});

Expand Down
2 changes: 1 addition & 1 deletion src/foreclojure/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@
(run-jetty (var app) {:join? false :port 8080}))

(defn -main [& args]
(run))
(run))
36 changes: 27 additions & 9 deletions src/foreclojure/problems.clj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
(amalloy.utils [debug :only [?]]
[reorder :only [reorder]])
[amalloy.utils :only [defcomp]]
compojure.core)
compojure.core
[clojure.contrib.json :only [json-str]])
(:require [sandbar.stateful-session :as session]
[clojure.string :as s]
(ring.util [response :as response])))
Expand Down Expand Up @@ -95,10 +96,12 @@
(defn store-completed-state! [username problem-id code]
(let [{user-id :_id} (fetch-one :users
:where {:user username}
:only [:_id])]
:only [:_id])
current-time (java.util.Date.)]
(when (not-any? #{problem-id} (get-solved username))
(update! :users {:_id user-id} {:$addToSet {:solved problem-id}})
(update! :problems {:_id problem-id} {:$inc {:times-solved 1}})
(update! :users {:_id problem-id} {:$set {:last-solved-date current-time}})
(send total-solved inc))
(record-golf-score! user-id problem-id (code-length code))
(save-solution user-id problem-id code)))
Expand All @@ -117,9 +120,9 @@
(str "Congratulations, you've solved the problem!"
"<br />" (next-problem-link _id)))
:else (str "You've solved the problem! If you "
(login-link "log in") " we can track your progress."))]
(login-link "log in" (str "/problem/" _id)) " we can track your progress."))]
(session/session-put! :code [_id code])
(flash-msg (str message " " gist-link) (str "/problem/" _id))))
[(str message " " gist-link) (str "/problem/" _id)] ))

(def restricted-list '[use require in-ns future agent send send-off pmap pcalls])

Expand All @@ -143,7 +146,7 @@
(try
(let [user-forms (s/join " " (map pr-str (read-string-safely code)))]
(if (empty? user-forms)
(flash-msg "Empty input is not allowed" *url*)
["Empty input is not allowed" *url*]
(loop [[test & more] tests
i 0]
(session/flash-put! :failing-test i)
Expand All @@ -152,9 +155,13 @@
(let [testcase (s/replace test "__" user-forms)]
(if (sb sb-tester (first (read-string-safely testcase)))
(recur more (inc i))
(flash-msg "You failed the unit tests." *url*)))))))
["You failed the unit tests." *url*]
))))))
(catch Exception e
(flash-msg (.getMessage e) *url*)))))
[(.getMessage e) *url*]))))

(defn static-run-code [id raw-code]
(apply flash-msg (run-code id raw-code)))

(defn render-test-cases [tests]
[:table {:class "testcases"}
Expand Down Expand Up @@ -189,6 +196,13 @@
:onclick "return false"}
[:span#graph-link "View Chart"]]])))

(defn rest-run-code [id raw-code]
(let [[message url] (run-code id raw-code)]
(json-str {:failingTest (session/flash-get :failing-test)
:message message
:golfScore (html (render-golf-score))
:golfChart (html (render-golf-chart))})))

(def-page code-box [id]
(let [{:keys [_id title tags description restricted tests approved user]}
(get-problem (Integer. id))]
Expand All @@ -214,7 +228,8 @@
[:div
[:div.message
[:span#message-text (session/flash-get :message)]]
(render-golf-score)]
[:div#golfscore
(render-golf-score)]]
(form-to {:id "run-code"} [:post *url*]
[:br]
[:br]
Expand Down Expand Up @@ -410,7 +425,10 @@
(POST "/problem/reject" [id]
(reject-problem (Integer. id) "We didn't like your problem."))
(POST "/problem/:id" [id code]
(run-code (Integer. id) code))
(static-run-code (Integer. id) code))
(POST "/rest/problem/:id" [id code]
{:headers {"Content-Type" "application/json"}}
(rest-run-code (Integer. id) code))
(GET "/problems/rss" [] (create-feed
"4Clojure: Recent Problems"
"http://4clojure.com/problems"
Expand Down
5 changes: 5 additions & 0 deletions src/foreclojure/users.clj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
:where {:user name}
:only [:_id])))

(def sort-by-solved-and-date (juxt (comp count :solved) :last-login))

(defn users-sort [users]
(reverse (sort-by sort-by-solved-and-date users)))

(defn get-users []
(let [users (from-mongo
(fetch :users
Expand Down
5 changes: 4 additions & 1 deletion test/foreclojure/test/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
(:use [foreclojure.core]
[clojure.test]
[foreclojure.users]
[foreclojure.problems]))
[foreclojure.problems]
[foreclojure.mongo]))

(prepare-mongo)

(defn users-solved []
(reduce #(if-let [v (%1 %2)]
Expand Down
30 changes: 30 additions & 0 deletions test/foreclojure/test/users.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
(ns foreclojure.test.users
(:use [foreclojure.users] :reload)
(:use [clojure.test])
(:use [midje.sweet]))


(deftest sorting-by-solved
(def users-by-solved
[{:user "user1" :solved [1] } {:user "user2" :solved [1 2 3 4]}
{:user "user3" :solved [2 2] } {:user "user4" :solved [3]}])
(def users-sorted-by-solved (users-sort users-by-solved))
(fact
(:user (first users-sorted-by-solved)) => "user2")
(fact
(:user (last users-sorted-by-solved)) => "user1"))

(deftest sorting-by-last-login-date
(def date-formatter (java.text.SimpleDateFormat. "MM/dd/yyyy"))
(def date1 (.parse date-formatter "11/01/2001"))
(def date2 (.parse date-formatter "8/1/2010"))
(def users-by-date
[{:user "user1" :last-login date1 } {:user "user2" :last-login date2}
{:user "user3" } {:user "user4" :last-login date1}])
(sort-by :last-login users-by-date)
(def users-sorted-by-date (users-sort users-by-date))
(fact
(:user (first users-sorted-by-date)) => "user2")
(fact
(:user (last users-sorted-by-date)) => "user3"))

0 comments on commit ed1301e

Please sign in to comment.