wcc 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/assets/template.d/mail-body.html.erb +94 -0
- data/assets/template.d/mail-body.plain.erb +7 -0
- data/assets/template.d/mail.alt.erb +21 -0
- data/assets/template.d/mail.plain.erb +3 -2
- data/bin/wcc-upgrade +9 -4
- data/lib/wcc/diff.rb +143 -0
- data/lib/wcc/mail.rb +24 -4
- data/lib/wcc.rb +31 -9
- metadata +8 -4
@@ -0,0 +1,94 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title><%= data.site.uri.host %> changed</title>
|
4
|
+
<style type="text/css">
|
5
|
+
.msg {
|
6
|
+
font-size: 0.98em;
|
7
|
+
}
|
8
|
+
|
9
|
+
.diff {
|
10
|
+
font-size: 12px;
|
11
|
+
font-family: 'Bitstream Vera Sans Mono','Courier',monospace;
|
12
|
+
}
|
13
|
+
|
14
|
+
.diff ul {
|
15
|
+
list-style: none;
|
16
|
+
display: table;
|
17
|
+
padding: 0;
|
18
|
+
margin: 0.5em 0 0 0.5em;
|
19
|
+
border: 1px solid #CCCCCC;
|
20
|
+
}
|
21
|
+
|
22
|
+
.diff li {
|
23
|
+
padding: 0;
|
24
|
+
display: table-row;
|
25
|
+
margin: 0;
|
26
|
+
background: #f8f8ff;
|
27
|
+
}
|
28
|
+
|
29
|
+
.diff .new, .diff .old {
|
30
|
+
color: #999;
|
31
|
+
}
|
32
|
+
|
33
|
+
.diff .ins {
|
34
|
+
background: #dfd;
|
35
|
+
/* color: #080;*/
|
36
|
+
}
|
37
|
+
|
38
|
+
.diff .ins .hilite {
|
39
|
+
background: #afa;
|
40
|
+
margin: 0;
|
41
|
+
padding: 0;
|
42
|
+
}
|
43
|
+
|
44
|
+
.diff .del {
|
45
|
+
background: #fdd;
|
46
|
+
/* color: #b00;*/
|
47
|
+
}
|
48
|
+
|
49
|
+
.diff .del .hilite {
|
50
|
+
background: #faa;
|
51
|
+
margin: 0;
|
52
|
+
padding: 0;
|
53
|
+
}
|
54
|
+
|
55
|
+
.diff .range {
|
56
|
+
background: #eaf2f5;
|
57
|
+
color: #999;
|
58
|
+
}
|
59
|
+
|
60
|
+
.diff .other {
|
61
|
+
}
|
62
|
+
</style>
|
63
|
+
</head>
|
64
|
+
<body>
|
65
|
+
<% if data.diff.nil? %>
|
66
|
+
<div class="msg">
|
67
|
+
Checked <a href="<%= data.site.uri.to_s %>"><%= data.site.uri.to_s %></a> the first time so no diff was possible.
|
68
|
+
</div>
|
69
|
+
<% else %>
|
70
|
+
<div class="msg">
|
71
|
+
Change at <a href="<%= data.site.uri.to_s %>"><%= data.site.uri.to_s %></a> - diff follows:
|
72
|
+
</div>
|
73
|
+
<div class="diff">
|
74
|
+
<ul>
|
75
|
+
<% for o in data.diff.di %>
|
76
|
+
<% if o.status == :new %>
|
77
|
+
<li class="new">+++<%= o.text %></li>
|
78
|
+
<% elsif o.status == :old %>
|
79
|
+
<li class="old">---<%= o.text %></li>
|
80
|
+
<% elsif o.status == :range %>
|
81
|
+
<li class="range">@@<%= o.text %></li>
|
82
|
+
<% elsif o.status == :ins %>
|
83
|
+
<li class="ins">+<%= o.html_hilite_text %></li>
|
84
|
+
<% elsif o.status == :del %>
|
85
|
+
<li class="del">-<%= o.html_hilite_text %></li>
|
86
|
+
<% else %>
|
87
|
+
<li class="other"><%= o.text.gsub(/^ /, " ") %></li>
|
88
|
+
<% end %>
|
89
|
+
<% end %>
|
90
|
+
</ul>
|
91
|
+
</div>
|
92
|
+
<% end %>
|
93
|
+
</body>
|
94
|
+
</html>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
From: <%= from.name %> <<%= from.address %>>
|
2
|
+
To: <%= to %>
|
3
|
+
Subject: [<%= data.tag %>] <%= data.site.uri.host %> changed
|
4
|
+
Content-Type: multipart/alternative; boundary="<%= data.boundary %>"
|
5
|
+
MIME-Version: 1.0
|
6
|
+
|
7
|
+
<% if data.bodies.key?(:plain) %>
|
8
|
+
--<%= data.boundary %>
|
9
|
+
Content-Type: text/plain; charset="utf-8"
|
10
|
+
Content-Transfer-Encoding: base64
|
11
|
+
|
12
|
+
<%= Base64.encode64(data.bodies[:plain]) %>
|
13
|
+
<% end %>
|
14
|
+
<% if data.bodies.key?(:html) %>
|
15
|
+
--<%= data.boundary %>
|
16
|
+
Content-Type: text/html; charset="utf-8"
|
17
|
+
Content-Transfer-Encoding: base64
|
18
|
+
|
19
|
+
<%= Base64.encode64(data.bodies[:html]) %>
|
20
|
+
<% end %>
|
21
|
+
--<%= data.boundary %>--
|
@@ -1,7 +1,8 @@
|
|
1
1
|
From: <%= from.name %> <<%= from.address %>>
|
2
2
|
To: <%= to %>
|
3
|
-
Subject: <%= data.
|
3
|
+
Subject: [<%= data.tag %>] <%= data.site.uri.host %> changed
|
4
4
|
Content-Type: text/plain; charset="utf-8"
|
5
5
|
Content-Transfer-Encoding: base64
|
6
|
+
MIME-Version: 1.0
|
6
7
|
|
7
|
-
<%= Base64.encode64(data.
|
8
|
+
<%= Base64.encode64(data.bodies[:plain]) %>
|
data/bin/wcc-upgrade
CHANGED
@@ -19,10 +19,15 @@ def traverse(root, dst_root, path)
|
|
19
19
|
src = root + rel
|
20
20
|
dst = dst_root + rel
|
21
21
|
if dst.exist?
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
# do compare
|
23
|
+
same = FileUtils.compare_file(src, dst)
|
24
|
+
# do nothing when same
|
25
|
+
if not same
|
26
|
+
print "Do you want to overwrite #{dst}? (y/n): "
|
27
|
+
answer = $stdin.gets
|
28
|
+
if answer == "y\n"
|
29
|
+
FileUtils.cp src, dst, :verbose => true
|
30
|
+
end
|
26
31
|
end
|
27
32
|
else
|
28
33
|
FileUtils.cp src, dst, :verbose => true
|
data/lib/wcc/diff.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
|
2
|
+
module WCC
|
3
|
+
class DiffItem
|
4
|
+
attr_accessor :status, :text, :hilite
|
5
|
+
|
6
|
+
def initialize(line)
|
7
|
+
if line.start_with?('+++')
|
8
|
+
@status = :new
|
9
|
+
@text = line.substring(3)
|
10
|
+
elsif line.start_with?('---')
|
11
|
+
@status = :old
|
12
|
+
@text = line.substring(3)
|
13
|
+
elsif line.start_with?('@@')
|
14
|
+
@status = :range
|
15
|
+
@text = line.substring(2)
|
16
|
+
elsif line.start_with?('+')
|
17
|
+
@status = :ins
|
18
|
+
@text = line.substring(1)
|
19
|
+
elsif line.start_with?('-')
|
20
|
+
@status = :del
|
21
|
+
@text = line.substring(1)
|
22
|
+
else
|
23
|
+
@status = :other
|
24
|
+
@text = line
|
25
|
+
end
|
26
|
+
@text.gsub!(/\n/, '')
|
27
|
+
@hilite = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def html_hilite_text(css_klass = 'hilite')
|
31
|
+
return @text if @hilite.nil?
|
32
|
+
|
33
|
+
i = 1
|
34
|
+
new_text = ''
|
35
|
+
in_span = false
|
36
|
+
@text.chars.to_a.each do |c|
|
37
|
+
if @hilite.include?(i)
|
38
|
+
if not in_span
|
39
|
+
new_text += "<span class=\"#{css_klass}\">"
|
40
|
+
end
|
41
|
+
new_text += c
|
42
|
+
in_span = true
|
43
|
+
else
|
44
|
+
if in_span
|
45
|
+
new_text += "</span>"
|
46
|
+
end
|
47
|
+
new_text += c
|
48
|
+
in_span = false
|
49
|
+
end
|
50
|
+
i += 1
|
51
|
+
end
|
52
|
+
new_text += "</span>" if in_span
|
53
|
+
new_text
|
54
|
+
end
|
55
|
+
|
56
|
+
def rchar
|
57
|
+
case status
|
58
|
+
when :new
|
59
|
+
'N'
|
60
|
+
when :old
|
61
|
+
'O'
|
62
|
+
when :range
|
63
|
+
'@'
|
64
|
+
when :ins
|
65
|
+
'i'
|
66
|
+
when :del
|
67
|
+
'd'
|
68
|
+
when :other
|
69
|
+
'_'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_s
|
74
|
+
case status
|
75
|
+
when :new
|
76
|
+
'+++'+text
|
77
|
+
when :old
|
78
|
+
'---'+text
|
79
|
+
when :range
|
80
|
+
'@@'+text
|
81
|
+
when :ins
|
82
|
+
'+'+text
|
83
|
+
when :del
|
84
|
+
'-'+text
|
85
|
+
when :other
|
86
|
+
text
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class Differ
|
92
|
+
attr_reader :di
|
93
|
+
|
94
|
+
def initialize(dstring)
|
95
|
+
@di = []
|
96
|
+
dstring.lines.each do |line|
|
97
|
+
# parse line
|
98
|
+
@di << DiffItem.new(line)
|
99
|
+
end
|
100
|
+
# TODO: compute_hilite, wrong +/- detection
|
101
|
+
end
|
102
|
+
|
103
|
+
def compute_hilite
|
104
|
+
s = rchar
|
105
|
+
puts s
|
106
|
+
|
107
|
+
mds = []
|
108
|
+
md = s.match(/(@|_)di(@|_)/)
|
109
|
+
while not md.nil?
|
110
|
+
mds << md
|
111
|
+
s = s.substring(md.begin(2)+1)
|
112
|
+
md = s.match(/(@|_)di(@|_)/)
|
113
|
+
end
|
114
|
+
|
115
|
+
offset = 0
|
116
|
+
mds.each do |md|
|
117
|
+
i = offset+md.begin(1)+1
|
118
|
+
offset = md.begin(2)+1
|
119
|
+
ranges = Diff::LCS.diff(@di[i].text, @di[i+1].text)
|
120
|
+
@di[i].hilite = []
|
121
|
+
@di[i+1].hilite = []
|
122
|
+
ranges.each do |chg|
|
123
|
+
chg.each do |c|
|
124
|
+
if c.action == '-' and c.element != ''
|
125
|
+
@di[i].hilite << c.position
|
126
|
+
end
|
127
|
+
if c.action == '+' and c.element != ''
|
128
|
+
@di[i+1].hilite << c.position
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def rchar
|
136
|
+
@di.map { |o| o.rchar }.join
|
137
|
+
end
|
138
|
+
|
139
|
+
def to_s
|
140
|
+
@di.map { |o| o.to_s }.join("\n")
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
data/lib/wcc/mail.rb
CHANGED
@@ -45,11 +45,31 @@ module WCC
|
|
45
45
|
@port = port
|
46
46
|
end
|
47
47
|
|
48
|
-
|
48
|
+
# Sends a mail built up from some [ERB] templates to the
|
49
|
+
# specified adresses.
|
50
|
+
#
|
51
|
+
# @param [OpenStruct] data used to construct ERB binding
|
52
|
+
# @param [ERB] main the main template
|
53
|
+
# @param [Hash] bodies :name, ERB template pairs
|
54
|
+
# @param [String] from the From: address
|
55
|
+
# @param [Array] tos array of To: addresses
|
56
|
+
def send(data, main, bodies, from, tos = [])
|
57
|
+
# generate a boundary that may be used for multipart
|
58
|
+
data.boundary = "frontier-#{data.site.id}"
|
59
|
+
# generate messages
|
60
|
+
msgs = {}
|
61
|
+
tos.each do |to|
|
62
|
+
data.bodies = {}
|
63
|
+
# eval all body templates
|
64
|
+
bodies.each do |name,template|
|
65
|
+
data.bodies[name] = template.result(binding)
|
66
|
+
end
|
67
|
+
# eval main template
|
68
|
+
msgs[to] = main.result(binding)
|
69
|
+
end
|
70
|
+
# send messages
|
49
71
|
Net::SMTP.start(@host, @port) do |smtp|
|
50
|
-
|
51
|
-
# eval ERB
|
52
|
-
msg = template.result(binding)
|
72
|
+
msgs.each do |to,msg|
|
53
73
|
smtp.send_message(msg, from.address, to.address)
|
54
74
|
end
|
55
75
|
end
|
data/lib/wcc.rb
CHANGED
@@ -16,9 +16,11 @@ require 'uri'
|
|
16
16
|
require 'yaml'
|
17
17
|
|
18
18
|
# ruby gem dependencies
|
19
|
+
#require 'diff-lcs'
|
19
20
|
require 'htmlentities'
|
20
21
|
|
21
22
|
# wcc
|
23
|
+
require 'wcc/diff'
|
22
24
|
require 'wcc/filter'
|
23
25
|
require 'wcc/mail'
|
24
26
|
require 'wcc/site'
|
@@ -31,6 +33,14 @@ class String
|
|
31
33
|
def strip_html
|
32
34
|
HTMLEntities.new.decode(self.gsub(/<[^>]+>/, ' '))
|
33
35
|
end
|
36
|
+
|
37
|
+
# Returns all characters from the i-th to the end.
|
38
|
+
#
|
39
|
+
# @param [Integer] i offset to start substring
|
40
|
+
# @return [String] slice(i...length)
|
41
|
+
def substring(i)
|
42
|
+
slice(i...length)
|
43
|
+
end
|
34
44
|
end
|
35
45
|
|
36
46
|
module WCC
|
@@ -262,7 +272,7 @@ module WCC
|
|
262
272
|
[text, "\n"].join
|
263
273
|
end
|
264
274
|
end
|
265
|
-
|
275
|
+
|
266
276
|
class Prog
|
267
277
|
def self.checkForUpdate(site)
|
268
278
|
WCC.logger.info "Requesting '#{site.uri.to_s}'"
|
@@ -308,8 +318,8 @@ module WCC
|
|
308
318
|
if site.new?
|
309
319
|
site.hash, site.content = new_hash, new_content
|
310
320
|
|
311
|
-
#
|
312
|
-
diff =
|
321
|
+
# signal that no diff was posible
|
322
|
+
diff = nil
|
313
323
|
else
|
314
324
|
# save old site to tmp file
|
315
325
|
old_site_file = Tempfile.new("wcc-#{site.id}-")
|
@@ -330,10 +340,11 @@ module WCC
|
|
330
340
|
return false if not Filter.accept(diff, site.filters)
|
331
341
|
|
332
342
|
data = OpenStruct.new
|
333
|
-
data.
|
334
|
-
data.
|
343
|
+
data.site = site
|
344
|
+
data.diff = diff.nil? ? nil : WCC::Differ.new(diff)
|
345
|
+
data.tag = Conf[:tag]
|
335
346
|
|
336
|
-
Conf.mailer.send(data, @@mail_plain, MailAddress.new(Conf[:from_mail]), site.emails)
|
347
|
+
Conf.mailer.send(data, @@mail_plain, @@mail_bodies, MailAddress.new(Conf[:from_mail]), site.emails)
|
337
348
|
|
338
349
|
system("logger -t '#{Conf[:tag]}' 'Change at #{site.uri.to_s} (tag #{site.id}) detected'") if Conf[:syslog]
|
339
350
|
|
@@ -345,9 +356,11 @@ module WCC
|
|
345
356
|
# first use of Conf initializes it
|
346
357
|
WCC.logger = Logger.new(STDOUT)
|
347
358
|
|
348
|
-
|
349
|
-
|
350
|
-
|
359
|
+
@@mail_plain = load_template('mail.alt.erb')
|
360
|
+
@@mail_bodies = {
|
361
|
+
:plain => load_template('mail-body.plain.erb'),
|
362
|
+
:html => load_template('mail-body.html.erb')
|
363
|
+
}
|
351
364
|
|
352
365
|
Conf.sites.each do |site|
|
353
366
|
if checkForUpdate(site)
|
@@ -357,5 +370,14 @@ module WCC
|
|
357
370
|
end
|
358
371
|
end
|
359
372
|
end
|
373
|
+
|
374
|
+
private
|
375
|
+
|
376
|
+
def self.load_template(name)
|
377
|
+
t_path = File.join(Conf[:template_dir], name)
|
378
|
+
t = File.open(t_path, 'r') { |f| f.read }
|
379
|
+
# <> omit newline for lines starting with <% and ending in %>
|
380
|
+
ERB.new(t, 0, "<>")
|
381
|
+
end
|
360
382
|
end
|
361
383
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wcc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 7
|
10
|
+
version: 0.0.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Christian Nicolai
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-10-
|
18
|
+
date: 2011-10-09 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: htmlentities
|
@@ -46,11 +46,15 @@ files:
|
|
46
46
|
- assets/conf.yml
|
47
47
|
- assets/filter.d/arg-test.rb
|
48
48
|
- assets/filter.d/test.rb
|
49
|
+
- assets/template.d/mail.alt.erb
|
50
|
+
- assets/template.d/mail-body.html.erb
|
51
|
+
- assets/template.d/mail-body.plain.erb
|
49
52
|
- assets/template.d/mail.plain.erb
|
50
53
|
- bin/wcc
|
51
54
|
- bin/wcc-init
|
52
55
|
- bin/wcc-upgrade
|
53
56
|
- doc/Filters.md
|
57
|
+
- lib/wcc/diff.rb
|
54
58
|
- lib/wcc/filter.rb
|
55
59
|
- lib/wcc/mail.rb
|
56
60
|
- lib/wcc/site.rb
|