summaryrefslogtreecommitdiff
path: root/src/datalayer.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/datalayer.clj')
-rw-r--r--src/datalayer.clj140
1 files changed, 96 insertions, 44 deletions
diff --git a/src/datalayer.clj b/src/datalayer.clj
index 6b2a466..8590a7d 100644
--- a/src/datalayer.clj
+++ b/src/datalayer.clj
@@ -1,4 +1,5 @@
(ns datalayer
+ (:import java.util.Date)
(:require redis
tags)
(:use clojure.contrib.sql
@@ -10,8 +11,6 @@
user
utils))
-
-
;;;; Message lookup
(defn recent-posts-query [user-id]
@@ -81,41 +80,46 @@ WHERE u.nick = ANY(?)"
;;;; Popular Posts
-(def popular-dumps-qry "
-select u.nick, u.avatar, r.key, m.message_id, m.content, m.created_on, count(*) as count,
- array_agg(u2.nick) as user_nicks
-from users u, messages m, rooms r, tags t, users u2
-where lower(u.nick) = lower(?)
-and u.user_id = m.user_id and m.message_id = t.message_id
-and m.room_id = r.room_id and m.is_image = true and r.admin_only = false
-and t.tag = 'favorite'
-and t.user_id = u2.user_id
-group by u.nick, u.avatar, r.key, m.message_id, m.content, m.created_on
-order by count desc limit ? offset ?")
-
-(defn fetch-popular-dumps [nick viewer-nick]
- (for [d (do-select [popular-dumps-qry nick 40 0])]
- (let [favers (.getArray (:user_nicks d))]
- (assoc d
- :favers favers
- :favorited (some #(= % viewer-nick) favers)))))
+(defn redis-popular-key [nick]
+ (str "popular:" nick))
(defn fetch-popular-dumps-redis [nick viewer-nick]
- (let [rkey (str "popular:" nick)
- msg-ids (redis/with-server redis-server
- (redis/zrevrange rkey 0 (dec num-popular-dumps)))
+ (let [msg-ids (redis/with-server redis-server
+ (redis/zrevrange (redis-popular-key nick)
+ 0
+ (dec num-popular-dumps)))
msg-ids (map maybe-parse-int msg-ids)]
(if-not (empty? msg-ids)
- (tags/fetch-dumps-by-ids msg-ids viewer-nick))))
+ (sort-by
+ #(* -1 (:count %))
+ (tags/fetch-dumps-by-ids msg-ids viewer-nick)))))
;;;; Redis Favscores
+(def score-piece-map
+ (zipmap
+ [:pawn :knight :bishop :rook :queen :king :skull]
+ ["♟" "♞" "♝" "♜" "♛" "♚" "☠"]))
+
+(defn score-to-piece [score]
+ (cond (= score -1) :skull
+ (= score 0) :pawn
+ (< score 50) :knight
+ (< score 150) :bishop
+ (< score 300) :rook
+ (< score 1000) :queen
+ :else :king))
+
+(def score-to-entity (comp score-piece-map score-to-piece))
+
+(def redis-favscores-key "favscores")
+
(defn fetch-redis-directory [page num]
(vec
(for [t (with-jedis
#(.zrevrangeWithScores %
- "favscores"
+ redis-favscores-key
(* page num)
(dec (* (inc page) num))))]
{:nick (.getElement t)
@@ -142,19 +146,27 @@ order by count desc limit ? offset ?")
;;;; Redis Hall of Fame
+(def redis-hall-key "hall")
+
(defn fetch-redis-hall [viewer-nick]
(let [ids (map maybe-parse-int
(redis/with-server redis-server
- (redis/zrevrange "hall" 0 (dec num-hall-dumps))))]
+ (redis/zrevrange redis-hall-key 0 (dec num-hall-dumps))))]
(if-not (empty? ids)
- (tags/fetch-dumps-by-ids ids viewer-nick))))
+ (sort-by
+ #(* -1 (:count %))
+ (tags/fetch-dumps-by-ids ids viewer-nick)))))
;;;; Message insertion
+(defn direct-message-key [u-id]
+ (str "directmessage:" u-id))
+
(def msg-insert-query
"INSERT INTO messages (user_id, room_id, content, is_image, is_text)
VALUES (?, ?, ?, ?, ?) RETURNING message_id, created_on")
+;; Note: direct-message recipients are inserted into postgres, but topics aren't.
(defn insert-message-into-postgres! [author-id room-id content is-image is-text recips]
(with-connection *db*
(transaction
@@ -169,43 +181,83 @@ order by count desc limit ? offset ?")
[msg-id author-id (:user_id r)]))
[msg-id ts]))))
-(defn insert-recips-into-redis! [recips author-id ts content]
- (let [dm-json (json-str {"author_id" author-id
- "recips" (map :nick recips)
- "content" content})]
+(defn insert-recips-into-redis! [recips author-id dt content room-key]
+ (let [msg-json (json-str {"author_id" author-id
+ "recips" (map :nick recips)
+ "key" room-key
+ "content" content})
+ ts (.getTime dt)]
(redis/with-server redis-server
(redis/atomically
(doseq [r recips]
- (redis/zadd (str "directmessage:" (:user_id r))
- (.getTime ts)
- dm-json))))))
+ (redis/zadd (direct-message-key (:user_id r))
+ ts
+ msg-json))))))
+
+(defn topic-key [topic]
+ (str "topic:" topic))
-(defn insert-message! [author-id author-nick room-id content]
+(defn insert-topics-into-redis! [topics recips author-nick author-avatar dt msg-id content room-key]
+ (let [ts (.getTime dt)
+ msg-json (json-str {"nick" author-nick
+ "avatar" author-avatar
+ "recips" (map :nick recips)
+ "content" content
+ "key" room-key
+ "message_id" msg-id
+ "ts" ts})]
+ (redis/with-server redis-server
+ (redis/atomically
+ (doseq [t topics]
+ (redis/lpush (topic-key t)
+ msg-json))))))
+
+(defn insert-message! [author-id author-nick author-avatar room content]
(let [msg-type (classify-msg content)
is-image (boolean (#{:image :mixed} msg-type))
is-text (boolean (#{:mixed :text} msg-type))
recips (get-recips content)
- [msg-id ts] (insert-message-into-postgres! author-id
- room-id
+ topics (get-topics content)
+ [msg-id dt] (insert-message-into-postgres! author-id
+ (:room_id room)
content
is-image
is-text
recips)]
- (if-not (empty? recips)
- (insert-recips-into-redis! recips author-id ts content))
+ (when-not (:admin_only room)
+ (if-not (empty? recips)
+ (insert-recips-into-redis! recips author-id dt content (:key room)))
+ (if-not (empty? topics)
+ (insert-topics-into-redis! topics recips author-nick author-avatar dt msg-id content (:key room))))
{:author author-nick
:msg-id msg-id
- :room room-id
- :db-ts ts
+ :room (:room_id room)
+ :db-ts dt
:content content
- :recips (map (comp lower-case :nick) recips)}))
+ :recips (map :nick recips)
+ }))
-(defn fetch-private-messages [user-id]
+(defn fetch-direct-messages [user-id]
(for [dm (redis/with-server redis-server
- (redis/zrevrange (str "directmessage:" user-id) 0 40))]
+ (redis/zrevrange (direct-message-key user-id) 0 40))]
(let [dm (read-json dm)
info (fetch-user-id (get dm "author_id"))]
{"nick" (:nick info)
"content" (get dm "content")
"recips" (get dm "recips" [])
"avatar" (:avatar info)})))
+
+(def topic-fetch-num 40)
+
+(defn fetch-topic [viewer-id topic]
+ (let [redis-msgs (redis/with-server redis-server
+ (redis/lrange (topic-key topic) 0 topic-fetch-num))
+ raw-msgs (for [m redis-msgs]
+ (let [m (keywordify (read-json m))]
+ (assoc m
+ :created_on (Date. (:ts m)))))]
+ (if viewer-id
+ (tags/add-user-favs-to-msgs
+ raw-msgs
+ viewer-id)
+ raw-msgs)))