rack-webprofiler 0.1.0.pre.beta2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -13
- data/CHANGELOG.md +36 -12
- data/README.md +16 -12
- data/docs/DSL.md +152 -0
- data/docs/GettingStarted.md +51 -0
- data/docs/README.md +6 -0
- data/lib/rack/templates/assets/css/profiler.css +1 -1
- data/lib/rack/templates/assets/css/rwpt.css +1 -1
- data/lib/rack/templates/assets/sass/_variables.scss +21 -2
- data/lib/rack/templates/assets/sass/profiler.scss +73 -61
- data/lib/rack/templates/assets/sass/rwpt.scss +2 -2
- data/lib/rack/templates/panel/show.erb +4 -4
- data/lib/rack/templates/profiler.erb +4 -0
- data/lib/rack/web_profiler/collector.rb +197 -125
- data/lib/rack/web_profiler/collectors/rack_collector.rb +74 -0
- data/lib/rack/web_profiler/{collector/rack → collectors}/request_collector.rb +43 -60
- data/lib/rack/web_profiler/{collector → collectors}/ruby_collector.rb +4 -3
- data/lib/rack/web_profiler/{collector → collectors}/time_collector.rb +12 -6
- data/lib/rack/web_profiler/collectors.rb +21 -27
- data/lib/rack/web_profiler/config.rb +4 -9
- data/lib/rack/web_profiler/controller.rb +131 -126
- data/lib/rack/web_profiler/engine.rb +10 -14
- data/lib/rack/web_profiler/model.rb +74 -23
- data/lib/rack/web_profiler/request.rb +22 -7
- data/lib/rack/web_profiler/response.rb +27 -0
- data/lib/rack/web_profiler/rouge/html_formatter.rb +25 -0
- data/lib/rack/web_profiler/router.rb +11 -6
- data/lib/rack/web_profiler/version.rb +1 -1
- data/lib/rack/web_profiler/view.rb +255 -139
- data/lib/rack/web_profiler.rb +47 -4
- data/rack-webprofiler.gemspec +1 -3
- metadata +32 -32
- data/lib/rack/web_profiler/collector/debug_collector.rb +0 -31
- data/lib/rack/web_profiler/collector/erb_collector.rb +0 -0
- data/lib/rack/web_profiler/collector/performance_collector.rb +0 -1
- data/lib/rack/web_profiler/collector/rack/rack_collector.rb +0 -23
- data/lib/rack/web_profiler/collector/view.rb +0 -44
- data/lib/rack/web_profiler/model/collection_record.rb +0 -46
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            module Rack
         | 
| 2 | 
            +
              #
         | 
| 3 | 
            +
              class WebProfiler::Rouge::HTMLFormatter < ::Rouge::Formatter
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                # Initialize the Formatter.
         | 
| 6 | 
            +
                #
         | 
| 7 | 
            +
                # @param request [Hash]
         | 
| 8 | 
            +
                def initialize(opts = {})
         | 
| 9 | 
            +
                  @formatter = opts[:inline_theme] \
         | 
| 10 | 
            +
                    ? ::Rouge::Formatters::HTMLInline.new(opts[:inline_theme])
         | 
| 11 | 
            +
                    : ::Rouge::Formatters::HTML.new
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  if opts[:line_numbers]
         | 
| 14 | 
            +
                    @formatter = ::Rouge::Formatters::HTMLTable.new(@formatter, opts)
         | 
| 15 | 
            +
                  else
         | 
| 16 | 
            +
                    @formatter = ::Rouge::Formatters::HTMLPygments.new(@formatter)
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                # @yield the html output.
         | 
| 21 | 
            +
                def stream(tokens, &b)
         | 
| 22 | 
            +
                  @formatter.stream(tokens, &b)
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
            end
         | 
| @@ -28,6 +28,7 @@ module Rack | |
| 28 28 | 
             
                  # Route the request.
         | 
| 29 29 | 
             
                  #
         | 
| 30 30 | 
             
                  # @param request [Rack::WebProfiler::Request]
         | 
| 31 | 
            +
                  # @param path [String]
         | 
| 31 32 | 
             
                  #
         | 
| 32 33 | 
             
                  # @return [Rack::Reponse, false]
         | 
| 33 34 | 
             
                  def route(request, path)
         | 
| @@ -58,8 +59,6 @@ module Rack | |
| 58 59 | 
             
                    request = @request.dup
         | 
| 59 60 | 
             
                    request.env[PATH_INFO] = "/#{path}"
         | 
| 60 61 |  | 
| 61 | 
            -
                    path_info = Utils.unescape(request.env[PATH_INFO])
         | 
| 62 | 
            -
                    clean_path_info = Utils.clean_path_info(path_info)
         | 
| 63 62 |  | 
| 64 63 | 
             
                    status, headers, body = rf.call(request.env)
         | 
| 65 64 | 
             
                    Rack::Response.new(body, status, headers)
         | 
| @@ -71,7 +70,7 @@ module Rack | |
| 71 70 | 
             
                  #
         | 
