herald 0.2 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/.gitignore +1 -0
- data/History.txt +18 -0
- data/README.md +48 -17
- data/TODO.txt +5 -8
- data/bin/herald +31 -0
- data/herald.gemspec +5 -5
- data/lib/herald.rb +37 -44
- data/lib/herald/batch.rb +55 -0
- data/lib/herald/command.rb +21 -0
- data/lib/herald/daemon.rb +122 -0
- data/lib/herald/notifiers/stdout.rb +1 -1
- data/lib/herald/version.rb +1 -1
- data/lib/herald/watcher.rb +3 -0
- data/test/herald_test.rb +60 -12
- metadata +28 -12
- data/lib/herald/untitled.txt +0 -5
data/.gemtest
ADDED
File without changes
|
data/.gitignore
CHANGED
data/History.txt
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
=== HEAD (unreleased as a gem)
|
2
|
+
|
3
|
+
* None
|
4
|
+
|
5
|
+
=== 0.3 / 2011-05-09
|
6
|
+
|
7
|
+
* Major Enhancements
|
8
|
+
* Added Herald::Daemon, Herald#daemonize! and Herald#kill
|
9
|
+
* Added herald executable
|
10
|
+
|
11
|
+
* Minor Enhancements
|
12
|
+
* Added Herald#delete, Herald#size, updated Herald#heralds
|
13
|
+
|
14
|
+
=== 0.2 / 2011-05-02
|
15
|
+
|
16
|
+
* Major Enhancements
|
17
|
+
* Added Ping, Post Notifiers
|
18
|
+
* Added Webite Watcher
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Herald
|
2
2
|
====
|
3
3
|
|
4
|
-
Herald is a simple notifier for Twitter and RSS.
|
4
|
+
Herald is a simple and flexible notifier for Twitter and RSS.
|
5
5
|
|
6
6
|
Pass Herald some keywords and sources to watch, and Herald will notify you using Growl, pinging or posting to a site, or running Ruby code as soon as those keywords appear.
|
7
7
|
|
@@ -16,7 +16,7 @@ Installation
|
|
16
16
|
|
17
17
|
git clone git://github.com/lukes/herald.git
|
18
18
|
gem build herald.gemspec
|
19
|
-
gem install herald-0.
|
19
|
+
gem install herald-0.3.gem
|
20
20
|
|
21
21
|
Usage
|
22
22
|
-----
|
@@ -60,7 +60,7 @@ Watching two RSS feeds and Twitter for two keywords
|
|
60
60
|
Or, if sources should have different keywords
|
61
61
|
|
62
62
|
Herald.watch do
|
63
|
-
check :rss, :from => "http://earthquake.usgs.gov/earthquakes/catalogs/eqs1day-M0.xml"
|
63
|
+
check :rss, :from => "http://earthquake.usgs.gov/earthquakes/catalogs/eqs1day-M0.xml" do
|
64
64
|
_for "christchurch"
|
65
65
|
end
|
66
66
|
check :twitter do
|
@@ -102,7 +102,7 @@ To post information about what Herald finds to a URI, pass Herald `action :post,
|
|
102
102
|
_for "vanity", "tweeting"
|
103
103
|
action :post, :uri => "http://twitter-loves-me.com/post"
|
104
104
|
end
|
105
|
-
|
105
|
+
|
106
106
|
#### Callbacks
|
107
107
|
|
108
108
|
If you'd like to do your own thing entirely each time a keyword appears, pass a callback in the form of a Ruby block
|
@@ -113,7 +113,6 @@ If you'd like to do your own thing entirely each time a keyword appears, pass a
|
|
113
113
|
`say "Viva!"`
|
114
114
|
end
|
115
115
|
end
|
116
|
-
|
117
116
|
|
118
117
|
Pass the callback a parameter to be given a `Herald::Item` object within your block. The object makes available everything Herald could find in the source.
|
119
118
|
|
@@ -124,6 +123,15 @@ Pass the callback a parameter to be given a `Herald::Item` object within your bl
|
|
124
123
|
end
|
125
124
|
end
|
126
125
|
|
126
|
+
#### Stdout
|
127
|
+
|
128
|
+
To print information about what Herald finds, pass Herald `action :stdout`. To save results to a file, include the parameter `:file => "log.txt"`
|
129
|
+
|
130
|
+
Herald.watch_twitter do
|
131
|
+
_for "newsworthy", "topic"
|
132
|
+
action :stdout, :file => "log.txt"
|
133
|
+
end
|
134
|
+
|
127
135
|
### Timer
|
128
136
|
|
129
137
|
By default Herald will sleep for 1 minute after checking each of the sources independently.
|
@@ -161,11 +169,21 @@ Start a second herald
|
|
161
169
|
|
162
170
|
Use the `Herald` class methods to inspect and edit your heralds as a batch
|
163
171
|
|
164
|
-
Herald.heralds # prints all running
|
165
|
-
Herald.
|
166
|
-
Herald.
|
172
|
+
Herald.heralds # prints all heralds (running and stopped)
|
173
|
+
Herald.heralds(:alive) # prints all running heralds
|
174
|
+
Herald.heralds(:stopped) # prints all stopped heralds
|
175
|
+
|
176
|
+
Herald.stop # stop all heralds
|
177
|
+
Herald.alive? # => true if any heralds are running
|
167
178
|
Herald.start # all heralds restarted
|
168
|
-
|
179
|
+
|
180
|
+
Herald.delete(herald) # remove this herald from the Herald.heralds list
|
181
|
+
Herald.delete(:stopped) # remove stopped heralds from Herald.heralds list
|
182
|
+
|
183
|
+
Herald.size # prints number of heralds
|
184
|
+
Herald.size(:alive) # prints number of running heralds
|
185
|
+
Herald.size(:stopped) # prints number of stopped heralds
|
186
|
+
|
169
187
|
### Look once
|
170
188
|
|
171
189
|
Rather than watching, if you just want to get a single poll of keywords, use `once()`. All the same parameters as with `watch()` can be used (`every` will be ignored)
|
@@ -180,7 +198,7 @@ As with watching, Herald will fork a new process (or one for every source you're
|
|
180
198
|
herald.start # waiting ... process ends at the same time you receive your notifications
|
181
199
|
herald.alive? # => false
|
182
200
|
|
183
|
-
###
|
201
|
+
### Callback scope and Herald metaprogramming
|
184
202
|
|
185
203
|
Callbacks allow a great deal of reflection into the internals of Herald.
|
186
204
|
|
@@ -203,12 +221,25 @@ If passed in within the scope of `Herald::Watcher` (`action` agents), it will ha
|
|
203
221
|
end
|
204
222
|
end
|
205
223
|
end
|
224
|
+
|
225
|
+
### Running Herald as a script
|
226
|
+
|
227
|
+
Herald cleans up after itself by killing any running herald processes on exit.
|
228
|
+
|
229
|
+
To instead have Herald run forever, add this to the end of your script
|
230
|
+
|
231
|
+
Herald.daemonize!
|
232
|
+
|
233
|
+
`daemonize!` cuts the apron strings, and once set, your heralds will run forever.
|
206
234
|
|
207
|
-
|
235
|
+
Use the Herald executable below when you wish to stop your free-spirited heralds.
|
208
236
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
herald -
|
214
|
-
|
237
|
+
### Herald executable
|
238
|
+
|
239
|
+
Print IDs of any running heralds
|
240
|
+
|
241
|
+
sudo herald --show-heralds
|
242
|
+
|
243
|
+
Pass the ID to the `kill` command to stop it running
|
244
|
+
|
245
|
+
sudo herald --kill 1
|
data/TODO.txt
CHANGED
@@ -1,14 +1,11 @@
|
|
1
|
-
- Catch and report on exceptions in @@subprocess, or thread, when exception has killed a @@subprocess, remove it from @@subprocess
|
2
|
-
|
3
|
-
- Best way to require gems? Can I vendorise crack gem?
|
4
|
-
|
5
1
|
- Comment in RDOC
|
6
2
|
|
7
3
|
- Handle exceptions in processes, by reporting the error, then set the @subprocess to nil
|
8
4
|
|
9
|
-
- Look at Gemspec
|
10
|
-
- Show dependency on ruby-growl if installed for mac
|
11
|
-
|
12
5
|
- Growl icon
|
13
6
|
|
14
|
-
- Custom Error classes
|
7
|
+
- Custom Error classes
|
8
|
+
|
9
|
+
- Serialize heralds in Herald::Daemon as YAML herald.to_s: pid
|
10
|
+
|
11
|
+
- Add support for linux and windows versions of growl
|
data/bin/herald
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
|
4
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'herald'
|
7
|
+
require 'herald/version'
|
8
|
+
require 'herald/command'
|
9
|
+
require 'slop'
|
10
|
+
|
11
|
+
class Herald
|
12
|
+
extend Herald::Daemon
|
13
|
+
end
|
14
|
+
|
15
|
+
opts = Slop.parse do
|
16
|
+
on :V, :version, 'Print the version' do
|
17
|
+
puts "Version #{Herald::VERSION}"
|
18
|
+
end
|
19
|
+
on :s, :"show-heralds", 'Show all running heralds'
|
20
|
+
on :k, :kill, 'Kill the herald', :as => :integer, :optional => true
|
21
|
+
on :h, :help, "Show this message"
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.banner = "Usage: herald [options]"
|
25
|
+
|
26
|
+
if opts[:help] || ARGV.empty?
|
27
|
+
puts opts.help
|
28
|
+
exit
|
29
|
+
end
|
30
|
+
|
31
|
+
Herald::Command.run(opts)
|
data/herald.gemspec
CHANGED
@@ -9,18 +9,19 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ["Luke Duncalfe"]
|
10
10
|
s.email = ["lduncalfe@eml.cc"]
|
11
11
|
s.homepage = "http://github.com/lukes/herald"
|
12
|
-
s.summary = %q{A simple notifier for Twitter, RSS, or email}
|
12
|
+
s.summary = %q{A simple and flexible notifier for Twitter, RSS, or email}
|
13
13
|
s.description = %q{A simple and flexible notifier for Twitter, RSS, or email}
|
14
14
|
|
15
15
|
# s.required_rubygems_version = ">= 1.3.6" # TODO test earliest dependency
|
16
16
|
s.add_development_dependency("minitest")
|
17
17
|
s.add_dependency("crack")
|
18
|
-
s.add_dependency("
|
18
|
+
s.add_dependency("slop")
|
19
|
+
s.add_dependency("hpricot", ">= 0.8")
|
19
20
|
# if gem is being installed on a mac, add a dependency on ruby-growl.
|
20
21
|
# note, this is not a fool-proof method of detecting the OS,
|
21
22
|
# apparently if return "java" if platform is JRuby
|
22
23
|
if RUBY_PLATFORM.downcase.include?("darwin")
|
23
|
-
s.add_dependency("ruby-growl", "
|
24
|
+
s.add_dependency("ruby-growl", ">= 2.1")
|
24
25
|
end
|
25
26
|
|
26
27
|
s.rubyforge_project = "herald"
|
@@ -28,7 +29,6 @@ Gem::Specification.new do |s|
|
|
28
29
|
|
29
30
|
s.files = `git ls-files`.split("\n")
|
30
31
|
s.test_files = `git ls-files -- test/*`.split("\n")
|
31
|
-
|
32
|
-
# s.default_executable = "herald"
|
32
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
33
33
|
s.require_paths = ["lib"]
|
34
34
|
end
|
data/lib/herald.rb
CHANGED
@@ -4,12 +4,17 @@ require 'herald/watcher'
|
|
4
4
|
require 'herald/notifier'
|
5
5
|
require 'herald/notifiers/stdout'
|
6
6
|
require 'herald/item'
|
7
|
+
require 'herald/batch'
|
8
|
+
require 'herald/daemon'
|
7
9
|
|
8
10
|
class Herald
|
9
11
|
|
10
12
|
@@heralds = []
|
13
|
+
@@daemon = false
|
11
14
|
|
12
15
|
attr_accessor :watchers, :keep_alive, :subprocess
|
16
|
+
extend Herald::Batch
|
17
|
+
extend Herald::Daemon
|
13
18
|
|
14
19
|
def self.watch(&block)
|
15
20
|
new(&block).start
|
@@ -32,45 +37,32 @@ class Herald
|
|
32
37
|
def self.watch_website(options = {}, &block)
|
33
38
|
watch() { check(:website, options, &block) }
|
34
39
|
end
|
35
|
-
|
36
|
-
#
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
40
|
+
|
41
|
+
# returns @@heralds
|
42
|
+
# can optionally take :alive or :stopped
|
43
|
+
def self.heralds(obj = nil)
|
44
|
+
if !obj.nil? && obj.respond_to?(:to_sym)
|
45
|
+
case obj.to_sym
|
46
|
+
when :stopped
|
47
|
+
return @@heralds.select { |h| !h.alive? }
|
48
|
+
when :alive
|
49
|
+
return @@heralds.select { |h| h.alive? }
|
50
|
+
end
|
51
|
+
# if obj is not :stopped or :alive
|
52
|
+
raise ArgumentError.new("Unknown parameter #{obj}")
|
41
53
|
end
|
42
|
-
|
54
|
+
@@heralds
|
43
55
|
end
|
44
56
|
|
45
|
-
def self.
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
true
|
51
|
-
end
|
52
|
-
|
53
|
-
# stop all heralds, and remove them
|
54
|
-
# from list of herald instances. mostly
|
55
|
-
# useful for clearing @@heralds when testing
|
56
|
-
def self.clear
|
57
|
-
stop()
|
58
|
-
@@heralds.clear
|
59
|
-
true
|
60
|
-
end
|
61
|
-
|
62
|
-
# just walk away, leaving whatever strays to themselves
|
63
|
-
def self.demonize!
|
64
|
-
@@heralds.clear
|
65
|
-
true
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.alive?
|
69
|
-
@@heralds.any? { |h| h.alive? }
|
57
|
+
def self.daemonize!
|
58
|
+
@@daemon = true
|
59
|
+
serialize_daemons()
|
60
|
+
puts "(Herald is now running in the background)\n"
|
61
|
+
self
|
70
62
|
end
|
71
63
|
|
72
|
-
def self.
|
73
|
-
@@
|
64
|
+
def self.is_daemon?
|
65
|
+
@@daemon
|
74
66
|
end
|
75
67
|
|
76
68
|
#
|
@@ -135,6 +127,8 @@ class Herald
|
|
135
127
|
Thread.list.each do |thread|
|
136
128
|
thread.join unless thread == Thread.main
|
137
129
|
end
|
130
|
+
# give this process a name
|
131
|
+
$0 = "ruby herald"
|
138
132
|
}
|
139
133
|
# if herald process is persistant
|
140
134
|
if @keep_alive
|
@@ -153,6 +147,7 @@ class Herald
|
|
153
147
|
end
|
154
148
|
@subprocess = nil # signal unalive state
|
155
149
|
end
|
150
|
+
Herald.serialize_daemons
|
156
151
|
self # return instance object
|
157
152
|
end
|
158
153
|
|
@@ -161,20 +156,18 @@ class Herald
|
|
161
156
|
# look at GOD
|
162
157
|
def stop
|
163
158
|
if @subprocess
|
164
|
-
|
165
|
-
Process.kill("TERM", @subprocess)
|
166
|
-
# if @subprocess PID does not exist,
|
167
|
-
# this will be due to an error in the subprocess
|
168
|
-
# which has terminated it
|
169
|
-
rescue Errno::ESRCH => e
|
170
|
-
# do nothing
|
171
|
-
end
|
159
|
+
Herald.kill(@subprocess)
|
172
160
|
end
|
173
161
|
@subprocess = nil
|
174
162
|
self
|
175
163
|
end
|
176
164
|
alias :end :stop
|
177
|
-
|
165
|
+
|
166
|
+
def delete
|
167
|
+
stop if alive?
|
168
|
+
@@heralds.delete(self)
|
169
|
+
true
|
170
|
+
end
|
178
171
|
|
179
172
|
def alive?
|
180
173
|
!!@subprocess
|
@@ -194,5 +187,5 @@ end
|
|
194
187
|
|
195
188
|
# queue a block to always stop all forked processes on exit
|
196
189
|
at_exit do
|
197
|
-
Herald.stop
|
190
|
+
Herald.stop unless Herald.is_daemon?
|
198
191
|
end
|
data/lib/herald/batch.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
class Herald
|
2
|
+
|
3
|
+
# batch methods
|
4
|
+
module Batch
|
5
|
+
|
6
|
+
def start
|
7
|
+
heralds.each do |herald|
|
8
|
+
herald.start
|
9
|
+
end
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def stop
|
14
|
+
heralds.each do |herald|
|
15
|
+
herald.stop
|
16
|
+
end
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
# stop all heralds, and remove them
|
21
|
+
# from list of herald instances. mostly
|
22
|
+
# useful for clearing @@heralds when testing
|
23
|
+
def clear
|
24
|
+
stop()
|
25
|
+
heralds.clear
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def alive?
|
30
|
+
heralds.any? { |h| h.alive? }
|
31
|
+
end
|
32
|
+
|
33
|
+
# returns size of @@heralds
|
34
|
+
# can optionally take :alive or :stopped
|
35
|
+
def size(obj = nil)
|
36
|
+
heralds(obj).size
|
37
|
+
end
|
38
|
+
|
39
|
+
# can optionally take a herald object or :stopped
|
40
|
+
def delete(obj = nil)
|
41
|
+
case
|
42
|
+
when obj.is_a?(Herald)
|
43
|
+
Array(obj)
|
44
|
+
else
|
45
|
+
heralds(obj)
|
46
|
+
# with the selected array of heralds
|
47
|
+
end.each do |h|
|
48
|
+
h.delete # call each herald's delete method
|
49
|
+
end
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Herald
|
2
|
+
|
3
|
+
class Command
|
4
|
+
|
5
|
+
def self.run(opts)
|
6
|
+
# show running heralds and exit
|
7
|
+
if opts[:"show-heralds"]
|
8
|
+
puts Herald.running_daemons
|
9
|
+
exit
|
10
|
+
end
|
11
|
+
# kill a herald and exit
|
12
|
+
if pid = opts[:kill]
|
13
|
+
Herald.kill(pid)
|
14
|
+
puts "Herald #{pid} killed"
|
15
|
+
exit
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
class Herald
|
2
|
+
|
3
|
+
module Daemon
|
4
|
+
|
5
|
+
#
|
6
|
+
# module methods:
|
7
|
+
#
|
8
|
+
|
9
|
+
# TODO turn this into pid_file and initialize on extended
|
10
|
+
@@pid_dir = nil
|
11
|
+
|
12
|
+
def self.extended(base)
|
13
|
+
unless File.exists?(pid_file)
|
14
|
+
require 'fileutils'
|
15
|
+
FileUtils.touch(pid_file)
|
16
|
+
File.chmod(0777, pid_file)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# returns location of writable .herald.pids file
|
21
|
+
# used to serialize daemons
|
22
|
+
def self.pid_file
|
23
|
+
@@pid_dir ||= begin
|
24
|
+
# select lastest installed herald gem location
|
25
|
+
if herald_gem_dir = Dir["#{Gem.dir}/gems/herald*"].last
|
26
|
+
"#{herald_gem_dir}/"
|
27
|
+
else
|
28
|
+
""
|
29
|
+
end
|
30
|
+
end
|
31
|
+
"#{@@pid_dir}.herald.pids"
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# mixin methods:
|
36
|
+
#
|
37
|
+
|
38
|
+
# kill can be passed :all, a pid, an array of pids, or a herald
|
39
|
+
def kill(obj)
|
40
|
+
pids = case
|
41
|
+
when obj == :all
|
42
|
+
serialized_daemons
|
43
|
+
when obj.is_a?(String) || obj.is_a?(Fixnum)
|
44
|
+
Array(obj)
|
45
|
+
when obj.is_a?(Array)
|
46
|
+
obj
|
47
|
+
when obj.is_a?(Herald)
|
48
|
+
Array(obj.subprocess)
|
49
|
+
else
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
if pids.nil?
|
53
|
+
raise ArgumentError.new("Unknown parameter #{obj}")
|
54
|
+
end
|
55
|
+
pids.each do |pid|
|
56
|
+
begin
|
57
|
+
Process.kill("TERM", pid.to_i)
|
58
|
+
# if @subprocess PID does not exist,
|
59
|
+
# this will be due to an error in the subprocess
|
60
|
+
# which has terminated it
|
61
|
+
rescue Errno::ESRCH => e
|
62
|
+
# do nothing
|
63
|
+
end
|
64
|
+
end
|
65
|
+
delete_daemons(pids)
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
# returns serialized daemons in .herald.pids and any unserialized ones
|
70
|
+
def running_daemons
|
71
|
+
daemons = (heralds.map{ |h| h.subprocess } + serialized_daemons).uniq
|
72
|
+
# whittle out any process that no longer exist
|
73
|
+
daemons.delete_if do |pid|
|
74
|
+
begin
|
75
|
+
Process.getpgid(pid.to_i)
|
76
|
+
false
|
77
|
+
rescue Errno::ESRCH => e
|
78
|
+
true
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# will serialize all daemons (running in this Ruby session
|
84
|
+
# plus any existing ones in the file).
|
85
|
+
# optionally can be passed a list of pids, in which case
|
86
|
+
# only these will be serialize
|
87
|
+
def serialize_daemons(daemons = nil)
|
88
|
+
# write file, truncating existing file to zero length
|
89
|
+
string = running_daemons.join("\n")
|
90
|
+
File.open(Herald::Daemon.pid_file, 'w') do |f|
|
91
|
+
f.write(string)
|
92
|
+
end
|
93
|
+
self
|
94
|
+
end
|
95
|
+
|
96
|
+
# returns pids from .herald.pids file
|
97
|
+
# TODO make this thread safe
|
98
|
+
def serialized_daemons
|
99
|
+
# open pid_file
|
100
|
+
File.open(Herald::Daemon.pid_file, 'r') do |f|
|
101
|
+
# read file, and map to an array of integers
|
102
|
+
f.read.split("\n").map do |d|
|
103
|
+
next unless d.match(/^\d+\Z/)
|
104
|
+
d.to_i
|
105
|
+
end.compact
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# deletes given pids from file
|
110
|
+
def delete_daemons(pids)
|
111
|
+
pids.map! { |pid| pid.to_i }
|
112
|
+
lines = File.readlines(Herald::Daemon.pid_file)
|
113
|
+
lines.delete_if { |line| pids.include?(line.to_i) }
|
114
|
+
File.open(Herald::Daemon.pid_file, 'w') do |f|
|
115
|
+
f.write(lines)
|
116
|
+
end
|
117
|
+
self
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
data/lib/herald/version.rb
CHANGED
data/lib/herald/watcher.rb
CHANGED
data/test/herald_test.rb
CHANGED
@@ -8,7 +8,7 @@ describe Herald do
|
|
8
8
|
after do
|
9
9
|
Herald.clear
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
describe "initialisation with watchers" do
|
13
13
|
it "must throw an acception if no 'check' param is given" do
|
14
14
|
assert_raises(RuntimeError) do
|
@@ -61,6 +61,13 @@ describe Herald do
|
|
61
61
|
herald.watchers.first.keywords.to_s.must_equal(keywords.to_s)
|
62
62
|
end
|
63
63
|
end
|
64
|
+
|
65
|
+
describe "delete herald" do
|
66
|
+
it "should allow itself to be deleted" do
|
67
|
+
@herald.delete
|
68
|
+
Herald.size.must_equal(0)
|
69
|
+
end
|
70
|
+
end
|
64
71
|
|
65
72
|
describe "initialisation with actions" do
|
66
73
|
it "should assign stdout as the default Notifier" do
|
@@ -70,27 +77,43 @@ describe Herald do
|
|
70
77
|
end
|
71
78
|
|
72
79
|
describe "Herald class methods (stop, start, alive?) must allow batch operations" do
|
73
|
-
it "must return array of
|
80
|
+
it "must return array of heralds" do
|
74
81
|
Herald.heralds.must_be_kind_of(Array)
|
75
82
|
Herald.heralds.size.must_equal(1)
|
76
83
|
Herald.heralds.first.must_be_kind_of(Herald)
|
77
84
|
herald_2 = Herald.watch { check :twitter; _for "test" }
|
85
|
+
herald_2.stop
|
78
86
|
Herald.heralds.size.must_equal(2)
|
87
|
+
Herald.heralds(:stopped).size.must_equal(1)
|
88
|
+
Herald.heralds(:alive).size.must_equal(1)
|
79
89
|
end
|
80
|
-
it "must
|
81
|
-
Herald.
|
90
|
+
it "must allow heralds to be deleted by passing delete and herald object" do
|
91
|
+
Herald.heralds.size.must_equal(1)
|
92
|
+
Herald.delete(@herald)
|
93
|
+
Herald.size.must_equal(0)
|
82
94
|
end
|
83
|
-
it "must allow heralds to be
|
84
|
-
Herald.
|
95
|
+
it "must allow all stopped heralds to be deleted" do
|
96
|
+
Herald.size.must_equal(1)
|
97
|
+
Herald.delete(:stopped).size.must_equal(1)
|
98
|
+
@herald.stop
|
99
|
+
Herald.delete(:stopped).size.must_equal(0)
|
85
100
|
end
|
86
|
-
it "
|
87
|
-
Herald.stop
|
101
|
+
it "size() must return size of @@heralds" do
|
88
102
|
Herald.heralds.size.must_equal(1)
|
89
|
-
Herald.
|
103
|
+
herald_2 = Herald.watch { check :twitter; _for "test" }
|
104
|
+
herald_2.stop
|
105
|
+
Herald.size.must_equal(2)
|
106
|
+
Herald.size(:stopped).must_equal(1)
|
107
|
+
Herald.size(:alive).must_equal(1)
|
90
108
|
end
|
91
|
-
it "must report
|
92
|
-
Herald.
|
93
|
-
|
109
|
+
it "must report on if there are any heralds alive" do
|
110
|
+
Herald.alive?.must_equal(true)
|
111
|
+
end
|
112
|
+
it "must allow heralds to be stopped" do
|
113
|
+
Herald.size(:alive).must_equal(1)
|
114
|
+
Herald.stop.must_equal(Herald)
|
115
|
+
Herald.size(:alive).must_equal(0)
|
116
|
+
Herald.size(:stopped).must_equal(1)
|
94
117
|
end
|
95
118
|
it "must allow heralds to be restarted" do
|
96
119
|
Herald.stop
|
@@ -100,5 +123,30 @@ describe Herald do
|
|
100
123
|
|
101
124
|
end
|
102
125
|
|
126
|
+
describe "Must allow running as a daemon, with methods to control processes" do
|
127
|
+
it "must determine a location to write the pid file to" do
|
128
|
+
Herald::Daemon.pid_file.must_match(/\.herald\.pids\Z/)
|
129
|
+
File.writable?(Herald::Daemon.pid_file).must_equal(true)
|
130
|
+
end
|
131
|
+
it "must allow Herald to be daemonized" do
|
132
|
+
Herald.is_daemon?.must_equal(false)
|
133
|
+
Herald.daemonize!.must_equal(Herald)
|
134
|
+
Herald.is_daemon?.must_equal(true)
|
135
|
+
end
|
136
|
+
it "must keep track of running heralds" do
|
137
|
+
Herald.running_daemons.size.must_equal(1)
|
138
|
+
Herald.watch_twitter { _for "test" }
|
139
|
+
Herald.running_daemons.size.must_equal(2)
|
140
|
+
end
|
141
|
+
it "Herald:#clear must delete all processes" do
|
142
|
+
Herald.clear.must_equal(Herald)
|
143
|
+
Herald.running_daemons.size.must_equal(0)
|
144
|
+
end
|
145
|
+
it "must allow you to delete pids" do
|
146
|
+
Herald.serialized_daemons.size.must_equal(1)
|
147
|
+
Herald.delete_daemons(Herald.running_daemons).must_equal(Herald)
|
148
|
+
Herald.serialized_daemons.size.must_equal(0)
|
149
|
+
end
|
150
|
+
end
|
103
151
|
|
104
152
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: herald
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: "0.
|
5
|
+
version: "0.3"
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Luke Duncalfe
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-05-
|
13
|
+
date: 2011-05-09 00:00:00 +12:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -36,46 +36,63 @@ dependencies:
|
|
36
36
|
type: :runtime
|
37
37
|
version_requirements: *id002
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
|
-
name:
|
39
|
+
name: slop
|
40
40
|
prerelease: false
|
41
41
|
requirement: &id003 !ruby/object:Gem::Requirement
|
42
42
|
none: false
|
43
43
|
requirements:
|
44
|
-
- -
|
44
|
+
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: "0
|
46
|
+
version: "0"
|
47
47
|
type: :runtime
|
48
48
|
version_requirements: *id003
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
|
-
name:
|
50
|
+
name: hpricot
|
51
51
|
prerelease: false
|
52
52
|
requirement: &id004 !ruby/object:Gem::Requirement
|
53
53
|
none: false
|
54
54
|
requirements:
|
55
|
-
- -
|
55
|
+
- - ">="
|
56
56
|
- !ruby/object:Gem::Version
|
57
|
-
version: "
|
57
|
+
version: "0.8"
|
58
58
|
type: :runtime
|
59
59
|
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: ruby-growl
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "2.1"
|
69
|
+
type: :runtime
|
70
|
+
version_requirements: *id005
|
60
71
|
description: A simple and flexible notifier for Twitter, RSS, or email
|
61
72
|
email:
|
62
73
|
- lduncalfe@eml.cc
|
63
|
-
executables:
|
64
|
-
|
74
|
+
executables:
|
75
|
+
- herald
|
65
76
|
extensions: []
|
66
77
|
|
67
78
|
extra_rdoc_files:
|
68
79
|
- README.md
|
69
80
|
- LICENSE
|
70
81
|
files:
|
82
|
+
- .gemtest
|
71
83
|
- .gitignore
|
72
84
|
- Gemfile
|
85
|
+
- History.txt
|
73
86
|
- LICENSE
|
74
87
|
- README.md
|
75
88
|
- Rakefile
|
76
89
|
- TODO.txt
|
90
|
+
- bin/herald
|
77
91
|
- herald.gemspec
|
78
92
|
- lib/herald.rb
|
93
|
+
- lib/herald/batch.rb
|
94
|
+
- lib/herald/command.rb
|
95
|
+
- lib/herald/daemon.rb
|
79
96
|
- lib/herald/item.rb
|
80
97
|
- lib/herald/notifier.rb
|
81
98
|
- lib/herald/notifiers/callback.rb
|
@@ -83,7 +100,6 @@ files:
|
|
83
100
|
- lib/herald/notifiers/ping.rb
|
84
101
|
- lib/herald/notifiers/post.rb
|
85
102
|
- lib/herald/notifiers/stdout.rb
|
86
|
-
- lib/herald/untitled.txt
|
87
103
|
- lib/herald/version.rb
|
88
104
|
- lib/herald/watcher.rb
|
89
105
|
- lib/herald/watchers/rss.rb
|
@@ -129,7 +145,7 @@ rubyforge_project: herald
|
|
129
145
|
rubygems_version: 1.6.2
|
130
146
|
signing_key:
|
131
147
|
specification_version: 3
|
132
|
-
summary: A simple notifier for Twitter, RSS, or email
|
148
|
+
summary: A simple and flexible notifier for Twitter, RSS, or email
|
133
149
|
test_files:
|
134
150
|
- test/herald_test.rb
|
135
151
|
- test/mocks/rss.xml
|