wcc 0.0.3 → 0.0.4

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.
data/README.md CHANGED
@@ -8,11 +8,21 @@ from old content to new content so minor changes produce only few lines of text
8
8
  Note: wcc relies on native `diff` command to produce the unified diff shown in mails -
9
9
  plans are to remove this dependency by using [something like this](https://github.com/samg/diffy) later...
10
10
 
11
+ Setup
12
+ -----
13
+
14
+ You need Ruby (preferably version 1.8.7) and Rubygems installed
15
+ (consider using [rvm](http://beginrescueend.com/)). Install wcc:
16
+
17
+ gem install wcc
18
+
19
+ (If you *don't* use [rvm](http://beginrescueend.com/) you should add a 'sudo'.)
20
+
11
21
  Usage
12
22
  -----
13
23
 
14
- wcc is packaged as a gem named 'wcc' and provides it's main script as ´wcc´ via the
15
- command line. It can invoked by hand or automatically via *cron* on a server environment.
24
+ The installed 'wcc' gem provides a ´wcc´ binary on the command line.
25
+ It can invoked by hand or automatically via *cron* on a server environment.
16
26
 
17
27
  For using wcc you need to specify some options:
18
28
 
@@ -20,7 +30,7 @@ For using wcc you need to specify some options:
20
30
  * or in a configuration file in [YAML](https://secure.wikimedia.org/wikipedia/en/wiki/YAML) format
21
31
 
22
32
  The location of the configuration file (usually called 'conf.yml' or something like this)
23
- can itself be given on command line as last argument. Each option has an hard-coded default
33
+ can itself be given on command line as last argument. Each option has a hard-coded default
24
34
  (e.g. the configuration file name is assumed to be './conf.yml'). Command line options
25
35
  overwrite configuration file entries.
26
36
 
@@ -32,16 +42,6 @@ An example crontab entry that runs wcc every 10 minutes might look like this:
32
42
 
33
43
  */10 * * * * root cd /path/to/dir/with/conf;./wcc
34
44
 
35
- By default wcc only outputs ERROR messages to avoid your cron daemon spammin' around.
36
- It is recommended to place 'conf.yml' (and optionally the 'filter.d') within an separate
37
- directory and use `cd` in cron entry.
38
-
39
- Setup
40
- -----
41
-
42
- You need Ruby (preferably version 1.8.7) and Rubygems installed
43
- (consider using [rvm](http://beginrescueend.com/)). Install wcc:
44
-
45
- gem install wcc
46
-
47
- (If you *don't* use [rvm](http://beginrescueend.com/) you should add a 'sudo'.)
45
+ By default wcc only outputs ERROR and FATAL messages to avoid your cron daemon spammin' around.
46
+ It is recommended to place 'conf.yml' (and optionally the 'filter.d' and 'template.d') within
47
+ a separate directory and use `cd` in cron entry.
data/doc/Filters.md ADDED
@@ -0,0 +1,37 @@
1
+ Filter-API
2
+ ==========
3
+
4
+ Filters formally are Ruby Proc blocks (mostly contained in small ruby
5
+ scripts) referenced by an ID that decide upon a given website diff whether
6
+ to notify the user (by email) or not.
7
+
8
+ These Proc blocks get registered using `Filter.add` with a given ID (a
9
+ string, not a :symbol to prevent some problems).
10
+
11
+ wcc provides an autoloading mechanism that loads all ruby files contained in
12
+ a specific directory - the *filter.d* - via `require`. The filter file
13
+ should contain some bootstrap code that may rely only on the *Filter* class
14
+ out of wcc:
15
+
16
+ Filter.add 'my_custom_id' do |data,arguments|
17
+ # do your filter magic here
18
+ # and return a boolean
19
+ end
20
+
21
+ The format of the `data` may change over time, currently it's a string
22
+ containing all lines separated by newline of the unified diff (raw from unix
23
+ diff). The arguments are a - possibly empty - hash directly passed in from
24
+ the configuration file to parameterize the filter (e.g. ignoring all diffs
25
+ shorter than let's say 10 lines).
26
+
27
+ The output of this filter should be boolean true or false, indicating that
28
+ an email should be sent or not.
29
+
30
+ In the configuration file a filter is referenced like this:
31
+
32
+ sites:
33
+ - url: ...
34
+ :
35
+ filters:
36
+ - test
37
+ - paramtest: { minLines: 10 }
data/lib/wcc/filter.rb ADDED
@@ -0,0 +1,40 @@
1
+
2
+ module WCC
3
+ class FilterRef
4
+ attr_reader :id, :arguments
5
+
6
+ def initialize(id, arguments = {})
7
+ @id = id
8
+ @arguments = arguments
9
+ end
10
+
11
+ def to_s; @id end
12
+ end
13
+
14
+ class Filter
15
+ @@filters = {}
16
+
17
+ def self.add(id, &block)
18
+ WCC.logger.info "Adding filter '#{id}'"
19
+ @@filters[id] = block
20
+ end
21
+
22
+ def self.accept(data, filters)
23
+ return true if filters.nil?
24
+
25
+ WCC.logger.info "Testing with filters: #{filters.join(', ')}"
26
+ filters.each do |fref|
27
+ block = @@filters[fref.id]
28
+ if block.nil?
29
+ WCC.logger.error "Requested filter '#{fref.id}' not found, skipping it."
30
+ next
31
+ end
32
+ if not block.call(data, fref.arguments)
33
+ WCC.logger.info "Filter '#{fref.id}' failed!"
34
+ return false
35
+ end
36
+ end
37
+ true
38
+ end
39
+ end
40
+ end
data/lib/wcc/mail.rb ADDED
@@ -0,0 +1,60 @@
1
+
2
+ module WCC
3
+ # An email address container with internal conversion
4
+ # routines.
5
+ class MailAddress
6
+ def initialize(email)
7
+ email = email.to_s if email.is_a?(MailAddress)
8
+ @email = email.strip
9
+ end
10
+
11
+ # Extract the 'name' out of an mail address:
12
+ # "Me <me@example.org>" -> "Me"
13
+ # "me2@example.org" -> "me2"
14
+ #
15
+ # @return [String] name
16
+ def name
17
+ if @email =~ /^[\w\s]+<.+@[^@]+>$/
18
+ @email.gsub(/<.+?>/, '').strip
19
+ else
20
+ @email.split("@")[0...-1].join("@")
21
+ end
22
+ end
23
+
24
+ # Return the real mail address:
25
+ # "Me <me@example.org>" -> "me@example.org"
26
+ # "me2@example.org" -> "me2@example.org"
27
+ #
28
+ # @return [String] mail address
29
+ def address
30
+ if @email =~ /^[\w\s]+<.+@[^@]+>$/
31
+ @email.match(/<([^>]+@[^@>]+)>/)[1]
32
+ else
33
+ @email
34
+ end
35
+ end
36
+
37
+ def to_s; @email end
38
+ end
39
+
40
+ # SmtpMailer is a specific implementation of an mail deliverer that
41
+ # does plain SMTP to host:port using [Net::SMTP].
42
+ class SmtpMailer
43
+ def initialize(host, port)
44
+ @host = host
45
+ @port = port
46
+ end
47
+
48
+ def send(data, template, from, tos = [])
49
+ Net::SMTP.start(@host, @port) do |smtp|
50
+ tos.each do |to|
51
+ # eval ERB
52
+ msg = template.result(binding)
53
+ smtp.send_message(msg, from.address, to.address)
54
+ end
55
+ end
56
+ rescue
57
+ WCC.logger.fatal "Cannot send mails via SMTP to #{@host}:#{@port} : #{$!.to_s}"
58
+ end
59
+ end
60
+ end
data/lib/wcc/site.rb ADDED
@@ -0,0 +1,75 @@
1
+
2
+ module WCC
3
+ class Site
4
+ attr_reader :uri, :emails, :filters, :auth, :cookie, :id
5
+
6
+ def initialize(url, strip_html, emails, filters, auth, cookie)
7
+ @uri = URI.parse(url)
8
+ @strip_html = strip_html
9
+ @emails = emails.is_a?(Array) ? emails : [emails]
10
+ @filters = filters.is_a?(Array) ? filters : [filters]
11
+ @auth = auth
12
+ @cookie = cookie
13
+ @id = Digest::MD5.hexdigest(url.to_s)[0...8]
14
+ # invalid hashes are ""
15
+ load_hash
16
+ end
17
+
18
+ def strip_html?; @strip_html end
19
+
20
+ def new?
21
+ hash.empty?
22
+ end
23
+
24
+ def load_hash
25
+ file = Conf.file(@id + '.md5')
26
+ if File.exists?(file)
27
+ WCC.logger.debug "Load hash from file '#{file}'"
28
+ File.open(file, 'r') { |f| @hash = f.gets; break }
29
+ else
30
+ WCC.logger.info "Site #{uri.host} was never checked before."
31
+ @hash = ""
32
+ end
33
+ end
34
+
35
+ def load_content
36
+ file = Conf.file(@id + '.site')
37
+ if File.exists?(file)
38
+ File.open(file, 'r') { |f| @content = f.read }
39
+ end
40
+ end
41
+
42
+ def hash; @hash end
43
+
44
+ def hash=(hash)
45
+ @hash = hash
46
+ File.open(Conf.file(@id + '.md5'), 'w') { |f| f.write(@hash) } unless Conf.simulate?
47
+ end
48
+
49
+ def content; load_content if @content.nil?; @content end
50
+
51
+ def content=(content)
52
+ @content = content
53
+ File.open(Conf.file(@id + '.site'), 'w') { |f| f.write(@content) } unless Conf.simulate?
54
+ end
55
+
56
+ def fetch
57
+ http = Net::HTTP.new(@uri.host, @uri.port)
58
+ if @uri.is_a?(URI::HTTPS)
59
+ http.use_ssl = true
60
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
61
+ end
62
+ http.start do |http|
63
+ req = Net::HTTP::Get.new(@uri.request_uri)
64
+ if @auth['type'] == 'basic'
65
+ WCC.logger.debug "Doing basic auth"
66
+ req.basic_auth(@auth['username'], @auth['password'])
67
+ end
68
+ if not @cookie.nil?
69
+ req.add_field("Cookie", @cookie)
70
+ end
71
+ http.request(req)
72
+ end
73
+ end
74
+ end
75
+ end
data/lib/wcc.rb CHANGED
@@ -1,12 +1,14 @@
1
1
 
2
2
  require 'base64'
3
3
  require 'digest/md5'
4
+ require 'erb'
4
5
  require 'iconv'
5
6
  require 'logger'
6
7
  require 'net/http'
7
8
  require 'net/https'
8
9
  require 'net/smtp'
9
10
  require 'optparse'
11
+ require 'ostruct'
10
12
  require 'pathname'
11
13
  require 'singleton'
12
14
  require 'tempfile'
@@ -16,8 +18,13 @@ require 'yaml'
16
18
  # ruby gem dependencies
17
19
  require 'htmlentities'
18
20
 
21
+ # wcc
22
+ require 'wcc/filter'
23
+ require 'wcc/mail'
24
+ require 'wcc/site'
25
+
19
26
  class String
20
- # Remove all HTML <tags> with at least one character name and
27
+ # Remove all HTML tags with at least one character name and
21
28
  # decode all HTML entities into utf-8 characters.
22
29
  #
23
30
  # @return [String] stripped string
@@ -31,6 +38,7 @@ module WCC
31
38
  DIFF_TIME_FMT = '%Y-%m-%d %H:%M:%S %Z'
32
39
 
33
40
  # logging via WCC.logger.blub
41
+
34
42
  def self.logger
35
43
  @logger
36
44
  end
@@ -57,10 +65,12 @@ module WCC
57
65
  :simulate => false,
58
66
  :clean => false,
59
67
  :nomails => false,
60
- :dir => '/var/tmp/wcc',
68
+ # when you want to use ./tmp it must be writeable
69
+ :cache_dir => '/var/tmp/wcc',
61
70
  :tag => 'wcc',
62
71
  :syslog => false,
63
- :filterd => './filter.d',
72
+ :filter_dir => './filter.d',
73
+ :template_dir => './template.d',
64
74
  :mailer => 'smtp',
65
75
  :smtp_host => 'localhost',
66
76
  :smtp_port => 25
@@ -75,14 +85,15 @@ module WCC
75
85
  opts.banner += "\nOptions:\n"
76
86
  opts.on('-v', '--verbose', 'Output more information') do self[:verbose] = true end
77
87
  opts.on('-d', '--debug', 'Enable debug mode') do self[:debug] = true end
78
- opts.on('-o', '--dir DIR', 'Save hash and diff files to DIR') do |dir| self[:dir] = dir end
88
+ opts.on('--cache-dir DIR', 'Save hash and diff files to DIR') do |dir| self[:cache_dir] = dir end
79
89
  opts.on('-s', '--simulate', 'Check for update but do not save hash or diff files') do self[:simulate] = true end
80
- opts.on('-c', '--clean', 'Remove all saved hash and diff files') do self[:clean] = true end
90
+ opts.on('--clean', 'Remove all saved hash and diff files') do self[:clean] = true end
81
91
  opts.on('-t', '--tag TAG', 'Set TAG used in output') do |t| self[:tag] = t end
82
92
  opts.on('-n', '--no-mails', 'Do not send any emails') do self[:nomails] = true end
83
93
  opts.on('-f', '--from MAIL', 'Set From: mail address') do |m| self[:from_mail] = m end
84
94
  opts.on('--host HOST', 'Set SMTP host') do |h| self[:host] = h end
85
95
  opts.on('--port PORT', 'Set SMTP port') do |p| self[:port] = p end
96
+ #opts.on('--init', '--initialize')
86
97
  opts.on('--show-config', 'Show config after loading config file (debug purposes)') do self[:show_config] = true end
87
98
  opts.on('-h', '-?', '--help', 'Display this screen') do
88
99
  puts opts
@@ -115,10 +126,11 @@ module WCC
115
126
  yaml = YAML.load_file(self[:conf])
116
127
  if yaml.is_a?(Hash) and (yaml = yaml['conf']).is_a?(Hash)
117
128
  @options[:from_mail] ||= yaml['from_addr']
118
- @options[:dir] ||= yaml['cache_dir']
129
+ @options[:cache_dir] ||= yaml['cache_dir']
119
130
  @options[:tag] ||= yaml['tag']
120
131
  @options[:syslog] ||= yaml['use_syslog']
121
- @options[:filterd] ||= yaml['filterd']
132
+ @options[:filter_dir] ||= yaml['filterd']
133
+ @options[:template_dir] ||= yaml['templated']
122
134
 
123
135
  if yaml['email'].is_a?(Hash)
124
136
  if yaml['email']['smtp'].is_a?(Hash)
@@ -142,18 +154,23 @@ module WCC
142
154
  exit 0
143
155
  end
144
156
 
145
- # create dir for hash files
146
- Dir.mkdir(self[:dir]) unless File.directory?(self[:dir])
157
+ # create cache dir for hash and diff files
158
+ Dir.mkdir(self[:cache_dir]) unless File.directory?(self[:cache_dir])
147
159
 
148
160
  if(self[:clean])
149
161
  WCC.logger.warn "Cleanup hash and diff files"
150
- Dir.foreach(self[:dir]) do |f|
162
+ Dir.foreach(self[:cache_dir]) do |f|
151
163
  File.delete(self.file(f)) if f =~ /^.*\.(md5|site)$/
152
164
  end
153
165
  end
154
166
 
155
167
  # read filter.d
156
- Dir[File.join(self[:filterd], '*.rb')].each { |file| require file }
168
+ Dir[File.join(self[:filter_dir], '*.rb')].each { |file| require file }
169
+
170
+ # attach --no-mails filter
171
+ WCC::Filter.add '--no-mails' do |data|
172
+ !self[:nomails]
173
+ end
157
174
  end
158
175
 
159
176
  def self.sites
@@ -163,19 +180,25 @@ module WCC
163
180
 
164
181
  WCC.logger.debug "Load sites from '#{Conf[:conf]}'"
165
182
 
166
- # may be false if file is empty
183
+ # may be *false* if file is empty
167
184
  yaml = YAML.load_file(Conf[:conf])
168
185
 
186
+ if not yaml
187
+ WCC.logger.info "No sites loaded"
188
+ return @sites
189
+ end
190
+
169
191
  yaml['sites'].to_a.each do |yaml_site|
170
- filterrefs = []
192
+ # query --no-mails filter for every site
193
+ frefs = [FilterRef.new('--no-mails')]
171
194
  (yaml_site['filters'] || []).each do |entry|
172
195
  if entry.is_a?(Hash)
173
196
  # hash containing only one key (filter id),
174
197
  # the value is the argument hash
175
198
  id = entry.keys[0]
176
- filterrefs << FilterRef.new(id, entry[id])
199
+ frefs << FilterRef.new(id, entry[id])
177
200
  else entry.is_a?(String)
178
- filterrefs << FilterRef.new(entry, {})
201
+ frefs << FilterRef.new(entry)
179
202
  end
180
203
  end
181
204
 
@@ -187,10 +210,10 @@ module WCC
187
210
  yaml_site['url'],
188
211
  yaml_site['strip_html'] || true,
189
212
  yaml_site['emails'].map { |m| MailAddress.new(m) } || [],
190
- filterrefs,
213
+ frefs,
191
214
  yaml_site['auth'] || {},
192
215
  cookie)
193
- end if not yaml.nil?
216
+ end
194
217
 
195
218
  WCC.logger.debug @sites.length.to_s + (@sites.length == 1 ? ' site' : ' sites') + " loaded\n" +
196
219
  @sites.map { |s| " #{s.uri.host.to_s}\n url: #{s.uri.to_s}\n id: #{s.id}" }.join("\n")
@@ -199,197 +222,21 @@ module WCC
199
222
  end
200
223
 
201
224
  def self.mailer
202
- if @mailer.nil?
203
- # smtp mailer
204
- if Conf[:mailer] == 'smtp'
205
- @mailer = SmtpMailer.new(Conf[:smtp_host], Conf[:smtp_port])
206
- end
225
+ return @mailer unless @mailer.nil?
226
+
227
+ # smtp mailer
228
+ if Conf[:mailer] == 'smtp'
229
+ @mailer = SmtpMailer.new(Conf[:smtp_host], Conf[:smtp_port])
207
230
  end
231
+
208
232
  @mailer
209
233
  end
210
234
 
211
- def self.file(path = nil) File.join(self[:dir], path) end
235
+ def self.file(path = nil) File.join(self[:cache_dir], path) end
212
236
  def self.simulate?; self[:simulate] end
213
- def self.send_mails?; !self[:nomails] end
214
237
  def self.[](key); Conf.instance[key] end
215
238
  end
216
239
 
217
- class FilterRef
218
- attr_reader :id, :arguments
219
-
220
- def initialize(id, arguments)
221
- @id = id
222
- @arguments = arguments
223
- end
224
-
225
- def to_s; @id end
226
- end
227
-
228
- class Site
229
- attr_reader :uri, :emails, :filters, :auth, :cookie, :id
230
-
231
- def initialize(url, strip_html, emails, filters, auth, cookie)
232
- @uri = URI.parse(url)
233
- @strip_html = strip_html
234
- @emails = emails.is_a?(Array) ? emails : [emails]
235
- @filters = filters.is_a?(Array) ? filters : [filters]
236
- @auth = auth
237
- @cookie = cookie
238
- @id = Digest::MD5.hexdigest(url.to_s)[0...8]
239
- # invalid hashes are ""
240
- load_hash
241
- end
242
-
243
- def strip_html?; @strip_html end
244
-
245
- def new?
246
- hash.empty?
247
- end
248
-
249
- def load_hash
250
- file = Conf.file(@id + '.md5')
251
- if File.exists?(file)
252
- WCC.logger.debug "Load hash from file '#{file}'"
253
- File.open(file, 'r') { |f| @hash = f.gets; break }
254
- else
255
- WCC.logger.info "Site #{uri.host} was never checked before."
256
- @hash = ""
257
- end
258
- end
259
-
260
- def load_content
261
- file = Conf.file(@id + '.site')
262
- if File.exists?(file)
263
- File.open(file, 'r') { |f| @content = f.read }
264
- end
265
- end
266
-
267
- def hash; @hash end
268
-
269
- def hash=(hash)
270
- @hash = hash
271
- File.open(Conf.file(@id + '.md5'), 'w') { |f| f.write(@hash) } unless Conf.simulate?
272
- end
273
-
274
- def content; load_content if @content.nil?; @content end
275
-
276
- def content=(content)
277
- @content = content
278
- File.open(Conf.file(@id + '.site'), 'w') { |f| f.write(@content) } unless Conf.simulate?
279
- end
280
-
281
- def fetch
282
- http = Net::HTTP.new(@uri.host, @uri.port)
283
- if @uri.is_a?(URI::HTTPS)
284
- http.use_ssl = true
285
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
286
- end
287
- http.start do |http|
288
- req = Net::HTTP::Get.new(@uri.request_uri)
289
- if @auth['type'] == 'basic'
290
- WCC.logger.debug "Doing basic auth"
291
- req.basic_auth(@auth['username'], @auth['password'])
292
- end
293
- if not @cookie.nil?
294
- req.add_field("Cookie", @cookie)
295
- end
296
- http.request(req)
297
- end
298
- end
299
- end
300
-
301
- class MailAddress
302
- def initialize(email)
303
- email = email.to_s if email.is_a?(MailAddress)
304
- @email = email.strip
305
- end
306
-
307
- def name
308
- if @email =~ /^[\w\s]+<.+@[^@]+>$/
309
- @email.gsub(/<.+?>/, '').strip
310
- else
311
- @email.split("@")[0...-1].join("@")
312
- end
313
- end
314
-
315
- def address
316
- if @email =~ /^[\w\s]+<.+@[^@]+>$/
317
- @email.match(/<([^>]+@[^@>]+)>/)[1]
318
- else
319
- @email
320
- end
321
- end
322
-
323
- def to_s; @email end
324
- end
325
-
326
- class Mail
327
- attr_reader :title, :message
328
-
329
- def initialize(title, message, options = {})
330
- @title = title
331
- @message = message
332
- @options = {:from => MailAddress.new(Conf[:from_mail])}
333
- @options[:from] = MailAddress.new(options[:from]) unless options[:from].nil?
334
- end
335
-
336
- def send(tos = [])
337
- Conf.mailer.send(self, @options[:from], tos)
338
- end
339
- end
340
-
341
- class SmtpMailer
342
- def initialize(host, port)
343
- @host = host
344
- @port = port
345
- end
346
-
347
- def send(mail, from, to = [])
348
- Net::SMTP.start(@host, @port) do |smtp|
349
- to.each do |toaddr|
350
- msg = "From: #{from.name} <#{from.address}>\n"
351
- msg += "To: #{toaddr}\n"
352
- msg += "Subject: #{mail.title.gsub(/\s+/, ' ')}\n"
353
- msg += "Content-Type: text/plain; charset=\"utf-8\"\n"
354
- msg += "Content-Transfer-Encoding: base64\n"
355
- msg += "\n"
356
- msg += Base64.encode64(mail.message)
357
-
358
- smtp.send_message(msg, from.address, toaddr.address)
359
- end
360
- end
361
- rescue
362
- WCC.logger.fatal "Cannot send mails at #{@host}:#{@port} : #{$!.to_s}"
363
- end
364
- end
365
-
366
- class Filter
367
- @@filters = {}
368
-
369
- def self.add(id, &block)
370
- WCC.logger.info "Adding filter '#{id}'"
371
- @@filters[id] = block
372
- end
373
-
374
- def self.accept(data, filters)
375
- return true if filters.nil?
376
-
377
- WCC.logger.info "Testing with filters: #{filters.join(', ')}"
378
- filters.each do |fref|
379
- block = @@filters[fref.id]
380
- if block.nil?
381
- WCC.logger.error "Requested filter '#{fref.id}' not found, skipping it."
382
- next
383
- end
384
- if not block.call(data, fref.arguments)
385
- WCC.logger.info "Filter #{fref.id} failed!"
386
- return false
387
- end
388
- end
389
- true
390
- end
391
- end
392
-
393
240
  class LogFormatter
394
241
  def initialize(use_color = true)
395
242
  @color = use_color
@@ -450,7 +297,7 @@ module WCC
450
297
  return false
451
298
  end
452
299
 
453
- # strip html _before_ diffing
300
+ # strip html
454
301
  new_content = new_content.strip_html if site.strip_html?
455
302
  new_hash = Digest::MD5.hexdigest(new_content)
456
303
 
@@ -459,7 +306,6 @@ module WCC
459
306
 
460
307
  # do not try diff or anything if site was never checked before
461
308
  if site.new?
462
- # update content
463
309
  site.hash, site.content = new_hash, new_content
464
310
 
465
311
  # set custom diff message
@@ -474,19 +320,20 @@ module WCC
474
320
  old_label = "OLD (%s)" % File.mtime(Conf.file(site.id + ".md5")).strftime(DIFF_TIME_FMT)
475
321
  new_label = "NEW (%s)" % Time.now.strftime(DIFF_TIME_FMT)
476
322
 
477
- # do update
478
323
  site.hash, site.content = new_hash, new_content
479
324
 
480
325
  # diff between OLD and NEW
481
326
  diff = %x[diff -U 1 --label "#{old_label}" --label "#{new_label}" #{old_site_file.path} #{Conf.file(site.id + '.site')}]
482
327
  end
483
328
 
329
+ # HACK: there *was* an update but no notification is required
484
330
  return false if not Filter.accept(diff, site.filters)
485
331
 
486
- Mail.new(
487
- "[#{Conf[:tag]}] #{site.uri.host} changed",
488
- "Change at #{site.uri.to_s} - diff follows:\n\n#{diff}"
489
- ).send(site.emails) if Conf.send_mails?
332
+ 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}"
335
+
336
+ Conf.mailer.send(data, @@mail_plain, MailAddress.new(Conf[:from_mail]), site.emails)
490
337
 
491
338
  system("logger -t '#{Conf[:tag]}' 'Change at #{site.uri.to_s} (tag #{site.id}) detected'") if Conf[:syslog]
492
339
 
@@ -495,8 +342,13 @@ module WCC
495
342
 
496
343
  # main
497
344
  def self.run!
345
+ # first use of Conf initializes it
498
346
  WCC.logger = Logger.new(STDOUT)
499
347
 
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)
351
+
500
352
  Conf.sites.each do |site|
501
353
  if checkForUpdate(site)
502
354
  WCC.logger.warn "#{site.uri.host.to_s} has an update!"
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: 25
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 3
10
- version: 0.0.3
9
+ - 4
10
+ version: 0.0.4
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-01 00:00:00 Z
18
+ date: 2011-10-02 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: htmlentities
@@ -41,6 +41,10 @@ extra_rdoc_files: []
41
41
 
42
42
  files:
43
43
  - bin/wcc
44
+ - doc/Filters.md
45
+ - lib/wcc/filter.rb
46
+ - lib/wcc/mail.rb
47
+ - lib/wcc/site.rb
44
48
  - lib/wcc.rb
45
49
  - README.md
46
50
  homepage: https://github.com/cmur2/wcc