diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..7ccc842a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Ignore all logfiles +/log/* diff --git a/app/controllers/tests_controller.rb b/app/controllers/tests_controller.rb index 900a415d..e8a132a2 100644 --- a/app/controllers/tests_controller.rb +++ b/app/controllers/tests_controller.rb @@ -1,19 +1,21 @@ class TestsController < Simpler::Controller def index @time = Time.now + render "tests/index" end def create + status 201 + render plain: "Create method in action!" end def plain - render plain: "plain_option_example" - status 201 + render plain: "Plain text responce example" + status 200 end def show @id = params[:id] - render plain: "This is an object (show tests method) with id #{@id}" end def question diff --git a/app/views/tests/show.html.erb b/app/views/tests/show.html.erb new file mode 100644 index 00000000..694ab011 --- /dev/null +++ b/app/views/tests/show.html.erb @@ -0,0 +1,10 @@ + + + + + Index | Simpler application + + +

This is the test object (show tests method) with id <%= @id %>

+ + diff --git a/config.ru b/config.ru index 3060cc20..6beefaa0 100644 --- a/config.ru +++ b/config.ru @@ -1,3 +1,5 @@ -require_relative 'config/environment' +require_relative "config/environment" +require_relative "lib/simpler/middleware/logger" +use Simpler::AppLogger, logdev: File.expand_path("log/app.log", Simpler.root) run Simpler.application diff --git a/lib/simpler/application.rb b/lib/simpler/application.rb index fe8f2480..bba58164 100644 --- a/lib/simpler/application.rb +++ b/lib/simpler/application.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "yaml" require "singleton" require "sequel" @@ -27,7 +29,10 @@ def routes(&block) def call(env) route = @router.route_for(env) + return not_found unless route + return not_found unless route.params.empty? || db_route_params_exists?(route.params) + env["simpler.route_params"] = route.params controller = route.controller.new(env) action = route.action @@ -38,7 +43,7 @@ def call(env) private def require_app - Dir["#{Simpler.root}/app/**/*.rb"].each { |file| require file } + Dir["#{Simpler.root}/app/**/*.rb"].sort.each { |file| require file } end def require_routes @@ -58,5 +63,12 @@ def make_response(controller, action) def not_found [404, { "Content-Type" => "text/plain" }, ["Not found"]] end + + def db_route_params_exists?(params) + corresponding_record = nil + params.each { |_param_name, param_value| corresponding_record = @db[:tests].first(id: param_value) } + + !corresponding_record.nil? + end end end diff --git a/lib/simpler/middleware/logger.rb b/lib/simpler/middleware/logger.rb new file mode 100644 index 00000000..dcf995e3 --- /dev/null +++ b/lib/simpler/middleware/logger.rb @@ -0,0 +1,55 @@ +require "logger" + +module Simpler + class AppLogger + def initialize(app, **options) + @logger = Logger.new(options[:logdev] || STDOUT) + @app = app + end + + def call(env) + @status, @header, @body = @app.call(env) + @request = Rack::Request.new(env) + + @logger.info(create_log) + + Rack::Response.new(@body, @status, @header).finish + end + + private + + def create_log + if @status == 404 + %Q( + Request: #{@request.request_method} #{@request.fullpath} + Handler: Nil + Parameters: #{@request.params} + Response: #{full_status} + ).delete!("\n") + else + %Q( + Request: #{@request.request_method} #{@request.fullpath} + Handler: #{controller}##{action} + Parameters: #{@request.params} + Response: #{full_status} \[#{@header["Content-Type"]}\] #{view} + ).delete!("\n") + end + end + + def controller + @request.env["simpler.controller"].class.name + end + + def action + @request.env["simpler.action"] + end + + def full_status + "#{@status}" + " #{Rack::Utils::HTTP_STATUS_CODES[@status]}" + end + + def view + "#{@request.env["simpler.template"] || [controller, action].join("/")}.html.erb" unless @request.env["simpler.text_plain"] + end + end +end diff --git a/lib/simpler/router.rb b/lib/simpler/router.rb index 14b3415c..77b7fdf6 100644 --- a/lib/simpler/router.rb +++ b/lib/simpler/router.rb @@ -1,8 +1,7 @@ -require_relative 'router/route' +require_relative "router/route" module Simpler class Router - def initialize @routes = [] end @@ -16,8 +15,8 @@ def post(path, route_point) end def route_for(env) - method = env['REQUEST_METHOD'].downcase.to_sym - path = env['PATH_INFO'] + method = env["REQUEST_METHOD"].downcase.to_sym + path = env["PATH_INFO"] @routes.find { |route| route.match?(method, path) } end @@ -25,7 +24,7 @@ def route_for(env) private def add_route(method, path, route_point) - route_point = route_point.split('#') + route_point = route_point.split("#") controller = controller_from_string(route_point[0]) action = route_point[1] route = Route.new(method, path, controller, action) @@ -36,6 +35,5 @@ def add_route(method, path, route_point) def controller_from_string(controller_name) Object.const_get("#{controller_name.capitalize}Controller") end - end end diff --git a/lib/simpler/router/route.rb b/lib/simpler/router/route.rb index 157667c7..a3763dbd 100644 --- a/lib/simpler/router/route.rb +++ b/lib/simpler/router/route.rb @@ -16,8 +16,13 @@ def initialize(method, path, controller, action) end def match?(method, path) - define_params(path) - edited_path = define_edited_path(path) || path + @params = define_params(path) + + edited_path = if @params.values.all? && (!@params.values.empty?) + define_edited_path(path) + else + path + end @method == method && edited_path == @path end @@ -31,16 +36,15 @@ def define_params(path) path.scan(ROUTE_PARAM_VALUE_REGEXP).each { |param| route_params_values << (param.delete "/") } @path.scan(ROUTE_PARAM_NAME_REGEXP).each { |param| route_params_names << param.delete(":").delete("/").to_sym } - @params = Hash[route_params_names.zip route_params_values] + Hash[route_params_names.zip route_params_values] end def define_edited_path(path) - str = path - @params.each do |param_name, param_value| - str = str.gsub param_value, ":#{param_name.to_s}" - end + edited_path = path + + @params.each { |param_name, param_value| edited_path = edited_path.gsub param_value, ":#{param_name.to_s}" } - str + edited_path end end end diff --git a/log/app.log b/log/app.log new file mode 100644 index 00000000..aa4618e0 --- /dev/null +++ b/log/app.log @@ -0,0 +1,11 @@ +I, [2021-07-20T21:29:48.157677 #288091] INFO -- : Request: GET /tests/2 Handler: TestsController#show Parameters: {:id=>"2"} Response: 200 OK [text/html] TestsController/show.html.erb +I, [2021-07-20T21:30:01.670387 #288091] INFO -- : Request: GET /tests/6 Handler: Nil Parameters: {} Response: 404 Not Found +I, [2021-07-20T21:30:14.369278 #288091] INFO -- : Request: GET /tests/3/question/25?one=1 Handler: Nil Parameters: {"one"=>"1"} Response: 404 Not Found +I, [2021-07-20T21:30:24.195654 #288091] INFO -- : Request: GET /tests Handler: TestsController#index Parameters: {} Response: 200 OK [text/html] tests/index.html.erb +I, [2021-07-20T21:32:27.196093 #288333] INFO -- : Request: POST /tests Handler: TestsController#create Parameters: {} Response: 201 Created [text/plain] +I, [2021-07-20T21:35:00.585388 #288333] INFO -- : Request: POST /tests Handler: TestsController#create Parameters: {} Response: 201 Created [text/plain] +I, [2021-07-20T21:35:02.896432 #288333] INFO -- : Request: GET /tests Handler: TestsController#index Parameters: {} Response: 200 OK [text/html] tests/index.html.erb +I, [2021-07-20T21:35:07.109826 #288333] INFO -- : Request: GET /tests/3/question/25?one=1 Handler: Nil Parameters: {"one"=>"1"} Response: 404 Not Found +I, [2021-07-20T21:35:10.289813 #288333] INFO -- : Request: GET /tests/6 Handler: Nil Parameters: {} Response: 404 Not Found +I, [2021-07-20T21:35:13.920833 #288333] INFO -- : Request: GET /tests/2 Handler: TestsController#show Parameters: {:id=>"2"} Response: 200 OK [text/html] TestsController/show.html.erb +I, [2021-07-20T21:35:20.181146 #288333] INFO -- : Request: GET /tests/plain Handler: TestsController#plain Parameters: {} Response: 200 OK [text/plain]