| 72 71 | 
             
                  # @return [String]
         | 
| 73 72 | 
             
                  def url_for_asset(path)
         | 
| 74 | 
            -
                    "#{ | 
| 73 | 
            +
                    "#{get_base_path}/assets/#{path}"
         | 
| 75 74 | 
             
                  end
         | 
| 76 75 |  | 
| 77 76 | 
             
                  # Get url for toobar.
         | 
| @@ -80,7 +79,7 @@ module Rack | |
| 80 79 | 
             
                  #
         | 
| 81 80 | 
             
                  # @return [String]
         | 
| 82 81 | 
             
                  def url_for_toolbar(token)
         | 
| 83 | 
            -
                    "#{ | 
| 82 | 
            +
                    "#{get_base_path}/toolbar/#{token}"
         | 
| 84 83 | 
             
                  end
         | 
| 85 84 |  | 
| 86 85 | 
             
                  # Get url for the webprofiler.
         | 
| @@ -92,14 +91,20 @@ module Rack | |
| 92 91 | 
             
                  def url_for_profiler(token = nil, panel = nil)
         | 
| 93 92 | 
             
                    query = ""
         | 
| 94 93 | 
             
                    query = "?panel=#{panel}" unless panel.nil?
         | 
| 95 | 
            -
                    "#{ | 
| 94 | 
            +
                    "#{get_base_path}/#{token}#{query}"
         | 
| 96 95 | 
             
                  end
         | 
| 97 96 |  | 
| 98 97 | 
             
                  # Get url to clean webprofiler.
         | 
| 99 98 | 
             
                  #
         | 
| 100 99 | 
             
                  # @return [String]
         | 
| 101 100 | 
             
                  def url_for_clean_profiler
         | 
| 102 | 
            -
                    "#{ | 
| 101 | 
            +
                    "#{get_base_path}/clean"
         | 
| 102 | 
            +
                  end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                  private
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                  def get_base_path
         | 
| 107 | 
            +
                    "#{@request.env["ORIGINAL_SCRIPT_NAME"]}#{BASE_PATH}"
         | 
| 103 108 | 
             
                  end
         | 
| 104 109 | 
             
                end
         | 
| 105 110 | 
             
              end
         | 
| @@ -5,29 +5,53 @@ module Rack | |
| 5 5 | 
             
              class WebProfiler
         | 
| 6 6 | 
             
                # View
         | 
| 7 7 | 
             
                class View
         | 
| 8 | 
            +
                  # Initialize a new view.
         | 
| 9 | 
            +
                  #
         | 
| 10 | 
            +
                  # @param template [String] template file path or content
         | 
| 11 | 
            +
                  # @option layout [String, nil] layout file path or content
         | 
| 12 | 
            +
                  # @option context [Rack::WebProfiler::View::Context, nil]
         | 
| 8 13 | 
             
                  def initialize(template, layout: nil, context: nil)
         | 
| 9 14 | 
             
                    @template  = template
         | 
| 10 15 | 
             
                    @layout    = layout
         | 
| 11 16 | 
             
                    @context   = context
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    @erb_options = {
         | 
| 19 | 
            +
                      safe_level: nil,
         | 
| 20 | 
            +
                      trim_mode:  "<>-",
         | 
| 21 | 
            +
                      eoutvar:    "@_erbout",
         | 
| 22 | 
            +
                    }
         | 
| 12 23 | 
             
                  end
         | 
| 13 24 |  | 
| 25 | 
            +
                  # Get the result of view rendering.
         | 
| 26 | 
            +
                  #
         | 
| 27 | 
            +
                  # @param variables [Hash, Binding] view variables
         | 
| 28 | 
            +
                  #
         | 
| 29 | 
            +
                  # @return [String]
         | 
| 14 30 | 
             
                  def result(variables = {})
         | 
| 15 31 | 
             
                    unless @template.nil?
         | 
| 16 32 | 
             
                      templates = [read_template(@template)]
         | 
| 17 33 | 
             
                      templates << read_template(@layout) unless @layout.nil?
         | 
| 18 34 |  | 
| 19 | 
            -
                       | 
| 35 | 
            +
                      templates.inject(nil) do |prev, temp|
         | 
| 20 36 | 
             
                        render(temp, variables) { prev }
         | 
| 21 37 | 
             
                      end
         | 
| 22 38 | 
             
                    end
         | 
| 23 39 | 
             
                  end
         | 
| 24 40 |  | 
| 41 | 
            +
                  # Get the context.
         | 
| 42 | 
            +
                  #
         | 
| 43 | 
            +
                  # @return [Rack::WebProfiler::View::Context]
         | 
| 25 44 | 
             
                  def context
         | 
| 26 45 | 
             
                    @context ||= Context.new
         | 
| 27 46 | 
             
                  end
         | 
| 28 47 |  | 
| 29 | 
            -
                   | 
| 48 | 
            +
                  protected
         | 
