Skip to content
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.DS_Store
.idea
.env
log/app.log
.byebug_history
6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
source 'https://rubygems.org'

gem 'sequel'
gem 'sqlite3'
gem 'rack'
gem 'byebug'
19 changes: 19 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
GEM
remote: https://rubygems.org/
specs:
byebug (11.0.1)
rack (2.0.7)
sequel (5.19.0)
sqlite3 (1.4.1)

PLATFORMS
ruby

DEPENDENCIES
byebug
rack
sequel
sqlite3

BUNDLED WITH
2.0.1
5 changes: 5 additions & 0 deletions app/controllers/tests_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ class TestsController < Simpler::Controller

def index
@time = Time.now
# render plain: "Hello world!"
end

def create

end

def show
@test = Test.first(id: params[:id])
end

end
12 changes: 12 additions & 0 deletions app/views/tests/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Show | Simpler application</title>
</head>
<body>
<h1>Simpler framework at work!</h1>

<p><%= @test.title %></p>
</body>
</html>
1 change: 1 addition & 0 deletions config.ru
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require_relative 'config/environment'

use AppLogger, logdev: File.expand_path('log/app.log', __dir__)
run Simpler.application
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Simpler.application.routes do
get '/tests', 'tests#index'
post '/tests', 'tests#create'
get '/tests/:id', 'tests#show'
end
1 change: 1 addition & 0 deletions lib/simpler.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'pathname'
require_relative 'simpler/middleware/logger'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Лучше подключить это сразу в config.ru, поскольку middleware там же подключается.

require_relative 'simpler/application'

module Simpler
Expand Down
6 changes: 6 additions & 0 deletions lib/simpler/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ def routes(&block)

def call(env)
route = @router.route_for(env)
return error_404 if route.nil?
env['simpler.params'] = route.params
controller = route.controller.new(env)
action = route.action

Expand All @@ -36,6 +38,10 @@ def call(env)

private

def error_404
[404, { 'Content-Type' => 'text/plain' }, ['Page Not Found']]
end

def require_app
Dir["#{Simpler.root}/app/**/*.rb"].each { |file| require file }
end
Expand Down
14 changes: 12 additions & 2 deletions lib/simpler/controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,31 @@ def initialize(env)
def make_response(action)
@request.env['simpler.controller'] = self
@request.env['simpler.action'] = action
@request.env['simpler.params'].merge!(@request.params)

set_default_headers
send(action)
write_response
set_default_headers

@response.finish
end

private

def status(status)
@response.status = status
end

def headers
@response.headers
end

def extract_name
self.class.name.match('(?<name>.+)Controller')[:name].downcase
end

def set_default_headers
return @response['Content-Type'] = 'text/plain' if @request.env['simpler.template'].is_a?(Hash)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

На самом деле, не факт что мы обязательно будет рендерить plain text. Может потребоваться рендеринг json, xml или pdf, например.

@response['Content-Type'] = 'text/html'
end

Expand All @@ -43,7 +53,7 @@ def render_body
end

def params
@request.params
@request.env['simpler.params']
end

def render(template)
Expand Down
25 changes: 25 additions & 0 deletions lib/simpler/middleware/logger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require 'logger'

class AppLogger
def initialize(app, **options)
@logger = Logger.new(options[:logdev] || STDOUT)
@app = app
end

def call(env)
status, headers, body = @app.call(env)
@logger.info(log_composer(env, status, headers))
[status, headers, body]
end

private

def log_composer(env, status, headers)
<<~HEREDOC
\nRequest: #{env['REQUEST_METHOD']} #{env['REQUEST_URI']}
Handler: #{env['simpler.controller'].class}##{env['simpler.action']}
Parameters: #{env['simpler.params']}
Response: #{status} #{headers['Content-Type']} #{env['simpler.template']}
HEREDOC
end
end
5 changes: 1 addition & 4 deletions lib/simpler/router.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ def post(path, route_point)
end

def route_for(env)
method = env['REQUEST_METHOD'].downcase.to_sym
path = env['PATH_INFO']

@routes.find { |route| route.match?(method, path) }
@routes.find { |route| route.match?(env) }
end

private
Expand Down
27 changes: 25 additions & 2 deletions lib/simpler/router/route.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,33 @@ def initialize(method, path, controller, action)
@action = action
end

def match?(method, path)
@method == method && path.match(@path)
def match?(env)
method = env['REQUEST_METHOD'].downcase.to_sym
request_path = env['PATH_INFO'].split('/')
@method == method && path_comparison(request_path)
end

def params
@params
end

private

def path_comparison(request_path)
@params = {}
route_path = @path.split('/')

request_path.zip(route_path).each do |elem_request_path, elem_route_path|
return false if elem_route_path.nil?

if elem_route_path.include?(':')
key = elem_route_path.delete(':').to_sym
@params[key] = element_request_path
else
elem_route_path == elem_request_path ? true : (return false)
end
end
end
end
end
end
4 changes: 2 additions & 2 deletions lib/simpler/view.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def initialize(env)
end

def render(binding)
template = File.read(template_path)
template = template_path.is_a?(Hash) ? template_path.first[1] : File.read(template_path)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Здесь лучше разделить логику рендеринга ответов разных типов между отдельными классами. Для каждого типа ответа может быть свой собственный класс с методом render. Тогда в обязанности View будет входить выбор нужного класса рендеринга и делегирование ему метода render.


ERB.new(template).result(binding)
end
Expand All @@ -31,7 +31,7 @@ def template

def template_path
path = template || [controller.name, action].join('/')

return path if template.is_a?(Hash)
Simpler.root.join(VIEW_BASE_PATH, "#{path}.html.erb")
end

Expand Down