From d6a58c2300a5907a14d4821bcaead3d41b7804d8 Mon Sep 17 00:00:00 2001 From: gered Date: Sun, 6 Apr 2014 16:14:01 -0400 Subject: [PATCH] add various db operations for getting/searching/listing ascii art --- src/toascii/models/art.clj | 26 +++++++++++++++----------- src/toascii/models/db.clj | 38 +++++++++++++++++++++++++++++++++++++- src/toascii/util.clj | 4 ++++ 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/src/toascii/models/art.clj b/src/toascii/models/art.clj index 91fabec..3f96029 100644 --- a/src/toascii/models/art.clj +++ b/src/toascii/models/art.clj @@ -1,6 +1,6 @@ (ns toascii.models.art (:require [toascii.models.db :as db] - [toascii.util :refer [convert-line-endings remove-leading-and-trailing-blank-lines]])) + [toascii.util :refer [convert-line-endings remove-leading-and-trailing-blank-lines parse-index]])) (defn- prep-ascii-art [s] (-> s @@ -12,25 +12,29 @@ (re-matches #"[a-z0-9\-]+" name))) (defn search [query] - ) + (if-not (valid-name? query) + (throw (new Exception "Invalid search term. Can only use characters valid in names."))) + (db/find-art-names query)) (defn get-count [name] - ) + (if-not (valid-name? name) + (throw (new Exception "Invalid name"))) + (db/get-art-count-by name)) (defn get-index [name index] - ) + (if-not (valid-name? name) + (throw (new Exception "Invalid name"))) + (if-let [idx (parse-index index)] + (db/get-ascii-art name idx) + (throw (new Exception "Invalid index")))) (defn get-random [name] - ) + (if-not (valid-name? name) + (throw (new Exception "Invalid name"))) + (db/get-random-ascii-art name)) (defn add [name s ip] (if-not (valid-name? name) (throw (new Exception "Invalid name"))) (let [prepped-ascii (prep-ascii-art s)] (db/add-ascii-art name prepped-ascii ip))) - - -(add - "heLllo" - " _ _ _ \n | |__ ___ | | | | ___ \n | '_ \\ / _ \\ | | | | / _ \\ \n | | | | | __/ | | | | | (_) |\n |_| |_| \\___| |_| |_| \\___/ \n " - "127.0.0.1") diff --git a/src/toascii/models/db.clj b/src/toascii/models/db.clj index b7d3c53..aed6a40 100644 --- a/src/toascii/models/db.clj +++ b/src/toascii/models/db.clj @@ -41,4 +41,40 @@ :ip ip :format "ascii" :hash (sha256 ascii) - :content ascii})))) \ No newline at end of file + :content ascii})))) + +(defn get-ascii-art + ([doc-id] + (->> (couch/get-document-with-db (db-library) doc-id) + :content)) + ([name index] + (if-let [doc-id (as-> (couch/get-view-with-db (db-library) "list" "byDate" {:key name}) x + (sort-by :date x) + (nth x index nil) + (:id x))] + (get-ascii-art doc-id) + (throw (new IndexOutOfBoundsException))))) + +(defn get-random-ascii-art [name] + (->> (couch/get-view-with-db (db-library) "list" "ids" {:key name}) + (rand-nth) + :value + (get-ascii-art))) + +(defn get-art-count [] + (->> (couch/get-view-with-db (db-library) "list" "count") + (first) + :value)) + +(defn get-art-count-by [name] + (->> (couch/get-view-with-db (db-library) "list" "count" {:key name :group true}) + (first) + :value)) + +(defn find-art-names [query] + ; HACK: to mimic a "starts with prefix" type of search with couchdb, we append unicode character \u9999 + ; to the search term and use it as the end key, effectively meaning "find all matches with keys + ; between 'prefix' and 'prefix\u9999'" which works because keys will be sorted lexicographically + ; by couchdb + (->> (couch/get-view-with-db (db-library) "list" "uniqueNames" {:startkey query :endkey (str query "\u9999") :group true}) + (map :key))) \ No newline at end of file diff --git a/src/toascii/util.clj b/src/toascii/util.clj index 04b7647..8398759 100644 --- a/src/toascii/util.clj +++ b/src/toascii/util.clj @@ -76,6 +76,10 @@ (Integer/parseInt s) (catch Exception ex))) +(defn parse-index [s] + (if-let [i (parse-int s)] + (if (>= i 0) i))) + (defn parse-boolean [x] (let [x (if (string? x) (-> x (.toLowerCase) (.trim))