Class: Rubee::BaseController
- Inherits:
-
Object
- Object
- Rubee::BaseController
- Includes:
- AuthTokenable, Authorizable, Hookable
- Defined in:
- lib/rubee/controllers/base_controller.rb
Direct Known Subclasses
AuthzController, TestController, TestRedirectController, TesttwoController, UsersController, WelcomeController
Constant Summary
Constants included from AuthTokenable
AuthTokenable::EXPIRE, AuthTokenable::KEY
Class Method Summary collapse
Instance Method Summary collapse
- #css ⇒ Object
- #extract_params(path, pattern) ⇒ Object
- #handle_websocket ⇒ Object
- #headers ⇒ Object
- #image ⇒ Object
-
#initialize(request, route) ⇒ BaseController
constructor
A new instance of BaseController.
- #js ⇒ Object
- #params ⇒ Object
- #render_template(file_name, locals = {}, **options) ⇒ Object
- #response_with(type: nil, object: nil, status: 200, mime_type: nil, render_view: nil, headers: {}, to: nil, file: nil, filename: nil, **options) ⇒ Object
- #websocket ⇒ Object
- #websocket_connections ⇒ Object
Methods included from Authorizable
Methods included from AuthTokenable
Methods included from Hookable
Constructor Details
#initialize(request, route) ⇒ BaseController
Returns a new instance of BaseController.
8 9 10 11 |
# File 'lib/rubee/controllers/base_controller.rb', line 8 def initialize(request, route) @request = request @route = route end |
Class Method Details
.attach_websocket! ⇒ Object
172 173 174 175 176 177 178 179 180 181 |
# File 'lib/rubee/controllers/base_controller.rb', line 172 def attach_websocket! around( :websocket, :handle_websocket, if: -> do redis_available = Rubee::Features.redis_available? Rubee::Logger.error(message: 'Please make sure redis server is running') unless redis_available redis_available end ) end |
Instance Method Details
#css ⇒ Object
34 35 36 37 38 39 40 41 42 |
# File 'lib/rubee/controllers/base_controller.rb', line 34 def css css_path = File.join(CSS_DIR, @request.path.sub('/css/', '')) if File.exist?(css_path) && File.file?(css_path) response_with(object: File.read(css_path), type: :css) else response_with(object: 'Css file is not found', type: :text) end end |
#extract_params(path, pattern) ⇒ Object
152 153 154 155 156 157 158 159 160 161 |
# File 'lib/rubee/controllers/base_controller.rb', line 152 def extract_params(path, pattern) regex_pattern = pattern.gsub(/\{(\w+)\}/, '(?<\1>[^/]+)') regex = Regexp.new("^#{regex_pattern}$") if (match = path.match(regex)) return match.named_captures&.transform_keys(&:to_sym) end {} end |
#handle_websocket ⇒ Object
163 164 165 166 167 168 169 |
# File 'lib/rubee/controllers/base_controller.rb', line 163 def handle_websocket res = Rubee::WebSocket.call(@request.env) do |payload| @params = payload yield end res end |
#headers ⇒ Object
143 144 145 146 |
# File 'lib/rubee/controllers/base_controller.rb', line 143 def headers @request.env.select { |k, _v| k.start_with?('HTTP_') } .collect { |key, val| [key.sub(/^HTTP_/, ''), val] } end |
#image ⇒ Object
13 14 15 16 17 18 19 20 21 22 |
# File 'lib/rubee/controllers/base_controller.rb', line 13 def image image_path = File.join(IMAGE_DIR, @request.path.sub('/images/', '')) if File.exist?(image_path) && File.file?(image_path) mime_type = Rack::Mime.mime_type(File.extname(image_path)) response_with(object: File.read(image_path), type: :image, mime_type: mime_type) else response_with(object: 'Image not found', type: :text) end end |
#js ⇒ Object
24 25 26 27 28 29 30 31 32 |
# File 'lib/rubee/controllers/base_controller.rb', line 24 def js js_path = File.join(JS_DIR, @request.path.sub('/js/', '')) if File.exist?(js_path) && File.file?(js_path) response_with(object: File.read(js_path), type: :js) else response_with(object: 'Js file is not found', type: :text) end end |
#params ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/rubee/controllers/base_controller.rb', line 117 def params raw_input = @request.body&.read&.to_s&.strip @request.body.rewind if @request.body.respond_to?(:rewind) parsed_input = if raw_input begin JSON.parse(raw_input) rescue StandardError begin URI.decode_www_form(raw_input).to_h.transform_keys(&:to_sym) rescue {} end end else {} end # Combine route params, request params, and body @params ||= extract_params(@request.path, @route[:path]) .merge(parsed_input) .merge(@request.params) .transform_keys(&:to_sym) .reject { |k, _v| k.to_sym == :_method } end |
#render_template(file_name, locals = {}, **options) ⇒ Object
100 101 102 103 104 105 106 |
# File 'lib/rubee/controllers/base_controller.rb', line 100 def render_template(file_name, locals = {}, **) lib = Rubee::PROJECT_NAME == 'rubee' ? 'lib/' : '' path = "#{lib}#{[:app_name] || 'app'}/views/#{file_name}.erb" erb_template = ERB.new(File.read(path)) erb_template.result(binding) end |
#response_with(type: nil, object: nil, status: 200, mime_type: nil, render_view: nil, headers: {}, to: nil, file: nil, filename: nil, **options) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/rubee/controllers/base_controller.rb', line 44 def response_with type: nil, object: nil, status: 200, mime_type: nil, render_view: nil, headers: {}, to: nil, file: nil, filename: nil, ** case type&.to_sym in :json rendered_json = object.is_a?(Array) ? object&.map(&:to_h).to_json : object.to_json [status, headers.merge('content-type' => 'application/json'), [rendered_json]] in :image [status, headers.merge('content-type' => mime_type), [object]] in :js [status, headers.merge('content-type' => 'application/javascript'), [object]] in :css [status, headers.merge('content-type' => 'text/css'), [object]] in :websocket object # hash is expected in :file [ status, headers.merge( 'content-disposition' => "attachment; filename=#{filename}", 'content-type' => 'application/octet-stream' ), file, ] in :text [status, headers.merge('content-type' => 'text/plain'), [object.to_s]] in :unauthentificated [401, headers.merge('content-type' => 'text/plain'), ['Unauthentificated']] in :redirect [302, headers.merge('location' => to.to_s), []] in :not_found [404, { 'content-type' => 'text/plain' }, ['Route not found']] else # rendering erb view is a default behavior # TODO: refactor view_file_name = self.class.name.split('Controller').first.gsub('::', '').snakeize erb_file = render_view ? render_view.to_s : "#{view_file_name}_#{@route[:action]}" lib = Rubee::PROJECT_NAME == 'rubee' ? 'lib/' : '' path_parts = Module.const_source_location(self.class.name)&.first&.split('/')&.reverse controller_index = path_parts.find_index { |part| part == 'controllers' } app_name = path_parts[controller_index + 1] view = render_template(erb_file, { object:, **([:locals] || {}) }, app_name:) # Since controller sits in the controllers folder we can get parent folder of it and pull out name of the app app_name_prefix = app_name == 'app' ? '' : "#{app_name}_" layout_path = "#{lib}#{app_name}/views/#{app_name_prefix}#{[:layout] || 'layout'}.erb" whole_erb = if File.exist?(layout_path) context = Object.new context.define_singleton_method(:_yield_template) { view } layout = File.read(layout_path) ERB.new(layout).result(context.instance_eval { binding }) else ERB.new(view).result(binding) end [status, headers.merge('content-type' => 'text/html'), [whole_erb]] end end |
#websocket ⇒ Object
108 109 110 111 112 113 114 115 |
# File 'lib/rubee/controllers/base_controller.rb', line 108 def websocket action = @params[:action] unless ['subscribe', 'unsubscribe', 'publish'].include?(action) response_with(object: "Unknown action: #{action}", type: :websocket) end public_send(action) end |
#websocket_connections ⇒ Object
148 149 150 |
# File 'lib/rubee/controllers/base_controller.rb', line 148 def websocket_connections Rubee::WebSocketConnections.instance end |