wcc 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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(/^ /, "&nbsp;") %></li>
88
+ <% end %>
89
+ <% end %>
90
+ </ul>
91
+ </div>
92
+ <% end %>
93
+ </body>
94
+ </html>
@@ -0,0 +1,7 @@
1
+ <% if data.diff.nil? %>
2
+ Checked <%= data.site.uri.to_s %> the first time so no diff was possible.
3
+ <% else %>
4
+ Change at <%= data.site.uri.to_s %> - diff follows:
5
+
6
+ <%= data.diff.to_s %>
7
+ <% end %>
@@ -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.title.gsub(/\s+/, ' ') %>
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.message) %>
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
- print "Do you want to overwrite #{dst}? (y/n): "
23
- answer = $stdin.gets
24
- if answer == "y\n"
25
- FileUtils.cp src, dst, :verbose => true
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
- def send(data, template, from, tos = [])
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
- tos.each do |to|
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
- # set custom diff message
312
- diff = "Site was first checked so no diff was possible."
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.title = "[#{Conf[:tag]}] #{site.uri.host} changed"
334
- data.message = "Change at #{site.uri.to_s} - diff follows:\n\n#{diff}"
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
- mp_path = File.join(Conf[:template_dir], 'mail.plain.erb')
349
- mp = File.open(mp_path, 'r') { |f| f.read }
350
- @@mail_plain = ERB.new(mp)
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: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 6
10
- version: 0.0.6
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-04 00:00:00 Z
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