file-watcher 1.0.0

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.
Files changed (4) hide show
  1. data/watch_config.rb +34 -0
  2. data/watch_job.rb +47 -0
  3. data/watcher.rb +90 -0
  4. metadata +79 -0
data/watch_config.rb ADDED
@@ -0,0 +1,34 @@
1
+ module WatchConfig
2
+
3
+ def self.included base
4
+ base.extend( ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+ def validate_new_job wj
9
+ raise "Error: Watch job is missing watch dir: #{wj.inspect}" unless wj.watch_criteria.keys.include? :target_dir
10
+
11
+ raise "Error: Watch directory doesn't exist: #{wj.watch_criteria[:target_dir]}" unless File.exist? wj.watch_criteria[:target_dir]
12
+
13
+ raise "Error: Watch configuration did not specify any events to watch for (#{wj.inspect})" if wj.watch_criteria[:events].empty?
14
+
15
+
16
+ raise "Error: Only http watch actions are supported: #{wj}" unless wj.watch_action.keys == [:http]
17
+
18
+ raise "Error: Invalid/Unsupported http method [#{wj.watch_action[:http][:method]}] in config [#{wj.watch_action.inspect}]" unless wj.watch_action[:http][:method] == :post
19
+ end
20
+
21
+ def new_watch_job &block
22
+ wj = WatchJob.new
23
+
24
+ yield wj
25
+
26
+ validate_new_job wj
27
+ self.registered_jobs << wj
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
34
+
data/watch_job.rb ADDED
@@ -0,0 +1,47 @@
1
+ require File.join( File.dirname(__FILE__), 'watch_config')
2
+ require 'cgi'
3
+ require 'net/http'
4
+ require 'uri'
5
+
6
+ class WatchJob
7
+ include WatchConfig
8
+ attr_accessor :watch_criteria, :watch_action
9
+
10
+ @@registered_jobs = []
11
+
12
+ def self.registered_jobs
13
+ @@registered_jobs
14
+ end
15
+
16
+
17
+ def do_post event
18
+ Net::HTTP.start(watch_action[:http][:hostname]) do |http|
19
+ if watch_action[:http][:ssl]
20
+ protocol = 'https'
21
+ else
22
+ protocol = 'http'
23
+ end
24
+
25
+ url = "#{protocol}://#{watch_action[:http][:auth_user]}:#{watch_action[:http][:auth_pass]}@#{watch_action[:http][:hostname]}:#{watch_action[:http][:port]}#{watch_action[:http][:command_uri]}"
26
+
27
+
28
+ body = watch_action[:http][:command].merge({ :args => watch_action[:http][:command][:args].dup.push(event.name) } )
29
+
30
+ puts "URL: #{url}"
31
+ puts "body: #{body}"
32
+
33
+ res = Net::HTTP.post_form(URI.parse(url), {'body' => body.to_json } )
34
+ puts "Response: #{res}"
35
+ end
36
+ end
37
+
38
+ def event_handler event
39
+ debugger
40
+ return unless event.name =~ watch_criteria[:file_glob]
41
+
42
+ if watch_action.keys.first == :http && watch_action[:http][:method] == :post
43
+ do_post event
44
+ end
45
+
46
+ end
47
+ end
data/watcher.rb ADDED
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'ruby-debug'
4
+ require 'base_app'
5
+ require 'rb-inotify'
6
+ require 'json'
7
+ require File.join( File.dirname(__FILE__), 'watch_job' )
8
+
9
+
10
+ #
11
+ # to watch the current directory, run:
12
+ #
13
+ # ruby watcher.rb -d . -c trigger
14
+ #
15
+ # This also specifies a 'command' directory - a place where if you
16
+ # touch a 'stop' file, the inotify loop will terminate.
17
+ #
18
+
19
+
20
+ class Watcher < BaseApp
21
+
22
+ def command_line_arguments
23
+ super.concat [["w","watch-job-dir=","Directory of watch jobs.", true],
24
+ ["c","control-dir=","Control directory to watch for a 'stop' file..", true]]
25
+ end
26
+
27
+ def make_flags_map flags
28
+ flags.inject({}) do |m,f|
29
+ m[f] = true
30
+ m
31
+ end
32
+ end
33
+
34
+ def stop_file_path
35
+ "#{@control_dir}/stop"
36
+ end
37
+
38
+ def handle_event event, flags
39
+ if event.name == 'stop'
40
+ if File.exist?(stop_file_path)
41
+ @notifier.stop
42
+ File.delete stop_file_path
43
+ return
44
+ end
45
+ end
46
+
47
+ # we don't care about things like 'ls' or other changes on the directory itself
48
+ return if flags[:isdir]
49
+
50
+ puts "handle event: #{event.name} was #{flags.inspect}"
51
+ end
52
+
53
+
54
+
55
+ def run
56
+ @control_dir = self.control_dir || '.'
57
+
58
+
59
+ Dir["#{@watch_job_dir}/*.rb"].each do |f|
60
+ require File.join( File.dirname(__FILE__), f)
61
+ end
62
+
63
+ @notifier = INotify::Notifier.new
64
+ # these are all the events we can watch for: :access, :attrib,
65
+ # :close_write, :close_nowrite, :create, :delete, :delete_self,
66
+ # :modify, :move_self, :moved_from, :moved_to, :open
67
+
68
+ # :access is too noisy for watching a directory (lots and lots of events)
69
+ # notifier.watch(@dir, :attrib, :close_write, :close_nowrite, :create, :delete, :delete_self, :modify, :move_self, :moved_from, :moved_to, :open) do |event|
70
+
71
+ WatchJob.registered_jobs.each do |job|
72
+ @notifier.watch(job.watch_criteria[:target_dir], *job.watch_criteria[:events]) do |event|
73
+ job.event_handler event
74
+ end
75
+ end
76
+
77
+ @notifier.watch(@control_dir, :close_write, :close_nowrite, :create, :delete, :modify, :moved_from, :moved_to, :delete_self, :move_self, :recursive) do |event|
78
+ puts "CONTROL DIR HIT: #{@control_dir}"
79
+ handle_event event, make_flags_map(event.flags)
80
+ end
81
+
82
+ puts "Entering run loop."
83
+ @notifier.run
84
+ puts "Exited run loop."
85
+ end
86
+ end
87
+
88
+ if $0 == __FILE__
89
+ Watcher.main
90
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: file-watcher
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Paul Santa Clara
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-02-25 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rb-inotify
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ - 8
30
+ - 4
31
+ version: 0.8.4
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ description: |
35
+ Use inotify to watch for file system modifcations and take a configured action.'
36
+
37
+ email: "kburton@relaynetwork.com "
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - watch_config.rb
46
+ - watcher.rb
47
+ - watch_job.rb
48
+ has_rdoc: true
49
+ homepage:
50
+ licenses: []
51
+
52
+ post_install_message:
53
+ rdoc_options: []
54
+
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ requirements: []
72
+
73
+ rubyforge_project:
74
+ rubygems_version: 1.3.6
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: Use inotify to watch for file system modifcations and take a configured action.
78
+ test_files: []
79
+