diff options
| author | sostler <sbostler@gmail.com> | 2009-12-18 21:56:51 -0500 |
|---|---|---|
| committer | sostler <sbostler@gmail.com> | 2009-12-18 21:56:51 -0500 |
| commit | 704efb06cd424de7411f198bc4c6ce6b99a9dcbe (patch) | |
| tree | 076c19e5c97264948f4d94f32b6869c5dd396f60 | |
| parent | 5a8312ca25868679df1acb3b3fc208482460ee0e (diff) | |
Checkin before leaving
| -rwxr-xr-x | db/0-create.psql | 4 | ||||
| -rw-r--r-- | src/site.clj | 48 | ||||
| -rwxr-xr-x | static/home.js | 2 | ||||
| -rw-r--r-- | static/index.html | 354 | ||||
| -rwxr-xr-x | static/pichat.js | 10 | ||||
| -rwxr-xr-x | template/chat.st | 4 |
6 files changed, 217 insertions, 205 deletions
diff --git a/db/0-create.psql b/db/0-create.psql index 35278c7..5bd8622 100755 --- a/db/0-create.psql +++ b/db/0-create.psql @@ -4,6 +4,7 @@ CREATE TABLE users ( hash text NOT NULL, email text NOT NULL, created_on timestamp NOT NULL DEFAULT now(), + avatar text, contact text, bio text ); @@ -19,7 +20,8 @@ CREATE TABLE messages ( user_id integer NOT NULL REFERENCES users, room_id integer NOT NULL REFERENCES rooms, content text NOT NULL, - created_on timestamp NOT NULL DEFAULT now() + created_on timestamp NOT NULL DEFAULT now(), + is_image bool ); CREATE TABLE user_session ( diff --git a/src/site.clj b/src/site.clj index cc7dfd3..7fdd5ed 100644 --- a/src/site.clj +++ b/src/site.clj @@ -1,5 +1,3 @@ -; site.clj - (ns pichat (:import java.lang.System java.text.SimpleDateFormat @@ -25,7 +23,7 @@ (.setRefreshInterval template-group 3) (defstruct user-struct :user-id :nick :last-seen) -(defstruct message-struct :nick :avatar :content :created_on) +(defstruct message-struct :nick :content :created_on) (def users (ref {})) (def messages (ref [])) @@ -101,7 +99,6 @@ (defn process-message-for-output [d] (let [avatar (d :avatar)] {"nick" (encode-html-entities (d :nick)) - "avatar" (if avatar (encode-html-entities avatar) nil) "created_on" (.format formatter (d :created_on)) "content" (encode-html-entities (d :content))})) @@ -118,17 +115,18 @@ "messages" (map process-message-for-json (new-messages since))})) (defn fetch-messages-by-room [room-id] - (let [query (str "SELECT m.content, m.created_on, u.nick, u.avatar " + (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 " "ORDER BY created_on DESC " "LIMIT 20")] (do-select [query room-id]))) -(defn fetch-messages-by-nick [nick] - (let [query (str "SELECT m.content, m.created_on, u.nick, u.avatar " +(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]))) @@ -151,7 +149,7 @@ (defn landing [session] (let [nick (session :nick)] (if nick - (redirect-to (str "/u/" nick)) + (redirect-to "/chat") (serve-file "static" "index.html")))) (defn login [session params] @@ -198,7 +196,7 @@ (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) + dumps (fetch-messages-by-nick profile-nick true) st (fetch-template "profile" session)] (do (.setAttribute st "is_home" is-home) @@ -264,26 +262,36 @@ ; TODO: session should store room-id of anon. users (resp-error "NOT_IN_CHAT")))) +;; http://snippets.dzone.com/posts/show/6995 +(def url-regex #"((http\:\/\/|https\:\/\/|ftp\:\/\/)|(www\.))+(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?") +(def pic-regex #"^.*\.(jpg|jpeg|png|gif|bmp)$") + +(defn is-image? [content] + (let [lower-content (.toLowerCase content)] + (if (and (re-matches url-regex lower-content) + (re-matches pic-regex lower-content)) + true false))) + (defn msg-transaction [nick msg] (dosync - (if (contains? (ensure users) nick) - (do (alter messages (swap cons) msg) - true) - false))) + (and (contains? (ensure users) nick) + (do (alter messages (swap cons) msg) + true)))) (defn msg-db [user-id room-id msg] - (with-connection db - (insert-values :messages - [:user_id :room_id :content] - [user-id room-id (msg :content)]))) + (let [content (msg :content) + is-image (is-image? content)] + (with-connection db + (insert-values :messages + [:user_id :room_id :content :is_image] + [user-id room-id content is-image])))) (defn msg [session params] (let [user-id (session :user-id) nick (session :nick) - avatar (session :avatar) - content (params :content) + content (.trim (params :content)) now (new Date) - msg (struct message-struct nick avatar content now)] + msg (struct message-struct nick content now)] (if (msg-transaction nick msg) (do (msg-db user-id 1 msg) diff --git a/static/home.js b/static/home.js index 5857368..8416703 100755 --- a/static/home.js +++ b/static/home.js @@ -15,7 +15,7 @@ function login() { var hash = hex_sha1(nick + '$' + password + '$dumpfm'); var onSuccess = function(json) { - location.href = "u/" + nick; + location.href = "/chat"; }; var onError = function(resp, textStatus, errorThrown) { diff --git a/static/index.html b/static/index.html index fb5224e..0ccb121 100644 --- a/static/index.html +++ b/static/index.html @@ -1,196 +1,193 @@ -<head> +<html> + <head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> <script type="text/javascript" src="static/sha1.js"></script> <script type="text/javascript" src="static/home.js"></script> - <script type="text/javascript" src="static/background.js"></script> + <script type="text/javascript" src="static/background.js"></script> <script> $(document).ready(initHome); </script> <link rel="stylesheet" type="text/css" href="static/reset.css"> - <link rel="shortcut icon" href="static/favicon.ico"> - - <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"></head> -<style type="text/css"> -<!-- -.white a:link { - text-decoration: none; - text-shadow: -1px 1px 1px #ccc; - color: #504F61; -} -.white a:visited { - text-decoration: none; - text-shadow: -1px 1px 1px #ccc; - color: #504F61; -} -.white a:hover { - text-decoration: none; - text-shadow: -1px 1px 1px #ccc; - background-color:#e3e3e3; - - color: #fff; -} -.white a:active { - text-decoration: none; - text-shadow: -1px 1px 1px #ccc; - color: #504F61; -} -#header7{ - background-color:#666; - background-image:url(/static/dblue2.png); - background-attachment:fixed; - margin: 0px auto -1px auto; - top: 0px; - width:100%; - left: 0px; - height: 60px; -} -#bar7{ - top:32px; - position:absolute; - font-family: Arial, Helvetica, sans-serif; - font-weight: bold; - width: 500px; - font-size: 20px; - left: 170px; - margin-left: 10%; - margin-right: 8%; - letter-spacing: -1px; - z-index: 999; -} -#main { - background-position:center; - width:500px; - margin: 0px auto -1px auto; - top:150px; - height:380px; - z-index:2; - opacity:0.9; - border-top-left-radius:10px; - border-top-right-radius:10px; - -webkit-border-top-left-radius:10px; - -webkit-border-top-right-radius:10px; - -moz-border-radius-topleft:10px; - -moz-border-radius-topright:10px; - border-bottom-left-radius:10px; - border-bottom-right-radius:10px; - -webkit-border-bottom-left-radius:10px; - -webkit-border-bottom-right-radius:10px; - -moz-border-radius-bottomleft:10px; - -moz-border-radius-bottomright:10px; - border:solid 4px #F5F5F5; - position: relative; - background-color: #FFF; - background-position:center; - background-repeat:no-repeat; -} -#logout7{ - top:5px; - position:relative; - font-size:13px; - margin-right: 10px; - float:right; - z-index: 999; - font-family: "Times New Roman", Times, serif; -} -#logo7{ - top:20px; - margin-left: 10%; - margin-right: 10%; - z-index:1000; - float:left; -} -#rapper7{ - top: 0px; - left:0px; - position:absolute; - width: 100%; - height: 78px; - z-index: 1000; -} -#bottombar{ - top: 69px; - left:0px; - position:absolute; - width: 100%; - height: 20px; - z-index: 1000; -} -p { - font-family: Arial, Helvetica, sans-serif; - font-size: 24px; -} -td { - font-family: Arial, Helvetica, sans-serif; - letter-spacing:-1px; - font-size: 12px; - color: #000000; -} -.btnav { border: 0px #000000 solid;} -body { - - background-color:#e3e3e3; - - background-image:url(static/brokenlink.gif); - background-position:center; - - background-repeat:no-repeat; - overflow:hidden; -} -.submit { - - - text-shadow: -1px 1px 1px #ccc; - - font-size:15px; -} -.feild { - height:40px; - width:300px; - border:3px #ccc; - background:#e3e3e3; - margin:10px; - font-size:30px; -} -.txt { - font-family:Arial, Helvetica, sans-serif; - font-size:12px; - text-shadow: -1px 1px 1px #ccc; -} - .line { - font-family:Arial, Helvetica, sans-serif; - - letter-spacing: -1px; - color:#000; - font-size:18px; - -} + <link rel="shortcut icon" href="static/favicon.ico"> + <style type="text/css"> + <!-- + .white a:link { + text-decoration: none; + text-shadow: -1px 1px 1px #ccc; + color: #504F61; + } + .white a:visited { + text-decoration: none; + text-shadow: -1px 1px 1px #ccc; + color: #504F61; + } + .white a:hover { + text-decoration: none; + text-shadow: -1px 1px 1px #ccc; + background-color:#e3e3e3; + + color: #fff; + } + .white a:active { + text-decoration: none; + text-shadow: -1px 1px 1px #ccc; + color: #504F61; + } + #header7{ + background-color:#666; + background-image:url(/static/dblue2.png); + background-attachment:fixed; + margin: 0px auto -1px auto; + top: 0px; + width:100%; + left: 0px; + height: 60px; + } + #bar7{ + top:32px; + position:absolute; + font-family: Arial, Helvetica, sans-serif; + font-weight: bold; + width: 500px; + font-size: 20px; + left: 170px; + margin-left: 10%; + margin-right: 8%; + letter-spacing: -1px; + z-index: 999; + } + #main { + background-position:center; + width:500px; + margin: 0px auto -1px auto; + top:150px; + height:380px; + z-index:2; + opacity:0.9; + border-top-left-radius:10px; + border-top-right-radius:10px; + -webkit-border-top-left-radius:10px; + -webkit-border-top-right-radius:10px; + -moz-border-radius-topleft:10px; + -moz-border-radius-topright:10px; + border-bottom-left-radius:10px; + border-bottom-right-radius:10px; + -webkit-border-bottom-left-radius:10px; + -webkit-border-bottom-right-radius:10px; + -moz-border-radius-bottomleft:10px; + -moz-border-radius-bottomright:10px; + border:solid 4px #F5F5F5; + position: relative; + background-color: #FFF; + background-position:center; + background-repeat:no-repeat; + } + #logout7{ + top:5px; + position:relative; + font-size:13px; + margin-right: 10px; + float:right; + z-index: 999; + font-family: "Times New Roman", Times, serif; + } + #logo7{ + top:20px; + margin-left: 10%; + margin-right: 10%; + z-index:1000; + float:left; + } + #rapper7{ + top: 0px; + left:0px; + position:absolute; + width: 100%; + height: 78px; + z-index: 1000; + } + #bottombar{ + top: 69px; + left:0px; + position:absolute; + width: 100%; + height: 20px; + z-index: 1000; + } + p { + font-family: Arial, Helvetica, sans-serif; + font-size: 24px; + } + td { + font-family: Arial, Helvetica, sans-serif; + letter-spacing:-1px; + font-size: 12px; + color: #000000; + } + .btnav { border: 0px #000000 solid;} + body { + + background-color:#e3e3e3; + + background-image:url(static/brokenlink.gif); + background-position:center; + + background-repeat:no-repeat; + overflow:hidden; + } + .submit { + + + text-shadow: -1px 1px 1px #ccc; + + font-size:15px; + } + .feild { + height:40px; + width:300px; + border:3px #ccc; + background:#e3e3e3; + margin:10px; + font-size:30px; + } + .txt { + font-family:Arial, Helvetica, sans-serif; + font-size:12px; + text-shadow: -1px 1px 1px #ccc; + } + .line { + font-family:Arial, Helvetica, sans-serif; + + letter-spacing: -1px; + color:#000; + font-size:18px; + + } ---> -</style> - -<body> -<div id="rapper7"> -<div id="header7"> - - <div id="bottombar"></div> + --> + </style> + <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> + </head> + <body> + <div id="rapper7"> + <div id="header7"> + <div id="bottombar"></div> <div align="center"> <p><img src="static/wordlogo2.gif" width="500" height="239"><br> </p> </div> - - <div class="white"></div> - <div align="center"><br /> + <div class="white"></div> + <div align="center"><br /></div> + </div> </div> </div> -</div> -</div> <div id="main" align="center"> - <p align="center"><br /> + <p align="center"><br /> </p> <div id="registerbox"> <p align="right" class="line"> </p> @@ -210,18 +207,19 @@ body { <p align="center"> </p> <p> </p> <div align="right" class="txt"> - <div align="center"><span class="txt"><a href="http://dump.fm/register" class="txt">Register</a></span></div> + <div align="center"><span class="txt"><a href="/register" class="txt">Register</a></span></div> </div> <div align="center"></div> </div> </div> - </div></div> +</div></div> </div> - </h1> - </div> +</h1> +</div> </div> <div style="position: fixed; bottom: 3px; right: 3px; font-size: xx-small; z-index: 10;"><button onclick="getBackground()" title="Rotate background image" style="font-size: xx-small;">+</button></div> -</body>
\ No newline at end of file +</body> +</html> diff --git a/static/pichat.js b/static/pichat.js index 826bcba..d489bba 100755 --- a/static/pichat.js +++ b/static/pichat.js @@ -15,7 +15,8 @@ function escapeHtml(txt) { } function buildUserDiv(user) { - return '<div>' + escapeHtml(user) + '</div>'; + var nick = escapeHtml(user); + return '<div><a href="/u/' + nick + '">' + nick + '</a></div>'; } // http://stackoverflow.com/questions/37684/replace-url-with-html-links-javascript @@ -29,6 +30,7 @@ var URLRegex = /((http\:\/\/|https\:\/\/|ftp\:\/\/)|(www\.))+(\w+:{0,1}\w*@)?(\S var PicRegex = /\.(jpg|jpeg|png|gif|bmp)$/i; function buildMsgContent(content) { + content = $.trim(content); var match = URLRegex.exec(content) if (match && PicRegex.test(match[0])) { return '<a href="' + match[0] + '" target="_blank">' @@ -39,7 +41,8 @@ function buildMsgContent(content) { } function buildMessageDiv(msg) { - return '<div class="msgDiv"><b>' + escapeHtml(msg.nick) + ': </b>' + var nick = escapeHtml(msg.nick); + return '<div class="msgDiv"><b><a href="/u/' + nick + ' ">' + nick + '</a>: </b>' + buildMsgContent(msg.content) + '</div>'; } @@ -150,6 +153,7 @@ function initProfile() { }); var onSubmit = function(original_element, edit, old) { + edit = $.trim(edit); if (edit == old) { return old }; // MAJOR TODO: Prevent entering script tags if (original_element == 'avatar' && edit.indexOf("<") != -1) { @@ -161,7 +165,7 @@ function initProfile() { url: "/update-profile", data: { 'attr': original_element, 'val': edit } }); - if (original_element == 'avatar') { + if (original_element == 'avatar') { var s = '<img id="avatarPic" src="' + edit + '" width="150" />'; $('#avatarPic').replaceWith(s); } diff --git a/template/chat.st b/template/chat.st index 3a8f79f..3a4cbfd 100755 --- a/template/chat.st +++ b/template/chat.st @@ -28,14 +28,14 @@ </div> <div id="userList"> $users: { u | - <div>$u$</div> + <div><a href="/u/$u$">$u$</a></div> }$ </div> <div id="messagePane"> <div id="messageList"> $messages: { m | - <div class="msgDiv oldmsg"><b>$m.nick$: </b> + <div class="msgDiv oldmsg"><b><a href="/u/$m.nick$">$m.nick$</a>: </b> <span class="content">$m.content$<span></div> }$ <hr /> |
