watcher_in_the_water 0.1

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.
@@ -0,0 +1,6 @@
1
+ === 0.1.0 / 2008-09-06
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
@@ -0,0 +1,13 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ bin/watcher_in_the_water
6
+ lib/watcher_in_the_water.rb
7
+ test/fixtures/dimrill_gate
8
+ test/fixtures/durins_bridge
9
+ test/fixtures/west_gate
10
+ test/live.yml
11
+ test/live_test.rb
12
+ test/test_watcher_in_the_water.rb
13
+ test/watcher/test.yml
@@ -0,0 +1,34 @@
1
+ = Watcher In The Water - http://en.wikipedia.org/wiki/Watcher_in_the_Water
2
+
3
+ == Description
4
+
5
+ Want to know when the page at a given URL changes? The Watcher in the
6
+ Water will tell you over Jabber; just create a ~/.watcher/config.yml
7
+ file and toss +watcher_in_the_water+ into your crontab!
8
+
9
+ ---
10
+ jid: watcher-in-the-water@jabber.org
11
+ password: mellon
12
+ recipient: phil@hagelb.org
13
+ urls:
14
+ - http://rubyconf.org
15
+
16
+ == Issues
17
+
18
+ XMPP4R takes a really long time to authenticate with my Jabber
19
+ server. Maybe it's just me though... No idea. This shouldn't run more
20
+ than once an hour or so, whatever; shouldn't matter.
21
+
22
+ == Install
23
+
24
+ $ sudo gem install technomancy-watcher_in_the_water --source=http://gems.github.com
25
+
26
+ == TODO
27
+
28
+ * Finish live tests?
29
+ * Just send a diff over IM?
30
+ * Only look at a given XPath?
31
+
32
+ == Author
33
+
34
+ By Phil Hagelberg (http://technomancy.us)
@@ -0,0 +1,16 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/watcher_in_the_water.rb'
6
+
7
+ Hoe.new('watcher_in_the_water', WatcherInTheWater::VERSION) do |p|
8
+ p.rubyforge_name = "seattlerb"
9
+ p.summary = "Want to know when the page at a given URL changes?
10
+ The Watcher in the Water will tell you over Jabber."
11
+ p.developer('Phil Hagelberg', 'http://technomancy.us')
12
+ p.url = 'http://en.wikipedia.org/wiki/Watcher_in_the_Water'
13
+ p.extra_deps << 'xmpp4r'
14
+ end
15
+
16
+ # vim: syntax=Ruby
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../lib/watcher_in_the_water'
4
+
5
+ WatcherInTheWater.configure(ARGV.first)
6
+ WatcherInTheWater.watch
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'open-uri'
5
+ require 'yaml'
6
+ require 'digest/sha1'
7
+ require 'xmpp4r'
8
+ require 'fileutils'
9
+
10
+ module WatcherInTheWater
11
+ include Jabber
12
+ VERSION = '0.1'
13
+
14
+ module_function
15
+
16
+ def configure(config = nil)
17
+ config = File.expand_path(config || '~/.watcher/config.yml')
18
+ FileUtils.cd(File.dirname(config))
19
+ @config = YAML.load(File.read(config))
20
+ rescue
21
+ abort "You need #{config} to contain a sender jabber ID, password,
22
+ a recipient jabber ID, and a list of URLs in YAML format. Example:
23
+
24
+ ---
25
+ jid: watcher-in-the-water@jabber.org
26
+ password: mellon
27
+ recipient: phil@hagelb.org
28
+ urls: ---
29
+ http://rubyconf.org
30
+ "
31
+ end
32
+
33
+ def watch
34
+ @config['urls'].each do |url|
35
+ content = open(url).read
36
+ hash = Digest::SHA1.hexdigest(content)
37
+ filename = 'hashes/' + url_transform(url)
38
+
39
+ if File.exist?(filename)
40
+ if File.read(filename) != hash
41
+ alert("#{url} changed to #{content[0 .. 200]}")
42
+ end
43
+ else
44
+ alert("Watching #{url} for you!")
45
+ end
46
+ FileUtils.mkdir_p(File.dirname(filename))
47
+ File.open(filename, 'w') { |f| f.write hash }
48
+ end
49
+ end
50
+
51
+ def alert(message)
52
+ connect
53
+ @client.send Message.new(@config['recipient'],
54
+ message).set_type(:normal).set_id('1')
55
+ end
56
+
57
+ def connect
58
+ return if @client
59
+ jid = JID.new("#{@config['jid']}/#{`hostname`.chomp}-watcher")
60
+ @client = Client.new(jid)
61
+ @client.connect
62
+ @client.auth(@config['password'])
63
+ end
64
+
65
+ def url_transform(url)
66
+ url.gsub(/[^\w]/, '_')[0 .. 50] + '_' + Digest::SHA1.hexdigest(url)
67
+ end
68
+ end
@@ -0,0 +1 @@
1
+ Dimrill Gate
@@ -0,0 +1 @@
1
+ Durin's Bridge
@@ -0,0 +1 @@
1
+ West Gate
@@ -0,0 +1,6 @@
1
+ ---
2
+ jid: test@hagelb.org
3
+ password: mellon
4
+ recipient: testrecipient@hagelb.org
5
+ urls:
6
+ - http://localhost:8123/
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ begin; gem 'miniunit'; rescue LoadError; end
3
+ require 'test/unit'
4
+ require 'mongrel'
5
+ require File.dirname(__FILE__) + '/../lib/watcher_in_the_water'
6
+
7
+ # launch Mongrel
8
+ class LiveServer < Mongrel::HttpHandler
9
+ attr_accessor :string
10
+ def process(request, response)
11
+ response.start(200) do |head,out|
12
+ out.write(@string || "hello!\n")
13
+ end
14
+ end
15
+ end
16
+
17
+ MONGREL = Mongrel::HttpServer.new("0.0.0.0", "3000")
18
+ MONGREL.register("/test", SimpleHandler.new)
19
+ MONGREL.run
20
+
21
+ class LiveTest < Test::Unit::TestCase
22
+ def setup
23
+ WatcherInTheWater.configure(File.dirname(__FILE__) + '/live.yml')
24
+ end
25
+
26
+ def test_live_usage
27
+ # should alert about all pages being watched on first run
28
+ # then should alert for a single change
29
+ # then should send no alerts if nothing's changed
30
+ end
31
+
32
+ def test_host_not_found
33
+ end
34
+
35
+ def test_404
36
+ end
37
+
38
+ def test_sender_jabber_down
39
+ end
40
+
41
+ def test_bad_auth
42
+ end
43
+
44
+ def test_recipient_jabber_down
45
+ end
46
+
47
+ def test_recipient_jid_not_found
48
+ end
49
+
50
+ private
51
+ def watch
52
+ system "#{File.dirname(__FILE__)}/../bin/watcher #{File.dirname(__FILE__)}/live.yml"
53
+ end
54
+ end
@@ -0,0 +1,60 @@
1
+ require 'rubygems'
2
+ begin; gem 'miniunit'; rescue LoadError; end
3
+ require 'test/unit'
4
+ require File.dirname(__FILE__) + '/../lib/watcher_in_the_water'
5
+
6
+ module WatcherInTheWater
7
+ # Let's mock out the Jabber connection
8
+ @client = Object.new
9
+ @messages = []
10
+ messages_for_closure = @messages
11
+
12
+ def @client.send(message)
13
+ WatcherInTheWater.messages << message
14
+ end
15
+
16
+ def self.messages; @messages; end
17
+ def self.config; @config; end
18
+ end
19
+
20
+ WatcherInTheWater.configure(File.dirname(__FILE__) + '/watcher/test.yml')
21
+
22
+ class TestWatcherInTheWater < Test::Unit::TestCase
23
+ def setup
24
+ FileUtils.rm_rf('hashes')
25
+ FileUtils.rm_rf('fixtures')
26
+ FileUtils.cp_r('../fixtures', 'fixtures')
27
+ WatcherInTheWater.messages.clear
28
+ end
29
+
30
+ def test_watch_first_time
31
+ WatcherInTheWater.watch
32
+
33
+ ['fixtures_dimrill_gate_d2785ed5a8c89b47e541e85b7216d0153a383651',
34
+ 'fixtures_durins_bridge_f81c948ae30baa391371150bc42cc935ebf8287c',
35
+ 'fixtures_west_gate_cdef5d9283f6bdeddfa89de21bbca8d5acb3c673'].each do |u|
36
+ assert_equal 40, File.read('hashes/' + u).length
37
+ end
38
+
39
+ assert_equal 3, WatcherInTheWater.messages.size
40
+ end
41
+
42
+ def test_watch_one_change
43
+ WatcherInTheWater.watch
44
+ WatcherInTheWater.messages.clear
45
+
46
+ File.open('fixtures/durins_bridge', 'w') { |f| f.puts "Durin's Super-Bridge!" }
47
+ WatcherInTheWater.watch
48
+
49
+ assert_equal 1, WatcherInTheWater.messages.size
50
+ end
51
+
52
+ def test_watch_no_changes
53
+ WatcherInTheWater.watch
54
+ WatcherInTheWater.messages.clear
55
+
56
+ WatcherInTheWater.watch
57
+
58
+ assert_equal [], WatcherInTheWater.messages
59
+ end
60
+ end
@@ -0,0 +1,8 @@
1
+ ---
2
+ jid: watcher-in-the-water@jabber.org
3
+ password: mellon
4
+ recipient: phil@hagelb.org
5
+ urls:
6
+ - fixtures/west_gate
7
+ - fixtures/durins_bridge
8
+ - fixtures/dimrill_gate
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: watcher_in_the_water
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Phil Hagelberg
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-11-07 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: xmpp4r
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.2
34
+ version:
35
+ description:
36
+ email:
37
+ - http://technomancy.us
38
+ executables:
39
+ - watcher_in_the_water
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - History.txt
44
+ - Manifest.txt
45
+ files:
46
+ - History.txt
47
+ - Manifest.txt
48
+ - README.rdoc
49
+ - Rakefile
50
+ - bin/watcher_in_the_water
51
+ - lib/watcher_in_the_water.rb
52
+ - test/fixtures/dimrill_gate
53
+ - test/fixtures/durins_bridge
54
+ - test/fixtures/west_gate
55
+ - test/live.yml
56
+ - test/live_test.rb
57
+ - test/test_watcher_in_the_water.rb
58
+ - test/watcher/test.yml
59
+ has_rdoc: true
60
+ homepage: http://en.wikipedia.org/wiki/Watcher_in_the_Water
61
+ post_install_message:
62
+ rdoc_options:
63
+ - --main
64
+ - README.txt
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ requirements: []
80
+
81
+ rubyforge_project: seattlerb
82
+ rubygems_version: 1.3.1
83
+ signing_key:
84
+ specification_version: 2
85
+ summary: Want to know when the page at a given URL changes? The Watcher in the Water will tell you over Jabber.
86
+ test_files:
87
+ - test/test_watcher_in_the_water.rb