cacophony 0.0.2

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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ *.swp
3
+ .bundle
4
+ Gemfile.lock
5
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in cacophony.gemspec
4
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,35 @@
1
+ = Cacophony notifier
2
+
3
+ * Author: David Lyons (http://loadedfingers.com)
4
+
5
+ == Caco-whatsie?
6
+
7
+ Cacophony is a small program that broadcasts notifications via a variety of mechanisms, such as growl, email and twitter.
8
+ It is great for notifiying you(or others) when a long running task is complete.
9
+ It operates as a standalone executable, and it also can read from STDIN to pipe output from your tasks to the notifiers.
10
+ The various notifiers are configured in ~/.cacophony, or via a config file passed via -c option.
11
+
12
+ == Requirements
13
+
14
+ * ruby 1.9.x
15
+ * trollop
16
+ * Growl (if you want growl notifications)
17
+
18
+ == Install
19
+
20
+ sudo gem install cacophony
21
+
22
+ Running cacophony for the first time will prompt you to create a sample configuration file, which you can edit as appropriate.
23
+
24
+ == Usage
25
+
26
+ Some examples:
27
+
28
+ cacophony -m 'just a message'
29
+ ./long_task_is_long | cacophony
30
+ ./long_task_is_long | cacophony -t 'job output:'
31
+ ./long_task_is_long && cacophony -m 'coffee break over'
32
+
33
+
34
+ == Developers
35
+ You can add customer notifiers by adding a class to lib/notifiers/. They must follow the naming pattern xNotifier, copy one of the existing classes for method signatures.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/bin/cacophony ADDED
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'yaml'
4
+ require 'trollop'
5
+ require 'fcntl'
6
+ require 'fileutils'
7
+
8
+ require 'cacophony'
9
+
10
+ #resolve symlinks FIX WHEN IN GEM
11
+ THIS_FILE = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
12
+ GEM_PATH = File.join('..','lib',File.dirname(THIS_FILE) )
13
+
14
+ RESULTS_SIZE = 50
15
+ DEFAULT_TITLE = 'Cacophony Notifier'
16
+ DEFAULT_MSG = 'Task finished!'
17
+
18
+ DEFAULT_CONF_PATH = '~/.cacophony'
19
+
20
+ opts = Trollop::options do
21
+ version "Cacophony v#{Cacophony::VERSION}(c) 2011 David Lyons"
22
+ banner <<-EOS
23
+ Cacophony is a small program that broadcasts notifications via a variety of mechanisms, such as growl, email and twitter.
24
+ It is great for notifiying you(or others) when a long running task is complete.
25
+ It operates as a standalone executable, and it also can read from STDIN to pipe output from your tasks to the notifiers.
26
+ The various notifiers are configured in #{DEFAULT_CONF_PATH}, or via a config file passed via -c option.
27
+
28
+ Usage:
29
+ cacophony [-options] [message]
30
+
31
+ Examples:
32
+ ./long_task_is_long | cacophony
33
+ ./long_task_is_long | cacophony -t 'job output:'
34
+ ./long_task_is_long && cacophony -m 'coffee break over'
35
+
36
+ Options:
37
+
38
+ EOS
39
+ opt :message, "The message to send via the notifiers", :short => 'm', :type => String, :default => DEFAULT_MSG
40
+ opt :title, "The title/subject to attach to messages", :short => 't', :type => String, :default => DEFAULT_TITLE
41
+ opt :conf_file, "Alternate location of config file (default: #{DEFAULT_CONF_PATH})", :short => 'c', :type => String
42
+ end
43
+ Trollop::die :conf_file, "must exist" unless File.exist?(opts[:conf_file]) if opts[:conf_file]
44
+
45
+ unless opts[:conf_file] || File.exist?(File.expand_path(DEFAULT_CONF_PATH))
46
+ puts "No cacophony config file found at #{DEFAULT_CONF_PATH}."
47
+ print "Would you like me to create a sample config file at #{DEFAULT_CONF_PATH} for you? (y/n):"
48
+ if $stdin.getc == 'y'
49
+ puts "Copying sample to #{DEFAULT_CONF_PATH}."
50
+ FileUtils.cp(File.join(File.dirname(THIS_FILE), '..', 'config', 'cacophony_sample.yaml'), File.expand_path(DEFAULT_CONF_PATH))
51
+ puts "Please edit this file to configure cacophony, and run again."
52
+ exit
53
+ end
54
+ end
55
+
56
+
57
+ CONF_FILE_PATH = opts[:conf_file] || File.join(File.expand_path('~'), '.cacophony')
58
+ begin
59
+ CONFIG = YAML.load_file(CONF_FILE_PATH)
60
+ rescue
61
+ Trollop::die "could not load config file: #{CONF_FILE_PATH}"
62
+ end
63
+
64
+ output = []
65
+
66
+
67
+ if STDIN.fcntl(Fcntl::F_GETFL, 0) == 0
68
+ ARGF.each do |line|
69
+ puts line
70
+ output << line
71
+ end
72
+ else
73
+ #output << ''
74
+ end
75
+
76
+ message = (opts[:message] == DEFAULT_MSG && m = ARGV.shift) ? m : opts[:message]
77
+ title = opts[:title]
78
+
79
+ notifer = Cacophony::Notifier.new(CONFIG)
80
+ notifer.notify(title, message, output)
data/cacophony.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "cacophony/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "cacophony"
7
+ s.version = Cacophony::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Dave Lyons"]
10
+ s.email = ["dalyons@gmail.com"]
11
+ s.homepage = "http://www.loadedfingers.com"
12
+ s.summary = %q{Broadcast messages from programs and the command line}
13
+ s.description = %q{see summary}
14
+
15
+ #s.rubyforge_project = "cacophony"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency('trollop')
23
+ end
@@ -0,0 +1,19 @@
1
+ #Cacophony sample config.
2
+ #Each availible notifier type is listed here, along with its options.
3
+ #To enable a notifier, uncomment it and set the options you require.
4
+
5
+ ##Growl notifer uses growl.
6
+ ##Please ensure 'Listen for availible notifications' and 'allow remote application registration' are ticked in System Preferences->Growl.
7
+ #growl_notifier:
8
+ # use_growl_gem: false
9
+ # sticky: true
10
+
11
+ ##Email notifier sends emails, below is a sample config for sending via gmail
12
+ #email_notifier:
13
+ # server: smtp.gmail.com
14
+ # port: 587
15
+ # tls: true
16
+ # username: USERNAME
17
+ # password: PASSWORD
18
+ # to_address: [addy1@gmail.com, addy2@somewhere.com]
19
+ # from_address: cacophony@test.com
@@ -0,0 +1,3 @@
1
+ module Cacophony
2
+ VERSION = "0.0.2"
3
+ end
data/lib/cacophony.rb ADDED
@@ -0,0 +1,34 @@
1
+ #require all the notifiers
2
+ require 'cacophony/version'
3
+ Dir.glob(File.join(File.dirname(__FILE__), 'notifiers', '*.rb')) {|f| require f}
4
+
5
+
6
+ module Cacophony
7
+ class Notifier
8
+
9
+ def initialize(conf)
10
+ raise 'need configuration hash' unless conf.is_a?(Hash) && conf.any?
11
+ @conf = conf
12
+ end
13
+
14
+ def notify(title, message, data)
15
+
16
+ threads = []
17
+ @conf.each do |notifier_type, opts|
18
+ begin
19
+ klass = Object.const_get(notifier_type.split('_').map(&:capitalize).join)
20
+ rescue
21
+ raise "Invalid configuration option(s): #{notifier_type}"
22
+ end
23
+
24
+ threads << Thread.new do
25
+ notifier = klass.new(opts || {} )
26
+ puts "Cacophony broadcasting via #{notifier_type.split('_').map(&:capitalize).join(' ')}"
27
+ notifier.notify(message, title, data)
28
+ end
29
+ end
30
+
31
+ threads.each{|t| t.join}
32
+ end
33
+ end
34
+ end
data/lib/growlnotify ADDED
Binary file
@@ -0,0 +1,47 @@
1
+
2
+ require 'net/smtp'
3
+
4
+
5
+ class EmailNotifier
6
+
7
+ def initialize(opts={})
8
+ @opts = opts
9
+ @from = opts['from'] || "Your sentient shell <shell@donotfearus.com>"
10
+ @to = opts['to'] || "Puny human"
11
+ @subject = opts['subject'] || "Job Complete"
12
+ @server = opts['server'] || 'localhost'
13
+ @port = opts['port'] || 25
14
+ @username = opts['username'] || nil
15
+ @password = opts['password'] || nil
16
+ @method = opts['method'] || :plain
17
+ @to_addresses = opts['to_address'].to_a
18
+ @from_address = opts['from_address'] || ''
19
+ @tls = opts['tls'] || false
20
+
21
+ end
22
+
23
+ def notify(message, title, data)
24
+
25
+ details = message.dup
26
+ details << "\n" + (data.any? ? "Last #{RESULTS_SIZE} lines...\n\n#{data.last(50).join}" : "No output.")
27
+
28
+ @to_addresses.each do |address|
29
+
30
+ msg = <<MESSAGE_END
31
+ From: #{@from}
32
+ To: #{@to}
33
+ Subject: #{title}: #{@subject}
34
+
35
+ #{details}
36
+
37
+ MESSAGE_END
38
+
39
+ smtp = Net::SMTP.new @server, @port
40
+ smtp.enable_starttls if @tls
41
+ smtp.start(@server, @username, @password, @method.to_sym) do
42
+ smtp.send_message(msg, @from_address, address)
43
+ end
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,38 @@
1
+ begin
2
+ require 'ruby-growl'
3
+ GROWL_GEM = true
4
+ rescue LoadError
5
+ GROWL_GEM = false
6
+ end
7
+
8
+ class GrowlNotifier
9
+ def initialize(opts = {})
10
+ @server = opts['server'] || '127.0.0.1'
11
+ @sticky = opts['sticky'] || false
12
+ @use_growl_gem = opts['use_growl_gem'] == false ? false : true
13
+ @output_lines = opts['output_lines'] || 2
14
+ end
15
+
16
+ def notify(message, title = '', data = [])
17
+ msg = message.dup
18
+ if data.any?
19
+ msg << "\n\n"
20
+ #msg << "......#{data.length - @output_lines} more lines\n"
21
+ #(@output_lines - 1).downto(0).each{|i| msg << "#{data.length - i}: #{data[i]}"}
22
+ data.last(@output_lines).each_with_index{|line,i| msg << "#{data.length - i}: #{line}"}
23
+ msg << "......#{data.length - @output_lines} more lines"
24
+ end
25
+ (@use_growl_gem && GROWL_GEM) ? notify_via_gem(msg, title) : notify_via_binary(msg, title)
26
+ end
27
+
28
+ private
29
+ def notify_via_gem(message, title)
30
+ growl = Growl.new "127.0.0.1", "ruby-growl",["ruby-growl_Notification"]
31
+ growl.notify "ruby-growl_Notification", title, message
32
+ end
33
+
34
+ def notify_via_binary(message, title)
35
+ growl_bin = File.join(GEM_PATH, 'bin', 'growlnotify')
36
+ system %{#{growl_bin} -m "#{msg}" "#{title}" #{"-s" if @sticky}}
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cacophony
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.2
6
+ platform: ruby
7
+ authors:
8
+ - Dave Lyons
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-02-09 00:00:00 +11:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: trollop
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ description: see summary
28
+ email:
29
+ - dalyons@gmail.com
30
+ executables:
31
+ - cacophony
32
+ extensions: []
33
+
34
+ extra_rdoc_files: []
35
+
36
+ files:
37
+ - .gitignore
38
+ - Gemfile
39
+ - README.rdoc
40
+ - Rakefile
41
+ - bin/cacophony
42
+ - cacophony.gemspec
43
+ - config/cacophony_sample.yaml
44
+ - lib/cacophony.rb
45
+ - lib/cacophony/version.rb
46
+ - lib/growlnotify
47
+ - lib/notifiers/email_notifier.rb
48
+ - lib/notifiers/growl_notifier.rb
49
+ has_rdoc: true
50
+ homepage: http://www.loadedfingers.com
51
+ licenses: []
52
+
53
+ post_install_message:
54
+ rdoc_options: []
55
+
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.5.0
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Broadcast messages from programs and the command line
77
+ test_files: []
78
+