diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/image_utils.clj | 3 | ||||
| -rwxr-xr-x | src/site.clj | 138 |
2 files changed, 95 insertions, 46 deletions
diff --git a/src/image_utils.clj b/src/image_utils.clj new file mode 100644 index 0000000..638cd05 --- /dev/null +++ b/src/image_utils.clj @@ -0,0 +1,3 @@ +(ns image-utils + (:import javax.imageio.ImageIO)) + diff --git a/src/site.clj b/src/site.clj index c36f1ae..7b75b71 100755 --- a/src/site.clj +++ b/src/site.clj @@ -14,6 +14,7 @@ clojure.contrib.sql compojure cookie-login + image-utils )) (let [db-host "localhost" @@ -63,9 +64,11 @@ "http://localhost:8080")) (def *image-directory* "images") +(def *avatar-directory* "avatars") -; Create image directory if it doesn't exist. +; Create image directories if they don't exist. (.mkdir (new File *image-directory*)) +(.mkdir (new File *avatar-directory*)) ;; Utils @@ -333,41 +336,48 @@ ;; Profile (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)) - offset (maybe-parse-int offset 0) - dump-offset (* offset *dumps-per-page*) - dumps (fetch-messages-by-nick profile-nick true dump-offset) - dump-count (count-messages-by-nick profile-nick true) - 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) (escape-html v))))) - (.setAttribute st "dumps" - (to-array (map process-message-for-output dumps))) - (if (< (+ dump-offset *dumps-per-page*) dump-count) - (.setAttribute st "next" (inc offset))) - (if (not= offset 0) - (.setAttribute st "prev" (max (dec offset) 0))) + (if-let [user-info (fetch-nick profile-nick)] + (let [nick (session :nick) + 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) + dump-count (count-messages-by-nick profile-nick true) + 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) (escape-html v))))) + (.setAttribute st "dumps" + (to-array (map process-message-for-output dumps))) + (if (< (+ dump-offset *dumps-per-page*) dump-count) + (.setAttribute st "next" (inc offset))) + (if (not= offset 0) + (.setAttribute st "prev" (max (dec offset) 0))) (.toString st))) - (resp-error "NO_USER")))) + (resp-error "NO_USER"))) + + +;; TODO: update chat w/ new avatar +(defn do-update-avatar [session params] + nil) + +(defn do-update-profile [user-id attr val] + (with-connection db + (update-values "users" ["user_id = ?" user-id] {attr val}))) (defn update-profile [session params] (let [user-id (session :user_id) attr (params :attr) val (params :val) attr-set #{"avatar" "contact" "bio"}] - (if (and user-id attr val + (if (and user-id attr val (contains? attr-set attr)) (do - (with-connection db - (update-values "users" ["user_id = ?" user-id] {attr val})) + (do-update-profile attr val) (if (= attr "avatar") [(session-assoc :avatar val) "OK"] "OK")) @@ -415,11 +425,12 @@ nick (session :nick) users (room :users)] (if nick - (if (contains? @users nick) - (alter users assoc-in [nick :last-seen] now) - (alter (room :users) assoc nick (user-struct-from-session session)))) - (resp-success (assoc (updates room since) - :timestamp now))))) + (if-let [user-info (@users nick)] + ; Incorporate avatar updates + (commute users assoc nick (merge user-info {:last-seen now + :avatar (user-info :avatar)})) + (commute (room :users) assoc nick (user-struct-from-session session)))) + (resp-success (assoc (updates room since) :timestamp now))))) (defn validated-refresh [session params] (let [room-key (params :room) @@ -525,32 +536,64 @@ ;; Upload +(def *avatar-dimensions* [50 50]) + +(defn is-image-file? [path] + true) + (defn format-filename [s] (let [spaceless (.replace s \space \-) subbed (re-gsub #"[^\w.-]" "" spaceless)] (str (System/currentTimeMillis) "-" subbed))) -(defn image-url-from-file [f] - (str-join "/" [*server-url* "images" (.getName f)])) +(defn image-url-from-file [d f] + (str-join "/" [*server-url* d (.getName f)])) + (defn do-upload [session image room] (let [filename (format-filename (:filename image)) dest (File. (rel-join *image-directory* filename)) - url (image-url-from-file dest) + url (image-url-from-file "images" dest) msg-id (msg-db (session :user_id) (room :room_id) url) - now (new Date) - msg (struct message-struct (session :nick) url now msg-id)] - (dosync - (add-message msg room)) - (copy (:tempfile image) dest) - [200 url])) + msg (struct message-struct (session :nick) url (new Date) msg-id)] + (do + (dosync + (add-message msg room)) + (copy (:tempfile image) dest) + (resp-success url)))) (defn upload [session params] (let [room-key (params :room) - nick (session :nick)] + nick (session :nick) + image (params :image)] (cond (not nick) [200 "NOT_LOGGED_IN"] + (not image) [200 "INVALID_REQUEST"] + (not (is-image-file? (image :filename))) [200 "INVALID_IMAGE"] (not (validate-room-access room-key session)) [200 "UNKNOWN_ROOM"] - :else (do-upload session (:image params) (@rooms room-key))))) + :else (do-upload session image (@rooms room-key))))) + +(defn copy-and-resize [image dest] + ; TODO: resize + (copy image dest)) + +;; NOTE -- Upload responses arent JSON-evaluated +(defn do-upload-avatar [session image] + (let [filename (format-filename (:filename image)) + dest (File. (rel-join *avatar-directory* filename)) + url (image-url-from-file "avatars" dest)] + (do + (copy-and-resize (:tempfile image) dest) + (do-update-profile (session :user_id) "avatar" url) + [(session-assoc :avatar url) + [200 url]]))) + +(defn upload-avatar [session params] + (let [image (params :image)] + (cond (not image) [200 "INVALID_REQUEST"] + (not (session :nick)) [200 "NOT_LOGGED_IN"] + (not (is-image-file? (image :filename))) [200 "INVALID_IMAGE"] + :else (do-upload-avatar session image)))) + ;; 404 (defn unknown-page [params] @@ -573,7 +616,8 @@ (defroutes static (GET "/static/*" (serve-static "static" (params :*))) - (GET "/images/*" (serve-static *image-directory* (params :*)))) + (GET "/images/*" (serve-static *image-directory* (params :*))) + (GET "/avatars/*" (serve-static *avatar-directory* (params :*)))) (defroutes pichat (GET "/" (no-cache (landing session))) @@ -605,7 +649,8 @@ (ANY "*" (unknown-page params))) (defroutes multipart - (POST "/upload" (upload session params))) + (POST "/upload/message" (upload session params)) + (POST "/upload/avatar" (upload-avatar session params))) ;; Add jpeg to list (def mimetypes @@ -647,7 +692,8 @@ (run-server {:port 8080} "/static/*" (servlet static) "/images/*" (servlet static) - "/upload" (servlet multipart) + "/avatars/*" (servlet static) + "/upload/*" (servlet multipart) "/*" (servlet pichat)) (send-off flusher flush!)
\ No newline at end of file |
