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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea
/log/**/*
!/log/.gitkeep
8 changes: 4 additions & 4 deletions app/controllers/tests_controller.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
class TestsController < Simpler::Controller

def index
@time = Time.now
end

def create

headers['WEIRD_HEADER'] = '1234'
status(200)
render(plain: "Params sent: #{@request.params}")
end

def create; end
end
1 change: 0 additions & 1 deletion app/models/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@
# Integer :level, default: 0
# end
class Test < Sequel::Model

end
4 changes: 4 additions & 0 deletions config.ru
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
require_relative 'config/environment'
require_relative 'middleware/logger'

use Logger
use Rack::Reloader, 0

run Simpler.application
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Simpler.application.routes do
get '/tests', 'tests#index'
get '/tests/:id', 'tests#index'
post '/tests', 'tests#create'
end
2 changes: 0 additions & 2 deletions lib/simpler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
require_relative 'simpler/application'

module Simpler

class << self
def application
Application.instance
Expand All @@ -12,5 +11,4 @@ def root
Pathname.new(File.expand_path('..', __dir__))
end
end

end
6 changes: 4 additions & 2 deletions lib/simpler/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

module Simpler
class Application

include Singleton

attr_reader :db
Expand All @@ -28,6 +27,10 @@ def routes(&block)

def call(env)
route = @router.route_for(env)

return @router.not_found(env) unless route

route.match_params(env)
controller = route.controller.new(env)
action = route.action

Expand All @@ -53,6 +56,5 @@ def setup_database
def make_response(controller, action)
controller.make_response(action)
end

end
end
50 changes: 47 additions & 3 deletions lib/simpler/controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

module Simpler
class Controller

attr_reader :name, :request, :response

def initialize(env)
@name = extract_name
@request = Rack::Request.new(env)
@request.params.merge!(env['matched.params'])
@response = Rack::Response.new
@body_written = false
end

def make_response(action)
Expand All @@ -17,11 +18,16 @@ def make_response(action)

set_default_headers
send(action)
write_response

write_from_convention_template unless @body_written

@response.finish
end

def append_path_params(params)
@request.params.merge!(params)
end

private

def extract_name
Expand All @@ -32,10 +38,11 @@ def set_default_headers
@response['Content-Type'] = 'text/html'
end

def write_response
def write_from_convention_template
body = render_body

@response.write(body)
@body_written = true
end

def render_body
Expand All @@ -47,8 +54,45 @@ def params
end

def render(template)
case template
when String
proceed_string_template(template)
when Hash
proceed_hash_options(template)
else
template_error("Template can be string or hash, but not #{template.class}.")
end

@body_written = true
end

def proceed_string_template(template)
@request.env['simpler.template'] = template
end

def proceed_hash_options(options)
if options.key?(:plain)
@request.env['simpler.render'] = :plain
@response.write(options[:plain].to_s)
else
template_error("Applying options #{options.keys} is not implemented yet")
end
end

def template_error(message)
@response.status = 500
@response.write(message)
@response.finish
end

def status(status)
puts('Status has already been set before setting') if @response.status

response.status = status
end

def headers
@response.headers
end
end
end
12 changes: 10 additions & 2 deletions lib/simpler/router.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

module Simpler
class Router

def initialize
@routes = []
end
Expand All @@ -22,6 +21,16 @@ def route_for(env)
@routes.find { |route| route.match?(method, path) }
end

def not_found(env)
response = Rack::Response.new
method = env['REQUEST_METHOD'].downcase.to_sym
path = env['PATH_INFO']

response.status = 404
response.write("Cannot find route by path '#{path}' with method '#{method}'")
response.finish
end

private

def add_route(method, path, route_point)
Expand All @@ -36,6 +45,5 @@ def add_route(method, path, route_point)
def controller_from_string(controller_name)
Object.const_get("#{controller_name.capitalize}Controller")
end

end
end
22 changes: 20 additions & 2 deletions lib/simpler/router/route.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
module Simpler
class Router
class Route

attr_reader :controller, :action

def initialize(method, path, controller, action)
Expand All @@ -12,9 +11,28 @@ def initialize(method, path, controller, action)
end

def match?(method, path)
@method == method && path.match(@path)
@method == method && path.match(path_to_regexp(@path))
end

def match_params(env)
params = {}
request_path_elements = env['PATH_INFO'].split('/')
@path.split('/').each_with_index do |param, index|
params[param.sub(':', '')] = request_path_elements[index] if param.start_with?(':')
end
env['matched.params'] = params
end

private

def path_to_regexp(path)
regexp_body = path
.split('/')
.map { |s| s.start_with?(':') ? '\d+' : s }
.join('/') + '(?:\/)?$'

Regexp.new(regexp_body)
end
end
end
end
2 changes: 0 additions & 2 deletions lib/simpler/view.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

module Simpler
class View

VIEW_BASE_PATH = 'app/views'.freeze

def initialize(env)
Expand Down Expand Up @@ -34,6 +33,5 @@ def template_path

Simpler.root.join(VIEW_BASE_PATH, "#{path}.html.erb")
end

end
end
Empty file added log/.gitkeep
Empty file.
40 changes: 40 additions & 0 deletions middleware/logger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class Logger
def initialize(app)
@app = app
end

def call(env)
@env = env
status, headers, body = @app.call(env)

log_entry = make_log_item(status, headers, body)
log(log_entry)

[status, headers, body]
end

def log(log_ingo)
filename = "#{Time.new.strftime('%d-%m-%Y')}.txt"
filepath = File.expand_path("log/#{filename}")

File.write(filepath, log_ingo, mode: File.exist?(filepath) ? 'a' : 'w')
end

def make_log_item(status, headers, _body)
response_info = collect_response_info
"
Request: #{@env['REQUEST_METHOD']} #{@env['REQUEST_METHOD']}
Handler: #{response_info[:controller]}##{response_info[:action]}
Parameters: #{query_string_parameters.merge(parameters)}
Response: #{status} [#{headers['Content-Type']}] #{response_info[:template]}"
end

def collect_response_info
controller = env['simpler.controller'].class.name
action = env['simpler.action']
parameters = env['matched.params'].merge(Rack::Utils.parse_query(env['QUERY_STRING']))
template = env['simpler.template'] || env['simpler.render']

{ controller: controller, action: action, parameters: parameters, template: template }
end
end