diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..203de7c1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +.idea +.env +log/app.log +.byebug_history \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..ffa6f2a5 --- /dev/null +++ b/Gemfile @@ -0,0 +1,6 @@ +source 'https://rubygems.org' + +gem 'sequel' +gem 'sqlite3' +gem 'rack' +gem 'byebug' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..9c51e0ef --- /dev/null +++ b/Gemfile.lock @@ -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 diff --git a/app/controllers/tests_controller.rb b/app/controllers/tests_controller.rb index 1526a689..1f28e199 100644 --- a/app/controllers/tests_controller.rb +++ b/app/controllers/tests_controller.rb @@ -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 diff --git a/app/views/tests/show.html.erb b/app/views/tests/show.html.erb new file mode 100644 index 00000000..a533bea8 --- /dev/null +++ b/app/views/tests/show.html.erb @@ -0,0 +1,12 @@ + + + + + Show | Simpler application + + +

Simpler framework at work!

+ +

<%= @test.title %>

+ + \ No newline at end of file diff --git a/config.ru b/config.ru index 3060cc20..5ac7059e 100644 --- a/config.ru +++ b/config.ru @@ -1,3 +1,4 @@ require_relative 'config/environment' +use AppLogger, 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.rb b/lib/simpler.rb index f9dfe3c4..ae7745a8 100644 --- a/lib/simpler.rb +++ b/lib/simpler.rb @@ -1,4 +1,5 @@ require 'pathname' +require_relative 'simpler/middleware/logger' require_relative 'simpler/application' module Simpler diff --git a/lib/simpler/application.rb b/lib/simpler/application.rb index 711946a9..dd64bdf6 100644 --- a/lib/simpler/application.rb +++ b/lib/simpler/application.rb @@ -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 @@ -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 diff --git a/lib/simpler/controller.rb b/lib/simpler/controller.rb index 9383b035..6eb00268 100644 --- a/lib/simpler/controller.rb +++ b/lib/simpler/controller.rb @@ -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('(?.+)Controller')[:name].downcase end def set_default_headers + return @response['Content-Type'] = 'text/plain' if @request.env['simpler.template'].is_a?(Hash) @response['Content-Type'] = 'text/html' end @@ -43,7 +53,7 @@ def render_body end def params - @request.params + @request.env['simpler.params'] end def render(template) diff --git a/lib/simpler/middleware/logger.rb b/lib/simpler/middleware/logger.rb new file mode 100644 index 00000000..422a7e39 --- /dev/null +++ b/lib/simpler/middleware/logger.rb @@ -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 \ No newline at end of file diff --git a/lib/simpler/router.rb b/lib/simpler/router.rb index 14b3415c..2d25414e 100644 --- a/lib/simpler/router.rb +++ b/lib/simpler/router.rb @@ -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 diff --git a/lib/simpler/router/route.rb b/lib/simpler/router/route.rb index 4c66b4b7..da643549 100644 --- a/lib/simpler/router/route.rb +++ b/lib/simpler/router/route.rb @@ -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 diff --git a/lib/simpler/view.rb b/lib/simpler/view.rb index 19a73b34..a055bf40 100644 --- a/lib/simpler/view.rb +++ b/lib/simpler/view.rb @@ -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) ERB.new(template).result(binding) end @@ -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