blinkr 0.2.9 → 0.3.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 +4 -4
- data/Gemfile +3 -0
- data/bin/blinkr +1 -0
- data/blinkr.gemspec +16 -8
- data/lib/blinkr.rb +2 -1
- data/lib/blinkr/cache.rb +5 -1
- data/lib/blinkr/config.rb +2 -1
- data/lib/blinkr/engine.rb +49 -36
- data/lib/blinkr/error.rb +30 -0
- data/lib/blinkr/extensions/a_title.rb +7 -1
- data/lib/blinkr/extensions/empty_a_href.rb +7 -1
- data/lib/blinkr/extensions/img_alt.rb +7 -1
- data/lib/blinkr/extensions/inline_css.rb +13 -2
- data/lib/blinkr/extensions/javascript.rb +5 -1
- data/lib/blinkr/extensions/links.rb +66 -22
- data/lib/blinkr/extensions/meta.rb +37 -8
- data/lib/blinkr/extensions/resources.rb +5 -1
- data/lib/blinkr/hacks.rb +20 -0
- data/lib/blinkr/http_utils.rb +10 -5
- data/lib/blinkr/manticore_wrapper.rb +59 -0
- data/lib/blinkr/phantomjs_wrapper.rb +22 -9
- data/lib/blinkr/report.html.slim +186 -210
- data/lib/blinkr/report.rb +22 -19
- data/lib/blinkr/sitemap.rb +5 -4
- data/lib/blinkr/typhoeus_wrapper.rb +19 -16
- data/lib/blinkr/version.rb +1 -1
- metadata +8 -6
- data/.gitignore +0 -18
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b54b1fe0983042827e5f00868dcf9e65ef5c2f2
|
4
|
+
data.tar.gz: f90a1abe798a9e3cfaebe7544f0e618b4379116d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bdbee3d503b16a6354a29171b775ff5bfb1667203529b158cc2e26ce3f58749402fea5098dd1a349387050d76e8454861dbe8919d8473cdf57e7d6205b6503c7
|
7
|
+
data.tar.gz: bfc4cc60420fed8c53c20bcec5b224fb341a3e3a3d53a054aaa2e4cdff2575d5f5b0f62b391c459b4df89cae5875e7b1353ab23723ac99138cd70d13aba7d460
|
data/Gemfile
CHANGED
data/bin/blinkr
CHANGED
data/blinkr.gemspec
CHANGED
@@ -4,26 +4,34 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'blinkr/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
7
|
+
spec.name = 'blinkr'
|
8
8
|
spec.version = Blinkr::VERSION
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
9
|
+
spec.authors = ['Pete Muir', 'Jason Porter']
|
10
|
+
spec.email = %w(pmuir@bleepbleep.org.uk lightguard.jp@gmail.com)
|
11
11
|
spec.summary = %q{A simple broken link checker}
|
12
12
|
spec.description = %q{A broken page and link checker for websites. Optionally uses phantomjs to render pages to check resource loading, links created by JS, and report any JS page load errors.}
|
13
|
-
spec.homepage
|
14
|
-
spec.license
|
13
|
+
spec.homepage = 'https://github.com/pmuir/blinkr'
|
14
|
+
spec.license = 'Apache-2.0'
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.files -= ['.gitignore', '.ruby-version', '.ruby-gemset']
|
18
|
+
|
19
|
+
|
17
20
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
21
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
22
|
+
spec.require_paths = ['lib']
|
20
23
|
|
21
|
-
spec.required_ruby_version = '~>
|
24
|
+
spec.required_ruby_version = '~> 1.9'
|
22
25
|
|
23
|
-
spec.add_development_dependency
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
24
27
|
spec.add_development_dependency 'rake', '~> 10.3'
|
25
28
|
spec.add_dependency 'nokogiri', '~> 1.5'
|
26
29
|
spec.add_dependency 'typhoeus', '~> 0.7'
|
27
30
|
spec.add_dependency 'slim', '~> 3.0'
|
28
31
|
spec.add_dependency 'parallel', '~> 1.3'
|
32
|
+
|
33
|
+
if defined? JRUBY_VERSION
|
34
|
+
spec.platform = 'java'
|
35
|
+
spec.add_dependency 'manticore', '~> 0.4'
|
36
|
+
end
|
29
37
|
end
|
data/lib/blinkr.rb
CHANGED
@@ -2,12 +2,13 @@ require 'blinkr/version'
|
|
2
2
|
require 'blinkr/engine'
|
3
3
|
require 'blinkr/report'
|
4
4
|
require 'blinkr/config'
|
5
|
+
require 'blinkr/error'
|
5
6
|
require 'blinkr/typhoeus_wrapper'
|
6
7
|
require 'yaml'
|
7
8
|
|
8
9
|
module Blinkr
|
9
10
|
def self.run(base_url, config = 'blinkr.yaml', single, verbose, vverbose)
|
10
|
-
args = {
|
11
|
+
args = {:base_url => base_url, :verbose => verbose, :vverbose => vverbose}
|
11
12
|
if !config.nil? && File.exists?(config)
|
12
13
|
config = Blinkr::Config.read config, args
|
13
14
|
else
|
data/lib/blinkr/cache.rb
CHANGED
@@ -9,7 +9,11 @@ module Blinkr
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def set(request, response)
|
12
|
-
|
12
|
+
if request.is_a? String # HACK for caching resource and js errors
|
13
|
+
@memory[request] = response
|
14
|
+
else
|
15
|
+
@memory[request] = response unless response.timed_out?
|
16
|
+
end
|
13
17
|
end
|
14
18
|
|
15
19
|
def size
|
data/lib/blinkr/config.rb
CHANGED
@@ -8,7 +8,8 @@ module Blinkr
|
|
8
8
|
Config.new(YAML.load_file(file).merge(args).merge({ :config_file => file }))
|
9
9
|
end
|
10
10
|
|
11
|
-
DEFAULTS = {:skips => [], :ignores => [], :max_retrys => 3, :browser => 'typhoeus',
|
11
|
+
DEFAULTS = {:skips => [], :ignores => [], :max_retrys => 3, :browser => 'typhoeus',
|
12
|
+
:viewport => 1200, :phantomjs_threads => 8, :report => 'blinkr.html'}
|
12
13
|
|
13
14
|
def initialize(hash={})
|
14
15
|
super(DEFAULTS.merge(hash))
|
data/lib/blinkr/engine.rb
CHANGED
@@ -9,6 +9,8 @@ require 'blinkr/extensions/javascript'
|
|
9
9
|
require 'blinkr/extensions/resources'
|
10
10
|
require 'blinkr/extensions/pipeline'
|
11
11
|
require 'json'
|
12
|
+
require 'pathname'
|
13
|
+
require 'fileutils'
|
12
14
|
require 'ostruct'
|
13
15
|
|
14
16
|
# Monkeypatch OpenStruct
|
@@ -27,7 +29,7 @@ module Blinkr
|
|
27
29
|
include HttpUtils
|
28
30
|
include Sitemap
|
29
31
|
|
30
|
-
def initialize
|
32
|
+
def initialize(config)
|
31
33
|
@config = config.validate
|
32
34
|
@extensions = []
|
33
35
|
load_pipeline
|
@@ -35,15 +37,25 @@ module Blinkr
|
|
35
37
|
|
36
38
|
def run
|
37
39
|
context = OpenStruct.new({:pages => {}})
|
38
|
-
|
40
|
+
if defined?(JRUBY_VERSION) && @config.browser == 'manticore'
|
41
|
+
require 'blinkr/manticore_wrapper'
|
42
|
+
bulk_browser = browser = ManticoreWrapper.new(@config, context)
|
43
|
+
else
|
44
|
+
bulk_browser = browser = TyphoeusWrapper.new(@config, context)
|
45
|
+
end
|
39
46
|
browser = PhantomJSWrapper.new(@config, context) if @config.browser == 'phantomjs'
|
40
47
|
page_count = 0
|
41
|
-
|
48
|
+
urls = sitemap_locations.uniq
|
49
|
+
puts "Fetching #{urls.size} pages from sitemap"
|
50
|
+
browser.process_all(urls, @config.max_page_retrys) do |response, resource_errors, javascript_errors|
|
51
|
+
url = response.request.base_url
|
42
52
|
if response.success?
|
43
|
-
url = response.request.base_url
|
44
53
|
puts "Loaded page #{url}" if @config.verbose
|
45
54
|
body = Nokogiri::HTML(response.body)
|
46
|
-
page = OpenStruct.new({
|
55
|
+
page = OpenStruct.new({:response => response, :body => body.freeze,
|
56
|
+
:errors => ErrorArray.new(@config),
|
57
|
+
:resource_errors => resource_errors || [],
|
58
|
+
:javascript_errors => javascript_errors || []})
|
47
59
|
context.pages[url] = page
|
48
60
|
collect page
|
49
61
|
page_count += 1
|
@@ -51,25 +63,26 @@ module Blinkr
|
|
51
63
|
puts "#{response.code} #{response.status_message} Unable to load page #{url} #{'(' + response.return_message + ')' unless response.return_message.nil?}"
|
52
64
|
end
|
53
65
|
end
|
54
|
-
|
55
|
-
|
56
|
-
puts "Loaded #{page_count} pages using #{browser.name}.
|
57
|
-
|
66
|
+
puts 'Executing Typhoeus::Hydra.run, this could take awhile' if @config.browser == 'typhoeus'
|
67
|
+
# browser.hydra.run if @config.browser == 'typhoeus'
|
68
|
+
puts "Loaded #{page_count} pages using #{browser.name}."
|
69
|
+
puts 'Analyzing pages'
|
70
|
+
analyze context, bulk_browser
|
71
|
+
context.pages.reject! { |_, page| page.errors.empty? }
|
72
|
+
|
58
73
|
unless @config.export.nil?
|
59
|
-
|
60
|
-
file.write(context.to_json)
|
61
|
-
end
|
74
|
+
FileUtils.mkdir_p Pathname.new(@config.report).parent
|
62
75
|
end
|
63
76
|
Blinkr::Report.new(context, self, @config).render
|
64
77
|
end
|
65
78
|
|
66
|
-
def append
|
67
|
-
|
79
|
+
def append(context)
|
80
|
+
execute :append, context
|
68
81
|
end
|
69
|
-
|
70
|
-
def transform
|
82
|
+
|
83
|
+
def transform(page, error, &block)
|
71
84
|
default = yield
|
72
|
-
result =
|
85
|
+
result = execute(:transform, page, error, default)
|
73
86
|
if result.empty?
|
74
87
|
default
|
75
88
|
else
|
@@ -77,33 +90,33 @@ module Blinkr
|
|
77
90
|
end
|
78
91
|
end
|
79
92
|
|
80
|
-
def analyze
|
81
|
-
|
93
|
+
def analyze(context, typhoeus)
|
94
|
+
execute :analyze, context, typhoeus
|
82
95
|
end
|
83
96
|
|
84
|
-
def collect
|
85
|
-
|
97
|
+
def collect(page)
|
98
|
+
execute :collect, page
|
86
99
|
end
|
87
100
|
|
88
101
|
private
|
89
102
|
|
90
103
|
class ErrorArray < Array
|
91
104
|
|
92
|
-
def initialize
|
105
|
+
def initialize(config)
|
93
106
|
@config = config
|
94
107
|
end
|
95
108
|
|
96
|
-
def <<
|
97
|
-
|
98
|
-
super
|
99
|
-
else
|
109
|
+
def <<(error)
|
110
|
+
if @config.ignored?(error.url, error.code, error.message)
|
100
111
|
self
|
112
|
+
else
|
113
|
+
super
|
101
114
|
end
|
102
115
|
end
|
103
116
|
|
104
117
|
end
|
105
118
|
|
106
|
-
def extension
|
119
|
+
def extension(ext)
|
107
120
|
@extensions << ext
|
108
121
|
end
|
109
122
|
|
@@ -113,7 +126,7 @@ module Blinkr
|
|
113
126
|
extension Blinkr::Extensions::Resources.new @config
|
114
127
|
end
|
115
128
|
|
116
|
-
def
|
129
|
+
def execute(method, *args)
|
117
130
|
result = []
|
118
131
|
@extensions.each do |e|
|
119
132
|
result << e.send(method, *args) if e.respond_to? method
|
@@ -122,24 +135,24 @@ module Blinkr
|
|
122
135
|
end
|
123
136
|
|
124
137
|
def load_pipeline
|
125
|
-
|
138
|
+
if @config.pipeline.nil?
|
139
|
+
puts 'Loaded default pipeline' if @config.verbose
|
140
|
+
default_pipeline
|
141
|
+
else
|
126
142
|
pipeline_file = File.join(File.dirname(@config.config_file), @config.pipeline)
|
127
|
-
if
|
128
|
-
p = eval(File.read(
|
143
|
+
if File.exists?(pipeline_file)
|
144
|
+
p = eval(File.read(pipeline_file), nil, pipeline_file, 1).load @config
|
129
145
|
p.extensions.each do |e|
|
130
|
-
extension(
|
146
|
+
extension(e)
|
131
147
|
end
|
132
148
|
if @config.verbose
|
133
149
|
puts "Loaded custom pipeline from #{@config.pipeline}"
|
134
|
-
pipeline = @extensions.inject{|memo, v| "#{memo}, #{v}" }
|
150
|
+
pipeline = @extensions.inject { |memo, v| "#{memo}, #{v}" }
|
135
151
|
puts "Pipeline: #{pipeline}"
|
136
152
|
end
|
137
153
|
else
|
138
154
|
raise "Cannot find pipeline file #{pipeline_file}"
|
139
155
|
end
|
140
|
-
else
|
141
|
-
puts "Loaded default pipeline" if @config.verbose
|
142
|
-
default_pipeline
|
143
156
|
end
|
144
157
|
end
|
145
158
|
|
data/lib/blinkr/error.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Blinkr
|
2
|
+
SEVERITY = [:success, :info, :warning, :danger]
|
3
|
+
class Error
|
4
|
+
attr_reader :severity, :category, :type, :title, :message, :snippet, :icon, :code, :detail, :url
|
5
|
+
|
6
|
+
def initialize (opts = {})
|
7
|
+
raise TypeError 'severity must be a string or symbol' unless opts[:severity].is_a?(String) || opts[:severity].is_a?(Symbol)
|
8
|
+
raise 'severity not a recognized value' unless SEVERITY.include? opts[:severity].to_sym
|
9
|
+
|
10
|
+
@severity = opts[:severity]
|
11
|
+
@category = opts[:category]
|
12
|
+
@type = opts[:type]
|
13
|
+
@title = opts[:title]
|
14
|
+
@message = opts[:message]
|
15
|
+
@snippet = opts[:snippet]
|
16
|
+
@icon = opts[:icon]
|
17
|
+
@code = opts[:code]
|
18
|
+
@url = opts[:url]
|
19
|
+
@detail = opts[:detail]
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_json(*args)
|
23
|
+
content = {}
|
24
|
+
instance_variables.each do |v|
|
25
|
+
content[v.to_s[1..-1]] = instance_variable_get v
|
26
|
+
end
|
27
|
+
content.to_json
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'blinkr/error'
|
2
|
+
|
1
3
|
module Blinkr
|
2
4
|
module Extensions
|
3
5
|
class ATitle
|
@@ -8,7 +10,11 @@ module Blinkr
|
|
8
10
|
|
9
11
|
def collect page
|
10
12
|
page.body.css('a:not([title])').each do |a|
|
11
|
-
page.errors <<
|
13
|
+
page.errors << Blinkr::Error.new({:severity => 'info', :category => 'SEO',
|
14
|
+
:type => '<a title=""> missing',
|
15
|
+
:title => "#{a['href']} (line #{a.line})",
|
16
|
+
:message => '<a title=""> missing',
|
17
|
+
:snippet => a.to_s, :icon => 'fa-info'})
|
12
18
|
end
|
13
19
|
end
|
14
20
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'blinkr/error'
|
2
|
+
|
1
3
|
module Blinkr
|
2
4
|
module Extensions
|
3
5
|
class EmptyAHref
|
@@ -9,7 +11,11 @@ module Blinkr
|
|
9
11
|
def collect page
|
10
12
|
page.body.css('a[href]').each do |a|
|
11
13
|
if a['href'].empty?
|
12
|
-
page.errors <<
|
14
|
+
page.errors << Blinkr::Error.new({:severity => 'info', :category => 'HTML Compatibility/Correctness',
|
15
|
+
:type => '<a href=""> empty',
|
16
|
+
:title => %Q{<a href=""> empty (line #{a.line})},
|
17
|
+
:message => %Q{<a href=""> empty}, :snippet => a.to_s,
|
18
|
+
:icon => 'fa-info'})
|
13
19
|
end
|
14
20
|
end
|
15
21
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'blinkr/error'
|
2
|
+
|
1
3
|
module Blinkr
|
2
4
|
module Extensions
|
3
5
|
class ImgAlt
|
@@ -8,7 +10,11 @@ module Blinkr
|
|
8
10
|
|
9
11
|
def collect page
|
10
12
|
page.body.css('img:not([alt])').each do |img|
|
11
|
-
page.errors << OpenStruct.new({
|
13
|
+
page.errors << OpenStruct.new({:severity => 'warning', :category => 'SEO',
|
14
|
+
:type => '<img alt=""> missing',
|
15
|
+
:title => "#{img['src']} (line #{img.line})",
|
16
|
+
:message => '<img alt=""> missing', :snippet => img.to_s,
|
17
|
+
:icon => 'fa-info'})
|
12
18
|
end
|
13
19
|
end
|
14
20
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'blinkr/error'
|
2
|
+
|
1
3
|
module Blinkr
|
2
4
|
module Extensions
|
3
5
|
class InlineCss
|
@@ -9,9 +11,18 @@ module Blinkr
|
|
9
11
|
def collect page
|
10
12
|
page.body.css('[style]').each do |elm|
|
11
13
|
if elm['style'] == ""
|
12
|
-
page.errors <<
|
14
|
+
page.errors << Blinkr::Error.new({:severity => 'info', :category => 'HTML Compatibility/Correctness',
|
15
|
+
:type => 'style attribute is empty',
|
16
|
+
:title => %Q{"#{elm['style']}" (line #{elm.line})},
|
17
|
+
:message => 'style attribute is empty', :snippet => elm.to_s,
|
18
|
+
:icon => 'fa-info'})
|
13
19
|
else
|
14
|
-
page.errors <<
|
20
|
+
page.errors << Blinkr::Error.new({:severity => 'info',
|
21
|
+
:category => 'HTML Compatibility/Correctness',
|
22
|
+
:type => 'Inline CSS detected',
|
23
|
+
:title => %Q{"#{elm['style']}" (line #{elm.line})},
|
24
|
+
:message => 'inline style', :snippet => elm.to_s,
|
25
|
+
:icon => 'fa-info'})
|
15
26
|
end
|
16
27
|
end
|
17
28
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'blinkr/error'
|
2
|
+
|
1
3
|
module Blinkr
|
2
4
|
module Extensions
|
3
5
|
class JavaScript
|
@@ -8,7 +10,9 @@ module Blinkr
|
|
8
10
|
|
9
11
|
def collect page
|
10
12
|
page.javascript_errors.each do |error|
|
11
|
-
page.errors <<
|
13
|
+
page.errors << Blinkr::Error.new(:severity => 'danger', :category => 'JavaScript',
|
14
|
+
:type => 'JavaScript error', :title => error['msg'],
|
15
|
+
:snippet => error['trace'], :icon => 'fa-gears')
|
12
16
|
end
|
13
17
|
end
|
14
18
|
|
@@ -1,50 +1,94 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'blinkr/error'
|
1
3
|
require 'blinkr/http_utils'
|
2
4
|
|
3
5
|
module Blinkr
|
4
6
|
module Extensions
|
5
7
|
class Links
|
6
|
-
include HttpUtils
|
8
|
+
include Blinkr::HttpUtils
|
7
9
|
|
8
|
-
def initialize
|
10
|
+
def initialize(config)
|
9
11
|
@config = config
|
10
12
|
@links = {}
|
11
13
|
end
|
12
14
|
|
13
|
-
def collect
|
15
|
+
def collect(page)
|
14
16
|
page.body.css('a[href]').each do |a|
|
15
17
|
attr = a.attribute('href')
|
16
18
|
src = page.response.effective_url
|
17
19
|
url = attr.value
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
unless @config.skipped?(url)
|
21
|
+
url = sanitize url, src
|
22
|
+
unless url.nil?
|
23
|
+
@links[url] ||= []
|
24
|
+
@links[url] << {:page => page, :line => attr.line, :snippet => attr.parent.to_s}
|
25
|
+
end
|
22
26
|
end
|
23
27
|
end
|
24
28
|
end
|
25
29
|
|
26
|
-
def analyze
|
27
|
-
puts
|
28
|
-
puts " #{@links.length} links to check "
|
29
|
-
puts
|
30
|
-
@links.
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
def analyze(context, browser)
|
31
|
+
puts '----------------------'
|
32
|
+
puts " #{@links.length} links to check "
|
33
|
+
puts '----------------------'
|
34
|
+
external_links = @links.reject { |k| k.start_with? @config.base_url }
|
35
|
+
processed = 0
|
36
|
+
# Find the internal links
|
37
|
+
@links.select{|k| k.start_with? @config.base_url}.each do |url, locations|
|
38
|
+
link = URI.parse(url)
|
39
|
+
link.fragment = nil
|
40
|
+
link.query = nil
|
41
|
+
unless context.pages.keys.include?(link.to_s) || context.pages.keys.include?((link.to_s + '/'))
|
42
|
+
locations.each do |location|
|
43
|
+
location[:page].errors << Blinkr::Error.new({:severity => :warning,
|
44
|
+
:category => 'Resource missing from sitemap',
|
45
|
+
:type => '<a href=""> target missing from sitemap',
|
46
|
+
:url => url, :title => "#{url} (line #{location[:line]})",
|
47
|
+
:code => nil,
|
48
|
+
:message => 'Missing from sitemap',
|
49
|
+
:detail => 'Checked with Typheous',
|
50
|
+
:snippet => location[:snippet],
|
51
|
+
:icon => 'fa-bookmark-o'
|
52
|
+
})
|
53
|
+
# It wasn't in the sitemap, so we'll add it to the "external_links" to still be checked
|
54
|
+
external_links[url] = locations
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
external_links.each do |url, metadata|
|
59
|
+
# if link start_with? @config.base_url check to see if it's in the sitemap.xml
|
60
|
+
browser.process(url, @config.max_retrys, :method => :get, :followlocation => true) do |resp|
|
61
|
+
puts "Loaded #{url} via #{browser.name} #{'(cached)' if resp.cached?}" if @config.verbose
|
62
|
+
if resp.code.to_i < 200 || resp.code.to_i > 300
|
63
|
+
response = resp
|
64
|
+
|
34
65
|
metadata.each do |src|
|
35
|
-
|
36
|
-
if
|
37
|
-
message =
|
66
|
+
detail = nil
|
67
|
+
if response.status_message.nil?
|
68
|
+
message = response.return_message
|
38
69
|
else
|
39
|
-
message =
|
40
|
-
detail =
|
70
|
+
message = response.status_message
|
71
|
+
detail = response.return_message unless resp.return_message == 'No error'
|
72
|
+
end
|
73
|
+
|
74
|
+
severity = :danger
|
75
|
+
if response.code.to_i >= 300 && response.code.to_i < 400
|
76
|
+
severity = :warning
|
41
77
|
end
|
42
|
-
src[:page].errors <<
|
78
|
+
src[:page].errors << Blinkr::Error.new({:severity => severity,
|
79
|
+
:category => 'Resources missing',
|
80
|
+
:type => '<a href=""> target cannot be loaded',
|
81
|
+
:url => url, :title => "#{url} (line #{src[:line]})",
|
82
|
+
:code => response.code.to_i, :message => message,
|
83
|
+
:detail => detail, :snippet => src[:snippet],
|
84
|
+
:icon => 'fa-bookmark-o'}) unless response.success?
|
43
85
|
end
|
44
86
|
end
|
87
|
+
processed += 1
|
88
|
+
puts "Processed #{processed} of #{external_links.size}" if @config.verbose
|
45
89
|
end
|
46
90
|
end
|
47
|
-
|
91
|
+
browser.hydra.run if browser.is_a? Blinkr::TyphoeusWrapper
|
48
92
|
end
|
49
93
|
|
50
94
|
end
|