summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortim b <timb@camcompu.home>2010-04-03 21:00:32 -0700
committertim b <timb@camcompu.home>2010-04-03 21:00:32 -0700
commitd32d26065494ccbd4a9ddba0789003e3daa5fa28 (patch)
tree2b0feb1eae6cc43e0f0c24e90ec255d603d4ddc1 /src
parentdccf497aca0ea62b7931976103c89e3b01ab1860 (diff)
committing stuff so i can merge pulled repo
Diffstat (limited to 'src')
-rw-r--r--src/tags.clj121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/tags.clj b/src/tags.clj
new file mode 100644
index 0000000..ba32635
--- /dev/null
+++ b/src/tags.clj
@@ -0,0 +1,121 @@
+(ns tags
+ (:import java.lang.System)
+ (:use clojure.contrib.sql
+ clojure.contrib.json.write
+ compojure
+ utils))
+
+; save all spaces in tags as dashes
+(defn normalize-tag-for-db [tag] (str tag))
+; (.replace tag " " "-"))
+; todo: remove unicode escape sequences and line breaks and stuff?
+
+
+; maybe show all dashes as spaces on output?
+(defn normalize-tag-for-out [tag] (str tag))
+
+(defn add-tag [user-id message-id tag]
+ (let [query "INSERT INTO tags2(user_id, message_id, tag) VALUES(?, ?, ?)"]
+ (try
+ (do-select [query user-id (maybe-parse-int message-id) (normalize-tag-for-db tag)])
+ ; catch error when inserting duplicate tags
+ (catch org.postgresql.util.PSQLException e
+ resp-error "TAG_EXISTS_ALREADY_OR_SOMETHING_ELSE_IS_FUCKED")
+ )))
+
+; to do: don't let people set tags on messages they can't access
+(defn validated-add-tag [session params]
+ (if (session :nick)
+ (add-tag (session :user_id) (params :message_id) (params :tag))
+ (resp-error "NO_USER")))
+
+(defn remove-tag [user-id message-id tag]
+ (let [query "DELETE FROM tags2 WHERE user_id = ? AND message_id = ? AND lower(tag) = ?"]
+ (do-select [query user-id (maybe-parse-int message-id) (normalize-tag-for-db (.toLowerCase tag))])))
+
+(defn validated-remove-tag [session params]
+ (if (session :nick)
+ (remove-tag (session :user_id) (params :message_id) (params :tag))
+ (resp-error "NO_USER")))
+
+
+(defn fetch-messages-by-tag [])
+
+; lol "Can't remove struct key"
+(defn remove-tags-for-output [row]
+ (dissoc (into {} row) :tags))
+
+(defn get-json-tags [row]
+ (assoc row :tags_json (json-str (row :tags))))
+
+; turn "a 1 b 2" to ({:nick a :tag 1}, {:nick b :tag 2})
+; this seems to be a waste of cpu and memory, but i'm trying to make these easily accessible from templates
+; also: i can't figure out how to access array indexes directly in StringTemplate templates
+(defn parse-tags-from-row [row]
+ (assoc row :tags
+ (for [t (partition 2 (.split (row :tags) " "))]
+ {"nick" (first t) "tag" (last t)})))
+
+(defn parse-tags-from-string [string]
+ (partition 2 (.split string " ")))
+
+(defn build-tag-map-by-tag [tags nick-tag]
+ (let [nick (first nick-tag) tag (last nick-tag)]
+ (if (tags tag)
+ (assoc tags tag (conj (tags tag) nick))
+ (assoc tags tag [nick]))))
+
+; making something like {"tag1": ["nick a", "nick b"], "tag2": ["nick c", "nick d"]}
+; why is building data structures in clojure so hard for me
+(defn parse-tags-from-row-as-map-by-tag [row]
+ (assoc row :tags
+ (reduce build-tag-map-by-tag {} (parse-tags-from-string (row :tags)))))
+
+(defn does-tag-exist?
+ ([tags tag]
+ (contains? tags tag))
+ ([tags tag from-nick]
+ (if (contains? tags tag)
+ (some #{from-nick} (tags tag)))))
+
+(defn add-favorited-flag [row session]
+ (if (does-tag-exist? (row :tags) "favorite" (session :nick))
+ (assoc row :favorited true)
+ row))
+
+
+(defn explain-query [query] (str "EXPLAIN ANALYZE " query))
+
+; todo: offset is slow. probably need to include message_id in 'next page' url (tumblr & reddit do that)
+(defn fetch-messages-with-tags-by-room-query [image-only]
+ (str "SELECT m.content, m.message_id, m.created_on, u.nick, u.avatar,
+ array_to_string(ARRAY(SELECT nick || ' ' || tag
+ FROM tags2, users
+ WHERE message_id = m.message_id AND tags2.user_id = users.user_id), ' ') as tags
+ 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 ?"))
+
+; offset is slow... problem with this one though it doesn't take into account deleted messages
+(defn fetch-messages-with-tags-by-room-fast-paging-query [image-only]
+ (str "SELECT m.content, m.message_id, m.created_on, u.nick, u.avatar,
+ array_to_string(ARRAY(SELECT nick || ' ' || tag
+ FROM tags2, users
+ WHERE message_id = m.message_id AND tags2.user_id = users.user_id), ' ') as tags
+ FROM users u, messages m
+ WHERE room_id = ? AND m.user_id = u.user_id
+ AND m.message_id BETWEEN ? AND ? "
+ (if image-only "AND m.is_image = true " "")
+ "ORDER BY created_on DESC
+ LIMIT ?"))
+
+(defn fetch-messages-with-tags-by-room
+ ([] (fetch-messages-with-tags-by-room 1 true *dumps-per-page* 0))
+ ([room-id] (fetch-messages-with-tags-by-room room-id true *dumps-per-page* 0))
+ ([room-id image-only] (fetch-messages-with-tags-by-room room-id image-only *dumps-per-page* 0))
+ ([room-id image-only amount offset]
+ (let [query (fetch-messages-with-tags-by-room-query image-only)]
+ (let [rows (do-select [query room-id amount offset])]
+ (map parse-tags-from-row-as-map-by-tag rows)))))