# frozen_string_literal: true require 'sitediff' require 'sitediff/diff' require 'sitediff/report' require 'digest/sha1' require 'fileutils' class SiteDiff # SiteDiff Result Object. class Result < Struct.new( :path, :before, :after, :before_encoding, :after_encoding, :error, :verbose ) STATUS_SUCCESS = 0 # Identical before and after STATUS_FAILURE = 1 # Different before and after STATUS_ERROR = 2 # Couldn't fetch page STATUS_TEXT = %w[unchanged changed error].freeze attr_reader :status, :diff ## # Creates a Result. def initialize(*args) super if error @status = STATUS_ERROR else if !before_encoding || !after_encoding @diff = Diff.binary_diffy( before, after, before_encoding, after_encoding ) else @diff = Diff.html_diffy(before, after) end @status = @diff ? STATUS_FAILURE : STATUS_SUCCESS end end ## # Whether the result has no diff. # # If there is a diff, it is not a success. # # TODO: Change "Success" to unchanged. def success? status == STATUS_SUCCESS end ## # Whether the result has an error. def error? status == STATUS_ERROR end # Textual representation of the status def status_text STATUS_TEXT[status] end # Printable URL def url(tag, prefix, cache) return unless prefix base = cache.read_tags.include?(tag) ? "/cache/#{tag}" : prefix base.to_s + path end # Filename to store diff def filename File.join(Report::DIFFS_DIR, "#{Digest::SHA1.hexdigest(path)}.html") end # Returns a URL to the result diff. # # Returns nil if the result has no diffs. def diff_url(relative: false) prefix = relative ? 'files/' : '/files/' return prefix + filename if status == STATUS_FAILURE end # Log the result to the terminal def log(verbose: true) case status when STATUS_SUCCESS SiteDiff.log path, :success, 'UNCHANGED' when STATUS_ERROR SiteDiff.log path + " (#{error})", :warning, 'ERROR' when STATUS_FAILURE SiteDiff.log path, :error, 'CHANGED' puts Diff.terminal_diffy(before, after) if verbose end end # Dump the result to a file def dump(dir, relative: false) dump_path = File.join(dir, filename) base = File.dirname(dump_path) FileUtils.mkdir_p(base) unless File.exist?(base) File.open(dump_path, 'w') do |f| f.write(Diff.generate_diff_output(self, relative:)) end end end end