diff options
Diffstat (limited to 'src/site.clj')
| -rw-r--r-- | src/site.clj | 271 |
1 files changed, 167 insertions, 104 deletions
diff --git a/src/site.clj b/src/site.clj index dc57748..c2d86fa 100644 --- a/src/site.clj +++ b/src/site.clj @@ -10,7 +10,7 @@ clojure.contrib.command-line clojure.contrib.duck-streams clojure.contrib.json.write - clojure.contrib.seq-utils + clojure.contrib.seq-utils clojure.contrib.sql clojure.contrib.str-utils clojure.contrib.def @@ -19,7 +19,7 @@ admin compojure email - fame + fame utils cookie-login session-sweeper @@ -415,12 +415,17 @@ FROM users u ;; Profile -(defn take-random-image [content] - (let [imgs (filter is-image? (.split content " "))] - (if (empty? imgs) nil (rand-elt imgs)))) +(defn take-images [content] + (filter is-image? (.split content " "))) -(defn msg-transformer [key f] - (fn [msg] (assoc msg key (f (msg key))))) +(defn pull-random-dump-images [dumps num] + (take num + (shuffle + (set (apply concat + (map + (comp take-images :content) + dumps)))))) + (defn count-dumps-posted [nick] (:count @@ -438,12 +443,6 @@ FROM users u and t.message_id = m.message_id and m.is_image = true" (.toLowerCase nick)])))) -(defn recently-faved [nick] - (do-select ["select distinct(u2.avatar, u2.nick) from users u, tags t, messages m, users u2 - where lower(u.nick) = ? and u.user_id = t.user_id and t.message_id = m.message_id - and m.user_id = u2.user_id order by t.created_on, u2.avatar, u2.nick limit 4" - (.toLowerCase nick)])) - (defn profile ([session profile-nick] (profile session profile-nick "profile")) ([session profile-nick template] @@ -453,18 +452,12 @@ FROM users u nick (session :nick) logger (make-time-logger) is-home (and nick (= nick profile-nick)) - has-avatar (non-empty-string? (user-info :avatar)) score (lookup-score profile-nick) - raw-dumps (logger tags/fetch-dumps-by-nick + dumps (logger tags/fetch-image-dumps + :user-tag-id (:user_id session) :nick profile-nick - :image-only true - :amount 5) - dumps (logger doall - (map (comp process-message-for-output - (msg-transformer :content take-random-image) - tags/remove-tags-for-output - tags/add-favorited-flag) - (take 5 raw-dumps) (repeat session)))] + :limit 10) + imgs (pull-random-dump-images dumps 5)] (do (.setAttribute st "is_home" is-home) (doseq [a [:nick :avatar :contact :bio]] @@ -473,8 +466,8 @@ FROM users u (if (non-empty-string? v) (escape-html v))))) (.setAttribute st "score" (comma-format score)) (.setAttribute st "score_ent" (score-to-entity score)) - (if (not (empty? dumps)) - (.setAttribute st "dumps" dumps)) + (if (not (empty? imgs)) + (.setAttribute st "imgs" imgs)) (.setAttribute st "debug_log_items" (logger)) (.toString st))) (resp-error "NO_USER")))) @@ -500,6 +493,23 @@ FROM users u :else (do (update-user-db user-id attr val) (resp-success "OK"))))) +;; Generic Handler + +(defn generic-profile-handler [session nick date msg-id + func redirecter unknown] + (if-let [user-info (fetch-nick nick)] + ;; If a valid msg-id is provided, the date is ignored. + ;; This makes urls such as /user/bogus/5 valid. + (cond msg-id (if-let [msg-id (maybe-parse-int msg-id)] + (func session user-info nil msg-id) + (redirecter user-info)) + ;; If an invalid date is provided, we redirect to the user's first favs page. + date (if-let [date (parse-yyyy-mm-dd-date date)] + (func session user-info date nil) + (redirecter user-info)) + :else (func session user-info nil nil)) + (unknown))) + ;; User log (defn build-mini-profile [user-info] @@ -514,35 +524,54 @@ FROM users u (.setAttribute "score" (comma-format score)) (.setAttribute "score_ent" (score-to-entity score)) (.toString)))) - -(defn user-log [session profile-nick offset] - (if-let [user-info (fetch-nick profile-nick)] - (let [st (fetch-template "userlog" session) - profile-nick (:nick user-info) ; Update to get right casing - nick (session :nick) - logger (make-time-logger) - has-avatar (non-empty-string? (:avatar user-info)) - offset (maybe-parse-int offset 0) - dump-offset (* offset *dumps-per-page*) - raw-dumps (logger tags/fetch-dumps-by-nick - :nick profile-nick - :amount (+ 1 *dumps-per-page*) - :offset dump-offset) - dumps (map tags/add-favorited-flag (take *dumps-per-page* raw-dumps) (repeat session)) - dumps (map tags/remove-tags-for-output dumps) - dumps (logger doall (map process-message-for-output dumps))] - (.setAttribute st "nick" profile-nick) - (.setAttribute st "is_home" (= nick profile-nick)) - (.setAttribute st "mini_profile" (build-mini-profile user-info)) - (if (> (count dumps) 0) - (.setAttribute st "dumps" dumps)) - (if (> (count raw-dumps) *dumps-per-page*) - (.setAttribute st "next" (inc offset))) - (if (not= offset 0) - (.setAttribute st "prev" (max (dec offset) 0))) - (.setAttribute st "debug_log_items" (logger)) - (.toString st)) - (resp-error "NO_USER"))) + +;; The next-page link is generated by retrieving one additional dump, +;; and creating a link from its date and message id. +(defn log-next-page-link [last-msg] + (format "/%s/%s/%s" + (:nick last-msg) + (format-yyyy-mm-dd (:created_on last-msg)) + (:message_id last-msg))) + +(defn user-log [session user-info date msg-id] + (let [st (fetch-template "userlog" session) + logger (make-time-logger) + raw-dumps (tags/fetch-image-dumps + :nick (:nick user-info) + :user-tag-id (:user_id session) + :msg-id msg-id + :date (if msg-id nil date) + :limit (inc *dumps-per-page*)) + back-dumps (if (or date msg-id) + (tags/fetch-image-dumps + :nick (:nick user-info) + :msg-id msg-id + :date (if msg-id nil date) + :limit (inc *dumps-per-page*) + :direction :forward)) + dumps (map process-message-for-output (butlast raw-dumps))] + (.setAttribute st "nick" (:nick user-info)) + (.setAttribute st "is_home" (= (:nick user-info) (:nick session))) + (.setAttribute st "mini_profile" (build-mini-profile user-info)) + (println back-dumps) + (if (> (count dumps) 0) + (.setAttribute st "dumps" dumps)) + (.setAttribute st "prev" + (if back-dumps + (cond + (> (count back-dumps) *dumps-per-page*) (log-next-page-link (last back-dumps)) + (> (count back-dumps) 1) (format "/%s/log" (:nick user-info)) + :else nil))) + (if (> (count raw-dumps) *dumps-per-page*) + (.setAttribute st "next" (log-next-page-link (last raw-dumps)))) + (.setAttribute st "debug_log_items" (logger)) + (.toString st))) + +(defn user-log-handler [session nick date msg-id] + (generic-profile-handler session nick date msg-id + user-log + (fn [u] (redirect-to (str "/" (:nick u)))) + #(resp-error "NO_USER"))) ;; Who faved me @@ -663,11 +692,12 @@ order by count desc limit ? offset ?") (let [now (System/currentTimeMillis) nick (session :nick) limit (if (:admin_only room) *vip-dumps-per-page* *dumps-per-page*) - message-list (reverse (tags/fetch-dumps-by-room :room-id (room :room_id) - :image-only false - :amount limit)) - message-list (map tags/add-favorited-flag message-list (repeat session)) - message-list (to-array (map process-message-for-output message-list))] + raw-msgs (reverse (tags/fetch-image-dumps :room (:key room) + :image-only false + :user-tag-id (:user_id session) + :hide-vip false + :limit limit)) + message-list (to-array (map process-message-for-output raw-msgs))] (if nick (dosync (login-user (user-struct-from-session session) room))) @@ -874,10 +904,10 @@ order by count desc limit ? offset ?") ;; message-user-id: get messages posted by this user ;; tag-user-id: get messages tagged by this user (defnk tagged-dumps-template [session params tags url page-title info-bar - :message-user-id false - :tag-user-id false - :logger (make-time-logger) - :include-vip false] + :message-user-id false + :tag-user-id false + :logger (make-time-logger) + :include-vip false] (let [st (fetch-template "tagged_dumps" session) offset (maybe-parse-int (params :offset) 0) dump-offset (* offset *dumps-per-page*) @@ -891,16 +921,16 @@ order by count desc limit ? offset ?") dumps (map tags/add-favorited-flag (take *dumps-per-page* raw-dumps) (repeat session)) dumps (map tags/remove-tags-for-output dumps) dumps (logger doall (map process-message-for-output dumps))] - (if (> (count raw-dumps) *dumps-per-page*) - (.setAttribute st "next" (inc offset))) - (if (not= offset 0) - (.setAttribute st "prev" (max (dec offset) 0))) - (.setAttribute st "dumps" dumps) - (.setAttribute st "infobar" info-bar) - (.setAttribute st "page_title" page-title) - (.setAttribute st "page_url" url) - (.setAttribute st "debug_log_items" (logger)) - (.toString st))) + (.setAttribute st "dumps" dumps) + (.setAttribute st "infobar" info-bar) + (.setAttribute st "page_title" page-title) + (.setAttribute st "page_url" url) + (if (not= offset 0) + (.setAttribute st "prev" (format "/%s/%s" url (max 0 (dec offset))))) + (if (> (count raw-dumps) *dumps-per-page*) + (.setAttribute st "next" (format "/%s/%s" url (inc offset)))) + (.setAttribute st "debug_log_items" (logger)) + (.toString st))) ;; gotta parse tag intersections myself because +'s get decoded into spaces ;; there's probably a less hacky way to do this @@ -920,29 +950,55 @@ order by count desc limit ? offset ?") page-title (str "dumps tagged as '" (escape-html (str-join "' and '" tags)) "'")] (tagged-dumps-template session params tags url page-title ""))) -(defn favorites [session params] - (if-let [user-info (fetch-nick (params :nick))] - (let [nick (params :nick) - user-info (fetch-nick nick) - user-id (:user_id user-info) - avatar (:avatar user-info) - url (str nick "/favorites") - page-title (str nick "'s favorites") - infobar (build-mini-profile user-info)] - (tagged-dumps-template session params "favorite" url page-title infobar - :tag-user-id user-id - :include-vip (is-vip? session))) - "NO_USER")) +(defn favorites-next-page-link [nick last-msg] + (format "/%s/favorites/%s/%s" + nick + (format-yyyy-mm-dd (:tagged_on last-msg)) + (:message_id last-msg))) + +(defn favorites [session user-info date msg-id] + (let [st (fetch-template "tagged_dumps" session) + logger (make-time-logger) + raw-dumps (tags/fetch-tagged-dumps + :nick (:nick user-info) + :user-tag-id (:user_id session) + :msg-id msg-id + :date (if msg-id nil date) + :limit (inc *dumps-per-page*)) + back-dumps (if (or date msg-id) + (tags/fetch-tagged-dumps + :nick (:nick user-info) + :msg-id msg-id + :date (if msg-id nil date) + :limit (inc *dumps-per-page*) + :direction :forward)) + dumps (map process-message-for-output (butlast raw-dumps))] + (.setAttribute st "prev" + (if back-dumps + (cond + (> (count back-dumps) *dumps-per-page*) (favorites-next-page-link (:nick user-info) + (last back-dumps)) + (> (count back-dumps) 1) (format "/%s/favorites" (:nick user-info)) + :else nil))) + (if (> (count raw-dumps) *dumps-per-page*) + (.setAttribute st "next" (favorites-next-page-link (:nick user-info) (last raw-dumps)))) + (.setAttribute st "dumps" dumps) + (.setAttribute st "infobar" (build-mini-profile user-info)) + (.setAttribute st "page_title" (format "%s'S FAVS" (:nick user-info))) + (.setAttribute st "debug_log_items" (logger)) + (.toString st))) + +(defn favorites-handler [session nick date msg-id] + (generic-profile-handler session nick date msg-id + favorites + (fn [u] (redirect-to (format "/%s/favorites" (:nick u)))) + #(resp-error "NO_USER"))) (defn json-favorites [session params] (let [nick (params :nick) user-id (user-id-from-nick nick) - raw-favs (tags/fetch-dumps-by-tag :tags "favorite" - :image-only false - :amount 50 - :offset 0 - :tag-user-id user-id - :with-tags false) + raw-favs (tags/fetch-tagged-dumps :nick nick + :limit 50) favs (reduce (fn [m fav] (assoc m (str (fav :message_id)) (fav :content))) {} raw-favs)] (str "RawFavs=" (json-str favs)))) @@ -1154,16 +1210,16 @@ order by count desc limit ? offset ?") (GET "/r/:room/log/:offset" (validated-log session (params :room) (params :offset) params)) (GET "/favicon.ico" (serve-static "static" "favicon.ico")) - (GET "/u/:nick" (profile session (params :nick))) - (GET "/u/:nick/" (profile session (params :nick))) + (GET "/u/:nick" (redirect-to (str "/" (params :nick)))) + (GET "/u/:nick/" (redirect-to (str "/" (params :nick)))) (GET "/u/:nick/tag/:tag" (tagged-dumps-by-nick session params (request-url request))) (GET "/u/:nick/tag/:tag/:offset" (tagged-dumps-by-nick session params (request-url request))) - (GET "/u/:nick/favorites" (favorites session params)) - (GET "/u/:nick/favorites/:offset" (favorites session params)) + (GET "/u/:nick/favorites" (redirect-to (format "/%s/favorites" (params :nick)))) + (GET "/u/:nick/favorites/:offset" (redirect-to (format "/%s/favorites" (params :nick)))) (GET "/json/:nick/favorites" (json-favorites session params)) ; have to put this route after favs - (GET "/u/:nick/:offset" (user-log session (params :nick) (params :offset))) + (GET "/u/:nick/:offset" (redirect-to (str "/" (params :nick)))) (GET "/p/:nick/:postid" (single-message session (params :nick) (params :postid))) ;; TODO: these shouldn't be GETs @@ -1223,14 +1279,21 @@ order by count desc limit ? offset ?") (GET "/:nick/" (profile session (params :nick))) (GET "/:nick/tag/:tag" (tagged-dumps-by-nick session params (request-url request))) (GET "/:nick/tag/:tag/:offset" (tagged-dumps-by-nick session params (request-url request))) - (GET "/:nick/favorites" (favorites session params)) - (GET "/:nick/favorites/:offset" (favorites session params)) + (GET "/:nick/favorites" (favorites-handler session (params :nick) nil nil)) + (GET "/:nick/favorites/" (favorites-handler session (params :nick) nil nil)) + (GET "/:nick/favorites/:date" (favorites-handler session (params :nick) (params :date) nil)) + (GET "/:nick/favorites/:date/" (favorites-handler session (params :nick) (params :date) nil)) + (GET "/:nick/favorites/:date/:msg" (favorites-handler session (params :nick) (params :date) (params :msg))) + (GET "/:nick/favs" (favorites-handler session (params :nick) nil nil)) + (GET "/:nick/favs/:date" (favorites-handler session (params :nick) (params :date) nil)) + (GET "/:nick/favs/:date/:msg" (favorites-handler session (params :nick) (params :date) (params :msg))) (GET "/:nick/popular" (popular session (params :nick))) - (GET "/:nick/favs" (favorites session params)) - (GET "/:nick/favs/:offset" (favorites session params)) - (GET "/:nick/log" (user-log session (params :nick) "0")) - (GET "/:nick/log/:offset" (user-log session (params :nick) (params :offset))) - (GET "/:nick/:offset" (user-log session (params :nick) (params :offset))) + (GET "/:nick/log" (user-log-handler session (params :nick) nil nil)) + (GET "/:nick/log/" (user-log-handler session (params :nick) nil nil)) + (GET "/:nick/:date" (user-log-handler session (params :nick) (params :date) nil)) + (GET "/:nick/:date/" (user-log-handler session (params :nick) (params :date) nil)) + (GET "/:nick/:date/:msg" (user-log-handler session (params :nick) (params :date) (params :msg))) + (GET "/" (landing session)) (ANY "*" (unknown-page))) |
