diff options
Diffstat (limited to 'src/rooms.clj')
| -rw-r--r-- | src/rooms.clj | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/rooms.clj b/src/rooms.clj new file mode 100644 index 0000000..57fbf3a --- /dev/null +++ b/src/rooms.clj @@ -0,0 +1,114 @@ +(ns rooms + (:use clojure.contrib.str-utils + utils)) + +(def *run-flusher* true) +(def *flusher-sleep* (seconds 4)) +(def *user-timeout* (seconds 15)) + +(def rooms (ref {})) +(def flusher (agent nil)) + +(defn flush-inactive-users! [x] + (doseq [[rid room] @rooms] + (dosync + (let [users (room :users) + now (System/currentTimeMillis) + cutoff (- now *user-timeout*) + alive? (fn [[n u]] (> (u :last-seen) cutoff))] + (ref-set users + (into {} (filter alive? (ensure users))))))) + (Thread/sleep *flusher-sleep*) + (when *run-flusher* + (send *agent* #'flush-inactive-users!)) + x) + +(defn start-user-flusher! [] + (send flusher flush-inactive-users!)) + +(def *default-room* "dumpfm") + +(defn default-room? [key] + (= (lower-case key) *default-room*)) + +(defn lookup-room [key] + (@rooms (lower-case key))) + +(defn fetch-room [key] + (first (do-select ["SELECT * FROM rooms WHERE key = LOWER(?)" key]))) + +(defn fetch-rooms [] + (do-select ["SELECT * FROM ROOMS"])) + +(defn count-messages-by-room [room-id image-only] + (let [query (str "SELECT COUNT(*) + FROM messages m, users u + WHERE room_id = ? AND m.user_id = u.user_id" + (if image-only " AND m.is_image = true " ""))] + (do-count [query room-id]))) + +(defn fetch-messages-by-room + ([room-id image-only] (fetch-messages-by-room room-id image-only 0)) + ([room-id image-only offset] + (let [query (str "SELECT m.content, m.message_id, m.created_on, u.nick, u.avatar + FROM users u, messages m + WHERE room_id = ? AND m.user_id = u.user_id " + (if image-only "AND m.is_image = true " "") + "ORDER BY created_on DESC + LIMIT ? OFFSET ?")] + (do-select [query room-id *dumps-per-page* offset])))) + +(defn build-room-map-from-db [room-db] + {:admin_only (room-db :admin_only) + :room_id (room-db :room_id) + :key (room-db :key) + :name (room-db :name) + :description (room-db :description) + :users (ref {}) + :messages (ref (fetch-messages-by-room (room-db :room_id) false)) + :topic (ref nil) + }) + + +(defn load-rooms! [] + (dosync + (doseq [room-db (fetch-rooms)] + (alter rooms assoc (lower-case (room-db :key)) + (build-room-map-from-db room-db))))) + +;; Room helpers + +(defn login-user [user room] + (alter (room :users) assoc (user :nick) user)) + +(defn add-message [msg room] + (alter (room :messages) (swap cons) msg)) + +(defn create-and-add-room! [key] + (do-select ["INSERT INTO rooms (key, name, description) + VALUES (?, ?, ?) RETURNING room_id" + key key key]) + (if-let [room-db (fetch-room key)] + (dosync + (alter rooms assoc (lower-case key) + (build-room-map-from-db room-db)) + room-db))) + +(defn get-or-create-room! [key] + (:room_id + (or (first (do-select ["SELECT room_id FROM rooms WHERE lower(key) = ?" + (lower-case key)])) + (create-and-add-room!) + (throw (Exception. (str "Unable to create room " key)))))) + +(defn- get-or-create-room-bot-id! [nick] + ((comp :user_id first) + (or (do-select ["SELECT user_id FROM users WHERE lower(nick) = ?" + (lower-case nick)]) + (do-select ["INSERT INTO users (nick, hash, email) + VALUES (?, ?, ?) RETURNING user_id" + nick "GARBAGE" "info@dump.fm"])))) + +(defn get-or-create-room-bot! [key] + (let [nick (str key "bo†")] + [nick (get-or-create-room-bot-id! nick)]))
\ No newline at end of file |
