mirror of
https://gitlab.com/wheres-the-tp/server.git
synced 2026-01-25 06:14:55 -06:00
new /addfooditem route handler, query
*needs re-run of ddl
This commit is contained in:
parent
dfe3309432
commit
7af08e122b
7 changed files with 84 additions and 55 deletions
|
|
@ -1,30 +1,25 @@
|
|||
|
||||
CREATE EXTENSION IF NOT EXISTS "postgis";
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
CREATE TYPE QUANTITY_ENUM AS ENUM ('lots', 'many', 'few', 'none');
|
||||
|
||||
CREATE TYPE CATEGORY_ENUM AS ENUM ('beverages', 'desserts', 'entrees', 'other');
|
||||
|
||||
create table food_items (
|
||||
CREATE TYPE QUANTITY AS ENUM ('lots', 'many', 'few', 'none');
|
||||
CREATE TYPE CATEGORY AS ENUM ('beverages', 'desserts', 'entrees', 'other');
|
||||
DROP TABLE IF EXISTS food_items CASCADE;
|
||||
CREATE TABLE food_items (
|
||||
id uuid PRIMARY KEY,
|
||||
name VARCHAR(100),
|
||||
place_id VARCHAR(50),
|
||||
category CATEGORY_ENUM,
|
||||
category CATEGORY,
|
||||
images VARCHAR,
|
||||
thumbImage VARCHAR,
|
||||
loc geography(POINT,4326)
|
||||
);
|
||||
|
||||
create table quantities (
|
||||
DROP TABLE quantities CASCADE;
|
||||
CREATE TABLE quantities (
|
||||
food_item_id uuid,
|
||||
date timestamp (1) with time zone,
|
||||
quantity QUANTITY_ENUM,
|
||||
quantity QUANTITY,
|
||||
PRIMARY KEY(food_item_id, date)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS food_loc_index ON food_items USING GIST ( loc );
|
||||
|
||||
INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
||||
VALUES (
|
||||
uuid_generate_v4(),
|
||||
|
|
@ -35,7 +30,6 @@ INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
|||
'http://images.media-allrecipes.com/userphotos/560x315/1107530.jpg',
|
||||
ST_GeogFromText('SRID=4326;POINT(-97.7532464 30.270667599999996)')
|
||||
);
|
||||
|
||||
INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
||||
VALUES (
|
||||
uuid_generate_v4(),
|
||||
|
|
@ -46,7 +40,6 @@ INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
|||
'https://timenewsfeed.files.wordpress.com/2013/06/jellydonut.jpg',
|
||||
ST_GeogFromText('SRID=4326;POINT(-97.742308 30.263963300000004)')
|
||||
);
|
||||
|
||||
INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
||||
VALUES (
|
||||
uuid_generate_v4(),
|
||||
|
|
@ -57,7 +50,6 @@ INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
|||
'http://www.momshealthyeats.com/wp-content/uploads/2011/11/spelt-fudge-brownie.jpg',
|
||||
ST_GeogFromText('SRID=4326;POINT(-97.7419085 30.265019100000004)')
|
||||
);
|
||||
|
||||
INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
||||
VALUES (
|
||||
uuid_generate_v4(),
|
||||
|
|
@ -68,7 +60,6 @@ INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
|||
'http://cookingontheside.com/wp-content/uploads/2009/04/oatmeal_raisin_cookies_stack-400.jpg',
|
||||
ST_GeogFromText('SRID=4326;POINT(-97.7532464 30.270667599999996)')
|
||||
);
|
||||
|
||||
INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
||||
VALUES (
|
||||
uuid_generate_v4(),
|
||||
|
|
@ -79,7 +70,6 @@ INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
|||
'https://dannivee.files.wordpress.com/2013/10/img_1950.jpg',
|
||||
ST_GeogFromText('SRID=4326;POINT(-97.742308 30.263963300000004)')
|
||||
);
|
||||
|
||||
INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
||||
VALUES (
|
||||
uuid_generate_v4(),
|
||||
|
|
@ -90,7 +80,6 @@ INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
|||
'http://3.bp.blogspot.com/-NUKSXr1qLHs/UQmsaEFgbTI/AAAAAAAAA_Y/l4psfVl4a5A/s1600/white-powdered-sugar-doughnuts-tracie-kaska.jpg',
|
||||
ST_GeogFromText('SRID=4326;POINT(-97.742308 30.263963300000004)')
|
||||
);
|
||||
|
||||
INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
||||
VALUES (
|
||||
uuid_generate_v4(),
|
||||
|
|
@ -101,7 +90,6 @@ INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
|||
'http://josephcphillips.com/wp-content/uploads/2015/02/snickerdoodles2.jpg',
|
||||
ST_GeogFromText('SRID=4326;POINT(-97.73798459999999 30.266898599999998)')
|
||||
);
|
||||
|
||||
INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
||||
VALUES (
|
||||
uuid_generate_v4(),
|
||||
|
|
@ -112,9 +100,7 @@ INSERT INTO food_items (id, name, place_id, category, images, thumbImage, loc)
|
|||
'http://www.foodandhealth.co.uk/wp-content/uploads/2016/05/Hot-stone-Vegan-Pizza.jpg',
|
||||
ST_GeogFromText('SRID=4326;POINT(-97.73798459999999 30.266898599999998)')
|
||||
);
|
||||
|
||||
INSERT INTO quantities SELECT id, current_timestamp, 'many' FROM food_items;
|
||||
|
||||
CREATE VIEW latest_quantities AS SELECT food_item_id, quantity, date from quantities q1 where date = (
|
||||
SELECT max(date) FROM quantities q2 WHERE q1.food_item_id=q2.food_item_id
|
||||
);
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
(ns aretherecookies.app
|
||||
(:gen-class)
|
||||
(:require [aretherecookies.handler :refer [food-items-handler quantity-handler]]
|
||||
(:require [aretherecookies.handler :refer [food-items-handler quantity-handler add-food-item-handler]]
|
||||
[aretherecookies.auth :refer [auth-backend]]
|
||||
[environ.core :refer [env]]
|
||||
[compojure.handler :refer [api]]
|
||||
|
|
@ -16,7 +16,8 @@
|
|||
(GET "/" [] (str {:csrf-token *anti-forgery-token*}))
|
||||
(POST "/test" [] "ok")
|
||||
(POST "/fooditems" [] food-items-handler)
|
||||
(POST "/quantity" [] quantity-handler))
|
||||
(POST "/quantity" [] quantity-handler)
|
||||
(POST "/addfooditem" [] add-food-item-handler))
|
||||
|
||||
(def app-config (assoc-in api-defaults [:security :anti-forgery] false))
|
||||
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@
|
|||
(defn facebook-me [token]
|
||||
(client/get (str "https://graph.facebook.com/me?access_token=" token) {:accept :json}))
|
||||
|
||||
(defn facebook-me-ok [token]
|
||||
(defn facebook-me-ok? [token]
|
||||
(= 200 (:status (facebook-me token))) (swap! tokens assoc (keyword token) true))
|
||||
|
||||
(defn facebook-token-auth [_ token]
|
||||
(cond
|
||||
(get @tokens (keyword token)) token
|
||||
(facebook-me-ok token) token))
|
||||
(facebook-me-ok? token) token))
|
||||
|
||||
(def auth-backend
|
||||
(backends/token {:token-name "facebook-token" :authfn facebook-token-auth}))
|
||||
|
|
@ -63,7 +63,10 @@
|
|||
:order (get-orderby filter)}))
|
||||
|
||||
(defn insert-quantity [{:keys [:foodItemId :quantity]}]
|
||||
(insert-quantity-query @pooled-db {:food_item_id (wrap-in-quotes foodItemId) :quantity (wrap-in-quotes quantity)}))
|
||||
(insert-quantity-query @pooled-db {:food_item_id foodItemId :quantity quantity}))
|
||||
|
||||
(defn select-latest-quantity [{:keys [:foodItemId]}]
|
||||
(select-latest-quantity-query @pooled-db {:food_item_id (wrap-in-quotes foodItemId)}))
|
||||
|
||||
(defn create-food-item [{:keys [:name :placeId :category :latitude :longitude]}]
|
||||
(insert-food-item @pooled-db {:name name :placeId placeId :category category :longitude longitude :latitude latitude}))
|
||||
|
|
|
|||
|
|
@ -1,24 +1,52 @@
|
|||
(ns aretherecookies.handler
|
||||
(:require [aretherecookies.db :refer [query-food-items insert-quantity]]
|
||||
[aretherecookies.parsers :refer [food-items-to-json
|
||||
parse-special-types]]
|
||||
(:require [aretherecookies.db :refer [query-food-items
|
||||
insert-quantity
|
||||
create-food-item]]
|
||||
[aretherecookies.parsers :refer [parse-special-types parse-location]]
|
||||
[clojure.data.json :as json]
|
||||
[clojure.string :as str]
|
||||
[buddy.auth :refer [authenticated? throw-unauthorized]]))
|
||||
|
||||
(defn safe-json
|
||||
"converts hashmaps into a JSON string suitable for a network response"
|
||||
[data]
|
||||
(json/write-str data :value-fn parse-special-types))
|
||||
|
||||
(defn bad-request
|
||||
"returns a HTTP 404 error with the supplied body"
|
||||
[body]
|
||||
{:status 400 :body (safe-json body)})
|
||||
|
||||
(defn food-items-handler [req]
|
||||
(println "req ---->" (:body req))
|
||||
(println "/fooditems ---->" (:body req))
|
||||
(let [{body :body} req]
|
||||
(json/write-str
|
||||
(safe-json
|
||||
(hash-map
|
||||
:filter (get body :filter)
|
||||
:fooditems (food-items-to-json (query-food-items body)))
|
||||
:value-fn parse-special-types)))
|
||||
:filter (:filter body)
|
||||
:fooditems (map parse-location (query-food-items body))))))
|
||||
|
||||
(defn quantity-handler [req]
|
||||
(let [{{foodItemId :foodItemId quantity :quantity} :body} req]
|
||||
(if-not (authenticated? req) (throw-unauthorized))
|
||||
(println "req ---->" foodItemId quantity)
|
||||
(println "/quantity ---->" foodItemId quantity)
|
||||
(json/write-str
|
||||
(insert-quantity {:foodItemId foodItemId :quantity quantity})
|
||||
:value-fn parse-special-types)))
|
||||
|
||||
(def required-keys [:name :placeId :latitude :longitude :category :quantity])
|
||||
(defn get-missing-keys
|
||||
[foodItem]
|
||||
(filter #(get foodItem %) required-keys))
|
||||
|
||||
(defn add-food-item-handler
|
||||
"validate food item fields from request and insert into database returning newly created item"
|
||||
[req]
|
||||
(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)
|
||||
(bad-request {"missingkeys" missing-keys})
|
||||
(as->
|
||||
(create-food-item food-item) %
|
||||
(map parse-location %)
|
||||
(safe-json %)))))
|
||||
|
|
|
|||
|
|
@ -12,24 +12,16 @@
|
|||
|
||||
(defn get-coords [item]
|
||||
(->
|
||||
item
|
||||
(:location)
|
||||
json/read-str
|
||||
(:coordinates)))
|
||||
|
||||
(defn build-lat-lng [[lng lat]]
|
||||
(hash-map :longitude lng :latitude lat))
|
||||
(:location item)
|
||||
json/read-str
|
||||
(:coordinates)))
|
||||
|
||||
(defn build-latlng [item]
|
||||
(let [[lng lat] (get-coords item)]
|
||||
(hash-map :longitude lng :latitude lat)))
|
||||
(let [[longitude latitude] (get-coords item)]
|
||||
(hash-map :longitude longitude :latitude latitude)))
|
||||
|
||||
(defn parse-location [item]
|
||||
(defn parse-location [food-item]
|
||||
(->
|
||||
item
|
||||
build-latlng
|
||||
(merge item)
|
||||
(dissoc :location)))
|
||||
|
||||
(defn food-items-to-json [query-result]
|
||||
(map parse-location query-result))
|
||||
(build-latlng food-item)
|
||||
(merge food-item)
|
||||
(dissoc :location)))
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ ORDER BY quantity DESC
|
|||
|
||||
-- :name insert-quantity-query
|
||||
INSERT INTO quantities (food_item_id, quantity, date)
|
||||
VALUES (:i:food_item_id, :i:quantity, current_timestamp)
|
||||
VALUES (:v:food_item_id::uuid, :v:quantity::quantity, current_timestamp)
|
||||
RETURNING *
|
||||
|
||||
-- :name select-latest-quantity-query
|
||||
|
|
@ -44,3 +44,22 @@ SELECT food_item_id, quantity, date AS updated
|
|||
FROM quantities
|
||||
WHERE food_item_id=:i:food_item_id
|
||||
ORDER BY date DESC LIMIT 1
|
||||
|
||||
-- :name insert-food-item
|
||||
INSERT INTO food_items (id, name, place_id, category, loc)
|
||||
VALUES (
|
||||
uuid_generate_v4(),
|
||||
:v:name,
|
||||
:v:placeId,
|
||||
:v:category::category,
|
||||
ST_SetSRID(ST_Point(:longitude, :latitude), 4326)::geography
|
||||
)
|
||||
RETURNING
|
||||
id AS id,
|
||||
name AS name,
|
||||
place_id AS place_id,
|
||||
category AS category,
|
||||
images AS images,
|
||||
thumbImage AS thumbImage,
|
||||
ST_AsGeoJSON(loc) AS location,
|
||||
ST_Distance(loc, ST_SetSRID(ST_Point(:longitude, :latitude), 4326)::geography) / 1609 AS distance
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue