herald 0.2 → 0.3
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/.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
|