file-watcher 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+