Class: SiteDiff

Inherits:
Object
  • Object
show all
Defined in:
lib/sitediff.rb,
lib/sitediff/api.rb,
lib/sitediff/cli.rb,
lib/sitediff/diff.rb,
lib/sitediff/cache.rb,
lib/sitediff/fetch.rb,
lib/sitediff/config.rb,
lib/sitediff/report.rb,
lib/sitediff/result.rb,
lib/sitediff/crawler.rb,
lib/sitediff/sanitize.rb,
lib/sitediff/exception.rb,
lib/sitediff/webserver.rb,
lib/sitediff/uriwrapper.rb,
lib/sitediff/config/preset.rb,
lib/sitediff/config/creator.rb,
lib/sitediff/sanitize/regexp.rb,
lib/sitediff/sanitize/dom_transform.rb,
lib/sitediff/webserver/resultserver.rb

Overview

SiteDiff Object.

Defined Under Namespace

Modules: Diff Classes: Api, Cache, Cli, Config, Crawler, Fetch, Report, Result, Sanitizer, SiteDiffException, SiteDiffReadFailure, UriWrapper, Webserver

Constant Summary collapse

ROOT_DIR =

SiteDiff installation directory.

File.dirname(File.dirname(__FILE__))
FILES_DIR =

Path to misc files. Ex: *.erb, *.css.

File.join(File.dirname(__FILE__), 'sitediff', 'files')

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config, cache, verbose: true, debug: false) ⇒ SiteDiff

Initialize SiteDiff.



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/sitediff.rb', line 79

def initialize(config, cache, verbose: true, debug: false)
  @cache = cache
  @verbose = verbose
  @debug = debug

  # Check for single-site mode
  validate_opts = {}
  if !config.before['url'] && @cache.tag?(:before)
    unless @cache.read_tags.include?(:before)
      raise SiteDiffException,
            "A cached 'before' is required for single-site mode"
    end
    validate_opts[:need_before] = false
  end
  config.validate(validate_opts)
  # Configure diff.
  Diff.diff_config(config)
  @config = config
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



16
17
18
# File 'lib/sitediff.rb', line 16

def config
  @config
end

#resultsObject (readonly)

Returns the value of attribute results.



16
17
18
# File 'lib/sitediff.rb', line 16

def results
  @results
end

Class Method Details

.ensure_dir(dir) ⇒ Object

Ensures that a directory exists and returns a Pathname for it.

Parameters:

  • dir (String)

    path/to/directory



215
216
217
218
219
# File 'lib/sitediff.rb', line 215

def self.ensure_dir(dir)
  dir = Pathname.new(dir) unless dir.is_a? Pathname
  dir.mkpath unless dir.directory?
  dir
end

.gemspecObject

Get SiteDiff gemspec.



205
206
207
208
# File 'lib/sitediff.rb', line 205

def self.gemspec
  file = "#{ROOT_DIR}/sitediff.gemspec"
  Gem::Specification.load(file)
end

.log(message, type = :info, label = nil) ⇒ Object

Logs a message.

Label will be colorized and message will not. Type dictates the color: can be :success, :error, or :failure.

TODO: Only print :debug messages in debug mode.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/sitediff.rb', line 30

def self.log(message, type = :info, label = nil)
  # Prepare label.
  label ||= type unless type == :info
  label = label.to_s
  unless label.empty?
    # Colorize label.
    fg = :black
    bg = :blue

    case type
    when :info
      bg = :cyan
    when :success
      bg = :green
    when :error
      bg = :red
    when :warning
      bg = :yellow
    end

    label = "[#{label}]"
    label = Rainbow(label)
    label = label.bg(bg) if bg
    label = label.fg(fg) if fg

    # Add a space after the label.
    label += ' '
  end

  puts label + message
end

Instance Method Details

#afterObject

Returns the “after” site’s URL.

TODO: Remove in favor of config.after_url.



74
75
76
# File 'lib/sitediff.rb', line 74

def after
  @config.after['url']
end

#beforeObject

Returns the “before” site’s URL.

TODO: Remove in favor of config.before_url.



66
67
68
# File 'lib/sitediff.rb', line 66

def before
  @config.before['url']
end

#process_results(path, read_results) ⇒ Object

Process a set of read results.

This is the callback that processes items fetched by the Fetcher.



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/sitediff.rb', line 124

def process_results(path, read_results)
  error = (read_results[:before].error || read_results[:after].error)
  if error
    diff = Result.new(path, nil, nil, nil, nil, error)
  else
    begin
      diff = Result.new(
        path,
        *sanitize(path, read_results),
        read_results[:before].encoding,
        read_results[:after].encoding,
        nil
      )
    rescue StandardError => e
      raise if @debug

      diff = Result.new(path, nil, nil, nil, nil, "Sanitization error: #{e.message}")
    end
  end
  @results[path] = diff

  # Print results in order!
  while (next_diff = @results[@ordered.first])
    next_diff.log(verbose: @verbose)
    @ordered.shift
  end
end

#reportObject

Get a reporter object to help with report generation.



193
194
195
196
197
198
199
200
201
# File 'lib/sitediff.rb', line 193

def report
  if @results.nil?
    raise SiteDiffException(
      'No results detected. Run SiteDiff.run before SiteDiff.report.'
    )
  end

  Report.new(@config, @cache, @results)
end

#runInteger

Compute diff as per config.

Returns:

  • (Integer)

    Number of paths which have diffs.



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/sitediff.rb', line 157

def run
  # Map of path -> Result object, populated by process_results
  @results = {}
  @ordered = @config.paths.dup

  unless @cache.read_tags.empty?
    SiteDiff.log("Using sites from cache: #{@cache.read_tags.sort.join(', ')}")
  end

  # TODO: Fix this after config merge refactor!
  # Not quite right. We are not passing @config.before or @config.after
  # so passing this instead but @config.after['curl_opts'] is ignored.
  curl_opts = @config.setting :curl_opts
  config_curl_opts = @config.before['curl_opts']
  curl_opts = config_curl_opts.clone.merge(curl_opts) if config_curl_opts
  fetcher = Fetch.new(
    @cache,
    @config.paths,
    @config.setting(:interval),
    @config.setting(:concurrency),
    curl_opts,
    debug: @debug,
    before: @config.before_url,
    after: @config.after_url
  )

  # Run the Fetcher with "process results" as a callback.
  fetcher.run(&method(:process_results))

  # Order by original path order
  @results = @config.paths.map { |path| @results[path] }
  results.map { |r| r unless r.success? }.compact.length
end

#sanitize(path_passed, read_results) ⇒ Object

Sanitize HTML.



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/sitediff.rb', line 100

def sanitize(path_passed, read_results)
  %i[before after].map do |tag|
    html = read_results[tag].content
    # TODO: See why encoding is empty while running tests.
    #
    # The presence of an "encoding" value used to be used to determine
    # if the sanitizer would be called. However, encoding turns up blank
    # during rspec tests for some reason.
    encoding = read_results[tag].encoding
    if encoding || html.length.positive?
      section = @config.send(tag, apply_preset: true)
      opts = { path: path_passed }
      opts[:output] = @config.output if @config.output
      Sanitizer.new(html, section, opts).sanitize
    else
      html
    end
  end
end