From 1a0bfbe6a6a38021d8da62d386690bec48acefdc Mon Sep 17 00:00:00 2001 From: Bart Akeley Date: Sun, 4 Mar 2018 09:01:23 -0600 Subject: [PATCH] /addImage endpoint --- project.clj | 3 ++- src/aretherecookies/app.clj | 7 +++++-- src/aretherecookies/aws.clj | 11 +++++++++++ src/aretherecookies/db.clj | 13 +++++++++++++ src/aretherecookies/handler.clj | 20 +++++++++++++++++--- src/aretherecookies/queries.sql | 6 ++++++ 6 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 src/aretherecookies/aws.clj diff --git a/project.clj b/project.clj index 2807b01..5c4f342 100644 --- a/project.clj +++ b/project.clj @@ -17,7 +17,8 @@ [ring/ring-jetty-adapter "1.4.0"] [com.layerware/hugsql "0.4.8"] [buddy/buddy-auth "2.1.0"] - [clj-http "3.7.0"]] + [clj-http "3.7.0"] + [amazonica "0.3.121"]] :plugins [[lein-ring "0.9.7"] [lein-environ "1.1.0"]] :ring {:handler aretherecookies.app/app} :profiles diff --git a/src/aretherecookies/app.clj b/src/aretherecookies/app.clj index fcb4208..20dd5a4 100644 --- a/src/aretherecookies/app.clj +++ b/src/aretherecookies/app.clj @@ -1,6 +1,6 @@ (ns aretherecookies.app (:gen-class) - (:require [aretherecookies.handler :refer [food-items-handler quantity-handler add-food-item-handler]] + (:require [aretherecookies.handler :refer [food-items-handler quantity-handler add-food-item-handler add-image-handler]] [aretherecookies.auth :refer [auth-backend]] [environ.core :refer [env]] [compojure.handler :refer [api]] @@ -8,6 +8,7 @@ [ring.adapter.jetty :as jetty] [ring.middleware.anti-forgery :refer :all] [ring.middleware.json :refer [wrap-json-body]] + [ring.middleware.multipart-params :refer [wrap-multipart-params]] [ring.middleware.defaults :refer [wrap-defaults api-defaults]] [buddy.auth :refer [throw-unauthorized]] [buddy.auth.middleware :refer [wrap-authentication wrap-authorization]])) @@ -17,7 +18,8 @@ (POST "/test" [] "ok") (POST "/fooditems" [] food-items-handler) (POST "/quantity" [] quantity-handler) - (POST "/addfooditem" [] add-food-item-handler)) + (POST "/addfooditem" [] add-food-item-handler) + (POST "/addimage/:foodItemId" [] add-image-handler)) (def app-config (assoc-in api-defaults [:security :anti-forgery] false)) @@ -30,5 +32,6 @@ (api #'app) (wrap-authorization auth-backend) (wrap-authentication auth-backend) + wrap-multipart-params (wrap-json-body {:keywords? true}) (jetty/run-jetty {:port port :join? false})))) diff --git a/src/aretherecookies/aws.clj b/src/aretherecookies/aws.clj new file mode 100644 index 0000000..f1364e0 --- /dev/null +++ b/src/aretherecookies/aws.clj @@ -0,0 +1,11 @@ +(ns aretherecookies.aws + (:require [environ.core :refer [env]] + [amazonica.aws.s3 :refer [put-object]] + [amazonica.core :refer [defcredential]])) + +(defcredential (env :aws-access-key-id) (env :aws-secret-access-key) (env :aws-region)) + +(defn put-s3 + "upload given filename and file to s3" + [file-name file] + (put-object :bucket-name "aretherecookies" :key file-name :file file)) \ No newline at end of file diff --git a/src/aretherecookies/db.clj b/src/aretherecookies/db.clj index 6868456..0d9d3e4 100644 --- a/src/aretherecookies/db.clj +++ b/src/aretherecookies/db.clj @@ -12,6 +12,8 @@ ; select-food-items ; within-radius ; has-category +; select-images +; update-images (hugsql/def-db-fns "aretherecookies/queries.sql") (def db-spec {:uri (env :database-jdbc-uri) @@ -78,3 +80,14 @@ :latitude latitude})) quantity (first (insert-quantity {:foodItemId (:id food-item) :quantity quantity}))] (merge food-item (select-keys quantity [:quantity :date])))) + +(defn get-images + "query database for a list of images for a food item id" + [foodItemId] + (let [images (:images (select-images @pooled-db {:id foodItemId}))] + (filter #(not (str/blank? %)) (str/split (str images) #",")))) + +(defn set-images + "update the list of images for given food item id" + [foodItemId images] + (update-images @pooled-db {:id foodItemId :images (str/join "," images)})) \ No newline at end of file diff --git a/src/aretherecookies/handler.clj b/src/aretherecookies/handler.clj index 837cc00..86a063a 100644 --- a/src/aretherecookies/handler.clj +++ b/src/aretherecookies/handler.clj @@ -1,8 +1,11 @@ (ns aretherecookies.handler (:require [aretherecookies.db :refer [query-food-items insert-quantity - create-food-item]] + create-food-item + get-images + set-images]] [aretherecookies.parsers :refer [parse-special-types parse-location]] + [aretherecookies.aws :refer [put-s3]] [clojure.data.json :as json] [clojure.string :as str] [buddy.auth :refer [authenticated? throw-unauthorized]])) @@ -36,7 +39,7 @@ (def required-keys [:name :placeId :latitude :longitude :category :quantity]) (defn get-missing-keys [foodItem] - (filter #(get foodItem %) required-keys)) + (remove #(get foodItem %) required-keys)) (defn add-food-item-handler "validate food item fields from request and insert into database returning newly created item" @@ -44,9 +47,20 @@ (println "/addfooditem ---->" (:body req)) (if-not (authenticated? req) (throw-unauthorized)) (let [food-item (:body req) missing-keys (get-missing-keys food-item)] - (if (< (count missing-keys) 0) + (if (> (count missing-keys) 0) (bad-request {"missingkeys" missing-keys}) (as-> (create-food-item food-item) % (parse-location %) (safe-json %))))) + +(defn add-image-handler + "given foodItemId from route and photo from multipart form post uploads image into s3 and adds URL into food item record" + [{{foodItemId :foodItemId {image :tempfile} :photo} :params}] + (let [existing-images (get-images foodItemId) + img-name (str foodItemId "/" (+ 1 (count existing-images)) ".png") + img-url (str "https://s3-us-west-2.amazonaws.com/aretherecookies/" img-name)] + (println "/addimage ---->" img-url) + (put-s3 img-name image) + (set-images foodItemId (conj existing-images img-url)) + img-url)) \ No newline at end of file diff --git a/src/aretherecookies/queries.sql b/src/aretherecookies/queries.sql index 60db918..3c1cda6 100644 --- a/src/aretherecookies/queries.sql +++ b/src/aretherecookies/queries.sql @@ -63,3 +63,9 @@ RETURNING thumbImage AS thumbImage, ST_AsGeoJSON(loc) AS location, ST_Distance(loc, ST_SetSRID(ST_Point(:longitude, :latitude), 4326)::geography) / 1609 AS distance + +-- :name select-images +SELECT images FROM food_items WHERE id=:v:id::uuid + +-- :name update-images +UPDATE food_items SET images=:v:images WHERE id=:v:id::uuid RETURNING images \ No newline at end of file