diff options
Diffstat (limited to 'src/site.clj')
| -rwxr-xr-x | src/site.clj | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/site.clj b/src/site.clj new file mode 100755 index 0000000..33b1bb3 --- /dev/null +++ b/src/site.clj @@ -0,0 +1,71 @@ +; site.clj
+
+(ns pichat
+ (:import java.lang.System)
+ (:use compojure
+ clojure.contrib.json.write))
+
+(defstruct user-struct :nick :last-seen)
+(defstruct message-struct :nick :content :timestamp)
+
+(def users (ref {}))
+(def messages (ref []))
+
+(defn resp-error [message]
+ {:status 400 :headers {} :body message})
+
+(defn resp-success [message]
+ {:status 200 :headers {} :body (json-str message)})
+
+(defn join-success [nick]
+ (alter users assoc nick (struct user-struct nick (System/currentTimeMillis)))
+ (let [users (keys @users)
+ messages (take 20 @messages)
+ data {"users" users "messages" messages}]
+ [(session-assoc :nick nick)
+ (resp-success data)]))
+
+(defn try-join [params]
+ (let [nick (params :nick)]
+ (dosync
+ (if (contains? @users nick)
+ (resp-error "NICK_TAKEN")
+ (join-success nick)))))
+
+(defn new-messages [since]
+ (reverse (take-while (fn [m] (> (m :timestamp) since)) @messages)))
+
+(defn refresh [nick]
+ (dosync
+ (let [last-seen (get-in @users [nick :last-seen])]
+ (alter users assoc-in [nick :last-seen] (System/currentTimeMillis))
+ (resp-success {"messages" (new-messages last-seen)}))))
+
+(defn swap [f]
+ (fn [& more] (apply f (reverse more))))
+
+(defn msg [session params]
+ (dosync
+ (let [nick (session :nick)
+ content (params :content)
+ msg (struct message-struct nick content (System/currentTimeMillis))]
+ (if (contains? @users nick)
+ (do (alter messages (swap cons) msg)
+ (resp-success "OK"))
+ (resp-error "UNKNOWN_USER")))))
+
+(defroutes pichat
+ (GET "/" (serve-file "static" "index.html"))
+ (GET "/static/*" (or (serve-file "static" (params :*))
+ :next))
+ (GET "/join" (try-join params))
+ (GET "/refresh" (refresh (session :nick)))
+ (GET "/msg" (msg session params))
+ (ANY "*" [404 "Page not found"]))
+
+(decorate pichat
+ (with-mimetypes)
+ (with-session {:type :memory, :expires (* 60 60)}))
+
+(run-server {:port 8080}
+ "/*" (servlet pichat))
|
