sitediff 0.0.2 → 1.1.1
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 +7 -0
- data/bin/sitediff +9 -3
- data/lib/sitediff.rb +153 -79
- data/lib/sitediff/api.rb +265 -0
- data/lib/sitediff/cache.rb +110 -47
- data/lib/sitediff/cli.rb +219 -165
- data/lib/sitediff/config.rb +439 -58
- data/lib/sitediff/config/creator.rb +93 -99
- data/lib/sitediff/config/preset.rb +75 -0
- data/lib/sitediff/crawler.rb +108 -72
- data/lib/sitediff/diff.rb +60 -12
- data/lib/sitediff/exception.rb +3 -1
- data/lib/sitediff/fetch.rb +62 -41
- data/lib/sitediff/files/diff.html.erb +20 -2
- data/lib/sitediff/files/jquery.min.js +2 -0
- data/lib/sitediff/files/normalize.css +349 -0
- data/lib/sitediff/files/report.html.erb +171 -0
- data/lib/sitediff/files/sidebyside.html.erb +5 -2
- data/lib/sitediff/files/sitediff.css +303 -30
- data/lib/sitediff/files/sitediff.js +367 -0
- data/lib/sitediff/report.rb +254 -0
- data/lib/sitediff/result.rb +59 -23
- data/lib/sitediff/sanitize.rb +222 -150
- data/lib/sitediff/sanitize/dom_transform.rb +111 -73
- data/lib/sitediff/sanitize/regexp.rb +69 -43
- data/lib/sitediff/uriwrapper.rb +104 -34
- data/lib/sitediff/webserver.rb +89 -77
- data/lib/sitediff/webserver/resultserver.rb +113 -77
- metadata +92 -76
- data/lib/sitediff/files/html_report.html.erb +0 -63
- data/lib/sitediff/files/rules/drupal.yaml +0 -33
- data/lib/sitediff/rules.rb +0 -65
@@ -0,0 +1,367 @@
|
|
1
|
+
/**
|
2
|
+
* @file
|
3
|
+
* SiteDiff report behaviors.
|
4
|
+
*/
|
5
|
+
|
6
|
+
'use strict';
|
7
|
+
|
8
|
+
/* global $ */
|
9
|
+
/**
|
10
|
+
* SiteDiff namespace.
|
11
|
+
*/
|
12
|
+
var SiteDiff = SiteDiff || {};
|
13
|
+
|
14
|
+
/**
|
15
|
+
* SiteDiff global map of diffs.
|
16
|
+
*/
|
17
|
+
SiteDiff.diffs = SiteDiff.diffs || {};
|
18
|
+
|
19
|
+
SiteDiff.currentDiff = -1;
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Scrolls the document to the said position.
|
23
|
+
*
|
24
|
+
* @param options
|
25
|
+
* Object specifying various options.
|
26
|
+
*
|
27
|
+
* x: X position.
|
28
|
+
* y: Y position.
|
29
|
+
* animate: Whether to animate.
|
30
|
+
* callback: A function to call after scrolling.
|
31
|
+
*/
|
32
|
+
SiteDiff.scrollToPosition = function (options) {
|
33
|
+
// Compute vertical and horizontal adjustments, if any.
|
34
|
+
// Example: Fixed elements, etc.
|
35
|
+
var xFix = 0;
|
36
|
+
var yFix = 0 - 100;
|
37
|
+
|
38
|
+
// Determine final x and y offsets.
|
39
|
+
var x = parseInt(options.x) + xFix;
|
40
|
+
x = Math.max(x, 0);
|
41
|
+
var y = parseInt(options.y) + yFix;
|
42
|
+
y = Math.max(y, 0);
|
43
|
+
|
44
|
+
// Perform the scroll with or without animation.
|
45
|
+
window.scrollTo(x, y);
|
46
|
+
|
47
|
+
// Trigger a callback, if any.
|
48
|
+
if (options.callback) {
|
49
|
+
options.callback();
|
50
|
+
}
|
51
|
+
};
|
52
|
+
|
53
|
+
/**
|
54
|
+
* Scrolls to a DOM element on the page.
|
55
|
+
*
|
56
|
+
* @param el
|
57
|
+
* The DOM element.
|
58
|
+
*
|
59
|
+
* @param options
|
60
|
+
* Object specifying various options.
|
61
|
+
*
|
62
|
+
* "callback" to trigger after scrolling.
|
63
|
+
*/
|
64
|
+
SiteDiff.scrollToElement = function (el, options) {
|
65
|
+
options = options || {};
|
66
|
+
var callback = options.callback || function () {};
|
67
|
+
|
68
|
+
// See if the element exists.
|
69
|
+
var $el = $(el).first();
|
70
|
+
if ($el.length == 1) {
|
71
|
+
// Inject callback to focus on the element we scroll to.
|
72
|
+
options.x = 0;
|
73
|
+
options.y = $el.offset().top;
|
74
|
+
options.callback = function () {
|
75
|
+
$el.focus();
|
76
|
+
callback.call(el);
|
77
|
+
};
|
78
|
+
SiteDiff.scrollToPosition(options);
|
79
|
+
}
|
80
|
+
};
|
81
|
+
|
82
|
+
/**
|
83
|
+
* Initialize behaviors.
|
84
|
+
*/
|
85
|
+
SiteDiff.init = function () {
|
86
|
+
// On the overview page.
|
87
|
+
switch ($(document.body).data('page')) {
|
88
|
+
case 'overview':
|
89
|
+
SiteDiff.initFilterForm();
|
90
|
+
break;
|
91
|
+
|
92
|
+
case 'diff':
|
93
|
+
SiteDiff.jumpToFirstDiff();
|
94
|
+
break;
|
95
|
+
}
|
96
|
+
};
|
97
|
+
|
98
|
+
/**
|
99
|
+
* Initializes report filters and overlay.
|
100
|
+
*/
|
101
|
+
SiteDiff.initFilterForm = function () {
|
102
|
+
SiteDiff.initDiffArray();
|
103
|
+
SiteDiff.initStatusFilter();
|
104
|
+
SiteDiff.initSearchFilter();
|
105
|
+
SiteDiff.initOverlay();
|
106
|
+
SiteDiff.initClickHandlers();
|
107
|
+
};
|
108
|
+
|
109
|
+
/**
|
110
|
+
* Initialize global diff array
|
111
|
+
*
|
112
|
+
*/
|
113
|
+
SiteDiff.initDiffArray = function() {
|
114
|
+
SiteDiff.diffs = $('.button-diff').map(function (i, element) {
|
115
|
+
var $el = $(element);
|
116
|
+
$el.data('diffindex', i);
|
117
|
+
return {
|
118
|
+
diff: $el.attr('href'),
|
119
|
+
element: $el,
|
120
|
+
index: i,
|
121
|
+
path: $el.parents('.description').find('.path').text()
|
122
|
+
};
|
123
|
+
});
|
124
|
+
};
|
125
|
+
|
126
|
+
/**
|
127
|
+
* Initializes the "status" filter.
|
128
|
+
*/
|
129
|
+
SiteDiff.initStatusFilter = function () {
|
130
|
+
$('.form-item--status input')
|
131
|
+
.on('change', function () {
|
132
|
+
// Get a list of applied filters.
|
133
|
+
var appliedFilters = $('.form-item--status input:checked')
|
134
|
+
.map(function () {
|
135
|
+
return this.getAttribute('value');
|
136
|
+
// applied.push(this.getAttribute('value'));
|
137
|
+
});
|
138
|
+
// Show only matching results, hide the rest.
|
139
|
+
$('#sitediff-report')
|
140
|
+
.find('.sitediff-result')
|
141
|
+
.each(function () {
|
142
|
+
var $row = $(this);
|
143
|
+
var status = $row.data('status');
|
144
|
+
if (
|
145
|
+
// Row matches applied filters.
|
146
|
+
$.inArray(status, appliedFilters) > -1 ||
|
147
|
+
// No filters are applied.
|
148
|
+
appliedFilters.length === 0
|
149
|
+
) {
|
150
|
+
$row.removeAttr('hidden');
|
151
|
+
}
|
152
|
+
else {
|
153
|
+
$row.attr('hidden', 'hidden');
|
154
|
+
}
|
155
|
+
});
|
156
|
+
});
|
157
|
+
};
|
158
|
+
|
159
|
+
/**
|
160
|
+
* Initializes the "search" filter.
|
161
|
+
*/
|
162
|
+
SiteDiff.initSearchFilter = function () {
|
163
|
+
$('#input-search')
|
164
|
+
.on('change keyup', function () {
|
165
|
+
var keyword = $(this).val().toLowerCase();
|
166
|
+
|
167
|
+
// Filter the records.
|
168
|
+
// TODO: Trigger one event per 250ms.
|
169
|
+
$('#sitediff-report')
|
170
|
+
.find('.sitediff-result')
|
171
|
+
.each(function () {
|
172
|
+
var $row = $(this);
|
173
|
+
var path = $row.find('.path').text();
|
174
|
+
|
175
|
+
// If keyword matches, keep the row visible.
|
176
|
+
if (path.toLowerCase().indexOf(keyword) > -1) {
|
177
|
+
$row.attr('hidden', null);
|
178
|
+
}
|
179
|
+
else {
|
180
|
+
$row.attr('hidden', 'hidden');
|
181
|
+
}
|
182
|
+
});
|
183
|
+
});
|
184
|
+
};
|
185
|
+
|
186
|
+
/**
|
187
|
+
* Set up the diff overlay to be displayed.
|
188
|
+
*/
|
189
|
+
SiteDiff.initOverlay = function () {
|
190
|
+
if (SiteDiff.diffs.length <= 0) return;
|
191
|
+
|
192
|
+
// add overlay
|
193
|
+
$('body').append($(
|
194
|
+
'<div class="overlay" style="display: none;"><div class="overlay__inner"><header>' +
|
195
|
+
'<div class="path"></div>' +
|
196
|
+
'<div class="prev"><a href="#" title="Previous diff (left arrow)">< Prev</a></div>' +
|
197
|
+
'<div class="next"><a href="#" title="Next diff (right arrow)">Next ></a></div>' +
|
198
|
+
'<div class="exit"><a href="#" title="Close diff display (Esc)">Close</a></div>' +
|
199
|
+
'</header><article></article></div></div>'));
|
200
|
+
// add header click handlers
|
201
|
+
$('.overlay header .exit').click(function (event) {
|
202
|
+
event.preventDefault();
|
203
|
+
SiteDiff.destroyOverlay();
|
204
|
+
});
|
205
|
+
$('.overlay header .prev').click(function (event) {
|
206
|
+
event.preventDefault();
|
207
|
+
SiteDiff.prevDiff();
|
208
|
+
});
|
209
|
+
$('.overlay header .next').click(function (event) {
|
210
|
+
event.preventDefault();
|
211
|
+
SiteDiff.nextDiff();
|
212
|
+
});
|
213
|
+
|
214
|
+
};
|
215
|
+
|
216
|
+
/**
|
217
|
+
* Set up click handlers for all diff buttons
|
218
|
+
*/
|
219
|
+
SiteDiff.initClickHandlers = function () {
|
220
|
+
SiteDiff.diffs.each( function (i, diff) {
|
221
|
+
diff.element.click({index: i}, function (event) {
|
222
|
+
event.preventDefault();
|
223
|
+
SiteDiff.openOverlay(event.data.index);
|
224
|
+
});
|
225
|
+
});
|
226
|
+
};
|
227
|
+
|
228
|
+
/**
|
229
|
+
* Set up key handlers for overlay.
|
230
|
+
*/
|
231
|
+
SiteDiff.initKeyHandlers = function () {
|
232
|
+
$(document).keyup(function (event) {
|
233
|
+
switch (event.which) {
|
234
|
+
case 37:
|
235
|
+
SiteDiff.prevDiff();
|
236
|
+
break;
|
237
|
+
case 39:
|
238
|
+
SiteDiff.nextDiff();
|
239
|
+
break;
|
240
|
+
case 27:
|
241
|
+
SiteDiff.destroyOverlay();
|
242
|
+
break;
|
243
|
+
}
|
244
|
+
});
|
245
|
+
};
|
246
|
+
|
247
|
+
/**
|
248
|
+
* Remove overlay key handlers.
|
249
|
+
*/
|
250
|
+
SiteDiff.removeKeyHandlers = function () {
|
251
|
+
$(document).off('keyup');
|
252
|
+
};
|
253
|
+
|
254
|
+
/**
|
255
|
+
* Open overlay for the diff identified by the `index`.
|
256
|
+
*
|
257
|
+
* @param integer index
|
258
|
+
* The index of the diff to be viewed.
|
259
|
+
*/
|
260
|
+
SiteDiff.openOverlay = function (index) {
|
261
|
+
SiteDiff.currentDiff = index;
|
262
|
+
SiteDiff.showDiff();
|
263
|
+
SiteDiff.initKeyHandlers();
|
264
|
+
$('.overlay').fadeIn(300);
|
265
|
+
};
|
266
|
+
|
267
|
+
/**
|
268
|
+
* Create the iframe to display the current diff.
|
269
|
+
*/
|
270
|
+
SiteDiff.showDiff = function () {
|
271
|
+
var diff = SiteDiff.diffs[SiteDiff.currentDiff];
|
272
|
+
var iframe = '<iframe src="' + diff.diff + '"></iframe>';
|
273
|
+
$('.overlay header .path').text(diff.path);
|
274
|
+
SiteDiff.setPrevNext();
|
275
|
+
$('.overlay article').html(iframe);
|
276
|
+
};
|
277
|
+
|
278
|
+
/**
|
279
|
+
* Hide the overlay and clean up.
|
280
|
+
*/
|
281
|
+
SiteDiff.destroyOverlay = function () {
|
282
|
+
$('.overlay article').empty();
|
283
|
+
SiteDiff.removeKeyHandlers();
|
284
|
+
$('.overlay').fadeOut(300, SiteDiff.scrollToButton);
|
285
|
+
};
|
286
|
+
|
287
|
+
/**
|
288
|
+
* Display the previous diff.
|
289
|
+
*/
|
290
|
+
SiteDiff.prevDiff = function () {
|
291
|
+
if (SiteDiff.currentDiff > 0) {
|
292
|
+
SiteDiff.currentDiff--;
|
293
|
+
SiteDiff.showDiff();
|
294
|
+
}
|
295
|
+
};
|
296
|
+
|
297
|
+
/**
|
298
|
+
* Display the next diff.
|
299
|
+
*/
|
300
|
+
SiteDiff.nextDiff = function () {
|
301
|
+
if (SiteDiff.currentDiff < SiteDiff.diffs.length - 1) {
|
302
|
+
SiteDiff.currentDiff++;
|
303
|
+
SiteDiff.showDiff();
|
304
|
+
}
|
305
|
+
};
|
306
|
+
|
307
|
+
/**
|
308
|
+
* Enable or disable prev and next buttons based on current diff.
|
309
|
+
*/
|
310
|
+
SiteDiff.setPrevNext = function () {
|
311
|
+
if (SiteDiff.currentDiff <= 0) {
|
312
|
+
// set prev disabled
|
313
|
+
$('.overlay header .prev').addClass('disabled');
|
314
|
+
}
|
315
|
+
else {
|
316
|
+
$('.overlay header .prev.disabled').removeClass('disabled');
|
317
|
+
}
|
318
|
+
if (SiteDiff.currentDiff >= SiteDiff.diffs.length - 1) {
|
319
|
+
// set next disabled
|
320
|
+
$('.overlay header .next').addClass('disabled');
|
321
|
+
}
|
322
|
+
else {
|
323
|
+
$('.overlay header .next.disabled').removeClass('disabled');
|
324
|
+
}
|
325
|
+
};
|
326
|
+
|
327
|
+
/**
|
328
|
+
* Scroll to the button associated with the current diff.
|
329
|
+
*/
|
330
|
+
SiteDiff.scrollToButton = function () {
|
331
|
+
var $diffButton = SiteDiff.diffs[SiteDiff.currentDiff].element;
|
332
|
+
if (! SiteDiff.isElementVisible($diffButton)) {
|
333
|
+
SiteDiff.scrollToElement($diffButton);
|
334
|
+
}
|
335
|
+
};
|
336
|
+
|
337
|
+
/**
|
338
|
+
* Check if an element is at least partly visible.
|
339
|
+
* @param element
|
340
|
+
*/
|
341
|
+
SiteDiff.isElementVisible = function (element) {
|
342
|
+
var topVisible = $(window).scrollTop();
|
343
|
+
var bottomVisible = topVisible + $(window).height();
|
344
|
+
var elemTop = $(element).offset().top;
|
345
|
+
var elemBottom = elemTop + $(element).height();
|
346
|
+
return ((elemBottom <= bottomVisible) && (elemTop >= topVisible));
|
347
|
+
};
|
348
|
+
|
349
|
+
/**
|
350
|
+
* Jumps to the first diff on the page.
|
351
|
+
*/
|
352
|
+
SiteDiff.jumpToFirstDiff = function () {
|
353
|
+
// Get the first diff hunk.
|
354
|
+
var $diff = $('#diff-container')
|
355
|
+
.find('.del, .ins')
|
356
|
+
.first();
|
357
|
+
if ($diff.length === 0) {
|
358
|
+
return;
|
359
|
+
}
|
360
|
+
|
361
|
+
// Scroll the window to it!
|
362
|
+
setTimeout(function () {
|
363
|
+
SiteDiff.scrollToElement($diff[0]);
|
364
|
+
}, 250);
|
365
|
+
};
|
366
|
+
|
367
|
+
$(document).ready(SiteDiff.init);
|
@@ -0,0 +1,254 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'json'
|
5
|
+
require 'minitar'
|
6
|
+
require 'sitediff'
|
7
|
+
require 'sitediff/config'
|
8
|
+
require 'zlib'
|
9
|
+
|
10
|
+
class SiteDiff
|
11
|
+
##
|
12
|
+
# SiteDiff Report Helper.
|
13
|
+
class Report
|
14
|
+
attr_reader :results, :cache
|
15
|
+
|
16
|
+
##
|
17
|
+
# Directory where diffs will be generated.
|
18
|
+
DIFFS_DIR = 'diffs'
|
19
|
+
|
20
|
+
##
|
21
|
+
# Name of file containing a list of pages with diffs.
|
22
|
+
FAILURES_FILE = 'failures.txt'
|
23
|
+
|
24
|
+
##
|
25
|
+
# Name of file containing HTML report of diffs.
|
26
|
+
REPORT_FILE_HTML = 'report.html'
|
27
|
+
|
28
|
+
##
|
29
|
+
# Name of file containing JSON report of diffs.
|
30
|
+
REPORT_FILE_JSON = 'report.json'
|
31
|
+
|
32
|
+
##
|
33
|
+
# Name of file containing exported file archive.
|
34
|
+
REPORT_FILE_TAR = 'report.tgz'
|
35
|
+
|
36
|
+
##
|
37
|
+
# Name of directory in which to build the portable report.
|
38
|
+
REPORT_BUILD_DIR = '_tmp_report'
|
39
|
+
|
40
|
+
##
|
41
|
+
# Name of the portable report directory.
|
42
|
+
REPORT_DIR = 'report'
|
43
|
+
|
44
|
+
##
|
45
|
+
# Path to settings used for report.
|
46
|
+
SETTINGS_FILE = 'settings.yaml'
|
47
|
+
|
48
|
+
##
|
49
|
+
# Creates a Reporter object.
|
50
|
+
#
|
51
|
+
# @param [Config] config.
|
52
|
+
# @param [Cache] cache.
|
53
|
+
# @param [Array] results.
|
54
|
+
def initialize(config, cache, results)
|
55
|
+
@config = config
|
56
|
+
@cache = cache
|
57
|
+
@results = results
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Generates an HTML report.
|
62
|
+
#
|
63
|
+
# @param [String] dir
|
64
|
+
# The directory in which the report is to be generated.
|
65
|
+
def generate_html(
|
66
|
+
dir,
|
67
|
+
report_before = nil,
|
68
|
+
report_after = nil
|
69
|
+
)
|
70
|
+
report_before ||= @config.before_url
|
71
|
+
report_after ||= @config.after_url
|
72
|
+
@config.before_time = get_timestamp(:before)
|
73
|
+
@config.after_time = get_timestamp(:after)
|
74
|
+
|
75
|
+
dir = SiteDiff.ensure_dir dir
|
76
|
+
|
77
|
+
write_diffs dir
|
78
|
+
write_failures dir
|
79
|
+
|
80
|
+
# Prepare report.
|
81
|
+
report = Diff.generate_html(
|
82
|
+
@results,
|
83
|
+
report_before,
|
84
|
+
report_after,
|
85
|
+
@cache,
|
86
|
+
@config
|
87
|
+
)
|
88
|
+
|
89
|
+
# Write report.
|
90
|
+
report_file = dir + REPORT_FILE_HTML
|
91
|
+
report_file.unlink if report_file.file?
|
92
|
+
report_file.open('w') { |f| f.write(report) }
|
93
|
+
|
94
|
+
write_settings dir, report_before, report_after
|
95
|
+
|
96
|
+
if @config.export
|
97
|
+
package_report(dir)
|
98
|
+
else
|
99
|
+
SiteDiff.log 'Report generated to ' + report_file.expand_path.to_s
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Generates a JSON report.
|
105
|
+
#
|
106
|
+
# @param dir
|
107
|
+
# The directory in which the report is to be generated.
|
108
|
+
def generate_json(dir)
|
109
|
+
dir = SiteDiff.ensure_dir dir
|
110
|
+
write_diffs dir
|
111
|
+
write_failures dir
|
112
|
+
|
113
|
+
# Prepare report.
|
114
|
+
report = {
|
115
|
+
paths_compared: @results.length,
|
116
|
+
paths_diffs: 0,
|
117
|
+
paths: {}
|
118
|
+
}
|
119
|
+
@results.each do |item|
|
120
|
+
report[:paths_diffs] += 1 unless item.success?
|
121
|
+
|
122
|
+
item_report = {
|
123
|
+
path: item.path,
|
124
|
+
status: item.status,
|
125
|
+
message: item.error
|
126
|
+
}
|
127
|
+
report[:paths][item.path] = item_report
|
128
|
+
end
|
129
|
+
report = JSON report
|
130
|
+
|
131
|
+
# Write report.
|
132
|
+
report_file = dir + REPORT_FILE_JSON
|
133
|
+
report_file.unlink if report_file.file?
|
134
|
+
report_file.open('w') { |f| f.write(report) }
|
135
|
+
|
136
|
+
write_settings dir
|
137
|
+
|
138
|
+
SiteDiff.log 'Report generated to ' + report_file.expand_path.to_s
|
139
|
+
end
|
140
|
+
|
141
|
+
##
|
142
|
+
# Package report for export.
|
143
|
+
def package_report(dir)
|
144
|
+
# Create temporaryreport directories.
|
145
|
+
temp_path = dir + REPORT_BUILD_DIR
|
146
|
+
temp_path.rmtree if temp_path.directory?
|
147
|
+
temp_path.mkpath
|
148
|
+
report_path = temp_path + REPORT_DIR
|
149
|
+
report_path.mkpath
|
150
|
+
files_path = report_path + 'files'
|
151
|
+
files_path.mkpath
|
152
|
+
diffs_path = dir + DIFFS_DIR
|
153
|
+
|
154
|
+
# Move files to place.
|
155
|
+
FileUtils.move(dir + REPORT_FILE_HTML, report_path)
|
156
|
+
FileUtils.move(diffs_path, files_path) if diffs_path.directory?
|
157
|
+
|
158
|
+
# Make tar file.
|
159
|
+
Dir.chdir(temp_path) do
|
160
|
+
Minitar.pack(
|
161
|
+
REPORT_DIR,
|
162
|
+
Zlib::GzipWriter.new(File.open(REPORT_FILE_TAR, 'wb'))
|
163
|
+
)
|
164
|
+
end
|
165
|
+
FileUtils.move(temp_path + REPORT_FILE_TAR, dir)
|
166
|
+
temp_path.rmtree
|
167
|
+
SiteDiff.log 'Archived report generated to ' + dir.join(REPORT_FILE_TAR).to_s
|
168
|
+
end
|
169
|
+
|
170
|
+
##
|
171
|
+
# Creates diff files in a directory named "diffs".
|
172
|
+
#
|
173
|
+
# If "dir" is /foo/bar, then diffs will be placed in /foo/bar/diffs.
|
174
|
+
#
|
175
|
+
# @param [Pathname] dir
|
176
|
+
# The directory in which a "diffs" directory is to be generated.
|
177
|
+
def write_diffs(dir)
|
178
|
+
raise Exception 'dir must be a Pathname' unless dir.is_a? Pathname
|
179
|
+
|
180
|
+
# Delete existing "diffs" dir, if exists.
|
181
|
+
diff_dir = dir + DIFFS_DIR
|
182
|
+
diff_dir.rmtree if diff_dir.exist?
|
183
|
+
|
184
|
+
# Write diffs to the diff directory.
|
185
|
+
@results.each { |r| r.dump(dir, @config.export) if r.status == Result::STATUS_FAILURE }
|
186
|
+
SiteDiff.log "All diff files written to #{diff_dir.expand_path}" unless @config.export
|
187
|
+
end
|
188
|
+
|
189
|
+
##
|
190
|
+
# Writes paths with diffs into a file.
|
191
|
+
#
|
192
|
+
# @param [Pathname] dir
|
193
|
+
# The directory in which the report is to be generated.
|
194
|
+
def write_failures(dir)
|
195
|
+
raise Exception 'dir must be a Pathname' unless dir.is_a? Pathname
|
196
|
+
|
197
|
+
failures = dir + FAILURES_FILE
|
198
|
+
SiteDiff.log "All failures written to #{failures.expand_path}"
|
199
|
+
failures.open('w') do |f|
|
200
|
+
@results.each { |r| f.puts r.path unless r.success? }
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
##
|
205
|
+
# Creates report settings.yaml file.
|
206
|
+
#
|
207
|
+
# TODO: Find a way to avoid having to create this file.
|
208
|
+
#
|
209
|
+
# @param [Pathname] dir
|
210
|
+
# The directory in which the report is to be generated.
|
211
|
+
def write_settings(dir, report_before = nil, report_after = nil)
|
212
|
+
raise Exception 'dir must be a Pathname' unless dir.is_a? Pathname
|
213
|
+
|
214
|
+
settings = {
|
215
|
+
'before' => report_before,
|
216
|
+
'after' => report_after,
|
217
|
+
'cached' => %w[before after]
|
218
|
+
}
|
219
|
+
dir.+(SETTINGS_FILE).open('w') { |f| YAML.dump(settings, f) }
|
220
|
+
end
|
221
|
+
|
222
|
+
##
|
223
|
+
# Returns CSS for HTML report.
|
224
|
+
def self.css
|
225
|
+
output = ''
|
226
|
+
output += File.read(File.join(SiteDiff::FILES_DIR, 'normalize.css'))
|
227
|
+
output += File.read(File.join(SiteDiff::FILES_DIR, 'sitediff.css'))
|
228
|
+
output
|
229
|
+
end
|
230
|
+
|
231
|
+
##
|
232
|
+
# Returns JS for HTML report.
|
233
|
+
def self.js
|
234
|
+
output = ''
|
235
|
+
output += File.read(File.join(SiteDiff::FILES_DIR, 'jquery.min.js'))
|
236
|
+
output += File.read(File.join(SiteDiff::FILES_DIR, 'sitediff.js'))
|
237
|
+
output
|
238
|
+
end
|
239
|
+
|
240
|
+
private
|
241
|
+
|
242
|
+
# Get crawl timestamps
|
243
|
+
def get_timestamp(tag)
|
244
|
+
timestamp_file = File.join(@config.directory, 'snapshot', tag.to_s, SiteDiff::Cache::TIMESTAMP_FILE)
|
245
|
+
if File.exist? timestamp_file
|
246
|
+
file = File::Stat.new(timestamp_file)
|
247
|
+
time = file.mtime
|
248
|
+
time.class == Time ? time.strftime('%Y-%m-%d %H:%M') : ''
|
249
|
+
else
|
250
|
+
'unknown'
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|