| 30 49 |  | 
| 50 | 
            +
                  # Read a template. Returns file content if template is a file path.
         | 
| 51 | 
            +
                  #
         | 
| 52 | 
            +
                  # @param template [String] template file path or content
         | 
| 53 | 
            +
                  #
         | 
| 54 | 
            +
                  # @return [String]
         | 
| 31 55 | 
             
                  def read_template(template)
         | 
| 32 56 | 
             
                    unless template.empty?
         | 
| 33 57 | 
             
                      path = ::File.expand_path("../../templates/#{template}", __FILE__)
         | 
| @@ -36,36 +60,35 @@ module Rack | |
| 36 60 | 
             
                    template
         | 
| 37 61 | 
             
                  end
         | 
| 38 62 |  | 
| 39 | 
            -
                   | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
                   | 
| 46 | 
            -
             | 
| 63 | 
            +
                  # Render view.
         | 
| 64 | 
            +
                  #
         | 
| 65 | 
            +
                  # @param str [String] view content
         | 
| 66 | 
            +
                  # @param variables [Hash, Binding] view variables
         | 
| 67 | 
            +
                  #
         | 
| 68 | 
            +
                  # @return [String]
         | 
| 69 | 
            +
                  #
         | 
| 70 | 
            +
                  # @todo better error when there is an ERB error.
         | 
| 47 71 | 
             
                  def render(str, variables = {})
         | 
| 48 | 
            -
                    opts = options
         | 
| 49 | 
            -
             | 
| 50 72 | 
             
                    format_variables(variables).each do |name, value|
         | 
| 51 73 | 
             
                      context.instance_variable_set("@#{name}", value)
         | 
| 52 74 | 
             
                    end
         | 
| 53 75 |  | 
| 76 | 
            +
                    erb = ::ERB.new(str, *@erb_options.values_at(:safe_level, :trim_mode, :eoutvar))
         | 
| 77 | 
            +
             | 
| 54 78 | 
             
                    context.instance_eval do
         | 
| 55 | 
            -
                      erb | 
| 56 | 
            -
                      erb.result(binding).sub(/\A\n/, '')
         | 
| 79 | 
            +
                      erb.result(binding).sub(/\A\n/, "")
         | 
| 57 80 | 
             
                    end
         | 
| 58 | 
            -
                    # @todo better error when there is an ERB error.
         | 
| 59 81 | 
             
                  end
         | 
| 60 82 |  | 
| 83 | 
            +
                  # Format variables to inject them into view context.
         | 
| 84 | 
            +
                  #
         | 
| 85 | 
            +
                  # @param v [Hash, Binding] variables
         | 
| 86 | 
            +
                  #
         | 
| 87 | 
            +
                  # @return [Hash]
         | 
| 61 88 | 
             
                  def format_variables(v)
         | 
| 62 89 | 
             
                    case v
         | 
| 63 90 | 
             
                    when Binding
         | 
| 64 | 
            -
                       | 
| 65 | 
            -
                      v.eval("instance_variables").each do |k|
         | 
| 66 | 
            -
                        h[k.to_s.sub(/^@/, '')] = v.eval("instance_variable_get(:#{k})")
         | 
| 67 | 
            -
                      end
         | 
| 68 | 
            -
                      h
         | 
| 91 | 
            +
                      binding_to_hash(v)
         | 
| 69 92 | 
             
                    when Hash
         | 
| 70 93 | 
             
                      v
         | 
| 71 94 | 
             
                    else
         | 
| @@ -73,163 +96,256 @@ module Rack | |
| 73 96 | 
             
                    end
         | 
| 74 97 | 
             
                  end
         | 
| 75 98 |  | 
| 76 | 
            -
                  #  | 
| 77 | 
            -
                   | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
                     | 
| 84 | 
            -
                       | 
| 99 | 
            +
                  # Returns a [Hash] from a [Binding].
         | 
| 100 | 
            +
                  #
         | 
| 101 | 
            +
                  # @param v [Binding]
         | 
| 102 | 
            +
                  #
         | 
| 103 | 
            +
                  # @return [Hash]
         | 
| 104 | 
            +
                  def binding_to_hash(v)
         | 
| 105 | 
            +
                    h = {}
         | 
| 106 | 
            +
                    v.eval("instance_variables").each do |k|
         | 
| 107 | 
            +
                      h[k.to_s.sub(/^@/, "")] = v.eval("instance_variable_get(:#{k})")
         | 
| 85 108 | 
             
                    end
         | 
| 109 | 
            +
                    h
         | 
| 110 | 
            +
                  end
         | 
| 86 111 |  | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 89 | 
            -
             | 
| 90 | 
            -
                     | 
| 91 | 
            -
             | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
                      return "" if path.nil?
         | 
| 95 | 
            -
             | 
| 96 | 
            -
                      variables ||= binding if variables.nil?
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                      capture do
         | 
| 99 | 
            -
                        WebProfiler::View.new(path, context: self).result(variables)
         | 
| 112 | 
            +
                  # Helpers.
         | 
