This repository was archived by the owner on Nov 28, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.rb
More file actions
174 lines (148 loc) · 5.19 KB
/
app.rb
File metadata and controls
174 lines (148 loc) · 5.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
require 'sinatra/base'
require 'mysql2'
require 'mysql2-cs-bind'
require 'erubis'
module Ishocon1
class AuthenticationError < StandardError; end
class PermissionDenied < StandardError; end
end
class Ishocon1::WebApp < Sinatra::Base
session_secret = ENV['ISHOCON1_SESSION_SECRET'] || 'showwin_happy'
use Rack::Session::Cookie, key: 'rack.session', secret: session_secret
set :erb, escape_html: true
set :public_folder, File.expand_path('../public', __FILE__)
set :protection, true
helpers do
def config
@config ||= {
db: {
host: ENV['ISHOCON1_DB_HOST'] || 'localhost',
port: ENV['ISHOCON1_DB_PORT'] && ENV['ISHOCON1_DB_PORT'].to_i,
username: ENV['ISHOCON1_DB_USER'] || 'ishocon',
password: ENV['ISHOCON1_DB_PASSWORD'] || 'ishocon',
database: ENV['ISHOCON1_DB_NAME'] || 'ishocon1'
}
}
end
def db
return Thread.current[:ishocon1_db] if Thread.current[:ishocon1_db]
client = Mysql2::Client.new(
host: config[:db][:host],
port: config[:db][:port],
username: config[:db][:username],
password: config[:db][:password],
database: config[:db][:database],
reconnect: true
)
client.query_options.merge!(symbolize_keys: true)
Thread.current[:ishocon1_db] = client
client
end
def time_now_db
Time.now - 9 * 60 * 60
end
def authenticate(email, password)
user = db.xquery('SELECT * FROM users WHERE email = ?', email).first
fail Ishocon1::AuthenticationError unless user[:password] == password
session[:user_id] = user[:id]
end
def authenticated!
fail Ishocon1::PermissionDenied unless current_user
end
def current_user
db.xquery('SELECT * FROM users WHERE id = ?', session[:user_id]).first
end
def update_last_login(user_id)
db.xquery('UPDATE users SET last_login = ? WHERE id = ?', time_now_db, user_id)
end
def buy_product(product_id, user_id)
db.xquery('INSERT INTO histories (product_id, user_id, created_at) VALUES (?, ?, ?)', \
product_id, user_id, time_now_db)
end
def already_bought?(product_id)
return false unless current_user
count = db.xquery('SELECT count(*) as count FROM histories WHERE product_id = ? AND user_id = ?', \
product_id, current_user[:id]).first[:count]
count > 0
end
def create_comment(product_id, user_id, content)
db.xquery('INSERT INTO comments (product_id, user_id, content, created_at) VALUES (?, ?, ?, ?)', \
product_id, user_id, content, time_now_db)
end
end
error Ishocon1::AuthenticationError do
session[:user_id] = nil
halt 401, erb(:login, layout: false, locals: { message: 'ログインに失敗しました' })
end
error Ishocon1::PermissionDenied do
halt 403, erb(:login, layout: false, locals: { message: '先にログインをしてください' })
end
get '/login' do
session.clear
erb :login, layout: false, locals: { message: 'ECサイトで爆買いしよう!!!!' }
end
post '/login' do
authenticate(params['email'], params['password'])
update_last_login(current_user[:id])
redirect '/'
end
get '/logout' do
session[:user_id] = nil
session.clear
redirect '/login'
end
get '/' do
page = params[:page].to_i || 0
products = db.xquery("SELECT * FROM products ORDER BY id DESC LIMIT 50 OFFSET #{page * 50}")
cmt_query = <<SQL
SELECT *
FROM comments as c
INNER JOIN users as u
ON c.user_id = u.id
WHERE c.product_id = ?
ORDER BY c.created_at DESC
LIMIT 5
SQL
cmt_count_query = 'SELECT count(*) as count FROM comments WHERE product_id = ?'
erb :index, locals: { products: products, cmt_query: cmt_query, cmt_count_query: cmt_count_query }
end
get '/users/:user_id' do
products_query = <<SQL
SELECT p.id, p.name, p.description, p.image_path, p.price, h.created_at
FROM histories as h
LEFT OUTER JOIN products as p
ON h.product_id = p.id
WHERE h.user_id = ?
ORDER BY h.id DESC
SQL
products = db.xquery(products_query, params[:user_id])
total_pay = 0
products.each do |product|
total_pay += product[:price]
end
user = db.xquery('SELECT * FROM users WHERE id = ?', params[:user_id]).first
erb :mypage, locals: { products: products, user: user, total_pay: total_pay }
end
get '/products/:product_id' do
product = db.xquery('SELECT * FROM products WHERE id = ?', params[:product_id]).first
comments = db.xquery('SELECT * FROM comments WHERE product_id = ?', params[:product_id])
erb :product, locals: { product: product, comments: comments }
end
post '/products/buy/:product_id' do
authenticated!
buy_product(params[:product_id], current_user[:id])
redirect "/users/#{current_user[:id]}"
end
post '/comments/:product_id' do
authenticated!
create_comment(params[:product_id], current_user[:id], params[:content])
redirect "/users/#{current_user[:id]}"
end
get '/initialize' do
db.query('DELETE FROM users WHERE id > 5000')
db.query('DELETE FROM products WHERE id > 10000')
db.query('DELETE FROM comments WHERE id > 200000')
db.query('DELETE FROM histories WHERE id > 500000')
"Finish"
end
end