Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'release/0.1.1'

  • Loading branch information...
commit 2de3c185368485907ef8f8349524117c2b6ef5fc 2 parents a492b3d + 44b3e02
@amalloy amalloy authored
View
2  README.md
@@ -40,7 +40,7 @@ vaguely like this:
* David Byrne <david.r.byrne@gmail.com>
* Alan Malloy
- * Anthony Simpson
+ * Anthony Grimes
* Carin Meier
Problem sources:
View
3  load-data.bat
@@ -0,0 +1,3 @@
+@echo off
+for /f %%a in ('lein classpath') do @set project_classpath=%%a
+java -cp %project_classpath% clojure.main .\src\foreclojure\data_set.clj
View
2  project.clj
@@ -1,4 +1,4 @@
-(defproject foreclojure "0.0.3"
+(defproject foreclojure "0.1.1"
:description "4clojure - a website for lisp beginners"
:dependencies [[org.clojure/clojure "1.2.1"]
[org.clojure/clojure-contrib "1.2.0"]
View
57 resources/public/css/style.css
@@ -1,4 +1,3 @@
-
body {
background-color: #bbddee;
font-size: 12px;
@@ -49,6 +48,7 @@ h3 {
color: #fff;
}
+a.novisited {color: #00e;}
#menu a:link {color: #fff;}
#menu a:visited {color: #fff;}
@@ -165,7 +165,10 @@ div#restrictions {
font-size: 16px;
}
-
+#contact {
+ color: #FFFFFF;
+ margin-left: 1.3em;
+}
textarea#code-box {
width: 500px;
@@ -190,6 +193,54 @@ table.my-table th {
padding: 10px 0px 0px 0px;
font-size: 14px;
font-weight: bold;
+}
- }
+button {
+ border: 1px solid #A1CC59;
+ color: #32401C;
+ font-size: 14px;
+ font-weight: bold;
+ height: 23px;
+ margin: 4px;
+ padding: 1px 6px 2px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ background: #BCEE68;
+ background: -moz-linear-gradient(top, #BCEE68, #A1CC59);
+ background: -webkit-gradient(linear, left top, left bottom, from(#BCEE68), to(#A1CC59));
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='#BCEE68', endColorstr='#A1CC59')";
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#BCEE68', endColorstr='#A1CC59');
+}
+
+button.large {
+ font-size: 16px;
+ padding: 3px 10px;
+ height: 26px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+}
+
+button:hover {
+ cursor: pointer;
+ outline: none;
+ text-decoration: none;
+ background: #D1F09E;
+ background: -moz-linear-gradient(top, #D1F09E, #A1CC59);
+ background: -webkit-gradient(linear, left top, left bottom, from(#D1F09E), to(#A1CC59));
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='#D1F09E', endColorstr='#A1CC59')";
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#D1F09E', endColorstr='#A1CC59');
+}
+
+button:active {
+ position: relative;
+ top: 1px;
+ outline: none;
+ background: #A1CC59;
+ background: -moz-linear-gradient(top, #A1CC59, #A7D45C);
+ background: -webkit-gradient(linear, left top, left bottom, from(#A1CC59), to(#A7D45C));
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='#A1CC59', endColorstr='#A7D45C')";
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#A1CC59', endColorstr='#A7D45C');
+}
View
4 src/foreclojure/core.clj
@@ -1,6 +1,7 @@
(ns foreclojure.core
(:use compojure.core
- [foreclojure static problems login register users config]
+ [foreclojure static problems login register
+ users config social]
ring.adapter.jetty
somnium.congomongo
[ring.middleware.reload :only [wrap-reload]])
@@ -28,6 +29,7 @@
problems-routes
users-routes
static-routes
+ social-routes
(route/resources "/")
(route/not-found "Page not found"))
View
139 src/foreclojure/data_set.clj
@@ -135,9 +135,9 @@
:description "Write a function which doubles a number."
:tags ["elementary"]
:tests ["(= (__ 2) 4)"
- "(= (__ 3) 6)"]
- :secret-tests ["(= (__ 11) 22)"
- "(= (__ 7) 14)"]})
+ "(= (__ 3) 6)"
+ "(= (__ 11) 22)"
+ "(= (__ 7) 14)"]})
(insert! :problems
{:_id 16
@@ -147,8 +147,8 @@
:tags ["elementary"]
:tests ["(= (__ \"Dave\") \"Hello, Dave!\")"
- "(= (__ \"Jenn\") \"Hello, Jenn!\")"]
- :secret-tests ["(= (__ \"Rhea\") \"Hello, Rhea!\")"]})
+ "(= (__ \"Jenn\") \"Hello, Jenn!\")"
+ "(= (__ \"Rhea\") \"Hello, Rhea!\")"]})
(insert! :problems
{:_id 17
@@ -174,8 +174,8 @@
:description "Write a function which returns the last element in a sequence."
:tags ["easy" "seqs" "core-functions"]
:tests ["(= (__ [1 2 3 4 5]) 5)"
- "(= (__ '(5 4 3)) 3)"]
- :secret-tests ["(= (__ [\"b\" \"c\" \"d\"]) \"d\")"]})
+ "(= (__ '(5 4 3)) 3)"
+ "(= (__ [\"b\" \"c\" \"d\"]) \"d\")"]})
(insert! :problems
{:_id 20
@@ -184,8 +184,8 @@
:description "Write a function which returns the second to last element from a sequence."
:tags["easy" "seqs"]
:tests ["(= (__ (list 1 2 3 4 5)) 4)"
- "(= (__ [\"a\" \"b\" \"c\"]) \"b\")"]
- :secret-tests ["(= (__ [[1 2] [3 4]]) [1 2])"]})
+ "(= (__ [\"a\" \"b\" \"c\"]) \"b\")"
+ "(= (__ [[1 2] [3 4]]) [1 2])"]})
(insert! :problems
{:_id 21
@@ -196,8 +196,8 @@
:tags["easy" "seqs" "core-functions"]
:tests ["(= (__ '(4 5 6 7) 2) 6)"
"(= (__ [:a :b :c] 0) :a)"
- "(= (__ [1 2 3 4] 1) 2)"]
- :secret-tests ["(= (__ '([1 2] [3 4] [5 6]) 2) [5 6])"]})
+ "(= (__ [1 2 3 4] 1) 2)"
+ "(= (__ '([1 2] [3 4] [5 6]) 2) [5 6])"]})
(insert! :problems
{:_id 22
@@ -208,9 +208,9 @@
:tags["easy" "seqs" "core-functions"]
:tests ["(= (__ '(1 2 3 3 1)) 5)"
"(= (__ \"Hello World\") 11)"
- "(= (__ [[1 2] [3 4] [5 6]]) 3)"]
- :secret-tests ["(= (__ '(13)) 1)"
- "(= (__ '(:a :b :c)) 3)"]})
+ "(= (__ [[1 2] [3 4] [5 6]]) 3)"
+ "(= (__ '(13)) 1)"
+ "(= (__ '(:a :b :c)) 3)"]})
(insert! :problems
{:_id 23
@@ -220,8 +220,8 @@
:description "Write a function which reverses a sequence."
:tags["easy" "seqs" "core-functions"]
:tests ["(= (__ [1 2 3 4 5]) [5 4 3 2 1])"
- "(= (__ (sorted-set 5 7 2 7)) '(7 5 2))"]
- :secret-tests ["(= (__ [[1 2][3 4][5 6]]) [[5 6][3 4][1 2]])"]})
+ "(= (__ (sorted-set 5 7 2 7)) '(7 5 2))"
+ "(= (__ [[1 2][3 4][5 6]]) [[5 6][3 4][1 2]])"]})
(insert! :problems
{:_id 24
@@ -231,9 +231,9 @@
:tags ["easy" "seqs"]
:tests ["(= (__ [1 2 3]) 6)"
"(= (__ (list 0 -2 5 5)) 8)"
- "(= (__ #{4 2 1}) 7)"]
- :secret-tests ["(= (__ '(0 0 -1)) -1)"
- "(= (__ '(1 10 3)) 14)"]})
+ "(= (__ #{4 2 1}) 7)"
+ "(= (__ '(0 0 -1)) -1)"
+ "(= (__ '(1 10 3)) 14)"]})
(insert! :problems
{:_id 25
@@ -242,9 +242,9 @@
:description "Write a function which returns only the odd numbers from a sequence."
:tags["easy" "seqs"]
:tests ["(= (__ #{1 2 3 4 5}) '(1 3 5))"
- "(= (__ [4 2 1 6]) '(1))"]
- :secret-tests ["(= (__ [2 2 4 6]) '())"
- "(= (__ [1 1 1 3]) '(1 1 1 3))"]})
+ "(= (__ [4 2 1 6]) '(1))"
+ "(= (__ [2 2 4 6]) '())"
+ "(= (__ [1 1 1 3]) '(1 1 1 3))"]})
(insert! :problems
{:_id 26
@@ -253,8 +253,8 @@
:description "Write a function which returns the first X fibonacci numbers."
:tags["easy" "Fibonacci" "seqs"]
:tests ["(= (__ 3) '(1 1 2))"
- "(= (__ 6) '(1 1 2 3 5 8))"]
- :secret-tests ["(= (__ 8) '(1 1 2 3 5 8 13 21))"]})
+ "(= (__ 6) '(1 1 2 3 5 8))"
+ "(= (__ 8) '(1 1 2 3 5 8 13 21))"]})
(insert! :problems
{:_id 27
@@ -265,9 +265,9 @@
:tags["easy" "seqs"]
:tests ["(false? (__ '(1 2 3 4 5)))"
"(true? (__ \"racecar\"))"
- "(true? (__ [:foo :bar :foo]))"]
- :secret-tests ["(true? (__ '(1 1 3 3 1 1)))"
- "(false? (__ '(:a :b :c)))"]})
+ "(true? (__ [:foo :bar :foo]))"
+ "(true? (__ '(1 1 3 3 1 1)))"
+ "(false? (__ '(:a :b :c)))"]})
(insert! :problems
{:_id 28
@@ -278,8 +278,8 @@
:tags["easy" "seqs" "core-functions"]
:tests ["(= (__ '((1 2) 3 [4 [5 6]])) '(1 2 3 4 5 6))"
- "(= (__ [\"a\" [\"b\"] \"c\"]) '(\"a\" \"b\" \"c\"))"]
- :secret-tests ["(= (__ '((((:a))))) '(:a))"]})
+ "(= (__ [\"a\" [\"b\"] \"c\"]) '(\"a\" \"b\" \"c\"))"
+ "(= (__ '((((:a))))) '(:a))"]})
(insert! :problems
{:_id 29
@@ -288,8 +288,8 @@
:description "Write a function which takes a string and returns a new string containing only the capital letters."
:tags["easy" "strings"]
:tests ["(= (__ \"HeLlO, WoRlD!\") \"HLOWRD\")"
- "(empty? (__ \"nothing\"))"]
- :secret-tests ["(= (__ \"$#A(*&987Zf\") \"AZ\")"]})
+ "(empty? (__ \"nothing\"))"
+ "(= (__ \"$#A(*&987Zf\") \"AZ\")"]})
(insert! :problems
{:_id 30
@@ -298,8 +298,8 @@
:description "Write a function which removes consecutive duplicates from a sequence."
:tags ["easy" "seqs"]
:tests ["(= (apply str (__ \"Leeeeeerrroyyy\")) \"Leroy\")"
- "(= (__ [1 1 2 3 3 2 2 3]) '(1 2 3 2 3))"]
- :secret-tests ["(= (__ [[1 2] [1 2] [3 4] [1 2]]) '([1 2] [3 4] [1 2]))"]})
+ "(= (__ [1 1 2 3 3 2 2 3]) '(1 2 3 2 3))"
+ "(= (__ [[1 2] [1 2] [3 4] [1 2]]) '([1 2] [3 4] [1 2]))"]})
(insert! :problems
{:_id 31
@@ -308,8 +308,8 @@
:description "Write a function which packs consecutive duplicates into sub-lists."
:tags ["easy" "seqs"]
:tests ["(= (__ [1 1 2 1 1 1 3 3]) '((1 1) (2) (1 1 1) (3 3)))"
- "(= (__ [:a :a :b :b :c]) '((:a :a) (:b :b) (:c)))"]
- :secret-tests ["(= (__ [[1 2] [1 2] [3 4]]) '(([1 2] [1 2]) ([3 4])))"]})
+ "(= (__ [:a :a :b :b :c]) '((:a :a) (:b :b) (:c)))"
+ "(= (__ [[1 2] [1 2] [3 4]]) '(([1 2] [1 2]) ([3 4])))"]})
(insert! :problems
{:_id 32
@@ -319,8 +319,8 @@
:tags ["easy" "seqs"]
:tests ["(= (__ [1 2 3]) '(1 1 2 2 3 3))"
"(= (__ [:a :a :b :b]) '(:a :a :a :a :b :b :b :b))"
- "(= (__ [[1 2] [3 4]]) '([1 2] [1 2] [3 4] [3 4]))"]
- :secret-tests ["(= (__ [44 33]) [44 44 33 33])"]})
+ "(= (__ [[1 2] [3 4]]) '([1 2] [1 2] [3 4] [3 4]))"
+ "(= (__ [44 33]) [44 44 33 33])"]})
(insert! :problems
{:_id 33
@@ -331,8 +331,8 @@
:tests ["(= (__ [1 2 3] 2) '(1 1 2 2 3 3))"
"(= (__ [:a :b] 4) '(:a :a :a :a :b :b :b :b))"
"(= (__ [4 5 6] 1) '(4 5 6))"
- "(= (__ [[1 2] [3 4]] 2) '([1 2] [1 2] [3 4] [3 4]))"]
- :secret-tests ["(= (__ [44 33] 2) [44 44 33 33])"]})
+ "(= (__ [[1 2] [3 4]] 2) '([1 2] [1 2] [3 4] [3 4]))"
+ "(= (__ [44 33] 2) [44 44 33 33])"]})
(insert! :problems
{:_id 34
@@ -342,8 +342,8 @@
:description "Write a function which creates a list of all integers in a given range."
:tags ["easy" "seqs" "core-functions"]
:tests ["(= (__ 1 4) '(1 2 3))"
- "(= (__ -2 2) '(-2 -1 0 1))"]
- :secret-tests ["(= (__ 5 8) '(5 6 7))"]})
+ "(= (__ -2 2) '(-2 -1 0 1))"
+ "(= (__ 5 8) '(5 6 7))"]})
(insert! :problems
{:_id 35
@@ -381,8 +381,8 @@
:description "Write a function which takes a variable number of parameters and returns the maximum value."
:tags ["easy" "core-functions"]
:tests ["(= (__ 1 8 3 4) 8)"
- "(= (__ 30 20) 30)"]
- :secret-tests ["(= (__ 45 67 11) 67)"]})
+ "(= (__ 30 20) 30)"
+ "(= (__ 45 67 11) 67)"]})
(insert! :problems
@@ -393,9 +393,9 @@
:description "Write a function which takes two sequences and returns the first item from each, then the second item from each, then the third, etc."
:tags ["easy" "seqs" "core-functions"]
:tests ["(= (__ [1 2 3] [:a :b :c]) '(1 :a 2 :b 3 :c))"
- "(= (__ [1 2] [3 4 5 6]) '(1 3 2 4))"]
- :secret-tests ["(= (__ [1 2 3 4] [5]) [1 5])"
- "(= (__ [30 20] [25 15]) [30 25 20 15])"]})
+ "(= (__ [1 2] [3 4 5 6]) '(1 3 2 4))"
+ "(= (__ [1 2 3 4] [5]) [1 5])"
+ "(= (__ [30 20] [25 15]) [30 25 20 15])"]})
@@ -407,8 +407,8 @@
:description "Write a function which separates the items of a sequence by an arbitrary value."
:tags ["easy" "seqs" "core-functions"]
:tests ["(= (__ 0 [1 2 3]) [1 0 2 0 3])"
- "(= (apply str (__ \", \" [\"one\" \"two\" \"three\"])) \"one, two, three\")"]
- :secret-tests ["(= (__ :z [:a :b :c :d]) [:a :z :b :z :c :z :d])"]})
+ "(= (apply str (__ \", \" [\"one\" \"two\" \"three\"])) \"one, two, three\")"
+ "(= (__ :z [:a :b :c :d]) [:a :z :b :z :c :z :d])"]})
(insert! :problems
{:_id 41
@@ -417,8 +417,8 @@
:description "Write a function which drops every Nth item from a sequence."
:tags ["easy" "seqs"]
:tests ["(= (__ [1 2 3 4 5 6 7 8] 3) [1 2 4 5 7 8])"
- "(= (__ [:a :b :c :d :e :f] 2) [:a :c :e])"]
- :secret-tests ["(= (__ [1 2 3 4 5 6] 4) [1 2 3 5 6])"]})
+ "(= (__ [:a :b :c :d :e :f] 2) [:a :c :e])"
+ "(= (__ [1 2 3 4 5 6] 4) [1 2 3 5 6])"]})
(insert! :problems
{:_id 42
@@ -428,8 +428,8 @@
:tags ["easy" "math"]
:tests ["(= (__ 1) 1)"
"(= (__ 3) 6)"
- "(= (__ 5) 120)"]
- :secret-tests ["(= (__ 8) 40320)"]})
+ "(= (__ 5) 120)"
+ "(= (__ 8) 40320)"]})
(insert! :problems
{:_id 43
@@ -438,8 +438,8 @@
:description "Write a function which reverses the interleave process into x number of subsequences."
:tags ["medium" "seqs"]
:tests ["(= (__ [1 2 3 4 5 6] 2) '((1 3 5) (2 4 6)))"
- "(= (__ (range 9) 3) '((0 3 6) (1 4 7) (2 5 8)))"]
- :secret-tests ["(= (__ (range 10) 5) '((0 5) (1 6) (2 7) (3 8) (4 9)))"]})
+ "(= (__ (range 9) 3) '((0 3 6) (1 4 7) (2 5 8)))"
+ "(= (__ (range 10) 5) '((0 5) (1 6) (2 7) (3 8) (4 9)))"]})
(insert! :problems
{:_id 44
@@ -449,9 +449,9 @@
:tags ["medium" "seqs"]
:tests ["(= (__ 2 [1 2 3 4 5]) '(3 4 5 1 2))"
"(= (__ -2 [1 2 3 4 5]) '(4 5 1 2 3))"
- "(= (__ 6 [1 2 3 4 5]) '(2 3 4 5 1))"]
- :secret-tests ["(= (__ 1 '(:a :b :c)) '(:b :c :a))"
- "(= (__ -4 '(:a :b :c)) '(:c :a :b))"]})
+ "(= (__ 6 [1 2 3 4 5]) '(2 3 4 5 1))"
+ "(= (__ 1 '(:a :b :c)) '(:b :c :a))"
+ "(= (__ -4 '(:a :b :c)) '(:c :a :b))"]})
(insert! :problems
{:_id 45
@@ -511,4 +511,27 @@
:tags ["medium" "seqs"]
:tests ["(= (set (__ [1 :a 2 :b 3 :c])) #{[1 2 3] [:a :b :c]})"
"(= (set (__ [:a \"foo\" \"bar\" :b])) #{[:a :b] [\"foo\" \"bar\"]})"
- "(= (set (__ [[1 2] :a [3 4] 5 6 :b])) #{[[1 2] [3 4]] [:a :b] [5 6]})"]})))
+ "(= (set (__ [[1 2] :a [3 4] 5 6 :b])) #{[[1 2] [3 4]] [:a :b] [5 6]})"]})
+
+ (insert! :problems
+ {:_id 51
+ :title "Advanced Destructuring"
+ :times-solved 0
+ :description "Here is an example of some more sophisticated destructuring."
+ :tags ["easy" "destructuring"]
+ :tests ["(= [1 2 [3 4 5] [1 2 3 4 5]] (let [[a b & c :as d] __] [a b c d]))"]})
+
+ (insert! :problems
+ {:_id 52
+ :title "Intro to Destructuring"
+ :times-solved 0
+ :description "Let bindings and function parameter lists support destructuring."
+ :tags ["easy" "destructuring"]
+ :tests ["(= [2 4] (let [[a b c d e f g] (range)] __))"]})))
+
+
+(doseq [{id :_id :keys [test secrets]}
+ (fetch :problems)]
+ (update! :problems
+ {:_id id}
+ {:$set {:test (concat test secrets) :secrets []}}))
View
7 src/foreclojure/login.clj
@@ -22,8 +22,7 @@
[:td (password-field :pwd)]]
[:tr
[:td]
- [:td (submit-button {:type "image" :src "/images/login.png"}
- "Log In")]]
+ [:td [:button {:type "submit"} "Log In"]]]
[:tr
[:td ]
[:td
@@ -52,7 +51,7 @@
[password-field :pwd "New password"]
[password-field :repeat-pwd "Repeat password"]])
[:tr
- [:td (submit-button "Reset now")]])]]))
+ [:td [:button {:type "submit"} "Reset now"]]])]]))
(defn do-update-password! [old-pwd new-pwd repeat-pwd]
(with-user [{:keys [user pwd]}]
@@ -79,7 +78,7 @@
(form-to [:post "/login/reset"]
(label :email "Email")
(text-field :email)
- (submit-button "Reset!"))]]])
+ [:button {:type "submit"} "Reset!"])]]])
(def pw-chars "abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVWXY1234567890")
View
22 src/foreclojure/problems.clj
@@ -3,7 +3,7 @@
[foreclojure.social :only [tweet-link gist!]]
[clojail core testers]
somnium.congomongo
- hiccup.form-helpers
+ (hiccup form-helpers page-helpers core)
[amalloy.utils.debug :only [?]]
compojure.core)
(:require [sandbar.stateful-session :as session]
@@ -26,22 +26,11 @@
:only [:_id :title :tags :times-solved]
:sort {:id 1})))
-(defn tweet-solution [id gist-url & [link-text]]
- (let [status-msg (str "Check out how I solved http://4clojure.com/problem/"
- id " - " gist-url " #clojure #4clojure")]
- (tweet-link status-msg link-text)))
-
(defn mark-completed [id code & [user]]
(let [user (or user (session/session-get :user))
- gist-url (gist! user id code)
- gist-link (if gist-url
- (str "<div class='share'>"
- "Share this "
- "<a href='" gist-url "'>solution</a>"
- " on " (tweet-solution id gist-url) "!"
- "</div>")
- (str "<div class='error'>Failed to create gist of "
- "your solution</div>"))
+ gist-link (html [:div.share
+ [:a.novisited {:href "/share/code"} "Share"]
+ " this solution with your friends!"])
message
(if user
@@ -51,6 +40,7 @@
(update! :problems {:_id id} {:$inc {:times-solved 1}}))
"Congratulations, you've solved the problem!")
"You've solved the problem! If you log in we can track your progress.")]
+ (session/session-put! :code [id code])
(flash-msg (str message " " gist-link) "/problems")))
(def restricted-list ['use 'require 'in-ns 'future 'agent 'send 'send-off 'pmap 'pcalls])
@@ -111,7 +101,7 @@
:code (session/flash-get :code))
(hidden-field :id id)
[:br]
- (submit-button {:type "image" :src "/images/run.png"} "Run"))]))
+ [:button.large {:type "submit"} "Run"])]))
(def-page problem-page []
[:div.congrats (session/flash-get :message)]
View
2  src/foreclojure/register.clj
@@ -17,7 +17,7 @@
[password-field :repeat-pwd "Repeat Password"]
[text-field :email "Email"]])
[:tr
- [:td (submit-button {:type "image" :src "/images/register.png"} "Register")]]]))
+ [:td [:button {:type "submit"} "Register"]]]]))
(defn do-register [user pwd repeat-pwd email]
(let [lower-user (.toLowerCase user)]
View
36 src/foreclojure/social.clj
@@ -1,7 +1,10 @@
(ns foreclojure.social
- (:use [foreclojure.utils])
- (:require [clj-github.gists :as gist])
- (:import (java.net URLEncoder)))
+ (:use foreclojure.utils
+ compojure.core
+ hiccup.page-helpers)
+ (:require [clj-github.gists :as gist]
+ [sandbar.stateful-session :as session])
+ (:import java.net.URLEncoder))
(defn tweet-link [status & [anchor-text]]
(str "<a href=\"http://twitter.com/home?status="
@@ -24,3 +27,30 @@
:repo
(str "https://gist.github.com/"))
(catch Throwable _ nil))))
+
+(defn tweet-solution [id gist-url & [link-text]]
+ (let [status-msg (str "Check out how I solved http://4clojure.com/problem/"
+ id " - " gist-url " #clojure #4clojure")]
+ (tweet-link status-msg link-text)))
+
+(def-page share-page []
+ (if-let [[id code] (session/session-get :code)]
+ (let [user (session/session-get :user)
+ gist-url (gist! user id code)
+ gist-link (if gist-url
+ [:div
+ [:div.code
+ [:h3 "Your Solution"]
+ [:pre code]]
+ [:br]
+ [:div.share
+ "Share this " (link-to gist-url "solution")
+ " on " (tweet-solution id gist-url) "?"]]
+ [:div.error
+ "Failed to create gist of your solution"])]
+ gist-link)
+ [:div.error
+ "Sorry...I don't remember you solving anything recently!"]))
+
+(defroutes social-routes
+ (GET "/share/code" [] (share-page)))
View
4 src/foreclojure/utils.clj
@@ -94,7 +94,9 @@
[:a#login {:href "/login"} "Login"]
[:a#register {:href "/register"} "Register"]])]]
[:div#content body]
- [:div#footer "The content on 4clojure.com is available under the EPL v 1.0 license." ]
+ [:div#footer
+ "The content on 4clojure.com is available under the EPL v 1.0 license."
+ [:a#contact {:href "mailto:team@4clojure.com"} "Contact us!"]]
(javascript-tag
" var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-22844856-1']);
Please sign in to comment.
Something went wrong with that request. Please try again.