| 113 | 
            +
                  module Helpers
         | 
| 114 | 
            +
                    # Common helpers.
         | 
| 115 | 
            +
                    module Common
         | 
| 116 | 
            +
                      def content_for(key, content = nil, &block)
         | 
| 117 | 
            +
                        block ||= proc { |*| content }
         | 
| 118 | 
            +
                        content_blocks[key.to_sym] << capture_later(&block)
         | 
| 100 119 | 
             
                      end
         | 
| 101 | 
            -
                    end
         | 
| 102 120 |  | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 105 | 
            -
                      case obj
         | 
| 106 | 
            -
                      when String
         | 
| 107 | 
            -
                        ::ERB::Util.html_escape(obj)
         | 
| 108 | 
            -
                      else
         | 
| 109 | 
            -
                        ::ERB::Util.html_escape(obj.inspect)
         | 
| 121 | 
            +
                      def content_for?(key)
         | 
| 122 | 
            +
                        content_blocks[key.to_sym].any?
         | 
| 110 123 | 
             
                      end
         | 
| 111 | 
            -
                    end
         | 
| 112 124 |  | 
| 113 | 
            -
             | 
| 114 | 
            -
             | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
                      case language
         | 
| 118 | 
            -
                      when :ruby
         | 
| 119 | 
            -
                        lexer = Rouge::Lexers::Ruby.new
         | 
| 120 | 
            -
                      when :json
         | 
| 121 | 
            -
                        lexer = Rouge::Lexers::Jsonnet.new
         | 
| 122 | 
            -
                      when :xml
         | 
| 123 | 
            -
                        lexer = Rouge::Lexers::XML.new
         | 
| 124 | 
            -
                      else
         | 
| 125 | 
            -
                        lexer = Rouge::Lexers::PlainText.new
         | 
| 125 | 
            +
                      def yield_content(key, default = nil)
         | 
| 126 | 
            +
                        return default if content_blocks[key.to_sym].empty?
         | 
| 127 | 
            +
                        content_blocks[key.to_sym].map { |b| capture(&b) }.join
         | 
| 126 128 | 
             
                      end
         | 
| 127 129 |  | 
| 128 | 
            -
                       | 
| 130 | 
            +
                      # Render a partial view.
         | 
| 131 | 
            +
                      #
         | 
| 132 | 
            +
                      # @param path [String] path to partial
         | 
| 133 | 
            +
                      # @option variables [Hash, nil] variables for partial
         | 
| 134 | 
            +
                      #
         | 
| 135 | 
            +
                      # @return [String]
         | 
| 136 | 
            +
                      def partial(path, variables: nil)
         | 
| 137 | 
            +
                        return "" if path.nil?
         | 
| 129 138 |  | 
| 130 | 
            -
             | 
| 131 | 
            -
                      formatter = Rouge::Formatters::HTMLPygments.new(formatter, css_class='highlight')
         | 
| 139 | 
            +
                        variables ||= binding if variables.nil?
         | 
| 132 140 |  | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 141 | 
            +
                        capture do
         | 
| 142 | 
            +
                          WebProfiler::View.new(path, context: self).result(variables)
         | 
| 143 | 
            +
                        end
         | 
| 144 | 
            +
                      end
         | 
| 135 145 |  | 
| 136 | 
            -
             | 
| 137 | 
            -
                       | 
| 138 | 
            -
                      @ | 
| 139 | 
            -
                       | 
| 140 | 
            -
                      @ | 
| 141 | 
            -
                       | 
| 142 | 
            -
             | 
| 146 | 
            +
                      # Escape html.
         | 
| 147 | 
            +
                      #
         | 
| 148 | 
            +
                      # @param obj
         | 
| 149 | 
            +
                      #
         | 
| 150 | 
            +
                      # @return [String]
         | 
| 151 | 
            +
                      def h(obj)
         | 
| 152 | 
            +
                        case obj
         | 
| 153 | 
            +
                        when String
         | 
| 154 | 
            +
                          ::ERB::Util.html_escape(obj)
         | 
| 155 | 
            +
                        else
         | 
| 156 | 
            +
                          ::ERB::Util.html_escape(obj.inspect)
         | 
| 157 | 
            +
                        end
         | 
| 158 | 
            +
                      end
         | 
| 143 159 |  | 
| 144 | 
            -
             | 
| 160 | 
            +
                      # Highlight text.
         | 
| 161 | 
            +
                      #
         | 
| 162 | 
            +
                      # @option code [String]
         | 
| 163 | 
            +
                      # @option mimetype [String, nil]
         | 
| 164 | 
            +
                      # @option language [String, nil]
         | 
| 165 | 
            +
                      # @option formatter_opts [Hash]
         | 
| 166 | 
            +
                      #
         | 
| 167 | 
            +
                      # @yield code.
         | 
| 168 | 
            +
                      #
         | 
| 169 | 
            +
                      # @return [String]
         | 
