wcc-rss-notificator 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ wcc-rss-notificator
2
+ ===================
3
+
4
+ This adds Atom feed support to [wcc](https://github.com/cmur2/wcc) encapsulated
5
+ in a separate gem.
6
+
7
+ Note: Currently there is only one feed for all users/recipients.
8
+
9
+ What you need to add to your conf.yml:
10
+
11
+ conf:
12
+ [...]
13
+ # enable rss plugin
14
+ rss: {}
15
+
16
+ recipients:
17
+ [...]
18
+ - me:
19
+ [...]
20
+ # write updates to Atom feed
21
+ - rss:
22
+ # wcc needs write permission on this file/directory:
23
+ #file: <cache.d>/atom.xml
24
+ # mandatory option! - this allows you to use different
25
+ # (or same) databases for each recipient
26
+ db_name: me
27
+ # wcc will keep the N newest entries in your feed
28
+ #num_keep: 1000
29
+ feed:
30
+ # mandatory option! - Note that this is *NOT* your feed's
31
+ # url or something, this should be just an unique identifier:
32
+ id: http://www.example.com/my-feed/
33
+ #title: Your cool feed
34
+ #subtitle: About things
35
+ #link: # this now should be the feed's url
36
+ #alternate_link: # this may be a websites url (favicon comes from here)
@@ -0,0 +1,93 @@
1
+ <style type="text/css">
2
+ .msg {
3
+ font-size: 0.98em;
4
+ }
5
+
6
+ .diff {
7
+ font-size: 12px;
8
+ font-family: 'Bitstream Vera Sans Mono','Courier',monospace;
9
+ }
10
+
11
+ .diff ul {
12
+ list-style: none;
13
+ display: table;
14
+ padding: 0;
15
+ margin: 0.5em 0 0 0.5em;
16
+ border: 1px solid #CCCCCC;
17
+ }
18
+
19
+ .diff li {
20
+ padding: 0;
21
+ display: table-row;
22
+ margin: 0;
23
+ background: #f8f8ff;
24
+ }
25
+
26
+ .diff .new, .diff .old {
27
+ color: #999;
28
+ }
29
+
30
+ .diff .ins {
31
+ background: #dfd;
32
+ }
33
+
34
+ .diff .ins .x {
35
+ background: #8f8;
36
+ margin: 0;
37
+ padding: 0;
38
+ }
39
+
40
+ .diff .del {
41
+ background: #fdd;
42
+ }
43
+
44
+ .diff .del .x {
45
+ background: #faa;
46
+ margin: 0;
47
+ padding: 0;
48
+ }
49
+
50
+ .diff .range {
51
+ background: #eaf2f5;
52
+ color: #999;
53
+ }
54
+
55
+ .diff .other {
56
+ }
57
+ </style>
58
+
59
+ <% if data.diff.nil? %>
60
+ <div class="msg">
61
+ Checked <a href="<%= data.site.uri.to_s %>"><%= data.site.uri.to_s %></a> the first time so no diff was possible.
62
+ </div>
63
+ <% else %>
64
+ <div class="msg">
65
+ Change at <a href="<%= data.site.uri.to_s %>"><%= data.site.uri.to_s %></a> - diff follows:
66
+ </div>
67
+ <div class="diff">
68
+ <ul>
69
+ <% for o in data.diff.di %>
70
+ <% if o.status == :new %>
71
+ <li class="new">+++<%= o.text %></li>
72
+ <% elsif o.status == :old %>
73
+ <li class="old">---<%= o.text %></li>
74
+ <% elsif o.status == :range %>
75
+ <li class="range">@@<%= o.text %></li>
76
+ <% elsif o.status == :ins %>
77
+ <li class="ins">+&nbsp;<%= o.html_hilite_text('x').lstrip %></li>
78
+ <% elsif o.status == :del %>
79
+ <li class="del">-&nbsp;<%= o.html_hilite_text('x').lstrip %></li>
80
+ <% else %>
81
+ <li class="other">&nbsp;&nbsp;<%= o.text.substring(1).lstrip %></li>
82
+ <% end %>
83
+ <% end %>
84
+ </ul>
85
+ </div>
86
+ <div>
87
+ nHunks: <%= data.diff.nhunks %>,
88
+ nIns: <%= data.diff.ninsertions %>,
89
+ nDel: <%= data.diff.ndeletions %>,
90
+ nLinesC: <%= data.diff.nlinesc %>,
91
+ nCharsC: <%= data.diff.ncharsc %>
92
+ </div>
93
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= data.site.uri.host %> changed
@@ -0,0 +1,162 @@
1
+
2
+ require 'rss/maker'
3
+ require 'socket' # only for getting hostname
4
+ require 'yaml'
5
+
6
+ class RSSNotificator
7
+ @@tpl = {}
8
+ @@shutdown_hooks = []
9
+
10
+ # TODO: can we hook into --clean?
11
+
12
+ def initialize(opts)
13
+ @dirty = false
14
+ if opts.is_a?(Hash)
15
+ @file = opts['file'] || WCC::Conf.file("atom.xml")
16
+ @db_name = opts['db_name']
17
+ @num_keep = opts['num_keep'] || 1000
18
+ @feed = {}
19
+ if opts['feed'].is_a?(Hash)
20
+ @feed = {
21
+ :title => opts['feed']['title'] || "wcc Updates Feed - #{Socket.gethostname}",
22
+ :subtitle => opts['feed']['subtitle'] || "The newest changes to your watched sites.",
23
+ :link => opts['feed']['link'],
24
+ :alt_link => opts['feed']['alternate_link'],
25
+ :id => opts['feed']['id']
26
+ }
27
+ end
28
+ if @feed[:id].nil?
29
+ raise ArgumentError, "Missing atom feed ID!"
30
+ end
31
+ if @db_name.nil?
32
+ raise ArgumentError, "Missing db name for atom feed!"
33
+ end
34
+ else
35
+ raise ArgumentError, "No options given for 'rss:' way of a recipient! Need at least db name and feed id."
36
+ end
37
+ @@shutdown_hooks << self
38
+ end
39
+
40
+ def get_feeddb
41
+ if @feeddb.nil?
42
+ feeddb_file = WCC::Conf.file("feed-db-#{@db_name}.yml")
43
+ WCC.logger.debug "Loading feed-db '#{@db_name}' from file '#{feeddb_file}'"
44
+ if not File.exists?(feeddb_file)
45
+ WCC.logger.warn "Feed-db '#{@db_name}' does not exist, will create it on save in '#{feeddb_file}'"
46
+ @feeddb = {'feed' => []}
47
+ else
48
+ # may be false if file is empty
49
+ @feeddb = YAML.load_file(feeddb_file)
50
+ if not @feeddb.is_a?(Hash)
51
+ WCC.logger.warn "Feed-db '#{@db_name}' is corrupt, will overwrite it on save"
52
+ @feeddb = {'feed' => []}
53
+ end
54
+ end
55
+ end
56
+ @feeddb
57
+ end
58
+
59
+ def notify!(data)
60
+ title = self.class.get_tpl(:title, 'rss-title.plain.erb').result(binding)
61
+ # remove trailing whitespace introduced by template
62
+ title.strip!
63
+ content = self.class.get_tpl(:content, 'rss-content.html.erb').result(binding)
64
+ id = "#{@feed['id']}item/#{Time.now.to_f}"
65
+
66
+ # append entries to class variable (not thread safe)
67
+ @dirty = true
68
+ feed = get_feeddb['feed']
69
+ feed.insert 0, {
70
+ 'title' => title,
71
+ #'description' => '', # summary
72
+ 'content' => content,
73
+ 'link' => data.site.uri.to_s,
74
+ 'id' => id,
75
+ 'updated' => Time.now.to_s
76
+ }
77
+ end
78
+
79
+ def shut_down
80
+ return unless @dirty
81
+
82
+ WCC.logger.debug "Writing feed-db '#{@db_name}' to file"
83
+
84
+ feeddb_file = WCC::Conf.file("feed-db-#{@db_name}.yml")
85
+ feeddb = get_feeddb
86
+ # auto-purge
87
+ feeddb['feed'] = feeddb['feed'].slice(0, @num_keep)
88
+ File.open(feeddb_file, 'w+') do |f| YAML.dump(feeddb, f) end
89
+
90
+ WCC.logger.info "Generating feed '#{@file}'..."
91
+
92
+ content = RSS::Maker.make('atom') do |m|
93
+ m.channel.title = @feed[:title]
94
+ m.channel.subtitle = @feed[:subtitle]
95
+ m.channel.author = "web change checker (aka wcc) #{WCC::VERSION}"
96
+ if not @feed[:link].nil?
97
+ m.channel.links.new_link do |li|
98
+ li.rel = "self"
99
+ li.type = "application/atom+xml"
100
+ li.href = @feed[:link]
101
+ end
102
+ end
103
+ if not @feed[:alternate_link].nil?
104
+ m.channel.links.new_link do |li|
105
+ li.rel = "alternate"
106
+ li.type = "text/html"
107
+ li.href = @feed[:alternate_link]
108
+ end
109
+ end
110
+ m.channel.id = @feed[:id]
111
+ m.channel.updated = Time.now.to_s
112
+ m.items.do_sort = true # sort items by date
113
+
114
+ # feeddb-hash to atom
115
+ feeddb['feed'].each do |e|
116
+ m.items.new_item do |i|
117
+ i.title = e['title']
118
+ #i.description = e['description']
119
+ i.content.content = e['content']
120
+ i.content.type = "html"
121
+ i.author = "wcc"
122
+ if not e['link'].nil?
123
+ i.links.new_link do |li|
124
+ li.rel = "alternate"
125
+ li.type = "text/html"
126
+ li.href = e['link']
127
+ end
128
+ end
129
+ i.id = e['id']
130
+ i.updated = e['updated']
131
+ end
132
+ end
133
+ end
134
+
135
+ File.open(@file, 'w+') do |f| f.write(content.to_s) end
136
+ end
137
+
138
+ def self.parse_conf(conf); {} end
139
+
140
+ def self.shut_down
141
+ @@shutdown_hooks.each do |s| s.shut_down end
142
+ end
143
+
144
+ def self.get_tpl(id, name)
145
+ if @@tpl[id].nil?
146
+ @@tpl[id] = WCC::Prog.load_template(name)
147
+ if @@tpl[id].nil?
148
+ src_path = Pathname.new(__FILE__) + "../../assets/template.d/#{name}"
149
+ t = File.open(src_path, 'r') { |f| f.read }
150
+ WCC::Prog.save_template(name, t)
151
+ # retry load
152
+ @@tpl[id] = WCC::Prog.load_template(name)
153
+ end
154
+ if @@tpl[id].nil?
155
+ @@tpl[id] = ERB.new("ERROR LOADING TEMPLATE '#{name}'!", 0, "<>")
156
+ end
157
+ end
158
+ @@tpl[id]
159
+ end
160
+ end
161
+
162
+ WCC::Notificators.map "rss", RSSNotificator
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wcc-rss-notificator
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Christian Nicolai
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-03-25 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description:
22
+ email: chrnicolai@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - assets/template.d/rss-content.html.erb
31
+ - assets/template.d/rss-title.plain.erb
32
+ - lib/wcc-rss-notificator.rb
33
+ - README.md
34
+ homepage: https://github.com/cmur2/wcc-rss-notificator
35
+ licenses: []
36
+
37
+ post_install_message:
38
+ rdoc_options: []
39
+
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ hash: 3
48
+ segments:
49
+ - 0
50
+ version: "0"
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ requirements: []
61
+
62
+ rubyforge_project: wcc-rss-notificator
63
+ rubygems_version: 1.8.6
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: RSS feed notificator plugin for wcc
67
+ test_files: []
68
+