diff options
| author | sostler <sbostler@gmail.com> | 2010-01-03 18:26:23 -0500 |
|---|---|---|
| committer | sostler <sbostler@gmail.com> | 2010-01-03 18:26:23 -0500 |
| commit | 4b51ea0eb70699285e1b6d6432b07722c793c57a (patch) | |
| tree | 17dcf5ccb1ce946b71de9209a23a3cc04cdf2355 | |
| parent | 75a590ec89a9b7afb070331a25069e75a33ec30b (diff) | |
Work checkin
| -rwxr-xr-x | src/site.clj | 107 | ||||
| -rwxr-xr-x | static/pichat.js | 7 | ||||
| -rwxr-xr-x | template/chat.st | 3 | ||||
| -rw-r--r-- | template/log.st | 26 | ||||
| -rwxr-xr-x | template/logged_dump.st | 3 | ||||
| -rwxr-xr-x | template/profile.st | 29 |
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$ + + $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$ + + $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$ + + $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> </p> + <span style="border: 2px solid blue; background-color: gray"> + $if(prev)$ + <a href="/u/$nick$/$prev$">PREV DUMPS</a> + $endif$ + + $if(dumps)$ + <a href="/u/$nick$/$next$">MORE DUMPS</a> + $endif$ + </span> + + <br><br> + <p> </p> <p><img src="broken.png" onerror="this.style.display='none'" /></p> - </div> + + </div> <div id="profile"> |