| 170 | 
            +
                      def highlight(code: "", mimetype: nil, language: nil, formatter_opts: {})
         | 
| 171 | 
            +
                        language = language.to_s if language.is_a? Symbol
         | 
| 172 | 
            +
             | 
| 173 | 
            +
                        lexer = ::Rouge::Lexer.guess(mimetype: mimetype) if mimetype.is_a? String
         | 
| 174 | 
            +
                        lexer = ::Rouge::Lexer.find_fancy(language)      if language.is_a? String
         | 
| 175 | 
            +
                        lexer ||= ::Rouge::Lexers::PlainText.new
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                        code = capture(&Proc.new) if block_given?
         | 
| 178 | 
            +
                        code ||= ""
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                        formatter = WebProfiler::Rouge::HTMLFormatter.new(formatter_opts)
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                        "<div class=\"highlight\">#{formatter.format(lexer.lex(code))}</div>"
         | 
| 183 | 
            +
                      end
         | 
| 145 184 |  | 
| 146 | 
            -
             | 
| 147 | 
            -
                       | 
| 148 | 
            -
             | 
| 185 | 
            +
                      #
         | 
| 186 | 
            +
                      #
         | 
| 187 | 
            +
                      # @yield
         | 
| 188 | 
            +
                      def capture(&block)
         | 
| 189 | 
            +
                        @capture = nil
         | 
| 190 | 
            +
                        buf_was  =  @_erbout
         | 
| 191 | 
            +
                        @_erbout = ""
         | 
| 149 192 |  | 
| 150 | 
            -
             | 
| 151 | 
            -
                      @content_blocks ||= Hash.new {|h,k| h[k] = [] }
         | 
| 152 | 
            -
                    end
         | 
| 153 | 
            -
                  end
         | 
| 193 | 
            +
                        result = yield
         | 
| 154 194 |  | 
| 155 | 
            -
             | 
| 156 | 
            -
             | 
| 195 | 
            +
                        @_erbout = buf_was
         | 
| 196 | 
            +
                        result.strip.empty? && @capture ? @capture : result
         | 
| 197 | 
            +
                      end
         | 
| 157 198 |  | 
| 158 | 
            -
             | 
| 159 | 
            -
             | 
| 160 | 
            -
                       | 
| 161 | 
            -
             | 
| 199 | 
            +
                      #
         | 
| 200 | 
            +
                      #
         | 
| 201 | 
            +
                      # @yield
         | 
| 202 | 
            +
                      def capture_later(&block)
         | 
| 203 | 
            +
                        proc { |*| @capture = capture(&block) }
         | 
| 204 | 
            +
                      end
         | 
| 205 | 
            +
             | 
| 206 | 
            +
                      private
         | 
| 162 207 |  | 
| 163 | 
            -
             | 
| 164 | 
            -
             | 
| 165 | 
            -
                       | 
| 208 | 
            +
                      #
         | 
| 209 | 
            +
                      #
         | 
| 210 | 
            +
                      # @return [Hash]
         | 
| 211 | 
            +
                      def content_blocks
         | 
| 212 | 
            +
                        @content_blocks ||= Hash.new { |h, k| h[k] = [] }
         | 
| 213 | 
            +
                      end
         | 
| 166 214 | 
             
                    end
         | 
| 167 215 |  | 
| 168 | 
            -
                     | 
| 169 | 
            -
             | 
| 216 | 
            +
                    # Collector helpers.
         | 
| 217 | 
            +
                    module Collector
         | 
| 218 | 
            +
                      # Get collector status from a collection.
         | 
| 219 | 
            +
                      #
         | 
| 220 | 
            +
                      # @param collector [Rack::WebProfiler::Collector::Definition]
         | 
| 221 | 
            +
                      # @param collection [Rack::WebProfiler::Model::CollectionRecord]
         | 
| 222 | 
            +
                      #
         | 
| 223 | 
            +
                      # @return [Symbol, nil]
         | 
| 224 | 
            +
                      def collector_status(collector, collection)
         | 
| 225 | 
            +
                        collector_data_storage(collector, collection, :status)
         | 
| 226 | 
            +
                      end
         | 
| 170 227 |  | 
| 171 | 
            -
                       | 
| 172 | 
            -
                       | 
| 173 | 
            -
             | 
| 228 | 
            +
                      #
         | 
| 229 | 
            +
                      #
         | 
| 230 | 
            +
                      # @param collector [Rack::WebProfiler::Collector::Definition]
         | 
| 231 | 
            +
                      # @param collection [Rack::WebProfiler::Model::CollectionRecord]
         | 
| 232 | 
            +
                      def collector_datas(collector, collection)
         | 
| 233 | 
            +
                        collector_data_storage(collector, collection, :datas)
         | 
| 234 | 
            +
                      end
         | 
| 174 235 |  | 
| 175 | 
            -
             | 
| 176 | 
            -
                       | 
| 236 | 
            +
                      #
         | 
| 237 | 
            +
                      # @param collector [Rack::WebProfiler::Collector::Definition]
         | 
