Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Natasha Chitter Challenge #2176

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,12 @@ end
group :development, :test do
gem 'rubocop', '1.20'
end

gem "sinatra", "~> 3.0"
gem "sinatra-contrib", "~> 3.0"
gem "webrick", "~> 1.8"
gem "rack-test", "~> 2.1"

gem "pg", "~> 1.4"

gem "bcrypt"
30 changes: 30 additions & 0 deletions Gemfile.lock

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good. Could you check all the gems are in use please? Thank you.

Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,21 @@ GEM
specs:
ansi (1.5.0)
ast (2.4.2)
bcrypt (3.1.18)
diff-lcs (1.4.4)
docile (1.4.0)
multi_json (1.15.0)
mustermann (3.0.0)
ruby2_keywords (~> 0.0.1)
parallel (1.20.1)
parser (3.0.2.0)
ast (~> 2.4.1)
pg (1.4.6)
rack (2.2.6.4)
rack-protection (3.0.6)
rack
rack-test (2.1.0)
rack (>= 1.3)
rainbow (3.0.0)
regexp_parser (2.1.1)
rexml (3.2.5)
Expand Down Expand Up @@ -36,6 +46,7 @@ GEM
rubocop-ast (1.11.0)
parser (>= 3.0.1.1)
ruby-progressbar (1.11.0)
ruby2_keywords (0.0.5)
simplecov (0.21.2)
docile (~> 1.1)
simplecov-html (~> 0.11)
Expand All @@ -46,18 +57,37 @@ GEM
terminal-table
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.3)
sinatra (3.0.6)
mustermann (~> 3.0)
rack (~> 2.2, >= 2.2.4)
rack-protection (= 3.0.6)
tilt (~> 2.0)
sinatra-contrib (3.0.6)
multi_json
mustermann (~> 3.0)
rack-protection (= 3.0.6)
sinatra (= 3.0.6)
tilt (~> 2.0)
terminal-table (3.0.1)
unicode-display_width (>= 1.1.1, < 3)
tilt (2.1.0)
unicode-display_width (2.0.0)
webrick (1.8.1)

PLATFORMS
ruby

DEPENDENCIES
bcrypt
pg (~> 1.4)
rack-test (~> 2.1)
rspec
rubocop (= 1.20)
simplecov
simplecov-console
sinatra (~> 3.0)
sinatra-contrib (~> 3.0)
webrick (~> 1.8)

RUBY VERSION
ruby 3.0.2p107
Expand Down
100 changes: 100 additions & 0 deletions app.rb

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent naming convention

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure about logic convention, something to research

Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
require 'sinatra/base'
require 'sinatra/reloader'
require_relative 'lib/database_connection'
require_relative 'lib/user_repository'
require_relative 'lib/peep_repository'
require 'bcrypt'

DatabaseConnection.connect

class Application < Sinatra::Base
enable :sessions
# This allows the app code to refresh
# without having to restart the server.
configure :development do
register Sinatra::Reloader
also_reload 'lib/user_repository'
also_reload 'lib/peep_repository'
end

get '/' do
user_repo = UserRepository.new
peep_repo = PeepRepository.new
peeps = peep_repo.all

@complete_peep_info = []

peeps.each do |peep|
user = user_repo.find(peep.user_id)
peep_info = {peep: peep, name: user.name, username: user.username}
@complete_peep_info << peep_info
end

return erb(:index) # add log in status logic
end

get '/login' do
return erb(:login)
end

post '/login' do
email = params[:email]
password = params[:password]

user_repo = UserRepository.new

user = user_repo.find_by_email(email)
stored_password = BCrypt::Password.new(user.password)

if stored_password == password
session[:user_id] = user.id
return erb(:login_success)
else
return erb(:wrong_password)
end
end

get '/peeps/new' do
if session[:user_id] == nil
return erb(:login)
else
return erb(:new_peep)
end
end

post '/peeps' do
if session[:user_id] == nil
return erb(:login)
else
peep_repo = PeepRepository.new
new_peep = Peep.new
new_peep.time = Time.now
new_peep.content = params[:content]
new_peep.user_id = session[:user_id]

