wcc 1.0.0 → 1.1.0

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
@@ -41,7 +41,7 @@ For using wcc you need to specify some options:
41
41
  * either via the command line (see `wcc -h`)
42
42
  * or in a configuration file in [YAML](https://secure.wikimedia.org/wikipedia/en/wiki/YAML) format
43
43
 
44
- The location of the configuration file (usually called 'conf.yml' or something like this)
44
+ The location of the configuration file (usually called 'conf.yml')
45
45
  can itself be given on command line as last argument. Each option has a hard-coded default
46
46
  (e.g. the configuration file name is assumed to be './conf.yml'). Command line options
47
47
  overwrite configuration file entries.
@@ -58,6 +58,24 @@ By default wcc only outputs ERROR and FATAL messages to avoid your cron daemon s
58
58
  It is recommended to place 'conf.yml' (and optionally the 'filter.d' and 'template.d') within
59
59
  a separate directory and use `cd` in cron entry.
60
60
 
61
+ Upgrade
62
+ -------
63
+
64
+ If you want to update your wcc run:
65
+
66
+ gem update
67
+
68
+ Then don't forget to run
69
+
70
+ wcc-upgrade
71
+
72
+ in your '/my/conf' directory which interactively asks to overwrite local 'assets'
73
+ like mail templates and filters with the original ones out of the gem (which you copied
74
+ there using ´wcc-init´ at the beginning).
75
+
76
+ NOTE: You should **make a backup** (especially of your **conf.yml**) of the '/my/conf'
77
+ directory **before upgrading**.
78
+
61
79
  License
62
80
  -------
63
81
 
data/assets/conf.yml CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  conf:
4
4
  from_addr: root@localhost
5
+ # # /var/tmp won't get ereased on restart!
5
6
  # cache_dir: /var/tmp/wcc
6
7
  # tag: wcc
7
8
  # use_syslog: yes
@@ -11,6 +12,9 @@ conf:
11
12
  # smtp:
12
13
  # host: localhost
13
14
  # port: 25
15
+ # ...or for TESTING purposes:
16
+ # email:
17
+ # fake_file
14
18
 
15
19
  sites:
16
20
  - url: http://google.com/
@@ -19,11 +23,19 @@ sites:
19
23
  - mail2@example.com
20
24
  filters:
21
25
  - test
22
- - arg-test: {number: 5}
26
+ - arg-test: {number: 5, hello: world}
27
+ - only_changes_of: {at_least: 4, t: lines}
28
+ # readable, isn't it?
23
29
  - url: https://my.secret.place/
24
30
  emails:
25
31
  - me@my.place
32
+ # only supports basic auth currently
26
33
  auth: {type: basic, username: me, password: secret}
27
34
  - url: http://your.cms.com/
28
35
  #emails: ...
36
+ # Don't add trailing newline just the pure bytes of your cookie
29
37
  cookie: file.cookie
38
+ - url: http://heavily.loaded.site/
39
+ # this will check at most every 30 minutes
40
+ # (or next time ´wcc´ gets called after 30mins passed)
41
+ check_interval: 30
@@ -1,8 +1,8 @@
1
1
 
2
- WCC::Filter.add 'arg-test' do |data,arguments|
2
+ WCC::Filters.add 'arg-test' do |data,args|
3
3
  puts "arg-test:"
4
- puts " #arguments = #{arguments.size}"
5
- arguments.each do |arg|
4
+ puts " #arguments = #{args.size}"
5
+ args.each do |arg|
6
6
  puts " - #{arg.inspect}"
7
7
  end
8
8
  true
@@ -0,0 +1,22 @@
1
+
2
+ WCC::Filters.add 'only_changes_of' do |data,args|
3
+ case args['t'] || args['type']
4
+ when 'lines',nil
5
+ cmp_val = data.diff.nlinesc
6
+ when 'chars'
7
+ cmp_val = data.diff.ncharsc
8
+ when 'ins','insertions'
9
+ cmp_val = data.diff.ninsertions
10
+ when 'del','deletions'
11
+ cmp_val = data.diff.ndeletions
12
+ when 'hunks'
13
+ cmp_val = data.diff.nhunks
14
+ end
15
+ next (cmp_val >= args['at_least']) if args.key?('at_least')
16
+ next (cmp_val > args['more_than']) if args.key?('more_than')
17
+ next (cmp_val <= args['at_most']) if args.key?('at_most')
18
+ next (cmp_val < args['fewer_then']) if args.key?('fewer_than')
19
+ next (cmp_val == args['exactly']) if args.key?('exactly')
20
+ next (cmp_val != args['not_quite']) if args.key('not_quite')
21
+ true
22
+ end
@@ -1,4 +1,4 @@
1
1
 
2
- WCC::Filter.add 'test' do |data|
2
+ WCC::Filters.add 'test' do |data|
3
3
  true
4
4
  end
@@ -87,6 +87,13 @@
87
87
  <% end %>
88
88
  </ul>
89
89
  </div>
90
+ <div>
91
+ nHunks: <%= data.diff.nhunks %>,
92
+ nIns: <%= data.diff.ninsertions %>,
93
+ nDel: <%= data.diff.ndeletions %>,
94
+ nLinesC: <%= data.diff.nlinesc %>,
95
+ nCharsC: <%= data.diff.ncharsc %>
96
+ </div>
90
97
  <% end %>
91
98
  </body>
92
99
  </html>
@@ -4,4 +4,6 @@ Checked <%= data.site.uri.to_s %> the first time so no diff was possible.
4
4
  Change at <%= data.site.uri.to_s %> - diff follows:
5
5
 
6
6
  <%= data.diff.to_s %>
7
+
8
+ nHunks: <%= data.diff.nhunks %>, nIns: <%= data.diff.ninsertions %>, nDel: <%= data.diff.ndeletions %>, nLinesC: <%= data.diff.nlinesc %>, nCharsC: <%= data.diff.ncharsc %>
7
9
  <% end %>
data/lib/wcc/diff.rb CHANGED
@@ -3,7 +3,8 @@ module WCC
3
3
  # TODO: Handle tabs/trailing whitespace in output
4
4
 
5
5
  class DiffItem
6
- attr_accessor :status, :text, :hilite
6
+ attr_reader :status, :text
7
+ attr_accessor :hilite
7
8
 
8
9
  def initialize(line)
9
10
  # parse line
@@ -125,6 +126,26 @@ module WCC
125
126
  end
126
127
  end
127
128
 
129
+ def nhunks
130
+ @di.inject(0) { |sum,o| sum += (o.status == :range ? 1 : 0) }
131
+ end
132
+
133
+ def ninsertions
134
+ @di.inject(0) { |sum,o| sum += (o.status == :ins ? 1 : 0) }
135
+ end
136
+
137
+ def ndeletions
138
+ @di.inject(0) { |sum,o| sum += (o.status == :del ? 1 : 0) }
139
+ end
140
+
141
+ def nlinesc
142
+ ninsertions + ndeletions
143
+ end
144
+
145
+ def ncharsc
146
+ @di.inject(0) { |sum,o| sum += (o.hilite.nil? ? 0 : o.hilite.nitems) }
147
+ end
148
+
128
149
  def rchar
129
150
  @di.map { |o| o.rchar }.join
130
151
  end
@@ -151,7 +172,7 @@ module WCC
151
172
  end
152
173
 
153
174
  def match(e)
154
- # don't care - this is called "diff" ;-)
175
+ # don't care
155
176
  end
156
177
 
157
178
  def discard_a(e)
data/lib/wcc/filter.rb CHANGED
@@ -11,7 +11,7 @@ module WCC
11
11
  def to_s; @id end
12
12
  end
13
13
 
14
- class Filter
14
+ class Filters
15
15
  @@filters = {}
16
16
 
17
17
  def self.add(id, &block)
data/lib/wcc/mail.rb CHANGED
@@ -41,6 +41,7 @@ module WCC
41
41
  # does plain SMTP to host:port using [Net::SMTP].
42
42
  class SmtpMailer
43
43
  def initialize(host, port)
44
+ WCC.logger.info "Send mail via SMTP to #{@host}:#{@port}"
44
45
  @host = host
45
46
  @port = port
46
47
  end
@@ -77,4 +78,36 @@ module WCC
77
78
  WCC.logger.fatal "Cannot send mails via SMTP to #{@host}:#{@port} : #{$!.to_s}"
78
79
  end
79
80
  end
81
+
82
+ # This "mailer" just dumps a mail's contents into eml files in the current
83
+ # working directory. This should be for TESTING ONLY as it doesn't
84
+ # take care of standards and stuff like that...
85
+ class FakeFileMailer
86
+ def initialize
87
+ WCC.logger.info "Write mail to eml-files in #{Dir.getwd}"
88
+ end
89
+
90
+ def send(data, main, bodies, from, tos = [])
91
+ # generate a boundary that may be used for multipart
92
+ data.boundary = "frontier-#{data.site.id}"
93
+ # generate messages
94
+ msgs = {}
95
+ tos.each do |to|
96
+ data.bodies = {}
97
+ # eval all body templates
98
+ bodies.each do |name,template|
99
+ data.bodies[name] = template.result(binding)
100
+ end
101
+ # eval main template
102
+ msgs[to] = main.result(binding)
103
+ end
104
+ # dump mails to eml-files
105
+ i = 0
106
+ msgs.each do |to,msg|
107
+ filename = "#{Time.new.strftime('%Y%m%d-%H%M%S')} to_#{i}.eml"
108
+ File.open(filename, 'w') { |f| f.write(msg) }
109
+ i += 1
110
+ end
111
+ end
112
+ end
80
113
  end
data/lib/wcc/site.rb CHANGED
@@ -1,15 +1,16 @@
1
1
 
2
2
  module WCC
3
3
  class Site
4
- attr_reader :uri, :emails, :filters, :auth, :cookie, :id
4
+ attr_reader :uri, :emails, :filters, :auth, :cookie, :check_interval, :id
5
5
 
6
- def initialize(url, strip_html, emails, filters, auth, cookie)
6
+ def initialize(url, strip_html, emails, filters, auth, cookie, check_interval)
7
7
  @uri = URI.parse(url)
8
8
  @strip_html = strip_html
9
9
  @emails = emails.is_a?(Array) ? emails : [emails]
10
10
  @filters = filters.is_a?(Array) ? filters : [filters]
11
11
  @auth = auth
12
12
  @cookie = cookie
13
+ @check_interval = check_interval
13
14
  @id = Digest::MD5.hexdigest(url.to_s)[0...8]
14
15
  # invalid hashes are ""
15
16
  load_hash
data/lib/wcc.rb CHANGED
@@ -45,7 +45,7 @@ end
45
45
 
46
46
  module WCC
47
47
 
48
- VERSION = "1.0.0"
48
+ VERSION = "1.1.0"
49
49
 
50
50
  DIFF_TIME_FMT = '%Y-%m-%d %H:%M:%S %Z'
51
51
 
@@ -154,6 +154,8 @@ module WCC
154
154
  # yaml parser should provide an integer here
155
155
  @options[:smtp_port] ||= yaml['email']['smtp']['port']
156
156
  end
157
+ elsif yaml['email'] == 'fake_file'
158
+ @options[:mailer] = 'fake_file'
157
159
  end
158
160
  end
159
161
 
@@ -183,7 +185,7 @@ module WCC
183
185
  Dir[File.join(self[:filter_dir], '*.rb')].each { |file| require file }
184
186
 
185
187
  # attach --no-mails filter
186
- WCC::Filter.add '--no-mails' do |data|
188
+ WCC::Filters.add '--no-mails' do |data|
187
189
  !self[:nomails]
188
190
  end
189
191
  end
@@ -227,7 +229,8 @@ module WCC
227
229
  yaml_site['emails'].map { |m| MailAddress.new(m) } || [],
228
230
  frefs,
229
231
  yaml_site['auth'] || {},
230
- cookie)
232
+ cookie,
233
+ yaml_site['check_interval'] || 5)
231
234
  end
