diff --git a/Gemfile b/Gemfile index 66526d43..876e73a0 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,7 @@ source 'https://rubygems.org' ruby '2.0.0' +gem 'pg' gem 'rspec', '~> 2.14.1' gem 'sinatra', '~> 1.4.5' gem 'sinatra-contrib', '~> 1.4.2' diff --git a/Gemfile.lock b/Gemfile.lock index bbeebb1e..f4cf3bf0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -14,6 +14,7 @@ GEM mime-types (1.25.1) multi_json (1.10.1) netrc (0.8.0) + pg (0.17.1) pry (0.10.1) coderay (~> 1.1.0) method_source (~> 0.8.1) @@ -55,6 +56,7 @@ PLATFORMS ruby DEPENDENCIES + pg pry-byebug rest-client rspec (~> 2.14.1) diff --git a/README.md b/README.md new file mode 100644 index 00000000..1fda7c14 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +Having fun with Pet-Shop-Server diff --git a/lib/petshop.rb b/lib/petshop.rb new file mode 100644 index 00000000..b970f06e --- /dev/null +++ b/lib/petshop.rb @@ -0,0 +1,155 @@ +require 'pg' +require 'json' +require 'rest-client' + +require_relative 'petshop/repos/cats_repo.rb' +require_relative 'petshop/repos/dogs_repo.rb' +require_relative 'petshop/repos/shops_repo.rb' +require_relative 'petshop/repos/users_repo.rb' + +module Petshop + def self.create_db_connection(dbname) + PG.connect(host: 'localhost', dbname: dbname) + end + + def self.clear_db(db) + db.exec <<-SQL + DELETE FROM cats; + DELETE FROM dogs; + DELETE FROM users; + DELETE FROM shops; + SQL + end + + def self.create_tables(db) + db.exec <<-SQL + CREATE TABLE IF NOT EXISTS shops( + id SERIAL PRIMARY KEY, + name VARCHAR + ); + CREATE TABLE IF NOT EXISTS users( + id SERIAL PRIMARY KEY, + username VARCHAR, + password VARCHAR + ); + CREATE TABLE IF NOT EXISTS dogs( + id SERIAL PRIMARY KEY, + shopid INT references shops(id), + userid INT references users(id), + name VARCHAR, + imageurl VARCHAR, + adopted BOOLEAN, + happiness INT + ); + CREATE TABLE IF NOT EXISTS cats( + id SERIAL PRIMARY KEY, + shopid INT references shops(id), + userid INT references users(id), + name VARCHAR, + imageurl VARCHAR, + adopted BOOLEAN + ); + SQL + end + + def self.seed_shops(db) + #parse JSON data for shops + shops = JSON.parse RestClient.get("http://pet-shop.api.mks.io/shops") + + sql = %q[ + INSERT INTO shops(id, name) + VALUES ($1, $2) + ] + + shops.each do |data| + id = data["id"] + name = data["name"] + + db.exec(sql, [id, name]) + end + + end + + def self.seed_users(db) + sql = %q[ + INSERT INTO users (username, password) + VALUES ('testuser', 'pass123') + ] + db.exec(sql) + end + + def self.seed_cats(db) + + #parse JSON data for shops + shops = JSON.parse RestClient.get("http://pet-shop.api.mks.io/shops") + + #get the cats information + cats = shops.map do |shop| + shop_id = shop['id'] + JSON.parse RestClient.get("http://pet-shop.api.mks.io/shops/#{shop_id}/cats") + end + + flatcats = cats.flatten + + sql = %q[ + INSERT INTO cats(id, shopid, name, imageurl, adopted) + VALUES ($1, $2, $3, $4, $5) + ] + + flatcats.each do |cat| + id = cat["id"] + shopid = cat["shopid"] + name = cat["name"] + imageurl = cat["imageurl"] + adopted = cat["adopted"] ? true : false + + db.exec(sql, [id, shopid, name, imageurl, adopted]) + end + +end + + def self.seed_dogs(db) + + #parse JSON data for shops + shops = JSON.parse RestClient.get("http://pet-shop.api.mks.io/shops") + + #get the dogs information + dogs = shops.map do |shop| + shop_id = shop['id'] + JSON.parse RestClient.get("http://pet-shop.api.mks.io/shops/#{shop_id}/dogs") + end + + flatdogs = dogs.flatten + + sql = %q[ + INSERT INTO dogs(id, shopid, name, imageurl, adopted, happiness) + VALUES ($1, $2, $3, $4, $5, $6) + ] + + flatdogs.each do |dog| + id = dog["id"] + shopid = dog["shopid"] + name = dog["name"] + imageurl = dog["imageurl"] + adopted = dog["adopted"] ? true : false + happiness = dog["happiness"] + + db.exec(sql, [id, shopid, name, imageurl, adopted, happiness]) + end + + end + + def self.drop_tables(db) + db.exec <<-SQL + DROP TABLE cats; + DROP TABLE dogs; + DROP TABLE users; + DROP TABLE shops; + SQL + end +end + + + + + diff --git a/lib/petshop/repos/cats_repo.rb b/lib/petshop/repos/cats_repo.rb new file mode 100644 index 00000000..b0ad329c --- /dev/null +++ b/lib/petshop/repos/cats_repo.rb @@ -0,0 +1,49 @@ +module Petshop + class CatsRepo + def self.all db + sql = %q[SELECT * FROM cats] + result = db.exec(sql) + result.entries + end + + def self.find db, id + sql = %q[SELECT * FROM cats WHERE id = $1] + result = db.exec(sql, [id]) + result.first + end + + def self.find_by_shopid db, shop_id + sql = %q[SELECT shopid, id, userid, name, imageurl as "imageUrl" FROM cats WHERE shopid = $1] + result = db.exec(sql, [shop_id]) + result.to_a + end + + def self.find_available db, adopted, shop_id + sql = %q[SELECT * FROM cats WHERE adopted != $1 AND shopid = $2] + result = db.exec(sql, [true], [shop_id]) + result.to_a + end + + + + + def self.save db, cat_name + if cat_name[:id] + sql = %q[UPDATE cats SET content = $1 WHERE id = $2 RETURNING *] + result = db.exec(sql, [cat_name[:name], cat_name[:id]]) + else + sql = %q[INSERT INTO cats (cat_name) VALUES ($1) RETURNING *] + result = db.exec(sql, [cat_name[:name], cat_name[:id]]) + end + + result.first + end + + def self.destroy db, id + sql = %q[DELETE FROM cats WHERE id = $1] + db.exec(sql, [id]) + post_exists?(db, id) + end + + end +end \ No newline at end of file diff --git a/lib/petshop/repos/dogs_repo.rb b/lib/petshop/repos/dogs_repo.rb new file mode 100644 index 00000000..c6e0bba8 --- /dev/null +++ b/lib/petshop/repos/dogs_repo.rb @@ -0,0 +1,40 @@ +module Petshop + class DogsRepo + def self.all db + sql = %q[SELECT * FROM dogs] + result = db.exec(sql) + result.entries + end + + def self.find db, id + sql = %q[SELECT * FROM dogs WHERE id = $1] + result = db.exec(sql, [id]) + result.first + end + + def self.find_by_shopid db, shop_id + sql = %q[SELECT shopid, id, userid, name, imageurl as "imageUrl", happiness FROM dogs WHERE shopid = $1] + result = db.exec(sql, [shop_id]) + result.to_a + end + + def self.save db, dog_name + if dog_name[:id] + sql = %q[UPDATE dogs SET content = $1 WHERE id = $2 RETURNING *] + result = db.exec(sql, [dog_name[:name], dog_name[:id]]) + else + sql = %q[INSERT INTO dogs (dog_name) VALUES ($1) RETURNING *] + result = db.exec(sql, [dog_name[:name], dog_name[:id]]) + end + + result.first + end + + def self.destroy db, id + sql = %q[DELETE FROM dogs WHERE id = $1] + db.exec(sql, [id]) + post_exists?(db, id) + end + + end +end \ No newline at end of file diff --git a/lib/petshop/repos/shops_repo.rb b/lib/petshop/repos/shops_repo.rb new file mode 100644 index 00000000..7f833fa2 --- /dev/null +++ b/lib/petshop/repos/shops_repo.rb @@ -0,0 +1,34 @@ +module Petshop + class ShopsRepo + def self.all db + sql = %q[SELECT * FROM shops] + result = db.exec(sql) + result.entries + end + + def self.find db, id + sql = %q[SELECT * FROM shops WHERE id = $1] + result = db.exec(sql, [id]) + result.first + end + + def self.save db, shop_name + if shop_name[:id] + sql = %q[UPDATE shops SET content = $1 WHERE id = $2 RETURNING *] + result = db.exec(sql, [shop_name[:name], shop_name[:id]]) + else + sql = %q[INSERT INTO shops (shop_name) VALUES ($1) RETURNING *] + result = db.exec(sql, [shop_name[:name], shop_name[:id]]) + end + + result.first + end + + def self.destroy db, id + sql = %q[DELETE FROM shops WHERE id = $1] + db.exec(sql, [id]) + post_exists?(db, id) + end + + end +end diff --git a/lib/petshop/repos/users_repo.rb b/lib/petshop/repos/users_repo.rb new file mode 100644 index 00000000..f859a72a --- /dev/null +++ b/lib/petshop/repos/users_repo.rb @@ -0,0 +1,28 @@ +module Petshop + class UsersRepo + # find a user by user ID. Intended to be used when + # someone is already authenticated. We keep their + # user id in the cookie. + def self.find db, user_id + sql = %q[SELECT * FROM users WHERE id = $1] + result = db.exec(sql, [user_id]) + result.first + end + + # find user by username. Intended to be used when + # someone tries to sign in. + def self.find_by_name db, username + sql = %q[SELECT * FROM users WHERE username = $1] + result = db.exec(sql, [username]) + result.first + end + + # when someone signs up use this method to save their + # information in the db. we're not encrypting passwords. + def self.save db, user_data + sql = %q[INSERT INTO users (username, password) VALUES ($1, $2) RETURNING *] + result = db.exec(sql, [user_data[:username], user_data[:password]]) + result.first + end + end +end diff --git a/server.rb b/server.rb index 07df95f4..6a746fe1 100644 --- a/server.rb +++ b/server.rb @@ -3,13 +3,21 @@ require 'rest-client' require 'json' +set :bind, '0.0.0.0' +enable :sessions + +require_relative 'lib/petshop.rb' + # # # This is our only html view... # get '/' do if session[:user_id] + user_id = session['user_id'] # TODO: Grab user from database - @current_user = $sample_user + # db = Petshop.create_db_connection('Petshop_Test') + # @current_user = Petshop::UsersRepo.find(db, user_id) + @current_user = $awesome_user end erb :index end @@ -19,26 +27,48 @@ # get '/shops' do headers['Content-Type'] = 'application/json' - RestClient.get("http://pet-shop.api.mks.io/shops") + # RestClient.get("http://pet-shop.api.mks.io/shops") + db = Petshop.create_db_connection('Petshop_Test') + Petshop::ShopsRepo.all(db).to_json end post '/signin' do + params = JSON.parse request.body.read username = params['username'] password = params['password'] - # TODO: Grab user by username from database and check password - user = { 'username' => 'alice', 'password' => '123' } + # # TODO: Grab user by username from database and check password + db = Petshop.create_db_connection('Petshop_Test') + user = Petshop::UsersRepo.find_by_name(db, params['username']) - if password == user['password'] + $awesome_user = { username: params['username']} + + if user + if password == user['password'] headers['Content-Type'] = 'application/json' - # TODO: Return all pets adopted by this user - # TODO: Set session[:user_id] so the server will remember this user has logged in - $sample_user.to_json + # # TODO: Return all pets adopted by this user + session[:user_id] = user['id'] + $awesome_user.to_json + + else + status 401 + end else - status 401 + status 401 end + + # user = { 'username' => 'alice', 'password' => '123' } + + # if password == user['password'] + # headers['Content-Type'] = 'application/json' + + # # TODO: Set session[:user_id] so the server will remember this user has logged in + # $sample_user.to_json + # else + # status 401 + # end end # # # # @@ -46,18 +76,30 @@ # # # # get '/shops/:id/cats' do headers['Content-Type'] = 'application/json' - id = params[:id] + #id = params[:id] + shop_id = params[:id] # TODO: Grab from database instead - RestClient.get("http://pet-shop.api.mks.io/shops/#{id}/cats") + #RestClient.get("http://pet-shop.api.mks.io/shops/#{id}/cats") + db = Petshop.create_db_connection('Petshop_Test') + cats = Petshop::CatsRepo.find_by_shopid(db, shop_id) + cats.to_json end +## CAT ADOPTION: WORK IN PROGRESS put '/shops/:shop_id/cats/:id/adopt' do headers['Content-Type'] = 'application/json' + params = JSON.parse request.body.read + shop_id = params[:shop_id] id = params[:id] + + db = Petshop.create_db_connection('Petshop_Test') + avail_cats = Petshop::CatsRepo.find_available(db, adopted) + avail_cats.to_json + # TODO: Grab from database instead - RestClient.put("http://pet-shop.api.mks.io/shops/#{shop_id}/cats/#{id}", - { adopted: true }, :content_type => 'application/json') + # RestClient.put("http://pet-shop.api.mks.io/shops/#{shop_id}/cats/#{id}", + # { adopted: true }, :content_type => 'application/json') # TODO (after you create users table): Attach new cat to logged in user end @@ -67,11 +109,15 @@ # # # # get '/shops/:id/dogs' do headers['Content-Type'] = 'application/json' - id = params[:id] + shop_id = params[:id] # TODO: Update database instead - RestClient.get("http://pet-shop.api.mks.io/shops/#{id}/dogs") + #RestClient.get("http://pet-shop.api.mks.io/shops/#{id}/dogs") + db = Petshop.create_db_connection('Petshop_Test') + dogs = Petshop::DogsRepo.find_by_shopid(db, shop_id) + dogs.to_json end +## DOG ADOPTION: WORK IN PROGRESS put '/shops/:shop_id/dogs/:id/adopt' do headers['Content-Type'] = 'application/json' shop_id = params[:shop_id] @@ -83,14 +129,14 @@ end -$sample_user = { - id: 999, - username: 'alice', - cats: [ - { shopId: 1, name: "NaN Cat", imageUrl: "http://i.imgur.com/TOEskNX.jpg", adopted: true, id: 44 }, - { shopId: 8, name: "Meowzer", imageUrl: "http://www.randomkittengenerator.com/images/cats/rotator.php", id: 8, adopted: "true" } - ], - dogs: [ - { shopId: 1, name: "Leaf Pup", imageUrl: "http://i.imgur.com/kuSHji2.jpg", happiness: 2, id: 2, adopted: "true" } - ] -} +# $sample_user = { +# id: 999, +# username: 'alice', +# cats: [ +# { shopId: 1, name: "NaN Cat", imageUrl: "http://i.imgur.com/TOEskNX.jpg", adopted: true, id: 44 }, +# { shopId: 8, name: "Meowzer", imageUrl: "http://www.randomkittengenerator.com/images/cats/rotator.php", id: 8, adopted: "true" } +# ], +# dogs: [ +# { shopId: 1, name: "Leaf Pup", imageUrl: "http://i.imgur.com/kuSHji2.jpg", happiness: 2, id: 2, adopted: "true" } +# ] +# }