| 238 | 
            +
                      # @param collection [Rack::WebProfiler::Model::CollectionRecord]
         | 
| 239 | 
            +
                      def collector_tab(collector, collection)
         | 
| 240 | 
            +
                        return nil unless collection_contains_datas_for_collector?(collection, collector)
         | 
| 177 241 |  | 
| 178 | 
            -
             | 
| 179 | 
            -
             | 
| 180 | 
            -
             | 
| 242 | 
            +
                        c = collector_view_context(collector, collection)
         | 
| 243 | 
            +
                        c.tab_content
         | 
| 244 | 
            +
                      end
         | 
| 181 245 |  | 
| 182 | 
            -
             | 
| 183 | 
            -
                       | 
| 184 | 
            -
             | 
| 246 | 
            +
                      #
         | 
| 247 | 
            +
                      # @param collector [Rack::WebProfiler::Collector::Definition]
         | 
| 248 | 
            +
                      # @param collection [Rack::WebProfiler::Model::CollectionRecord]
         | 
| 249 | 
            +
                      def collector_panel(collector, collection)
         | 
| 250 | 
            +
                        return nil unless collection_contains_datas_for_collector?(collection, collector)
         | 
| 185 251 |  | 
| 186 | 
            -
             | 
| 187 | 
            -
             | 
| 188 | 
            -
             | 
| 252 | 
            +
                        c = collector_view_context(collector, collection)
         | 
| 253 | 
            +
                        c.panel_content
         | 
| 254 | 
            +
                      end
         | 
| 189 255 |  | 
| 190 | 
            -
             | 
| 256 | 
            +
                      #
         | 
| 257 | 
            +
                      # @param collector [Rack::WebProfiler::Collector::Definition]
         | 
| 258 | 
            +
                      # @param collection [Rack::WebProfiler::Model::CollectionRecord]
         | 
| 259 | 
            +
                      def collector_has_tab?(collector, collection)
         | 
| 260 | 
            +
                        collector_data_storage(collector, collection, :show_tab)
         | 
| 261 | 
            +
                        # !collector_tab(collector, collection).nil?
         | 
| 262 | 
            +
                      end
         | 
| 191 263 |  | 
| 192 | 
            -
             | 
| 193 | 
            -
                       | 
| 194 | 
            -
             | 
| 195 | 
            -
             | 
| 196 | 
            -
                         | 
| 264 | 
            +
                      #
         | 
| 265 | 
            +
                      # @param collector [Rack::WebProfiler::Collector::Definition]
         | 
| 266 | 
            +
                      # @param collection [Rack::WebProfiler::Model::CollectionRecord]
         | 
| 267 | 
            +
                      def collector_has_panel?(collector, collection)
         | 
| 268 | 
            +
                        collector_data_storage(collector, collection, :show_panel)
         | 
| 269 | 
            +
                        # !collector_panel(collector, collection).nil?
         | 
| 197 270 | 
             
                      end
         | 
| 198 | 
            -
                    end
         | 
| 199 271 |  | 
| 200 | 
            -
             | 
| 201 | 
            -
             | 
| 272 | 
            +
                      private
         | 
| 273 | 
            +
             | 
| 274 | 
            +
                      # Get a collector view Context.
         | 
| 275 | 
            +
                      #
         | 
| 276 | 
            +
                      # @param collector [Rack::WebProfiler::Collector::Definition]
         | 
| 277 | 
            +
                      # @param collection [Rack::WebProfiler::Model::CollectionRecord]
         | 
| 278 | 
            +
                      #
         | 
| 279 | 
            +
                      # @return [Rack::WebProfiler::View::Context]
         | 
| 280 | 
            +
                      def collector_view_context(collector, collection)
         | 
| 281 | 
            +
                        collectors_view_context[collector.identifier] ||= begin
         | 
| 282 | 
            +
                          v = WebProfiler::Collector::View.new(collector.template)
         | 
| 283 | 
            +
                          v.result(collector: collector, collection: collection)
         | 
| 284 | 
            +
                          v.context
         | 
| 285 | 
            +
                        end
         | 
| 286 | 
            +
                      end
         | 
| 202 287 |  | 
| 203 | 
            -
                       | 
| 204 | 
            -
                       | 
| 205 | 
            -
             | 
| 288 | 
            +
                      #
         | 
| 289 | 
            +
                      #
         | 
| 290 | 
            +
                      # @param collector [Rack::WebProfiler::Collector::Definition]
         | 
| 291 | 
            +
                      # @param collection [Rack::WebProfiler::Model::CollectionRecord]
         | 
| 292 | 
            +
                      # @param key [Symbol, String]
         | 
| 293 | 
            +
                      #
         | 
| 294 | 
            +
                      # @return
         | 
| 295 | 
            +
                      def collector_data_storage(collector, collection, key = nil)
         | 
| 296 | 
            +
                        return nil unless collection_contains_datas_for_collector?(collection, collector)
         | 
| 297 | 
            +
             | 
