diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..7106fcab --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +./log diff --git a/app/controllers/tests_controller.rb b/app/controllers/tests_controller.rb index 1526a689..8e3890dd 100644 --- a/app/controllers/tests_controller.rb +++ b/app/controllers/tests_controller.rb @@ -1,11 +1,15 @@ class TestsController < Simpler::Controller - def index @time = Time.now + # render plain: "#{@time} This is text from Plain" end def create - + render plain: 'This is text from Plain create' end + def show + @test = Test.where(id: params[:id]) + render plain: "Action Show: params: #{params}, @test = #{@test} " + end end diff --git a/app/models/test.rb b/app/models/test.rb index 86376668..98cea0cb 100644 --- a/app/models/test.rb +++ b/app/models/test.rb @@ -4,5 +4,4 @@ # Integer :level, default: 0 # end class Test < Sequel::Model - end diff --git a/app/views/tests/show.html.erb b/app/views/tests/show.html.erb new file mode 100644 index 00000000..35e0eea1 --- /dev/null +++ b/app/views/tests/show.html.erb @@ -0,0 +1,12 @@ + + + + + Show | Simpler application + + +

Simpler framework at work!

+ +

<%= @time %>

+ + diff --git a/config.ru b/config.ru index 3060cc20..283bc97a 100644 --- a/config.ru +++ b/config.ru @@ -1,3 +1,4 @@ require_relative 'config/environment' +use Logger 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/db/test_guru.sqlite b/db/test_guru.sqlite index 8624a03a..7116c4cf 100644 Binary files a/db/test_guru.sqlite and b/db/test_guru.sqlite differ diff --git a/lib/logger.rb b/lib/logger.rb new file mode 100644 index 00000000..77faeb71 --- /dev/null +++ b/lib/logger.rb @@ -0,0 +1,39 @@ +class Logger + def initialize(app) + @app = app + end + + def call(env) + log_file = File.open('log/app.log', 'a+') + request = Rack::Request.new(env) + status, headers, body = @app.call(env) + response = Rack::Response.new(body, status, headers) + write_log(log_file, request, status, headers) + + response.finish + end + + private + + def write_log(file, request, status, headers) + log_body = log_form(request, status, headers) + file.write(log_body) + + file.close + end + + def log_form(request, status, headers) + method = request.request_method + url = request.fullpath + controller = request.env['simpler.controller'] + action = request.env['simpler.action'] + pattern = request.env['simpler.pattern'] + params = request.env['simpler.route_params'] + + "#{Time.now} + Request: #{method} #{url} + Handler: #{controller.class.name}##{action} + Parameters: #{params} + Response: #{status} [#{headers['Content-Type']}] #{pattern} \n\n" + end +end diff --git a/lib/simpler.rb b/lib/simpler.rb index f9dfe3c4..d4d365c9 100644 --- a/lib/simpler.rb +++ b/lib/simpler.rb @@ -2,7 +2,6 @@ require_relative 'simpler/application' module Simpler - class << self def application Application.instance @@ -12,5 +11,4 @@ def root Pathname.new(File.expand_path('..', __dir__)) end end - end diff --git a/lib/simpler/application.rb b/lib/simpler/application.rb index 711946a9..cae066b0 100644 --- a/lib/simpler/application.rb +++ b/lib/simpler/application.rb @@ -6,7 +6,6 @@ module Simpler class Application - include Singleton attr_reader :db @@ -20,6 +19,7 @@ def bootstrap! setup_database require_app require_routes + require_logger end def routes(&block) @@ -27,15 +27,23 @@ def routes(&block) end def call(env) - route = @router.route_for(env) - controller = route.controller.new(env) - action = route.action + if (route = @router.route_for(env)) + env['simpler.route_params'] = route.params + controller = route.controller.new(env) + action = route.action - make_response(controller, action) + make_response(controller, action) + else + not_found + end end private + def not_found + Rack::Response.new("Resource not exist!\n", 404, {}).finish + end + def require_app Dir["#{Simpler.root}/app/**/*.rb"].each { |file| require file } end @@ -44,6 +52,10 @@ def require_routes require Simpler.root.join('config/routes') end + def require_logger + require_relative '../logger' + end + def setup_database database_config = YAML.load_file(Simpler.root.join('config/database.yml')) database_config['database'] = Simpler.root.join(database_config['database']) @@ -53,6 +65,5 @@ def setup_database def make_response(controller, action) controller.make_response(action) end - end end diff --git a/lib/simpler/controller.rb b/lib/simpler/controller.rb index 9383b035..e5216544 100644 --- a/lib/simpler/controller.rb +++ b/lib/simpler/controller.rb @@ -2,7 +2,6 @@ module Simpler class Controller - attr_reader :name, :request, :response def initialize(env) @@ -15,7 +14,8 @@ def make_response(action) @request.env['simpler.controller'] = self @request.env['simpler.action'] = action - set_default_headers + set_headers + set_status send(action) write_response @@ -24,12 +24,25 @@ def make_response(action) private - def extract_name - self.class.name.match('(?.+)Controller')[:name].downcase + def set_status(status = nil) + case @request.request_method + when 'GET' + @response.status = Rack::Utils::SYMBOL_TO_STATUS_CODE[:ok] + when 'POST' + @response.status = Rack::Utils::SYMBOL_TO_STATUS_CODE[:created] + when 'PATCH' + @response.status = Rack::Utils::SYMBOL_TO_STATUS_CODE[:no_content] + end + + @response.status = status unless status.nil? end - def set_default_headers - @response['Content-Type'] = 'text/html' + def set_headers(type = 'text/html') + @response['Content-Type'] = type + end + + def extract_name + self.class.name.match('(?.+)Controller')[:name].downcase end def write_response @@ -43,12 +56,15 @@ def render_body end def params - @request.params + @request.params.merge(form_param) + end + + def form_param + @request.env['simpler.route_params'].merge!(@request.params) end def render(template) @request.env['simpler.template'] = template end - end end diff --git a/lib/simpler/router.rb b/lib/simpler/router.rb index 14b3415c..b05449b3 100644 --- a/lib/simpler/router.rb +++ b/lib/simpler/router.rb @@ -2,7 +2,6 @@ module Simpler class Router - def initialize @routes = [] end @@ -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 4c66b4b7..299b157b 100644 --- a/lib/simpler/router/route.rb +++ b/lib/simpler/router/route.rb @@ -1,20 +1,43 @@ module Simpler class Router class Route - - attr_reader :controller, :action + attr_reader :controller, :action, :params def initialize(method, path, controller, action) @method = method @path = path @controller = controller @action = action + @params = {} end def match?(method, path) - @method == method && path.match(@path) + @method == method && path_match?(path) + end + + private + + def path_match?(path) + path_request = path.split('/') + path_router = @path.split('/') + compare(path_request, path_router) end + def compare(path_request, path_router) + return false if path_request.size != path_router.size + + path_router.each_with_index do |item, index| + if item =~ /^:[\d\w]+$/ + save_params(item, path_request[index]) + next + end + return false if item != path_request[index] + end + end + + def save_params(key, value) + @params[key] = value + end end end end diff --git a/lib/simpler/tmp b/lib/simpler/tmp new file mode 100644 index 00000000..83ee94c3 --- /dev/null +++ b/lib/simpler/tmp @@ -0,0 +1,15 @@ +b) Для запросов необходимо записывать HTTP-метод запроса, + URL, контроллер и метод который будет обрабатывать запрос, + хэш параметров который будет доступен при вызове метода params + +c) Для ответов необходимо записывать код статуса ответа, +тип тела ответа и название шаблона +(если ответ рендерился с помощью шаблона представления) + +Пример: + + +Request: GET /tests?category=Backend +Handler: TestsController#index +Parameters: {'category' => 'Backend'} +Response: 200 OK [text/html] tests/index.html.erb diff --git a/lib/simpler/view.rb b/lib/simpler/view.rb index 19a73b34..515d5dfc 100644 --- a/lib/simpler/view.rb +++ b/lib/simpler/view.rb @@ -2,7 +2,6 @@ module Simpler class View - VIEW_BASE_PATH = 'app/views'.freeze def initialize(env) @@ -10,12 +9,32 @@ def initialize(env) end def render(binding) + extend? ? extending_render : file_render(binding) + end + + private + + def extending_render + send(key_hash) + end + + def key_hash + @env['simpler.template'].keys[0] + end + + def plain + @env['simpler.template'].values[0] + "\n" + end + + def file_render(binding) template = File.read(template_path) ERB.new(template).result(binding) end - private + def extend? + @env['simpler.template'].instance_of?(Hash) + end def controller @env['simpler.controller'] @@ -31,9 +50,9 @@ def template def template_path path = template || [controller.name, action].join('/') + @env['simpler.pattern'] = "#{path}.html.erb" Simpler.root.join(VIEW_BASE_PATH, "#{path}.html.erb") end - end end diff --git a/log/app.log b/log/app.log new file mode 100644 index 00000000..2af53370 --- /dev/null +++ b/log/app.log @@ -0,0 +1,66 @@ +2022-07-16 16:23:47 +0500 + Request: GET /tests?level=2 + Handler: TestsController#index + Parameters: {"level"=>"2"} + Response: 200 [text/html] tests/index.html.erb + +2022-07-16 16:31:37 +0500 + Request: GET /tests/102 + Handler: TestsController#show + Parameters: {} + Response: 200 [text/html] + +2022-07-16 16:34:07 +0500 + Request: GET /tests/102 + Handler: TestsController#show + Parameters: {} + Response: 200 [text/html] + +2022-07-16 16:34:27 +0500 + Request: GET /tests/102 + Handler: TestsController#show + Parameters: {} + Response: 200 [text/html] + +2022-07-16 16:35:36 +0500 + Request: GET /tests/102 + Handler: TestsController#show + Parameters: {} + Response: 200 [text/html] + +2022-07-16 16:36:44 +0500 + Request: GET /tests/102 + Handler: TestsController#show + Parameters: {} + Response: 200 [text/html] + +2022-07-16 16:38:11 +0500 + Request: GET /tests/102 + Handler: TestsController#show + Parameters: {} + Response: 200 [text/html] + +2022-07-16 16:46:56 +0500 + Request: GET /tests/102 + Handler: TestsController#show + Parameters: {} + Response: 200 [text/html] + +2022-07-16 16:48:05 +0500 + Request: GET /tests/102 + Handler: TestsController#show + Parameters: {":id"=>"102"} + Response: 200 [text/html] + +2022-07-16 16:48:38 +0500 + Request: GET /tests/101 + Handler: TestsController#show + Parameters: {":id"=>"101"} + Response: 200 [text/html] + +2022-07-16 16:48:50 +0500 + Request: GET /tests/101?level=2 + Handler: TestsController#show + Parameters: {":id"=>"101", "level"=>"2"} + Response: 200 [text/html] +