Class: Slimmer::Skin
- Inherits:
-
Object
- Object
- Slimmer::Skin
- Defined in:
- lib/slimmer/skin.rb,
lib/slimmer/test.rb
Instance Attribute Summary collapse
-
#asset_host ⇒ Object
Returns the value of attribute asset_host.
-
#logger ⇒ Object
Returns the value of attribute logger.
-
#options ⇒ Object
Returns the value of attribute options.
-
#strict ⇒ Object
Returns the value of attribute strict.
-
#template_cache ⇒ Object
Returns the value of attribute template_cache.
Instance Method Summary collapse
- #artefact_from_header(response) ⇒ Object
- #context(html, error) ⇒ Object
- #error(template_name, body, rack_env) ⇒ Object
- #ignorable?(error) ⇒ Boolean
-
#initialize(options = {}) ⇒ Skin
constructor
A new instance of Skin.
- #load_template(name) ⇒ Object
- #parse_html(html, description_for_error_message) ⇒ Object
- #process(processors, body, template, rack_env) ⇒ Object
- #report_parse_errors_if_strict!(nokogiri_doc, description_for_error_message) ⇒ Object
- #success(source_request, response, body) ⇒ Object
- #template(template_name) ⇒ Object
- #template_url(template_name) ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ Skin
Returns a new instance of Skin.
8 9 10 11 12 13 14 15 |
# File 'lib/slimmer/skin.rb', line 8 def initialize = {} @options = @asset_host = [:asset_host] @template_cache = [:cache] @logger = [:logger] || NullLogger.instance @strict = [:strict] || (%w{development test}.include?(ENV['RACK_ENV'])) end |
Instance Attribute Details
#asset_host ⇒ Object
Returns the value of attribute asset_host.
6 7 8 |
# File 'lib/slimmer/skin.rb', line 6 def asset_host @asset_host end |
#logger ⇒ Object
Returns the value of attribute logger.
6 7 8 |
# File 'lib/slimmer/skin.rb', line 6 def logger @logger end |
#options ⇒ Object
Returns the value of attribute options.
6 7 8 |
# File 'lib/slimmer/skin.rb', line 6 def @options end |
#strict ⇒ Object
Returns the value of attribute strict.
6 7 8 |
# File 'lib/slimmer/skin.rb', line 6 def strict @strict end |
#template_cache ⇒ Object
Returns the value of attribute template_cache.
6 7 8 |
# File 'lib/slimmer/skin.rb', line 6 def template_cache @template_cache end |
Instance Method Details
#artefact_from_header(response) ⇒ Object
141 142 143 144 145 146 147 148 149 150 |
# File 'lib/slimmer/skin.rb', line 141 def artefact_from_header(response) if response.headers.include?(Headers::ARTEFACT_HEADER) Artefact.new JSON.parse(response.headers[Headers::ARTEFACT_HEADER]) else nil end rescue JSON::ParserError => e logger.error "Slimmer: Failed while parsing artefact header: #{[ e., e.backtrace ].flatten.join("\n")}" nil end |
#context(html, error) ⇒ Object
61 62 63 64 65 66 67 68 69 70 |
# File 'lib/slimmer/skin.rb', line 61 def context(html, error) context_size = 5 lines = [""] + html.split("\n") from = [1, error.line - context_size].max to = [lines.size - 1, error.line + context_size].min context = (from..to).zip(lines[from..to]).map {|lineno, line| "%4d: %s" % [lineno, line] } marker = " " * (error.column - 1) + "-----v" context.insert(context_size, marker) context.join("\n") end |
#error(template_name, body, rack_env) ⇒ Object
134 135 136 137 138 139 |
# File 'lib/slimmer/skin.rb', line 134 def error(template_name, body, rack_env) processors = [ Processors::TitleInserter.new() ] process(processors, body, template(template_name), rack_env) end |
#ignorable?(error) ⇒ Boolean
72 73 74 75 |
# File 'lib/slimmer/skin.rb', line 72 def ignorable?(error) ignorable_codes = [801] ignorable_codes.include?(error.code) || error..match(/Element script embeds close tag/) || error..match(/Unexpected end tag : noscript/) end |
#load_template(name) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/slimmer/skin.rb', line 23 def load_template(template_name) url = template_url(template_name) headers = {} headers[:govuk_request_id] = GovukRequestId.value if GovukRequestId.set? response = RestClient.get(url, headers) response.body rescue RestClient::Exception => e raise TemplateNotFoundException, "Unable to fetch: '#{template_name}' from '#{url}' because #{e}", caller rescue Errno::ECONNREFUSED, SocketError, OpenSSL::SSL::SSLError => e raise CouldNotRetrieveTemplate, "Unable to fetch: '#{template_name}' from '#{url}' because #{e}", caller end |
#parse_html(html, description_for_error_message) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/slimmer/skin.rb', line 45 def parse_html(html, ) doc = Nokogiri::HTML.parse(html) if strict errors = doc.errors.select {|e| e.error?}.reject {|e| ignorable?(e)} if errors.size > 0 error = errors.first = "In #{}: '#{error.}' at line #{error.line} col #{error.column} (code #{error.code}).\n" << "Add ?skip_slimmer=1 to the url to show the raw backend request.\n\n" << context(html, error) raise end end doc end |
#process(processors, body, template, rack_env) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/slimmer/skin.rb', line 77 def process(processors,body,template, rack_env) logger.debug "Slimmer: starting skinning process" src = parse_html(body.to_s, "backend response") dest = parse_html(template, "template") start_time = Time.now logger.debug "Slimmer: Start time = #{start_time}" processors.each do |p| processor_start_time = Time.now logger.debug "Slimmer: Processor #{p} started at #{processor_start_time}" begin p.filter(src,dest) rescue => e logger.error "Slimmer: Failed while processing #{p}: #{[ e., e.backtrace ].flatten.join("\n")}" if defined?(Airbrake) Airbrake.notify_or_ignore(e, rack_env: rack_env) end raise if strict end processor_end_time = Time.now process_time = processor_end_time - processor_start_time logger.debug "Slimmer: Processor #{p} ended at #{processor_end_time} (#{process_time}s)" end end_time = Time.now logger.debug "Slimmer: Skinning process completed at #{end_time} (#{end_time - start_time}s)" dest.to_html end |
#report_parse_errors_if_strict!(nokogiri_doc, description_for_error_message) ⇒ Object
41 42 43 |
# File 'lib/slimmer/skin.rb', line 41 def report_parse_errors_if_strict!(nokogiri_doc, ) nokogiri_doc end |
#success(source_request, response, body) ⇒ Object
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/slimmer/skin.rb', line 106 def success(source_request, response, body) artefact = artefact_from_header(response) wrapper_id = [:wrapper_id] || 'wrapper' processors = [ Processors::TitleInserter.new(), Processors::TagMover.new(), Processors::NavigationMover.new(self), Processors::ConditionalCommentMover.new(), Processors::BodyInserter.new(wrapper_id), Processors::BodyClassCopier.new, Processors::InsideHeaderInserter.new, Processors::HeaderContextInserter.new(), Processors::SectionInserter.new(artefact), Processors::MetadataInserter.new(response, artefact, [:app_name]), Processors::SearchParameterInserter.new(response), Processors::SearchPathSetter.new(response), Processors::RelatedItemsInserter.new(self, artefact), Processors::ReportAProblemInserter.new(self, source_request.url, response.headers, wrapper_id), Processors::SearchRemover.new(response.headers), ] template_name = response.headers[Headers::TEMPLATE_HEADER] || 'core_layout' process(processors, body, template(template_name), source_request.env) end |
#template(template_name) ⇒ Object
17 18 19 20 21 |
# File 'lib/slimmer/skin.rb', line 17 def template(template_name) template_cache.fetch(template_name) do load_template(template_name) end end |
#template_url(template_name) ⇒ Object
35 36 37 38 39 |
# File 'lib/slimmer/skin.rb', line 35 def template_url(template_name) host = asset_host.dup host += '/' unless host =~ /\/$/ "#{host}templates/#{template_name}.html.erb" end |