wcc 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -2,11 +2,11 @@ web change checker
2
2
  ==================
3
3
 
4
4
  This is a powerful ruby program to track changes of websites and get notified via mail on
5
- change with configurable scope of adresses per website. All mails contain a unified diff
5
+ change with configurable scope of addresses per website. All mails contain a unified diff
6
6
  from old content to new content so minor changes produce only few lines of text even on large sites.
7
7
 
8
8
  Since version 2.0 wcc has a completely rewritten notification system so emails are now only *one*
9
- way to recieve notifications - the currently supported other are XMPP/Jabber and the Syslog.
9
+ way to receive notifications - the currently supported other are XMPP/Jabber and the syslog.
10
10
  These changes are reflected in 'conf.yml' as well so take care of migrating it (that basically
11
11
  means to create a *recipients* section and update your site entries from *emails* to *notify*).
12
12
 
data/doc/Filters.md CHANGED
@@ -8,23 +8,23 @@ to notify the user (by email) or not.
8
8
  These Proc blocks get registered using `Filter.add` with a given ID (a
9
9
  string, not a :symbol to prevent some problems).
10
10
 
11
- wcc provides an autoloading mechanism that loads all ruby files contained in
11
+ wcc provides an auto-loading mechanism that loads all ruby files contained in
12
12
  a specific directory - the *filter.d* - via `require`. The filter file
13
13
  should contain some bootstrap code that may rely only on the *Filter* class
14
14
  out of wcc:
15
15
 
16
16
  Filter.add 'my_custom_id' do |data,arguments|
17
17
  # do your filter magic here
18
- # and return a boolean
18
+ # and return a Boolean
19
19
  end
20
20
 
21
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
22
+ containing all lines separated by newline of the unified diff (raw from Unix
23
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
24
+ the configuration file to parametrize the filter (e.g. ignoring all diffs
25
25
  shorter than let's say 10 lines).
26
26
 
27
- The output of this filter should be boolean true or false, indicating that
27
+ The output of this filter should be Boolean true or false, indicating that
28
28
  an email should be sent or not.
29
29
 
30
30
  In the configuration file a filter is referenced like this:
data/lib/wcc/mail.rb CHANGED
@@ -84,9 +84,10 @@ module WCC
84
84
  :smtp_port => conf['smtp']['port'] || 25
85
85
  }
86
86
  elsif conf['fake_file'].is_a?(Hash)
87
+ from_mail = MailAddress.new(conf['fake_file']['from'] || "#{Etc.getlogin}@localhost")
87
88
  return {
88
89
  :mailer => 'fake_file',
89
- :from_mail => conf['fake_file']['from'] || "#{Etc.getlogin}@localhost"
90
+ :from_mail => from_mail
90
91
  }
91
92
  end
92
93
  end
data/lib/wcc/site.rb CHANGED
@@ -55,13 +55,25 @@ module WCC
55
55
  end
56
56
 
57
57
  def fetch
58
- http = Net::HTTP.new(@uri.host, @uri.port)
59
- if @uri.is_a?(URI::HTTPS)
60
- http.use_ssl = true
61
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
58
+ retrieve(@uri)
59
+ end
60
+
61
+ def fetch_redirect(new_uri)
62
+ retrieve(new_uri)
63
+ end
64
+
65
+ private
66
+
67
+ def retrieve(uri)
68
+ con = Net::HTTP.new(uri.host, uri.port)
69
+ if uri.is_a?(URI::HTTPS)
70
+ con.use_ssl = true
71
+ con.verify_mode = OpenSSL::SSL::VERIFY_NONE
62
72
  end
63
- http.start do |http|
64
- req = Net::HTTP::Get.new(@uri.request_uri)
73
+ con.start do |http|
74
+ #http.open_timeout = 20
75
+ #http.read_timeout = 60
76
+ req = Net::HTTP::Get.new(uri.request_uri)
65
77
  if @auth['type'] == 'basic'
66
78
  WCC.logger.debug "Doing basic auth"
67
79
  req.basic_auth(@auth['username'], @auth['password'])
data/lib/wcc/syslog.rb CHANGED
@@ -1,11 +1,31 @@
1
1
 
2
2
  module WCC
3
3
  class SyslogNotificator
4
- def initialize
4
+
5
+ LEVELS = ['crit', 'emerg', 'alert', 'err', 'warning', 'notice', 'info', 'debug']
6
+
7
+ def initialize(opts)
8
+ if LEVELS.include?(opts)
9
+ @prio = opts
10
+ @enable = true
11
+ else
12
+ @enable = false
13
+ raise ArgumentError, "The given priority '#{opts}' is not known, use one of: #{LEVELS.join(', ')}."
14
+ end
15
+ begin
16
+ # from ruby std lib
17
+ require 'syslog'
18
+ rescue LoadError
19
+ @enable = false
20
+ raise ArgumentError, "Won't log to syslog since your system does NOT support syslog!"
21
+ end
5
22
  end
6
23
 
24
+ # TODO: ERB template for syslog
7
25
  def notify!(data)
8
- system("logger -t '#{data.tag}' 'Change at #{data.site.uri.to_s} (tag #{data.site.id}) detected'")
26
+ Syslog.open(data.tag, Syslog::LOG_PID | Syslog::LOG_CONS) do |s|
27
+ s.send(@prio.to_sym, "Change at #{data.site.uri.to_s} (tag #{data.site.id}) detected")
28
+ end if @enable
9
29
  end
10
30
 
11
31
  def self.parse_conf(conf); {} end
data/lib/wcc/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
 
2
2
  module WCC
3
- VERSION = "2.1.0"
3
+ VERSION = "2.2.0"
4
4
  end
data/lib/wcc.rb CHANGED
@@ -104,7 +104,7 @@ module WCC
104
104
  :cache_dir => '/var/tmp/wcc',
105
105
  :tag => 'wcc',
106
106
  :filter_dir => './filter.d',
107
- :template_dir => './template.d',
107
+ :template_dir => './template.d'
108
108
  }
