Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
152 lines (133 sloc) 5.16 KB
(ns tryclojure.core
(:use ring.adapter.jetty
[hiccup form-helpers page-helpers]
[ring.middleware reload stacktrace params file session]
[noir.response :only [json]]
[clojure.stacktrace :only [root-cause]]
[clojail.core :only [sandbox]]
[clojail.testers :only [secure-tester-without-def]])
(:require [noir.server :as server]
[noir.session :as session])
(defpartial links []
[(link-to "" "The official Clojure website")
(link-to "" "Getting started with Clojure")
(link-to "" "Clojure mailing list")
(link-to "" "A comprehensive Clojure tutorial")
(link-to "" "The Joy of Clojure: a book by Michael Fogus and Chris Houser")
(link-to "" "Disclojure")
(link-to "" "Planet Clojure")]))
(defpartial bottom-html []
"You can find the site's source and such on its "
(link-to "" "github")
" page."]
"Please note that this REPL is sandboxed, so you wont be able to do everything in it "
"that you would in a local unsandboxed REPL. Keep in mind that this site is designed for "
"beginners to try out Clojure and not necessarily as a general-purpose server-side REPL."]
"One quirk you might run into is that things you bind with def can sometimes disappear. "
"The sandbox wipes defs if you def too many things, so don't be surprised. Furthermore, "
"The sandbox will automatically be wiped after 15 minutes and if you evaluate more after that,"
"It'll be in an entirely new namespace/sandbox."]
"TryClojure is written in Clojure and JavaScript (JQuery), powered by "
(link-to "" "clojail")
" and Chris Done's "
(link-to "" "jquery-console")]
[:p.bottom "Design by " (link-to "" "Andrew Gwozdziewyc")])
(defpartial home-text []
"Welcome to Try Clojure. Above, you have a Clojure REPL. You can type expressions and see "
"their results right here in your browser. We also have a brief tutorial to give you a "
"taste of Clojure. Try it out by typing <code class=\"expr\">tutorial</code> in the console!"])
(defpartial fire-html []
(:html4 doctype)
(include-css "/resources/public/css/tryclojure.css")
(include-js "/resources/public/javascript/jquery-1.4.2.min.js"
[:title "Try Clojure"]]
[:span.logo-try "Try"] " "
[:span.logo-clojure "Clo" [:em "j"] "ure"]]]
[:a#links.buttons "links"]
[:a#about.buttons.last "about"]]
[:div#changer (home-text)]]
[:p.bottom "©2011 Anthony Grimes (Raynes) and contributors"]
"Built with "
(link-to "" "Noir")
(defpage "/" []
(defpage "/about" []
(defpage "/links" []
(defpage [:post "/tutorial"] {n :n}
(slurp (str "resources/public/tutorial/page" n ".html")))
(defn eval-form [form sbox]
(with-open [out (]
(let [result (sbox form {#'*out* out})]
{:expr form
:result [out result]})))
(defn eval-string [expr sbox]
(let [form (binding [*read-eval* false] (read-string expr))]
(eval-form form sbox)))
(def sandboxes (atom {:counter 0}))
(def try-clojure-tester
(into secure-tester-without-def
(defn add-user [old]
(let [count (inc (:counter old))]
(assoc old
:counter count
count (sandbox try-clojure-tester :timeout 2000))))
(defn eval-request [expr]
(if-let [sb (@sandboxes (session/get :sb))]
(let [sbs (swap! sandboxes add-user)
count (:counter sbs)]
(session/put! :sb count)
(future (Thread/sleep 900000)
(swap! sandboxes dissoc count))
(sbs count)))))
(catch TimeoutException _
{:error true :message "Execution Timed Out!"})
(catch Exception e
{:error true :message (.getMessage (root-cause e))})))
(defpage "/eval.json" {:keys [expr]}
(let [{:keys [expr result error message] :as res} (eval-request expr)]
(if error
(let [[out res] result]
{:expr (pr-str expr)
:result (str out (pr-str res))})))))
(server/add-middleware wrap-file (System/getProperty "user.dir"))
(defn to-port [s]
(when-let [port s] (Long. port)))
(defn tryclj [port]
(or (to-port port)
(to-port (System/getenv "PORT")) ;; For deploying to Heroku
(defn -main [& args] (tryclj (first args)))
Something went wrong with that request. Please try again.