peep_repo.create(new_peep)

return erb(:new_peep_success)
end
end

get '/signup' do
return erb(:signup)
end

post '/signup' do
repo = UserRepository.new
new_user = User.new

new_user.name = params[:name] # name and username must be unique
new_user.username = params[:username]
new_user.email = params[:email]
new_user.password = params[:password]

repo.create(new_user)

return erb(:signup_success)
end

# add invalid_parameters? method
end
3 changes: 3 additions & 0 deletions config.ru
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# file: config.ru
require './app'
run Application
38 changes: 38 additions & 0 deletions lib/database_connection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# file: lib/database_connection.rb

require 'pg'

# This class is a thin "wrapper" around the
# PG library. We'll use it in our project to interact
# with the database using SQL.

class DatabaseConnection
# This method connects to PostgreSQL using the
# PG gem. We connect to 127.0.0.1, and select
# the database name given in argument.
def self.connect
if ENV['DATABASE_URL'] != nil
@connection = PG.connect(ENV['DATABASE_URL'])
return
end

if ENV['ENV'] == 'test'
database_name = 'chitter_challenge_test'
else
database_name = 'chitter_challenge'
end
@connection = PG.connect({ host: '127.0.0.1', dbname: database_name })
end

# This method executes an SQL query
# on the database, providing some optional parameters
# (you will learn a bit later about when to provide these parameters).
def self.exec_params(query, params)
if @connection.nil?
raise 'DatabaseConnection.exec_params: Cannot run a SQL query as the connection to'\
'the database was never opened. Did you make sure to call first the method '\
'`DatabaseConnection.connect` in your app.rb file (or in your tests spec_helper.rb)?'
end
@connection.exec_params(query, params)
end
end
3 changes: 3 additions & 0 deletions lib/peep.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Peep
attr_accessor :id, :time, :content, :user_id
end
30 changes: 30 additions & 0 deletions lib/peep_repository.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require_relative 'peep'

class PeepRepository
def all
peeps = []

sql = 'SELECT id, time, content, user_id FROM peeps ORDER BY time DESC;'
result_set = DatabaseConnection.exec_params(sql, [])

result_set.each do |record|
peep = Peep.new
peep.id = record['id']
peep.time = record['time']
peep.content = record['content']
peep.user_id = record['user_id']

peeps << peep
end

return peeps
end

def create(peep)
sql = 'INSERT INTO peeps (time, content, user_id) VALUES ($1, $2, $3);'
params = [peep.time, peep.content, peep.user_id]
result_set = DatabaseConnection.exec_params(sql, params)

return peep
end
end
3 changes: 3 additions & 0 deletions lib/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class User
attr_accessor :id, :name, :username, :email, :password
end
42 changes: 42 additions & 0 deletions lib/user_repository.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
require_relative 'user'
require 'bcrypt'

class UserRepository
def create(new_user)
encrypted_password = BCrypt::Password.create(new_user.password)

sql = 'INSERT INTO users (name, username, email, password) VALUES ($1, $2, $3, $4);'
params = [new_user.name, new_user.username, new_user.email, encrypted_password]
DatabaseConnection.exec_params(sql, params)

return new_user
end

def find_by_email(email)
sql = 'SELECT id, name, username, email, password FROM users WHERE email = $1;'
result_set = DatabaseConnection.exec_params(sql, [email])

user = User.new
user.id = result_set[0]['id']
user.name = result_set[0]['name']
user.username = result_set[0]['username']
user.email = result_set[0]['email']
user.password = result_set[0]['password']

return user
end

def find(id)
sql = 'SELECT id, name, username, email, password FROM users WHERE id = $1;'
result_set = DatabaseConnection.exec_params(sql, [id])

user = User.new
user.id = result_set[0]['id']
user.name = result_set[0]['name']
user.username = result_set[0]['username']
user.email = result_set[0]['email']
user.password = result_set[0]['password']

return user
end
end
Loading