summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsostler <sbostler@gmail.com>2010-01-03 18:26:23 -0500
committersostler <sbostler@gmail.com>2010-01-03 18:26:23 -0500
commit4b51ea0eb70699285e1b6d6432b07722c793c57a (patch)
tree17dcf5ccb1ce946b71de9209a23a3cc04cdf2355
parent75a590ec89a9b7afb070331a25069e75a33ec30b (diff)
Work checkin
-rwxr-xr-xsrc/site.clj107
-rwxr-xr-xstatic/pichat.js7
-rwxr-xr-xtemplate/chat.st3
-rw-r--r--template/log.st26
-rwxr-xr-xtemplate/logged_dump.st3
-rwxr-xr-xtemplate/profile.st29
6 files changed, 129 insertions, 46 deletions
diff --git a/src/site.clj b/src/site.clj
index 3f8fa48..dbd1432 100755
--- a/src/site.clj
+++ b/src/site.clj
@@ -112,8 +112,10 @@
([] (reverse (take 25 @messages))))
(defn process-user [u]
- {"nick" (u :nick)
- "avatar" (encode-html-entities (u :avatar))})
+ (if (u :avatar)
+ {"nick" (u :nick)
+ "avatar" (encode-html-entities (u :avatar))}
+ {"nick" (u :nick)}))
(defn prepare-user-list []
(map process-user (sort-by #(% :nick)
@@ -125,24 +127,32 @@
([since] {"users" (prepare-user-list)
"messages" (map process-message-for-json (new-messages since))}))
+(def dumps-per-page 20)
+
+(defn maybe-parse-int [s f]
+ (if s (Integer/parseInt s) f))
+
(defn fetch-messages-by-room
- ([room-id] (fetch-messages-by-room room-id 1))
- ([room-id offset]
+ ([room-id image-only] (fetch-messages-by-room room-id image-only 1))
+ ([room-id image-only offset]
(let [query (str "SELECT m.content, m.created_on, u.nick "
"FROM messages m, users u "
"WHERE room_id = ? AND m.user_id = u.user_id "
+ (if image-only "AND m.is_image = true " "")
"ORDER BY created_on DESC "
- "LIMIT 20 OFFSET ?")]
+ "LIMIT " dumps-per-page " OFFSET ?")]
(do-select [query room-id offset]))))
-(defn fetch-messages-by-nick [nick image-only]
- (let [query (str "SELECT m.content, m.created_on, u.nick "
- "FROM messages m, users u "
- "WHERE m.user_id = u.user_id AND u.nick = ? "
- (if image-only "AND m.is_image = true " "")
- "ORDER BY created_on DESC "
- "LIMIT 20")]
- (do-select [query nick])))
+(defn fetch-messages-by-nick
+ ([nick image-only] (fetch-messages-by-nick nick image-only 0))
+ ([nick image-only offset]
+ (let [query (str "SELECT m.content, m.created_on, u.nick "
+ "FROM messages m, users u "
+ "WHERE m.user_id = u.user_id AND u.nick = ? "
+ (if image-only "AND m.is_image = true " "")
+ "ORDER BY created_on DESC "
+ "LIMIT " dumps-per-page " OFFSET ?")]
+ (do-select [query nick offset]))))
;; Templates
@@ -205,20 +215,23 @@
(defn non-empty-string? [s]
(and s (> (count s) 0)))
-(defn profile [session profile-nick]
+(defn profile [session profile-nick offset]
(let [user-info (fetch-nick profile-nick)]
(if user-info
(let [nick (session :nick)
- is-home (and nick (= nick profile-nick))
- has-avatar (non-empty-string? (user-info :avatar))
- dumps (fetch-messages-by-nick profile-nick true)
+ is-home (and nick (= nick profile-nick))
+ has-avatar (non-empty-string? (user-info :avatar))
+ offset (maybe-parse-int offset 0)
+ dump-offset (* offset dumps-per-page)
+ dumps (fetch-messages-by-nick profile-nick true dump-offset)
st (fetch-template "profile" session)]
+
(do
(.setAttribute st "is_home" is-home)
(doseq [a [:nick :avatar :contact :bio]]
(let [v (user-info a)]
(.setAttribute st (name a)
- (if (non-empty-string? v) (encode-html-entities v) nil))))
+ (if (non-empty-string? v) (encode-html-entities v)))))
(.setAttribute st "dumps"
(to-array (map process-message-for-output dumps)))
(.toString st)))
@@ -253,7 +266,7 @@
st (fetch-template "chat" session)
message-list (to-array
(map process-message-for-output
- (reverse (fetch-messages-by-room 1))))]
+ (reverse (fetch-messages-by-room 1 false))))]
(if nick
(dosync
(alter users assoc nick (user-struct-from-session session))))
@@ -282,24 +295,25 @@
(resp-error "NOT_IN_CHAT"))))
;; http://snippets.dzone.com/posts/show/6995
-(def single-url-regex #"^((http\:\/\/|https\:\/\/|ftp\:\/\/)|(www\.))+(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))$")
-(def pic-regex #"\.(jpg|jpeg|png|gif|bmp)")
+(def single-url-regex #"(?i)^((http\:\/\/|https\:\/\/|ftp\:\/\/)|(www\.))+(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$")
+(def pic-regex #"(?i)\.(jpg|jpeg|png|gif|bmp)$")
+
+(defn strip-params [s]
+ (.replaceFirst s "\\?.*$" ""))
(defn is-image? [content]
- ; TODO: trim content, strip params
- (let [lower-content (.toLowerCase content)]
- (if (and (re-matches single-url-regex lower-content)
- (re-matches pic-regex lower-content))
- true false)))
+ (if (and (re-find single-url-regex content)
+ (re-find pic-regex (strip-params content)))
+ true false))
(defn msg-transaction [nick msg]
(dosync
(and (contains? (ensure users) nick)
- (do (alter messages (swap cons) msg)
- true))))
+ (alter messages (swap cons) msg))))
+
(defn msg-db [user-id room-id msg]
- (let [content (msg :content)
+ (let [content (.trim (msg :content))
is-image (is-image? content)]
(with-connection db
(insert-values :messages
@@ -320,14 +334,19 @@
;; Chat Log
-(defn maybe-parse-int [s f]
- (if s (Integer/parseInt s) f))
+; TODO: Optimize log counts
-(defn log [session params]
+(defn log [session offset]
(let [st (fetch-template "log" session)
- offset (maybe-parse-int (params :offset) 1)
+ offset (maybe-parse-int offset 0)
+ dump-offset (* offset dumps-per-page)
dumps (to-array (map process-message-for-output
- (fetch-messages-by-room 1 offset)))]
+ (fetch-messages-by-room 1 true dump-offset)))
+ more-dumps true]
+ (if more-dumps
+ (.setAttribute st "next" (inc offset)))
+ (if (not= offset 0)
+ (.setAttribute st "prev" (max (dec offset) 0)))
(.setAttribute st "dumps" dumps)
(.toString st)))
@@ -336,21 +355,31 @@
(defn upload [session params]
"TODO")
+;; Compojure Routes
+
+(defn no-cache [resp]
+ [{:headers {"Cache-Control" "no-cache, no-store, max-age=0, must-revalidate"}}
+ resp])
+
(defroutes pichat
- (GET "/" (landing session))
+ (GET "/" (no-cache (landing session)))
(GET "/static/*" (or (serve-file "static" (params :*))
:next))
(GET "/favicon.ico" (serve-file "static" "favicon.ico"))
- (GET "/u/:nick" (profile session (-> request :route-params :nick)))
+ (GET "/u/:nick" (profile session (-> request :route-params :nick) "0"))
+ (GET "/u/:nick/:offset" (profile session
+ (-> request :route-params :nick)
+ (-> request :route-params :offset)))
(GET "/update-profile" (update-profile session params))
(GET "/login" (login session params))
(GET "/logout" (logout session))
(GET "/register" (serve-file "static" "register.html"))
(GET "/submit-registration" (register session params))
- (GET "/chat" (chat session))
+ (GET "/chat" (no-cache (chat session)))
(GET "/refresh" (refresh session))
(GET "/msg" (msg session params))
- (GET "/log" (log session params))
+ (GET "/log" (log session "0"))
+ (GET "/log/:offset" (log session (-> request :route-params :offset)))
(GET "/upload" (upload session))
(ANY "*" [404 "Page not found"]))
@@ -361,7 +390,7 @@
; Load messages from database
(dosync
- (ref-set messages (fetch-messages-by-room 1)))
+ (ref-set messages (fetch-messages-by-room 1 false)))
(run-server {:port 8080}
"/*" (servlet pichat))
diff --git a/static/pichat.js b/static/pichat.js
index 435dc0d..81882fe 100755
--- a/static/pichat.js
+++ b/static/pichat.js
@@ -35,9 +35,14 @@ function buildMessageDiv(msg) {
}
function buildUserDiv(user) {
- return '<div class="username"><a href="/u/' + escapeHtml(user.nick) + '">' +
+ if (user.avatar) {
+ return '<div class="username"><a href="/u/' + escapeHtml(user.nick) + '">' +
'<img src="' + user.avatar + '" width="50" height="50">' +
escapeHtml(user.nick) + '</a></div>';
+ } else {
+ return '<div class="username"><a href="/u/' + escapeHtml(user.nick) + '">' +
+ escapeHtml(user.nick) + '</a></div>';
+ }
}
function handleMsgError(resp) {
diff --git a/template/chat.st b/template/chat.st
index 52cbfbc..b9c88b4 100755
--- a/template/chat.st
+++ b/template/chat.st
@@ -20,7 +20,8 @@
<div id="userList">
$users: { u |
<div class="username"><a href="/u/$u.nick$">
- <img src="$u.avatar$" width="50" height="50">$u.nick$</a><br>
+ $if(u.avatar)$<img src="$u.avatar$" width="50" height="50">$endif$
+ $u.nick$</a><br>
</div>
}$
</div>
diff --git a/template/log.st b/template/log.st
index 6120032..0fbacaa 100644
--- a/template/log.st
+++ b/template/log.st
@@ -14,8 +14,32 @@
<body>
$banner()$
<h2>Log</h2>
+
+ <div style="text-align: right;">
+ $if(prev)$
+ <a href="/log/$prev$">PREV DUMPS</a>
+ $endif$
+ &nbsp;&nbsp;&nbsp;
+ $if(dumps)$
+ <a href="/log/$next$">MORE DUMPS</a>
+ $endif$
+ </div>
+
+ $if(dumps)$
$dumps: { d | $logged_dump(dump=d)$ }$
+ $else$
+ No dumps!
+ $endif$
+
+ <div style="text-align: right;">
+ $if(prev)$
+ <a href="/log/$prev$">PREV DUMPS</a>
+ $endif$
+ &nbsp;&nbsp;&nbsp;
+ $if(dumps)$
+ <a href="/log/$next$">MORE DUMPS</a>
+ $endif$
+ </div>
- <a href="/log?offset=$next$">MORE DUMPS</a>
</body>
</html>
diff --git a/template/logged_dump.st b/template/logged_dump.st
index 706f24b..86e23fc 100755
--- a/template/logged_dump.st
+++ b/template/logged_dump.st
@@ -31,8 +31,7 @@ img{
}
</style>
<div class="logged-dump">
-
- <div>$dump.created_on$</div>
+ <div>$dump.created_on$ -- by <a href="/u/$dump.nick$">$dump.nick$</a></div>
<div class="content">$dump.content$</div>
<hr />
</div>
diff --git a/template/profile.st b/template/profile.st
index 5f77c68..45dbb32 100755
--- a/template/profile.st
+++ b/template/profile.st
@@ -17,7 +17,19 @@
<div id="log">
<div id="loghead">
$nick$'s log
- </div><div id="posts">
+ </div>
+ <br>
+ <div style="text-align: left;">
+ $if(prev)$
+ <a href="/u/$nick$/$prev$">PREV DUMPS</a>
+ $endif$
+ &nbsp;&nbsp;&nbsp;
+ $if(dumps)$
+ <a href="/u/$nick$/$next$">MORE DUMPS</a>
+ $endif$
+ </div>
+
+ <div id="posts">
$if(dumps)$
$dumps:{ d | $logged_dump(dump=d)$ }$
@@ -27,12 +39,25 @@
$endif$
<p>&nbsp;</p>
+ <span style="border: 2px solid blue; background-color: gray">
+ $if(prev)$
+ <a href="/u/$nick$/$prev$">PREV DUMPS</a>
+ $endif$
+ &nbsp;&nbsp;&nbsp;
+ $if(dumps)$
+ <a href="/u/$nick$/$next$">MORE DUMPS</a>
+ $endif$
+ </span>
+
+ <br><br>
+
<p>&nbsp;</p>
<p><img
src="broken.png"
onerror="this.style.display='none'"
/></p>
- </div>
+
+ </div>
<div id="profile">