summaryrefslogtreecommitdiff
path: root/src/site.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/site.clj')
-rw-r--r--src/site.clj271
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)))