# frozen_string_literal: true require_relative "models" require_relative "views" require "roda" module RankKing module Models require "sequel/model" require_relative "db" class Pool < Sequel::Model end end class App < Roda opts[:check_dynamic_arity] = false opts[:check_arity] = :warn plugin :default_headers, "Content-Type" => "text/html", # "Strict-Transport-Security" => "max-age=16070400;", # Uncomment if only allowing https:// access "X-Frame-Options" => "deny", "X-Content-Type-Options" => "nosniff", "X-XSS-Protection" => "1; mode=block" plugin :content_security_policy do |csp| csp.default_src :none # csp.style_src :self, "https://cdn.jsdelivr.net" csp.form_action :self csp.script_src :self csp.connect_src :self csp.base_uri :none csp.frame_ancestors :none end css_opts = {cache: false, style: :compressed} # :nocov: if ENV["RACK_ENV"] == 'development' css_opts.merge!(source_map_embed: true, source_map_contents: true, source_map_file: ".") end plugin :render_coverage if defined?(SimpleCov) # :nocov: plugin :route_csrf plugin :flash # plugin :assets, css: "app.scss", css_opts: css_opts, timestamp_paths: true # plugin :render, escape: true, layout: "./layout", :template_opts=>{chain_appends: !defined?(SimpleCov), freeze: true, skip_compiled_encoding_detection: true} plugin :public plugin :Integer_matcher_max plugin :typecast_params_sized_integers, sizes: [64], default_size: 64 # plugin :hash_branch_view_subdir plugin :custom_block_results logger = if ENV["RACK_ENV"] == "test" Class.new{def write(_) end}.new else $stderr end plugin :common_logger, logger plugin :not_found do Views::Layout.call(title: "File Not Found") end if ENV["RACK_ENV"] == "development" plugin :exception_page class RodaRequest def assets exception_page_assets super end end else def self.freeze Sequel::Model.freeze_descendents DB.freeze super end end plugin :error_handler do |e| case e when Roda::RodaPlugins::RouteCsrf::InvalidToken @page_title = "Invalid Security Token" response.status = 400 view(content: "

An invalid security token was submitted with this request, and this request could not be processed.

") else $stderr.print "#{e.class}: #{e.message}\n" $stderr.puts e.backtrace next exception_page(e, assets: true) if ENV["RACK_ENV"] == "development" # @page_title = "Internal Server Error" # view(content: "") end end plugin :sessions, key: "_App.session", #cookie_options: {secure: ENV['RACK_ENV'] != 'test'}, # Uncomment if only allowing https:// access secret: ENV.send((ENV["RACK_ENV"] == "development" ? :[] : :delete), "APP_SESSION_SECRET") # if Unreloader.autoload? # plugin :autoload_hash_branches # autoload_hash_branch_dir("./routes") # end # Unreloader.autoload("routes", delete_hook: proc{|f| hash_branch(File.basename(f).delete_suffix(".rb"))}){} class Template < Phlex::HTML def initialize(block) @block = block end def template instance_eval(&@block) end end # def render(&block) # template = Template.new(block) # instance_variables # .reject { _1.start_with?("@_") } # .each { template.instance_variable_set(_1, instance_variable_get(_1)) } # Views::Layout.call do # plain "" # end # # Views::Layout.call(template) # # Views::Layout.call do |layout| # # layout.page_title "New Pool" # # plain "" # # end # end def view(&block) Class.new(Phlex::HTML, &block).call end route do |r| # r.public # r.assets check_csrf! r.root do if DB[:pools].empty? r.redirect "/pools/new" else render do h1 { "ohai" } end end end r.on "pools" do r.is "new" do r.get do @csrf_token = csrf_token(r.path) view do Views::Layout.new(title: "New Pool") do Views::NewPool.new(csrf_token: @csrf_token) end end # Views::Layout.call(title: "New Pool") do # render Views::NewPool.new(csrf_token: csrf_token(r.path)) # end # layout = Views::Layout.new do |layout| # layout.page_title "New Pool" # render Views::NewPool.new(csrf_token: csrf_token(r.path)) # end # layout.call # @csrf_token = csrf_token(r.path) # render do # form(method: "post") do # input(type: "hidden", name: "_csrf", value: @csrf_token) # label(for: "name") # input(type: "text", name: "name", id: "name", required: true) # input(type: "submit", value: "Create") # end # end end r.post do pool = Models::Pool.create(name: r.params.fetch("name")) r.redirect "/pools/#{pool.id}" end end r.is Integer do |id| pool = Models::Pool[id] render do h2 { pool.name } end end end end end end