From 4afe87d705666fd74b779773de5ba2b0ab324f92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9E=D1=82=D1=82=D0=BE=20=D0=93=D1=80=D0=B5=D0=B9?= Date: Sun, 1 Oct 2023 20:30:27 +0300 Subject: [PATCH 1/2] hw --- app/controllers/tests_controller.rb | 9 ++++++++ app/views/tests/index.html.erb | 2 +- app/views/tests/show.html.erb | 12 ++++++++++ config.ru | 2 ++ config/routes.rb | 1 + lib/simpler/application.rb | 24 ++++++++++++++++--- lib/simpler/controller.rb | 28 ++++++++++++++++++---- lib/simpler/router.rb | 2 +- lib/simpler/router/route.rb | 28 ++++++++++++++++++++-- lib/simpler/view.rb | 8 +++++-- log/app.log | 14 +++++++++++ middleware/custom_logger.rb | 36 +++++++++++++++++++++++++++++ 12 files changed, 153 insertions(+), 13 deletions(-) create mode 100644 app/views/tests/show.html.erb create mode 100644 log/app.log create mode 100644 middleware/custom_logger.rb diff --git a/app/controllers/tests_controller.rb b/app/controllers/tests_controller.rb index 1526a689..8354e852 100644 --- a/app/controllers/tests_controller.rb +++ b/app/controllers/tests_controller.rb @@ -2,10 +2,19 @@ class TestsController < Simpler::Controller def index @time = Time.now + # render plain: 'Plain text response', status: 404 + render 'tests/index', status: 201 end def create end + def show + @test_id = params[:id] + @time = Time.now + render 'tests/show' + # render plain: 'Show', status: 201 + end + end diff --git a/app/views/tests/index.html.erb b/app/views/tests/index.html.erb index 39fce580..0915cef4 100644 --- a/app/views/tests/index.html.erb +++ b/app/views/tests/index.html.erb @@ -9,4 +9,4 @@

<%= @time %>

- \ No newline at end of file + diff --git a/app/views/tests/show.html.erb b/app/views/tests/show.html.erb new file mode 100644 index 00000000..91c52e54 --- /dev/null +++ b/app/views/tests/show.html.erb @@ -0,0 +1,12 @@ + + + + + Show | Simpler application + + +

Simpler framework at work!

+ +

<%= @test_id %>