232
235
 
233
236
  WCC.logger.debug @sites.length.to_s + (@sites.length == 1 ? ' site' : ' sites') + " loaded\n" +
@@ -242,6 +245,8 @@ module WCC
242
245
  # smtp mailer
243
246
  if Conf[:mailer] == 'smtp'
244
247
  @mailer = SmtpMailer.new(Conf[:smtp_host], Conf[:smtp_port])
248
+ elsif Conf[:mailer] == 'fake_file'
249
+ @mailer = FakeFileMailer.new
245
250
  end
246
251
 
247
252
  @mailer
@@ -341,17 +346,18 @@ module WCC
341
346
  diff = %x[diff -U 1 --label "#{old_label}" --label "#{new_label}" #{old_site_file.path} #{Conf.file(site.id + '.site')}]
342
347
  end
343
348
 
344
- # HACK: there *was* an update but no notification is required
345
- return false if not Filter.accept(diff, site.filters)
349
+ system("logger -t '#{Conf[:tag]}' 'Change at #{site.uri.to_s} (tag #{site.id}) detected'") if Conf[:syslog]
346
350
 
351
+ # construct the data made available to filters and templates
347
352
  data = OpenStruct.new
348
353
  data.site = site
349
354
  data.diff = diff.nil? ? nil : WCC::Differ.new(diff)
350
355
  data.tag = Conf[:tag]
351
356
 
352
- Conf.mailer.send(data, @@mail_plain, @@mail_bodies, MailAddress.new(Conf[:from_mail]), site.emails)
357
+ # HACK: there *was* an update but no notification is required
358
+ return false if not Filters.accept(data, site.filters)
353
359
 
354
- system("logger -t '#{Conf[:tag]}' 'Change at #{site.uri.to_s} (tag #{site.id}) detected'") if Conf[:syslog]
360
+ Conf.mailer.send(data, @@mail_plain, @@mail_bodies, MailAddress.new(Conf[:from_mail]), site.emails)
355
361
 
356
362
  true
357
363
  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: 23
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
+ - 1
8
9
  - 0
9
- - 0
10
- version: 1.0.0
10
+ version: 1.1.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-10-10 00:00:00 Z
18
+ date: 2011-10-12 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: htmlentities
@@ -59,6 +59,7 @@ extra_rdoc_files:
59
59
  files:
60
60
  - assets/conf.yml
61
61
  - assets/filter.d/arg-test.rb
62
+ - assets/filter.d/only_changes_of.rb
62
63
  - assets/filter.d/test.rb
63
64
  - assets/template.d/mail.alt.erb
64
65
  - assets/template.d/mail-body.html.erb
@@ -78,7 +79,7 @@ files:
78
79
  homepage: https://github.com/cmur2/wcc
79
80
  licenses:
80
81
  - Apache License Version 2.0
81
- post_install_message:
82
+ post_install_message: "NOTE: Remember to \xC2\xB4wcc-upgrade\xC2\xB4 your conf.yml directory!"
82
83
  rdoc_options: []
83
84
 
84
85
  require_paths: