gina-conveyor 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/.gitignore +9 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +49 -0
  4. data/LICENSE +25 -0
  5. data/README.md +24 -0
  6. data/Rakefile +2 -0
  7. data/bin/conveyor +4 -0
  8. data/conveyor.gemspec +30 -0
  9. data/lib/conveyor/belt.rb +59 -0
  10. data/lib/conveyor/foreman.rb +182 -0
  11. data/lib/conveyor/input/commands.rb +21 -0
  12. data/lib/conveyor/input/console.rb +39 -0
  13. data/lib/conveyor/input.rb +12 -0
  14. data/lib/conveyor/job_state.rb +2 -0
  15. data/lib/conveyor/output/channel.rb +22 -0
  16. data/lib/conveyor/output/console.rb +39 -0
  17. data/lib/conveyor/output/email.rb +36 -0
  18. data/lib/conveyor/output/logfile.rb +38 -0
  19. data/lib/conveyor/output.rb +76 -0
  20. data/lib/conveyor/queue.rb +80 -0
  21. data/lib/conveyor/status.rb +29 -0
  22. data/lib/conveyor/version.rb +3 -0
  23. data/lib/conveyor/websocket.rb +37 -0
  24. data/lib/conveyor/worker.rb +120 -0
  25. data/lib/conveyor/workers/syntax.rb +127 -0
  26. data/lib/conveyor.rb +62 -0
  27. data/webviewer/.gitignore +15 -0
  28. data/webviewer/Gemfile +39 -0
  29. data/webviewer/Gemfile.lock +119 -0
  30. data/webviewer/README.rdoc +261 -0
  31. data/webviewer/Rakefile +7 -0
  32. data/webviewer/app/assets/images/rails.png +0 -0
  33. data/webviewer/app/assets/javascripts/application.js +16 -0
  34. data/webviewer/app/assets/javascripts/welcome.js.coffee +61 -0
  35. data/webviewer/app/assets/stylesheets/application.css.scss +6 -0
  36. data/webviewer/app/assets/stylesheets/welcome.css.scss +3 -0
  37. data/webviewer/app/controllers/application_controller.rb +3 -0
  38. data/webviewer/app/controllers/welcome_controller.rb +4 -0
  39. data/webviewer/app/helpers/application_helper.rb +2 -0
  40. data/webviewer/app/helpers/welcome_helper.rb +2 -0
  41. data/webviewer/app/mailers/.gitkeep +0 -0
  42. data/webviewer/app/models/.gitkeep +0 -0
  43. data/webviewer/app/views/layouts/application.html.haml +14 -0
  44. data/webviewer/app/views/welcome/index.html.haml +3 -0
  45. data/webviewer/config/application.rb +59 -0
  46. data/webviewer/config/boot.rb +6 -0
  47. data/webviewer/config/database.yml +25 -0
  48. data/webviewer/config/environment.rb +5 -0
  49. data/webviewer/config/environments/development.rb +37 -0
  50. data/webviewer/config/environments/production.rb +67 -0
  51. data/webviewer/config/environments/test.rb +37 -0
  52. data/webviewer/config/initializers/backtrace_silencers.rb +7 -0
  53. data/webviewer/config/initializers/inflections.rb +15 -0
  54. data/webviewer/config/initializers/mime_types.rb +5 -0
  55. data/webviewer/config/initializers/secret_token.rb +7 -0
  56. data/webviewer/config/initializers/session_store.rb +8 -0
  57. data/webviewer/config/initializers/wrap_parameters.rb +14 -0
  58. data/webviewer/config/locales/en.yml +5 -0
  59. data/webviewer/config/routes.rb +58 -0
  60. data/webviewer/config.ru +4 -0
  61. data/webviewer/db/seeds.rb +7 -0
  62. data/webviewer/doc/README_FOR_APP +2 -0
  63. data/webviewer/lib/assets/.gitkeep +0 -0
  64. data/webviewer/lib/tasks/.gitkeep +0 -0
  65. data/webviewer/log/.gitkeep +0 -0
  66. data/webviewer/public/404.html +26 -0
  67. data/webviewer/public/422.html +26 -0
  68. data/webviewer/public/500.html +25 -0
  69. data/webviewer/public/favicon.ico +0 -0
  70. data/webviewer/public/robots.txt +5 -0
  71. data/webviewer/script/rails +6 -0
  72. data/webviewer/test/fixtures/.gitkeep +0 -0
  73. data/webviewer/test/functional/.gitkeep +0 -0
  74. data/webviewer/test/functional/welcome_controller_test.rb +7 -0
  75. data/webviewer/test/integration/.gitkeep +0 -0
  76. data/webviewer/test/performance/browsing_test.rb +12 -0
  77. data/webviewer/test/test_helper.rb +13 -0
  78. data/webviewer/test/unit/.gitkeep +0 -0
  79. data/webviewer/test/unit/helpers/welcome_helper_test.rb +4 -0
  80. data/webviewer/vendor/assets/javascripts/.gitkeep +0 -0
  81. data/webviewer/vendor/assets/stylesheets/.gitkeep +0 -0
  82. data/webviewer/vendor/plugins/.gitkeep +0 -0
  83. data/worker-examples/barrow_webcam.worker.disabled +19 -0
  84. data/worker-examples/barrow_webcam.worker.example +16 -0
  85. data/worker-examples/conveyor.worker.example +5 -0
  86. data/worker-examples/devel.worker +17 -0
  87. metadata +260 -0
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ conf.d/*.yml
2
+ *.swp
3
+ workers/*.worker
4
+ log/*
5
+ *.log
6
+ .DS_Store
7
+ .workers
8
+ pkg
9
+ .conveyor
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,49 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ gina-conveyor (0.0.2)
5
+ activemodel (~> 3.2.0)
6
+ activesupport (~> 3.2.0)
7
+ em-websocket (~> 0.3.6)
8
+ eventmachine (~> 0.12.10)
9
+ listen (~> 0.4.2)
10
+ rainbow (~> 1.1.4)
11
+ rb-readline (~> 0.4.2)
12
+
13
+ GEM
14
+ remote: http://rubygems.org/
15
+ specs:
16
+ activemodel (3.2.3)
17
+ activesupport (= 3.2.3)
18
+ builder (~> 3.0.0)
19
+ activesupport (3.2.3)
20
+ i18n (~> 0.6)
21
+ multi_json (~> 1.0)
22
+ addressable (2.2.8)
23
+ builder (3.0.0)
24
+ em-websocket (0.3.6)
25
+ addressable (>= 2.1.1)
26
+ eventmachine (>= 0.12.9)
27
+ eventmachine (0.12.10)
28
+ ffi (1.0.11)
29
+ i18n (0.6.0)
30
+ listen (0.4.2)
31
+ rb-fchange (~> 0.0.5)
32
+ rb-fsevent (~> 0.9.1)
33
+ rb-inotify (~> 0.8.8)
34
+ multi_json (1.3.5)
35
+ rainbow (1.1.4)
36
+ rake (0.9.2.2)
37
+ rb-fchange (0.0.5)
38
+ ffi
39
+ rb-fsevent (0.9.1)
40
+ rb-inotify (0.8.8)
41
+ ffi (>= 0.5.0)
42
+ rb-readline (0.4.2)
43
+
44
+ PLATFORMS
45
+ ruby
46
+
47
+ DEPENDENCIES
48
+ gina-conveyor!
49
+ rake
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2011 University of Alaska. All rights reserved.
2
+
3
+ Developed by: Will Fisher and Scott Macfarlane
4
+ Geographic Information Network of Alaska
5
+ University of Alaska Fairbanks
6
+ http://www.gina.alaska.edu
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining
9
+ a copy of this software and associated documentation files (the
10
+ 'Software'), to deal in the Software without restriction, including
11
+ without limitation the rights to use, copy, modify, merge, publish,
12
+ distribute, sublicense, and/or sell copies of the Software, and to
13
+ permit persons to whom the Software is furnished to do so, subject to
14
+ the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be
17
+ included in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
20
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ Conveyor
2
+ ========
3
+
4
+ Start of a thought on some code to handle moving data around when it shows up on various systems
5
+
6
+ Installation
7
+ ------------
8
+
9
+ git clone https://github.com/gina-alaska/conveyor.git
10
+ cd conveyor
11
+ bundle install
12
+
13
+ Usage
14
+ -----
15
+
16
+ thor list # list available commands
17
+ thor help [command] # show help for the given command
18
+ thor belt list # list the currently active belts
19
+ thor worker watch # tell the workers to start watching directories!
20
+
21
+ License
22
+ -------
23
+
24
+ See LICENSE file for licensing and credits. Think BSD/MIT.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/bin/conveyor ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'conveyor'
3
+
4
+ Conveyor.start
data/conveyor.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ lib = File.expand_path('../lib/', __FILE__)
4
+ $:.unshift lib unless $:.include?(lib)
5
+
6
+ require 'conveyor/version'
7
+
8
+ Gem::Specification.new do |gem|
9
+ gem.authors = ["Will Fisher"]
10
+ gem.email = ["will@gina.alaska.edu"]
11
+ gem.summary = %q{GINA Data Conveyor}
12
+ gem.description = %q{Conveyor is used for shuffling data around}
13
+ gem.homepage = "http://github.com/gina-alaska/conveyor.git"
14
+
15
+ gem.files = `git ls-files`.split($\)
16
+ gem.executables = %w{conveyor}
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.name = "gina-conveyor"
19
+ gem.require_paths = ["lib"]
20
+ gem.version = Conveyor::VERSION
21
+
22
+ gem.add_development_dependency('rake')
23
+ gem.add_dependency('activemodel', '~> 3.2.0')
24
+ gem.add_dependency('activesupport', '~> 3.2.0')
25
+ gem.add_dependency('listen', '~> 0.4.2')
26
+ gem.add_dependency('rainbow', '~> 1.1.4')
27
+ gem.add_dependency('rb-readline', '~> 0.4.2')
28
+ gem.add_dependency('eventmachine', '~> 0.12.10')
29
+ gem.add_dependency('em-websocket', '~> 0.3.6')
30
+ end
@@ -0,0 +1,59 @@
1
+ module Conveyor
2
+ # Does not persist, do not use any class variables
3
+ class Belt
4
+ SETTLE_TIME = 30
5
+
6
+ include Conveyor::Output
7
+
8
+ attr_reader :command_file
9
+
10
+ def initialize(watch_path, command_file)#, opts = {})
11
+ @work_dir = watch_path
12
+ @command_file = command_file
13
+ @queue = Conveyor::Queue.new
14
+ end
15
+
16
+ def count
17
+ @queue.count
18
+ end
19
+
20
+ def name
21
+ File.basename(@command_file, '.worker')
22
+ end
23
+
24
+ def touch(files)
25
+ files.each do |f|
26
+ @queue.push(f)
27
+ end
28
+ end
29
+
30
+ def check
31
+ job = @queue.reserve
32
+ # puts job.inspect
33
+ if job && (Time.now - job[:updated_at]) > SETTLE_TIME
34
+ Worker.new(job[:file], @command_file).start
35
+ # Worker done remove it from the queue
36
+ @queue.pop(job[:file])
37
+ else
38
+ # File not ready yet
39
+ @queue.unreserve(job[:file]) unless job.nil?
40
+ end
41
+ rescue => e
42
+ puts e.message
43
+ puts e.backtrace
44
+ end
45
+
46
+ private
47
+
48
+ def process(file)
49
+ end
50
+
51
+ def escape_glob(glob)
52
+ if glob.class == String
53
+ Regexp.new(glob)
54
+ else
55
+ glob
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,182 @@
1
+ module Conveyor
2
+ # Handle the incoming watch requests and assign the workers
3
+ class Foreman
4
+ include Singleton
5
+ include Conveyor::Output
6
+
7
+ attr_accessor :workers, :channel, :config
8
+
9
+ def initialize
10
+ loglvl(:debug)
11
+ read_configs
12
+
13
+ @listeners = {}
14
+ @belts = {}
15
+ end
16
+
17
+ def logfile
18
+ @config[:logfile]
19
+ end
20
+
21
+ def name
22
+ 'Foreman'
23
+ end
24
+
25
+ def channel
26
+ @channel ||= EM::Channel.new
27
+ end
28
+
29
+ def read_configs
30
+ @config = {
31
+ "worker_defs" => File.expand_path('.workers', Dir.pwd),
32
+ "logfile" => File.expand_path('log/conveyor.log', Dir.pwd),
33
+ "threadpool" => 5,
34
+ "websocket" => {
35
+ "disabled" => false,
36
+ "host" => "0.0.0.0",
37
+ "port" => 9876
38
+ }
39
+ }
40
+
41
+ @config_file = '.conveyor'
42
+ if File.exists? @config_file
43
+ @config.merge! YAML.load(File.open(@config_file))
44
+ elsif File.exists?('~/.conveyor')
45
+ @config_file = '~/.conveyor'
46
+ @config.merge! YAML.load(File.open(@config_file))
47
+ else
48
+ write_config(@config)
49
+ end
50
+
51
+ # New version of conveyor update config file with new params
52
+ if !@config['version'] || @config['version'] != Conveyor::VERSION
53
+ @config['version'] = Conveyor::VERSION
54
+ write_config(@config)
55
+ end
56
+
57
+ @config.symbolize_keys!
58
+ @config[:websocket].symbolize_keys!
59
+ end
60
+
61
+ def write_config(config)
62
+ File.open(@config_file, 'w') { |fp| fp << config.to_yaml }
63
+ end
64
+
65
+ def watch(*args, &block)
66
+ @listener_opts = args.extract_options!
67
+ @listener_dir = File.expand_path(args.first)
68
+ raise "Directory #{@listener_dir} not found" unless File.directory? @listener_dir
69
+
70
+ @listener_opts[:latency] ||= 1
71
+ # Set a large latency if we force polling, prevents high cpu usage
72
+ @listener_opts[:latency] = 1 if @listener_opts[:latency] < 1 and @listener_opts[:force_polling]
73
+
74
+ yield
75
+ end
76
+
77
+ def match(*args, &block)
78
+ opts = args.extract_options!
79
+ debug "Filters: #{args.inspect}"
80
+
81
+ listener = Listen.to(@listener_dir)
82
+ if @listener_opts[:latency]
83
+ listener.latency(@listener_opts[:latency])
84
+ else
85
+ listener.latency(0.5)
86
+ end
87
+
88
+ listener.ignore(opts[:ignore]) if @listener_opts[:ignore]
89
+ if @listener_opts[:force_polling]
90
+ debug "Force polling"
91
+ listener.force_polling(true)
92
+ end
93
+ listener.filter(*args)
94
+
95
+ b = @belts[@listener_dir] = Belt.new(@listener_dir, @current_worker)
96
+ callback = lambda do |modified, added, removed|
97
+ begin
98
+ files = modified + added
99
+ b.touch(files) unless files.empty?
100
+ rescue => e
101
+ puts "Error: " + e.message
102
+ puts e.backtrace
103
+ end
104
+ end
105
+
106
+ listener.change(&callback)
107
+ @listeners[@listener_dir] = listener
108
+ rescue => e
109
+ error "ERROR: #{e.message}"
110
+ error e.backtrace
111
+ end
112
+
113
+ def file(glob)
114
+ /#{glob}$/
115
+ end
116
+
117
+ def extension(glob)
118
+ /\.#{glob}$/
119
+ end
120
+
121
+ def any
122
+ '*'
123
+ end
124
+
125
+ def notify_list
126
+ @notify_list.flatten!
127
+ @notify_list.uniq!
128
+ @notify_list
129
+ end
130
+
131
+ def stop!
132
+ @listeners.each { |dir,l| info "Stopping #{dir} listener"; l.stop }
133
+ @listeners = {}
134
+ @notify_list = []
135
+ end
136
+
137
+ def start
138
+ load!
139
+ @listeners.each do |k, listener|
140
+ info "Watching #{k}"
141
+ listener.start(false)
142
+ end
143
+ end
144
+
145
+ def output_status
146
+ status = @belts.collect { |dir, b| "#{b.name}: #{b.count}" }
147
+ print "\r#{status.join(', ')}"
148
+ end
149
+
150
+ def check
151
+ @belts.each do |dir, b|
152
+ EM.defer do
153
+ b.check
154
+ end
155
+ end
156
+ end
157
+
158
+ def load!
159
+ stop!
160
+
161
+ info "Loading workers from #{@config[:worker_defs]}"
162
+ FileUtils.mkdir_p(@config[:worker_defs])
163
+
164
+ Dir.glob(File.join(@config[:worker_defs], '*.worker')) do |file|
165
+ begin
166
+ @current_worker = File.expand_path(file)
167
+ instance_eval File.read(@current_worker)
168
+ rescue => e
169
+ error [
170
+ "Error loading #{@current_worker}, skipping",
171
+ e.message,
172
+ e.backtrace
173
+ ].flatten
174
+ end
175
+ end
176
+ end
177
+
178
+ def method_missing(method, value = nil)
179
+ return method.to_s
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,21 @@
1
+ module Conveyor
2
+ module Input
3
+ class Commands
4
+ class << self
5
+ def stop(*opts)
6
+ Kernel.exit
7
+ end
8
+ alias_method :exit, :stop
9
+
10
+ def listeners(*opts)
11
+ puts "Watching: "
12
+ puts "\t" + Conveyor::Foreman.instance.workers.keys.join("\n\t")
13
+ end
14
+
15
+ def unknown(cmd = nil)
16
+ puts "Unknown command #{cmd}"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,39 @@
1
+ module Conveyor
2
+ module Input
3
+ class Console
4
+ include Singleton
5
+
6
+ def initialize
7
+ end
8
+
9
+ def listen
10
+ save_tty_settings
11
+ while line = Readline.readline('> ', true)
12
+ handle line
13
+ end
14
+ rescue Interrupt => e
15
+ restore_tty_settings
16
+ exit
17
+ end
18
+
19
+ def handle(line)
20
+ cmd = line.split(/\s+/)
21
+ return if cmd.empty?
22
+
23
+ if Commands.respond_to? cmd.first
24
+ Commands.send(cmd.shift, cmd.join(' '))
25
+ else
26
+ Commands.unknown(*cmd)
27
+ end
28
+ end
29
+
30
+ def save_tty_settings
31
+ @stty_save = `stty -g`.chomp
32
+ end
33
+
34
+ def restore_tty_settings
35
+ system('stty', @stty_save);
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,12 @@
1
+ require 'conveyor/input/commands'
2
+ require 'conveyor/input/console'
3
+
4
+ module Conveyor
5
+ module Input
6
+ class << self
7
+ def listen
8
+ Conveyor::Input::Console.instance.listen
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,2 @@
1
+ module Conveyor
2
+ end
@@ -0,0 +1,22 @@
1
+ module Conveyor
2
+ module Output
3
+ class Channel
4
+ include Singleton
5
+
6
+ def initialize
7
+ end
8
+
9
+ def write(name, msgtype, *msg)
10
+ @channel = Conveyor::Foreman.instance.channel
11
+ return false if @channel.nil?
12
+
13
+ options = msg.extract_options!
14
+ format = '[%s] [%s::%s] %s'
15
+
16
+ Array.new(msg).each do |m|
17
+ @channel.push [msgtype, sprintf(format, Time.now, name, msgtype, m)]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,39 @@
1
+ module Conveyor
2
+ module Output
3
+ class Console
4
+ class << self
5
+ def output(*msg)
6
+ options = msg.extract_options!
7
+ options[:color] ||= :default
8
+ options[:tab] ||= 0
9
+
10
+ format = "\t"*options[:tab]
11
+ format << "\r[%s] %s"
12
+ if msg.class == Array
13
+ msg.each do |m|
14
+ puts sprintf(format, Time.now, m).color(options[:color])
15
+ end
16
+ else
17
+ puts sprintf(format, Time.now, msg).color(options[:color])
18
+ end
19
+ end
20
+ alias_method :info, :output
21
+ alias_method :debug, :output
22
+
23
+ def warning(*msg)
24
+ options = msg.extract_options!
25
+ options[:color] ||= :yellow
26
+ msg.flatten!
27
+ output(*msg, options)
28
+ end
29
+
30
+ def error(*msg)
31
+ options = msg.extract_options!
32
+ options[:color] ||= :red
33
+ msg.flatten!
34
+ output(*msg, options)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,36 @@
1
+ module Conveyor
2
+ module Output
3
+ class Email
4
+ class << self
5
+ def say(*msg)
6
+ # Do nothing
7
+ end
8
+ alias_method :info, :say
9
+ alias_method :debug, :say
10
+
11
+ def reset!
12
+ @msg_queue = []
13
+ end
14
+
15
+ def warning(*msg)
16
+ # Do nothing
17
+ end
18
+
19
+ def error(*msg)
20
+ @msg_queue ||= []
21
+ options = msg.extract_options!
22
+
23
+ msg = msg.join("\n") if msg.class == Array
24
+ @msg_queue << msg
25
+ end
26
+
27
+ def mail
28
+ return if @msg_queue.nil? || @msg_queue.empty?
29
+ puts "Sending email to #{Conveyor::Foreman.instance.notify_list}"
30
+ puts @msg_queue
31
+ reset!
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,38 @@
1
+ module Conveyor
2
+ module Output
3
+ class Logfile
4
+ class << self
5
+ def write(logfile, name, msgtype, *msg)
6
+ return false if logfile.nil?
7
+
8
+ options = msg.extract_options!
9
+
10
+ format = '[%s] [%s::%s] %s'
11
+
12
+ if msg.class == Array
13
+ msg.each do |m|
14
+ output logfile,
15
+ sprintf(format, Time.now, name, msgtype, m)
16
+ end
17
+ else
18
+ output logfile,
19
+ sprintf(format, Time.now, name, msgtype, msg)
20
+ end
21
+ end
22
+
23
+ def output(logfile, msg = nil, &block)
24
+ FileUtils.mkdir_p(File.dirname(logfile))
25
+ fp = File.open(logfile, 'a')
26
+
27
+ if block_given?
28
+ yield fp
29
+ elsif !msg.nil?
30
+ fp << msg + "\n"
31
+ end
32
+
33
+ fp.close
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,76 @@
1
+ require 'conveyor/output/console'
2
+ require 'conveyor/output/email'
3
+ require 'conveyor/output/logfile'
4
+ require 'conveyor/output/channel'
5
+
6
+ module Conveyor
7
+ module Output
8
+ MSGLVLS = {
9
+ :debug => 1,
10
+ :info => 10,
11
+ :warning => 20,
12
+ :error => 30
13
+ }
14
+
15
+ def should_log?(lvl, maxlvl = nil)
16
+ if maxlvl.nil? && @loglvl.nil?
17
+ loglvl :debug
18
+ should_log? lvl
19
+ elsif maxlvl.nil?
20
+ MSGLVLS[lvl.to_sym] >= @loglvl
21
+ else
22
+ MSGLVLS[lvl.to_sym] >= MSGLVLS[maxlvl.to_sym]
23
+ end
24
+ end
25
+
26
+ def loglvl(lvl)
27
+ @loglvl = MSGLVLS[lvl.to_sym] || MSGLVLS[:debug]
28
+ end
29
+
30
+ # Overrite this method to control logfile used
31
+ def logfile
32
+ nil
33
+ end
34
+
35
+ # Override this method to control name used
36
+ def name
37
+ nil
38
+ end
39
+
40
+ def say(*msg)
41
+ output(:info, *msg)
42
+ end
43
+
44
+ def info(*msg)
45
+ output(:info, *msg)
46
+ end
47
+
48
+ def warning(*msg)
49
+ output(:warning, *msg)
50
+ end
51
+
52
+ def error(*msg)
53
+ output(:error, *msg)
54
+ end
55
+
56
+ def debug(*msg)
57
+ output(:debug, *msg)
58
+ end
59
+
60
+ def output(msgtype, *msg)
61
+ return false unless should_log?(msgtype)
62
+ Console.send(msgtype, *msg)
63
+ Logfile.write(logfile, name, msgtype, *msg)
64
+ Email.send(msgtype, *msg)
65
+ Channel.instance.write(name, msgtype, *msg)
66
+ end
67
+
68
+ def send_notifications
69
+ Email.mail
70
+ end
71
+
72
+ def notify(*emails)
73
+ Conveyor::Foreman.instance.notify_list << emails
74
+ end
75
+ end
76
+ end