| 298 | 
            +
                        storage = collection.datas[collector.identifier.to_sym]
         | 
| 299 | 
            +
                        storage[key] if !key.nil? && storage.key?(key)
         | 
| 300 | 
            +
                      end
         | 
| 206 301 |  | 
| 207 | 
            -
             | 
| 208 | 
            -
                       | 
| 209 | 
            -
             | 
| 210 | 
            -
             | 
| 302 | 
            +
                      # Check if collector is valid.
         | 
| 303 | 
            +
                      #
         | 
| 304 | 
            +
                      # @param collector [Rack::WebProfiler::Collector::Definition]
         | 
| 305 | 
            +
                      #
         | 
| 306 | 
            +
                      # @return [Boolean]
         | 
| 307 | 
            +
                      def valid_collector?(collector)
         | 
| 308 | 
            +
                        !collector.nil? \
         | 
| 309 | 
            +
                          && collector.is_a?(WebProfiler::Collector::Definition)
         | 
| 310 | 
            +
                      end
         | 
| 211 311 |  | 
| 212 | 
            -
             | 
| 213 | 
            -
                       | 
| 214 | 
            -
             | 
| 215 | 
            -
             | 
| 312 | 
            +
                      # Check if collection is valid.
         | 
| 313 | 
            +
                      #
         | 
| 314 | 
            +
                      # @param collection [Rack::WebProfiler::Model::CollectionRecord]
         | 
| 315 | 
            +
                      #
         | 
| 316 | 
            +
                      # @return [Boolean]
         | 
| 317 | 
            +
                      def valid_collection?(collection)
         | 
| 318 | 
            +
                        !collection.nil? \
         | 
| 319 | 
            +
                          && collection.is_a?(WebProfiler::Model::CollectionRecord)
         | 
| 320 | 
            +
                      end
         | 
| 216 321 |  | 
| 217 | 
            -
             | 
| 218 | 
            -
                       | 
| 219 | 
            -
             | 
| 220 | 
            -
             | 
| 221 | 
            -
             | 
| 322 | 
            +
                      # @param collector [Rack::WebProfiler::Collector::Definition]
         | 
| 323 | 
            +
                      # @param collection [Rack::WebProfiler::Model::CollectionRecord]
         | 
| 324 | 
            +
                      #
         | 
| 325 | 
            +
                      # @return [Boolean]
         | 
| 326 | 
            +
                      def collection_contains_datas_for_collector?(collection, collector)
         | 
| 327 | 
            +
                        valid_collector?(collector) \
         | 
| 328 | 
            +
                          && valid_collection?(collection) \
         | 
| 329 | 
            +
                          && collection.datas.key?(collector.identifier.to_sym)
         | 
| 330 | 
            +
                      end
         | 
| 222 331 |  | 
| 223 | 
            -
             | 
| 332 | 
            +
                      private
         | 
| 224 333 |  | 
| 225 | 
            -
             | 
| 226 | 
            -
                       | 
| 334 | 
            +
                      # Get the collectors view context.
         | 
| 335 | 
            +
                      #
         | 
| 336 | 
            +
                      # @return [Hash]
         | 
| 337 | 
            +
                      def collectors_view_context
         | 
| 338 | 
            +
                        @collectors_view_context ||= {}
         | 
| 339 | 
            +
                      end
         | 
| 227 340 | 
             
                    end
         | 
| 228 341 | 
             
                  end
         | 
| 229 342 |  | 
| 343 | 
            +
                  # View Context.
         | 
| 230 344 | 
             
                  class Context
         | 
| 231 | 
            -
             | 
| 232 | 
            -
                     | 
| 345 | 
            +
             | 
| 346 | 
            +
                    # Include helpers into the Context.
         | 
| 347 | 
            +
                    include Helpers::Common
         | 
| 348 | 
            +
                    include Helpers::Collector
         | 
| 233 349 | 
             
                  end
         | 
| 234 350 | 
             
                end
         | 
| 235 351 | 
             
              end
         | 
    
        data/lib/rack/web_profiler.rb
    CHANGED
    
    | @@ -10,29 +10,69 @@ module Rack | |
| 10 10 | 
             
                autoload :Controller, "rack/web_profiler/controller"
         | 
| 11 11 | 
             
                autoload :Engine,     "rack/web_profiler/engine"
         | 
| 12 12 | 
             
                autoload :Model,      "rack/web_profiler/model"
         | 
| 13 | 
            +
                autoload :Response,   "rack/web_profiler/response"
         | 
| 13 14 | 
             
                autoload :Request,    "rack/web_profiler/request"
         | 
| 14 15 | 
             
                autoload :Router,     "rack/web_profiler/router"
         | 
| 15 16 | 
             
                autoload :View,       "rack/web_profiler/view"
         | 
| 16 17 |  | 
| 18 | 
            +
                # Classes about Rouge gem customization.
         | 
| 19 | 
            +
                module Rouge
         | 