109
109
  end
110
110
 
@@ -211,20 +211,9 @@ module WCC
211
211
  yaml_rec[name].to_a.each do |yaml_way|
212
212
  # TODO: find options and pass them to every notificator
213
213
  if yaml_way.is_a?(Hash)
214
- prim_key = yaml_way.keys.first # and only!
215
- klass = Notificators.mappings[prim_key]
216
- if klass.nil?
217
- WCC.logger.error "Referenced notificator '#{prim_key}' not found!"
218
- else
219
- rec << klass.new(yaml_way[prim_key])
220
- end
214
+ new_notificator(name, yaml_way.keys.first, yaml_way[yaml_way.keys.first], rec)
221
215
  else
222
- klass = Notificators.mappings[yaml_way]
223
- if klass.nil?
224
- WCC.logger.error "Referenced notificator '#{yaml_way}' not found!"
225
- else
226
- rec << klass.new
227
- end
216
+ new_notificator(name, yaml_way, nil, rec)
228
217
  end
229
218
  end
230
219
  @recipients[name] = rec
@@ -289,9 +278,26 @@ module WCC
289
278
  return Conf.instance.recipients
290
279
  end
291
280
 
292
- def self.file(path = nil) File.join(self[:cache_dir], path) end
281
+ def self.file(path = nil); File.join(self[:cache_dir], path) end
293
282
  def self.simulate?; self[:simulate] end
294
283
  def self.[](key); Conf.instance[key] end
284
+
285
+ private
286
+
287
+ def new_notificator(rec_name, not_name, opts, rec_out)
288
+ klass = Notificators.mappings[not_name]
289
+ if klass.nil?
290
+ WCC.logger.error "Referenced notificator '#{not_name}' not found!"
291
+ return
292
+ end
293
+ begin
294
+ if opts.nil?; rec_out << klass.new
295
+ else rec_out << klass.new(opts)
296
+ end
297
+ rescue => ex
298
+ WCC.logger.error "Recipient '#{rec_name}' not notifiable via '#{not_name}' (skip): #{ex}"
299
+ end
300
+ end
295
301
  end
296
302
 
297
303
  class Notificators
@@ -346,8 +352,44 @@ module WCC
346
352
  WCC.logger.error "Cannot connect to #{site.uri.to_s} : #{ex.to_s}"
347
353
  return false
348
354
  end
349
- if not res.kind_of?(Net::HTTPOK)
355
+ if res.kind_of?(Net::HTTPOK)
356
+ # be happy!
357
+ elsif res.kind_of?(Net::HTTPMovedPermanently)
358
+ loc = res['Location']
359
+ if loc.nil?
360
+ WCC.logger.error "Site #{site.uri.to_s} moved permanently, skippong it - no new location given."
361
+ else
362
+ WCC.logger.error "Site #{site.uri.to_s} moved permanently to '#{loc}', skipping it - please update your conf.yml adequately!"
363
+ end
364
+ return false
365
+ elsif res.kind_of?(Net::HTTPSeeOther) or res.kind_of?(Net::HTTPTemporaryRedirect)
366
+ loc = URI.parse(res['Location'])
367
+ WCC.logger.warn "Redirect: requesting '#{loc.to_s}'"
368
+ res = site.fetch_redirect(loc)
369
+ if not res.kind_of?(Net::HTTPOK)
370
+ WCC.logger.error "Redirected site #{loc.to_s} returned #{res.code} code, skipping it."
371
+ WCC.logger.error "Headers: #{res.to_hash.inspect}"
372
+ return false
373
+ end
374
+ elsif res.kind_of?(Net::HTTPUnauthorized)
375
+ WCC.logger.error "Site #{site.uri.to_s} demands authentication for '#{res['www-authenticate']}', skipping it - consider using 'auth:' option in your conf.yml."
376
+ return false
377
+ elsif res.kind_of?(Net::HTTPNotFound)
378
+ WCC.logger.error "Site #{site.uri.to_s} not found, skipping it."
379
+ return false
380
+ elsif res.kind_of?(Net::HTTPForbidden)
381
+ WCC.logger.error "Site #{site.uri.to_s} forbids access, skipping it."
382
+ return false
383
+ elsif res.kind_of?(Net::HTTPInternalServerError)
384
+ WCC.logger.error "Site #{site.uri.to_s} has internal errors, skipping it."
385
+ return false
386
+ elsif res.kind_of?(Net::HTTPServiceUnavailable)
387
+ #retry_after = res['Retry-After']
388
+ WCC.logger.warn "Site #{site.uri.to_s} currently not available, skipping it."
389
+ return false
390
+ else
350
391
  WCC.logger.error "Site #{site.uri.to_s} returned #{res.code} code, skipping it."
392
+ WCC.logger.error "Headers: #{res.to_hash.inspect}"
351
393
  return false
352
394
  end
353
395
 
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: 11
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 2
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 2.1.0
10
+ version: 2.2.0
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-11-09 00:00:00 Z
18
+ date: 2011-11-24 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: htmlentities