+ + diff --git a/config.ru b/config.ru index 3060cc20..9a6e0ec2 100644 --- a/config.ru +++ b/config.ru @@ -1,3 +1,5 @@ +require_relative 'middleware/custom_logger' require_relative 'config/environment' +use CustomLogger, logdev: File.expand_path('log/app.log', __dir__) run Simpler.application diff --git a/config/routes.rb b/config/routes.rb index 4a751251..1700ff3a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Simpler.application.routes do get '/tests', 'tests#index' post '/tests', 'tests#create' + get '/tests/:id', 'tests#show' end diff --git a/lib/simpler/application.rb b/lib/simpler/application.rb index 711946a9..de315a8a 100644 --- a/lib/simpler/application.rb +++ b/lib/simpler/application.rb @@ -28,14 +28,32 @@ def routes(&block) def call(env) route = @router.route_for(env) - controller = route.controller.new(env) - action = route.action + # begin + # controller = route.controller.new(env) + # action = route.action - make_response(controller, action) + # make_response(controller, action) + # rescue + # @response = Rack::Response.new + # @response = [404, {}, []] + # end + + if route + controller = route.controller.new(env) + action = route.action + + make_response(controller, action) + else + not_found_response + end end private + def not_found_response + [404, {'Content-Type' => 'text/plain'}, ['Not found (404 Error)']] + end + def require_app Dir["#{Simpler.root}/app/**/*.rb"].each { |file| require file } end diff --git a/lib/simpler/controller.rb b/lib/simpler/controller.rb index 9383b035..7ef4d575 100644 --- a/lib/simpler/controller.rb +++ b/lib/simpler/controller.rb @@ -3,7 +3,7 @@ module Simpler class Controller - attr_reader :name, :request, :response + attr_reader :name, :request, :response, :status def initialize(env) @name = extract_name @@ -32,8 +32,14 @@ def set_default_headers @response['Content-Type'] = 'text/html' end + def set_headers + @response.headers + end + def write_response body = render_body + @request.env['simpler.response.status'] = @response.status + @request.env['simpler.response.header'] = set_headers['Content-Type'] @response.write(body) end @@ -43,11 +49,25 @@ def render_body end def params - @request.params + @request.env['simpler.params'].merge!(@request.params) end - def render(template) - @request.env['simpler.template'] = template + # def render(template, status = {}) + # case template + # when String + # set_headers['Content-Type'] = 'text/html' + # when Hash + # if template.has_key?(:plain) + # set_headers['Content-Type'] = 'text/plain' + # end + # end + + def render(template, status = {}) + @request.env['simpler.template'] = template + if status.is_a?(Integer) && status >= 100 + status = status[:status] || template[:status] + @response.status = status + end end end diff --git a/lib/simpler/router.rb b/lib/simpler/router.rb index 14b3415c..835726ff 100644 --- a/lib/simpler/router.rb +++ b/lib/simpler/router.rb @@ -19,7 +19,7 @@ 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?(method, path, env) } end private diff --git a/lib/simpler/router/route.rb b/lib/simpler/router/route.rb index 4c66b4b7..227fe375 100644 --- a/lib/simpler/router/route.rb +++ b/lib/simpler/router/route.rb @@ -11,8 +11,32 @@ def initialize(method, path, controller, action) @action = action end - def match?(method, path) - @method == method && path.match(@path) + def match?(method, path, env) + @method == method && parse_path(path, env) + end + + private + + def parse_path(path, env) + params = {} + router_parts = @path.split('/') # ["", "tests", ":id"] + request_parts = path.split('/') # ["", "tests", "1"] + + return false if router_parts.size != request_parts.size # false + + router_parts.each_index do |index| + unless router_parts[index] == request_parts[index] # если части не совпадают полностью + match_data = router_parts[index].match(/^:(.+)/) # ["", "tests", ":id"] поочередно проверяются на соответствие /^:(.+)/ + # выбирается часть с :id + # match_data = [':id'] + + return false if match_data.nil? + + params[match_data[1].to_sym] = request_parts[index] # params[:id] = 1 (соответствующая часть пути) + end + end + + env['simpler.params'] = params end end diff --git a/lib/simpler/view.rb b/lib/simpler/view.rb index 19a73b34..24aa0700 100644 --- a/lib/simpler/view.rb +++ b/lib/simpler/view.rb @@ -10,9 +10,13 @@ def initialize(env) end def render(binding) - template = File.read(template_path) + if template.is_a?(Hash) + template[:plain] + else + template = File.read(template_path) - ERB.new(template).result(binding) + ERB.new(template).result(binding) + end end private diff --git a/log/app.log b/log/app.log new file mode 100644 index 00000000..baa3f647 --- /dev/null +++ b/log/app.log @@ -0,0 +1,14 @@ +I, [2023-10-01T20:28:44.252388 #6864] INFO -- : +******************************************************** +Request: GET /tests/1 +Handler: TestsController#show +Parameters: {:id=>"1"} +Response: 200 [text/html] tests/show + +I, [2023-10-01T20:28:50.838787 #6864] INFO -- : +******************************************************** +Request: GET /tests +Handler: TestsController#index +Parameters: {} +Response: 200 [text/html] tests/index + diff --git a/middleware/custom_logger.rb b/middleware/custom_logger.rb new file mode 100644 index 00000000..b0f74958 --- /dev/null +++ b/middleware/custom_logger.rb @@ -0,0 +1,36 @@ +require 'logger' + +class CustomLogger + + def initialize(app, **options) + @logger = Logger.new(options[:logdev] || STDOUT) + @app = app + end + + def call(env) + response = @app.call(env) + @logger.info(message(env)) + response + end + + def message(env) + controller = env['simpler.controller'] + + if controller + <<~LOGGER + + ******************************************************** + Request: #{env['REQUEST_METHOD']} #{env['PATH_INFO']} + Handler: #{controller.name.capitalize}Controller##{env['simpler.action']} + Parameters: #{env['simpler.params']} + Response: #{env['simpler.response.status']} [#{env['simpler.response.header']}] #{env['simpler.template']} + LOGGER + else + <<~LOGGER + + Request: #{env['REQUEST_METHOD']} #{env['PATH_INFO']} + Response: #{} + LOGGER + end + end +end From 81735f2285cec23c18a3f4fd72f3051cfeb2570e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9E=D1=82=D1=82=D0=BE=20=D0=93=D1=80=D0=B5=D0=B9?= Date: Mon, 2 Oct 2023 19:04:37 +0300 Subject: [PATCH 2/2] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/tests_controller.rb | 6 ++-- lib/simpler/application.rb | 9 ------ lib/simpler/controller.rb | 31 ++++++++---------- lib/simpler/router/route.rb | 14 ++++---- log/app.log | 50 +++++++++++++++++++++++++++++ 5 files changed, 72 insertions(+), 38 deletions(-) diff --git a/app/controllers/tests_controller.rb b/app/controllers/tests_controller.rb index 8354e852..8e7f93f1 100644 --- a/app/controllers/tests_controller.rb +++ b/app/controllers/tests_controller.rb @@ -2,8 +2,9 @@ class TestsController < Simpler::Controller def index @time = Time.now - # render plain: 'Plain text response', status: 404 - render 'tests/index', status: 201 + render 'tests/index' + status 201 + headers['Content-Type'] = 'text/plain' end def create @@ -14,7 +15,6 @@ def show @test_id = params[:id] @time = Time.now render 'tests/show' - # render plain: 'Show', status: 201 end end diff --git a/lib/simpler/application.rb b/lib/simpler/application.rb index de315a8a..2daf4b02 100644 --- a/lib/simpler/application.rb +++ b/lib/simpler/application.rb @@ -28,15 +28,6 @@ def routes(&block) def call(env) route = @router.route_for(env) - # begin - # controller = route.controller.new(env) - # action = route.action - - # make_response(controller, action) - # rescue - # @response = Rack::Response.new - # @response = [404, {}, []] - # end if route controller = route.controller.new(env) diff --git a/lib/simpler/controller.rb b/lib/simpler/controller.rb index 7ef4d575..682c93ee 100644 --- a/lib/simpler/controller.rb +++ b/lib/simpler/controller.rb @@ -16,6 +16,7 @@ def make_response(action) @request.env['simpler.action'] = action set_default_headers + set_default_status send(action) write_response @@ -28,18 +29,26 @@ def extract_name self.class.name.match('(?.+)Controller')[:name].downcase end + def set_default_status + status 200 + end + + def status(code) + @response.status = code + end + def set_default_headers - @response['Content-Type'] = 'text/html' + headers['Content-Type'] = 'text/html' end - def set_headers + def headers @response.headers end def write_response body = render_body @request.env['simpler.response.status'] = @response.status - @request.env['simpler.response.header'] = set_headers['Content-Type'] + @request.env['simpler.response.header'] = headers['Content-Type'] @response.write(body) end @@ -52,22 +61,8 @@ def params @request.env['simpler.params'].merge!(@request.params) end - # def render(template, status = {}) - # case template - # when String - # set_headers['Content-Type'] = 'text/html' - # when Hash - # if template.has_key?(:plain) - # set_headers['Content-Type'] = 'text/plain' - # end - # end - - def render(template, status = {}) + def render(template) @request.env['simpler.template'] = template - if status.is_a?(Integer) && status >= 100 - status = status[:status] || template[:status] - @response.status = status - end end end diff --git a/lib/simpler/router/route.rb b/lib/simpler/router/route.rb index 227fe375..bbff331d 100644 --- a/lib/simpler/router/route.rb +++ b/lib/simpler/router/route.rb @@ -19,20 +19,18 @@ def match?(method, path, env) def parse_path(path, env) params = {} - router_parts = @path.split('/') # ["", "tests", ":id"] - request_parts = path.split('/') # ["", "tests", "1"] + router_parts = @path.split('/') + request_parts = path.split('/') - return false if router_parts.size != request_parts.size # false + return false if router_parts.size != request_parts.size router_parts.each_index do |index| - unless router_parts[index] == request_parts[index] # если части не совпадают полностью - match_data = router_parts[index].match(/^:(.+)/) # ["", "tests", ":id"] поочередно проверяются на соответствие /^:(.+)/ - # выбирается часть с :id - # match_data = [':id'] + unless router_parts[index] == request_parts[index] + match_data = router_parts[index].match(/^:(.+)/) return false if match_data.nil? - params[match_data[1].to_sym] = request_parts[index] # params[:id] = 1 (соответствующая часть пути) + params[match_data[1].to_sym] = request_parts[index] end end diff --git a/log/app.log b/log/app.log index baa3f647..ccd4997c 100644 --- a/log/app.log +++ b/log/app.log @@ -12,3 +12,53 @@ Handler: TestsController#index Parameters: {} Response: 200 [text/html] tests/index +I, [2023-10-02T19:01:22.890165 #2328] INFO -- : +Request: GET /favicon.ico +Response: + +I, [2023-10-02T19:02:26.432485 #2370] INFO -- : +******************************************************** +Request: GET /tests +Handler: TestsController#index +Parameters: {} +Response: 201 [text/html] tests/index + +I, [2023-10-02T19:02:28.887108 #2370] INFO -- : +******************************************************** +Request: GET /tests/1 +Handler: TestsController#show +Parameters: {:id=>"1"} +Response: 200 [text/html] tests/show + +I, [2023-10-02T19:02:31.419626 #2370] INFO -- : +Request: GET /tests/1/2 +Response: + +I, [2023-10-02T19:02:46.355274 #2370] INFO -- : +******************************************************** +Request: GET /tests/1 +Handler: TestsController#show +Parameters: {:id=>"1"} +Response: 200 [text/html] tests/show + +I, [2023-10-02T19:02:46.821204 #2370] INFO -- : +******************************************************** +Request: GET /tests/ +Handler: TestsController#index +Parameters: {} +Response: 201 [text/html] tests/index + +I, [2023-10-02T19:03:17.334902 #2528] INFO -- : +******************************************************** +Request: GET /tests/ +Handler: TestsController#index +Parameters: {} +Response: 201 [text/plain] tests/index + +I, [2023-10-02T19:03:55.068058 #2559] INFO -- : +******************************************************** +Request: GET /tests/ +Handler: TestsController#index +Parameters: {} +Response: 201 [text/html] {:plain=>"Plain text response"} +