| 20 | 
            +
                  autoload :HTMLFormatter, "rack/web_profiler/rouge/html_formatter"
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                # Env key constants.
         | 
| 24 | 
            +
                ENV_RUNTIME_START = "rack_webprofiler.runtime_start".freeze
         | 
| 25 | 
            +
                ENV_RUNTIME       = "rack_webprofiler.runtime".freeze
         | 
| 26 | 
            +
                ENV_EXCEPTION     = "rack_webprofiler.exception".freeze
         | 
| 27 | 
            +
             | 
| 17 28 | 
             
                class << self
         | 
| 29 | 
            +
                  # Configure the WebProfiler.
         | 
| 30 | 
            +
                  #
         | 
| 31 | 
            +
                  # @yield the Config object.
         | 
| 32 | 
            +
                  #
         | 
| 33 | 
            +
                  # @return [Rack::WebProfiler::Config]
         | 
| 18 34 | 
             
                  def config
         | 
| 19 35 | 
             
                    @config ||= Config.new
         | 
| 20 36 | 
             
                    @config.build!(&Proc.new) if block_given?
         | 
| 21 37 | 
             
                    @config
         | 
| 22 38 | 
             
                  end
         | 
| 23 39 |  | 
| 40 | 
            +
                  # Register one or many collectors.
         | 
| 41 | 
            +
                  #
         | 
| 42 | 
            +
                  # @param collector_class [Array, Class]
         | 
| 24 43 | 
             
                  def register_collector(collector_class)
         | 
| 25 44 | 
             
                    config.collectors.add_collector collector_class
         | 
| 26 45 | 
             
                  end
         | 
| 46 | 
            +
                  alias register_collectors register_collector
         | 
| 27 47 |  | 
| 48 | 
            +
                  # Unregister one or many collectors.
         | 
| 49 | 
            +
                  #
         | 
| 50 | 
            +
                  # @param collector_class [Array, Class]
         | 
| 28 51 | 
             
                  def unregister_collector(collector_class)
         | 
| 29 52 | 
             
                    config.collectors.remove_collector collector_class
         | 
| 30 53 | 
             
                  end
         | 
| 54 | 
            +
                  alias unregister_collectors unregister_collector
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  def data(k = nil, v = :undefined)
         | 
| 57 | 
            +
                    @data ||= {}
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                    return @data if k === nil
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                    @data[k] = v unless v === :undefined
         | 
| 62 | 
            +
                    @data[k] if @data.key?(k)
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                  def reset_data!
         | 
| 66 | 
            +
                    @data = {}
         | 
| 67 | 
            +
                  end
         | 
| 31 68 | 
             
                end
         | 
| 32 69 |  | 
| 70 | 
            +
                attr_reader :data
         | 
| 71 | 
            +
             | 
| 33 72 | 
             
                # Initialize
         | 
| 34 73 | 
             
                #
         | 
| 35 74 | 
             
                # @param app [Proc]
         | 
| 75 | 
            +
                # @option tmp_dir [String]
         | 
| 36 76 | 
             
                def initialize(app, tmp_dir: nil)
         | 
| 37 77 | 
             
                  @app = app
         | 
| 38 78 |  | 
| @@ -46,9 +86,11 @@ module Rack | |
| 46 86 | 
             
                #
         | 
| 47 87 | 
             
                # @return [Array]
         | 
| 48 88 | 
             
                def call(env)
         | 
| 89 | 
            +
                  WebProfiler.reset_data!
         | 
| 90 | 
            +
             | 
| 49 91 | 
             
                  begin
         | 
| 50 92 | 
             
                    request = WebProfiler::Request.new(env)
         | 
| 51 | 
            -
                     | 
| 93 | 
            +
                    env[ENV_RUNTIME_START] = Time.now.to_f
         | 
| 52 94 |  | 
| 53 95 | 
             
                    response = WebProfiler::Router.response_for(request)
         | 
| 54 96 | 
             
                    return response.finish if response.is_a? Rack::Response
         | 
| @@ -74,10 +116,11 @@ module Rack | |
| 74 116 | 
             
                #
         | 
| 75 117 | 
             
                # @return [Rack::Response]
         | 
| 76 118 | 
             
                def process(request, body, status, headers, exception = nil)
         | 
| 77 | 
            -
                  request. | 
| 119 | 
            +
                  request.env[ENV_RUNTIME]   = Time.now.to_f - request.env[ENV_RUNTIME_START]
         | 
| 120 | 
            +
                  request.env[ENV_EXCEPTION] = nil
         | 
| 78 121 |  | 
| 79 | 
            -
                   | 
| 80 | 
            -
                    request. | 
| 122 | 
            +
                  if !exception.nil?
         | 
| 123 | 
            +
                    request.env[ENV_EXCEPTION] = exception
         | 
| 81 124 | 
             
                    WebProfiler::Engine.process_exception(request).finish
         | 
| 82 125 | 
             
                  else
         | 
| 83 126 | 
             
                    WebProfiler::Engine.process(request, body, status, headers).finish
         |