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.
File without changes
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  *.gem
2
2
  .bundle
3
3
  .rvmrc
4
+ .herald.pids
4
5
  Gemfile.lock
5
6
  pkg/*
@@ -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.2.gem
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 heralds
165
- Herald.stop # all heralds stopped
166
- Herald.alive? # => false
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
- ### A bit about callback scope and Herald metaprogramming
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
- ### Herald binary [Not Implemented]
235
+ Use the Herald executable below when you wish to stop your free-spirited heralds.
208
236
 
209
- herald -watch twitter -for #eqnz
210
- herald -once twitter -for #herald
211
- herald -show-heralds
212
- herald -modify 1 -watch rss -from http://example.com/.rss
213
- herald -pause 1
214
- herald -kill 1
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
@@ -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)
@@ -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("hpricot", "~> 0.8")
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", "~> 3.0")
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
- # s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
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
@@ -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
- # batch methods
37
- def self.start
38
- return false if @@heralds.empty?
39
- @@heralds.each do |herald|
40
- herald.start
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
- true
54
+ @@heralds
43
55
  end
44
56
 
45
- def self.stop
46
- return false unless Herald.alive?
47
- @@heralds.each do |herald|
48
- herald.stop
49
- end
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.heralds
73
- @@heralds
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
- begin
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
- alias :kill :stop
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
@@ -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
@@ -7,7 +7,7 @@ class Herald
7
7
  def parse_options(options)
8
8
  # option to send stdout to file
9
9
  if file = options.delete(:file)
10
- $stdout = File.new(file, 'w')
10
+ $stdout = File.new(file, 'a')
11
11
  end
12
12
  end
13
13
 
@@ -1,3 +1,3 @@
1
1
  class Herald
2
- VERSION = "0.2"
2
+ VERSION = "0.3"
3
3
  end
@@ -48,6 +48,9 @@ class Herald
48
48
  # parse a hash like { 120 => "seconds" }
49
49
  def every(time);
50
50
  quantity = time.keys.first.to_i
51
+ if quantity < 1
52
+ raise ArgumentError.new("Quantity must be greater than 0")
53
+ end
51
54
  unit = case time.values.first
52
55
  when /^second/
53
56
  1
@@ -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 running heralds" do
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 report on if there are any heralds alive" do
81
- Herald.alive?.must_equal(true)
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 stopped" do
84
- Herald.stop.must_equal(true)
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 "alive? must report false if heralds exist, but none are running" do
87
- Herald.stop
101
+ it "size() must return size of @@heralds" do
88
102
  Herald.heralds.size.must_equal(1)
89
- Herald.alive?.must_equal(false)
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 false if heralds are told to stop, and no herald are alive" do
92
- Herald.stop
93
- Herald.stop.must_equal(false)
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.2"
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-03 00:00:00 +12:00
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: hpricot
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.8"
46
+ version: "0"
47
47
  type: :runtime
48
48
  version_requirements: *id003
49
49
  - !ruby/object:Gem::Dependency
50
- name: ruby-growl
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: "3.0"
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
@@ -1,5 +0,0 @@
1
- require 'herald'
2
- herald = Herald.watch do
3
- check :website, :from => "http://www.google.co.nz", :within_tags => ["#some_id", #another_id]
4
- _for "search"
5
- end