rowl 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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2009 Jason Madigan
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ Rowl
2
+ ====
3
+ Rowl is a simple [Growl] notification sender for Ruby.
4
+
5
+ Installation
6
+ ============
7
+
8
+ As a RubyGem
9
+
10
+ sudo gem install rowl
11
+
12
+ Since Rowl is tiny (and has no dependencies), you may just want to drop it into an existing project
13
+
14
+ git clone git://github.com/jasonmadigan/rowl
15
+ mv rowl/lib/rowl.rb <location>
16
+
17
+ Then require it
18
+
19
+ require 'rowl'
20
+
21
+ Usage
22
+ =====
23
+
24
+ Before using Rowl, it's probably worth noting some things:
25
+
26
+ * Applications need to register themselves with Growl before they can send notifications
27
+ * Applications can have a number of different types of notifications associated with them
28
+ * Registration requires you to include any types of notifications you'll wish to use later on
29
+ * These notification types are user configurable - they can be enabled/disabled, styled etc. how a user wants
30
+ * You only need to send a register your application once, but you'll want to store the application name you registered, along with any notification types, for future reference
31
+
32
+ So, sending a notification is a little more involved than it might first seem. This reason why the API here is a little less terse than I'd like. Anyway.
33
+
34
+ Load it (as a gem)
35
+
36
+ require 'rubygems'
37
+ require 'rowl'
38
+
39
+ Use it like so
40
+
41
+ registration = Rowl::Registration.new("My Application", [{:name => "My Notification", :enabled => true}, {:name => "My Other Notification Type", :enabled => false}])
42
+ Rowl::Notification.new( :application => registration.application,
43
+ :notification => registration.notifications.first,
44
+ :host => "localhost",
45
+ :password => registration.password,
46
+ :title => "Title",
47
+ :description => "Description" )
48
+
49
+ Patches, Bugs & Hatemail
50
+ ========================
51
+
52
+ * Feel free to fork the project and send me a pull request with any changes if you come any bugs or general nastiness
53
+ * All that I ask is that you don't touch the rakefile, version, or history (I'll update these and push out gem updates)
54
+ * Tests would be nice, but I'm not going to reject a perfectly good fix if they're missing
55
+
56
+ Copyright & Licensing
57
+ =====================
58
+ Copyright (c) 2009 Jason Madigan. MIT license, see LICENSE for details.
59
+
60
+ [Growl]: http://growl.info
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "rowl"
8
+ gem.summary = %Q{Rowl is a simple Growl notification sender for Ruby.}
9
+ gem.description = %Q{Rowl is a simple Growl notification sender for Ruby.}
10
+ gem.email = "jason@jasonmadigan.com"
11
+ gem.homepage = "http://github.com/jasonmadigan/rowl"
12
+ gem.authors = ["Jason Madigan"]
13
+ gem.add_development_dependency "thoughtbot-shoulda"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/*_test.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/*_test.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ if File.exist?('VERSION')
48
+ version = File.read('VERSION')
49
+ else
50
+ version = ""
51
+ end
52
+
53
+ rdoc.rdoc_dir = 'rdoc'
54
+ rdoc.title = "rowl #{version}"
55
+ rdoc.rdoc_files.include('README*')
56
+ rdoc.rdoc_files.include('lib/**/*.rb')
57
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
data/lib/rowl.rb ADDED
@@ -0,0 +1,176 @@
1
+ # Protocol Description: http://growl.info/documentation/developer/protocol.php
2
+
3
+ require 'digest/md5'
4
+ require 'socket'
5
+ require 'rubygems'
6
+ require 'ruby-debug'
7
+
8
+ module Rowl
9
+
10
+ GROWL_UDP_PORT = 9887
11
+ GROWL_PROTOCOL_VERSION = 1
12
+ GROWL_TYPE_REGISTRATION = 0
13
+ GROWL_TYPE_NOTIFICATION = 1
14
+ REGISTRATION_FORMAT = "CCnCCa*" # Growl Network Registration Packet Format
15
+ NOTIFICATION_FORMAT = "CCnnnnna*" # Growl Network Notification Packet Format
16
+
17
+ class Registration
18
+
19
+ attr_accessor :application, :notifications, :host, :password
20
+
21
+ def initialize(application, notifications, host="localhost", password=nil)
22
+ @defaults = []
23
+ @application = application
24
+ @notifications = []
25
+ @password = password
26
+ @host = host
27
+
28
+ # Register notifications
29
+ notifications.each do |notification|
30
+ add_notification_type(notification[:name], notification[:enabled])
31
+ end
32
+
33
+ send_registration
34
+ end
35
+
36
+ def app_name
37
+ chars = ("a".."z").to_a + ("1".."9").to_a
38
+ Array.new(8, '').collect{chars[rand(chars.size)]}.join
39
+ end
40
+
41
+ def add_notification_type(notification, enabled)
42
+ if enabled.nil?
43
+ enabled = true
44
+ end
45
+ @notifications << notification
46
+ if enabled
47
+ @defaults << @notifications.length - 1
48
+ end
49
+ end
50
+
51
+ def send_registration
52
+ socket = UDPSocket.open
53
+ socket.send(payload, 0, @host, 9887)
54
+ end
55
+
56
+ def payload
57
+ length = 0
58
+ data = []
59
+ data_format = ""
60
+
61
+ packet = [
62
+ GROWL_PROTOCOL_VERSION,
63
+ GROWL_TYPE_REGISTRATION
64
+ ]
65
+
66
+ packet << @application.length
67
+ packet << @notifications.length
68
+ packet << @defaults.length
69
+
70
+ data << @application
71
+ data_format = "a#{@application.length}"
72
+
73
+ @notifications.each do |notify|
74
+ data << notify.length
75
+ data << notify
76
+ data_format << "na#{notify.length}"
77
+ end
78
+
79
+ @defaults.each do |notify|
80
+ data << notify
81
+ data_format << "C"
82
+ end
83
+
84
+ data = data.pack(data_format)
85
+
86
+ packet << data
87
+ packet = packet.pack(REGISTRATION_FORMAT)
88
+
89
+ if @password
90
+ checksum = Digest::MD5.digest(packet+@password)
91
+ else
92
+ checksum = Digest::MD5.digest(packet)
93
+ end
94
+
95
+ packet << checksum
96
+
97
+ return packet
98
+ end
99
+ end
100
+
101
+ class Notification
102
+ def initialize(opts={})
103
+ opts = {
104
+ :priority => 0,
105
+ :sticky => false,
106
+ :host => "localhost"
107
+ }.merge(opts)
108
+
109
+ @application = opts[:application]
110
+ @password = opts[:password]
111
+ @host = opts[:host]
112
+ @notification = opts[:notification]
113
+ @title = opts[:title]
114
+ @description = opts[:description]
115
+ @priority = opts[:priority]
116
+ @sticky = opts[:sticky]
117
+
118
+ send_notification
119
+ end
120
+
121
+ def send_notification
122
+ socket = UDPSocket.open
123
+ socket.send(payload, 0, @host, 9887)
124
+ end
125
+
126
+ def payload
127
+ flags = 0
128
+ data = []
129
+
130
+ packet = [
131
+ GROWL_PROTOCOL_VERSION,
132
+ GROWL_TYPE_NOTIFICATION,
133
+ ]
134
+
135
+ flags = 0
136
+ flags |= ((0x7 & @priority) << 1) # 3 bits for priority
137
+ flags |= 1 if @sticky # 1 bit for sticky
138
+
139
+ packet << flags
140
+ packet << @notification.length
141
+ packet << @title.length
142
+ packet << @description.length
143
+ packet << @application.length
144
+
145
+ data << @notification
146
+ data << @title
147
+ data << @description
148
+ data << @application
149
+
150
+ packet << data.join
151
+ packet = packet.pack(NOTIFICATION_FORMAT)
152
+
153
+ if @password
154
+ checksum = Digest::MD5.digest(packet+@password)
155
+ else
156
+ checksum = Digest::MD5.digest(packet)
157
+ end
158
+
159
+ packet << checksum
160
+ @datagram = packet
161
+ end
162
+
163
+ end
164
+
165
+ end
166
+
167
+ if __FILE__ == $0
168
+ registration = Rowl::Registration.new("My Application", [{:name => "My Notification", :enabled => true}, {:name => "My Other Notification Type", :enabled => false}])
169
+ Rowl::Notification.new( :application => registration.application,
170
+ :notification => registration.notifications.first,
171
+ :host => "localhost",
172
+ :password => registration.password,
173
+ :title => "Title",
174
+ :description => "Description" )
175
+ end
176
+
data/test/rowl_test.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ class RowlTest < Test::Unit::TestCase
4
+ context "A Rowl instance" do
5
+
6
+ setup do
7
+ @registration = Rowl::Registration.new("My Application", [{:name => "My Notification", :enabled => true}, {:name => "My Other Notification Type", :enabled => false}])
8
+ end
9
+
10
+ should "have registered" do
11
+ assert_not_nil @registration
12
+ end
13
+
14
+ should "be able to send a notifcation as a registered application" do
15
+ assert_not_nil Rowl::Notification.new( :application => @registration.application,
16
+ :notification => @registration.notifications.first,
17
+ :host => "localhost",
18
+ :password => @registration.password,
19
+ :title => "Title",
20
+ :description => "Description" )
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'rowl'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rowl
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jason Madigan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-15 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: thoughtbot-shoulda
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: Rowl is a simple Growl notification sender for Ruby.
26
+ email: jason@jasonmadigan.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.md
34
+ files:
35
+ - .document
36
+ - .gitignore
37
+ - LICENSE
38
+ - README.md
39
+ - Rakefile
40
+ - VERSION
41
+ - lib/rowl.rb
42
+ - test/rowl_test.rb
43
+ - test/test_helper.rb
44
+ has_rdoc: true
45
+ homepage: http://github.com/jasonmadigan/rowl
46
+ licenses: []
47
+
48
+ post_install_message:
49
+ rdoc_options:
50
+ - --charset=UTF-8
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ requirements: []
66
+
67
+ rubyforge_project:
68
+ rubygems_version: 1.3.5
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: Rowl is a simple Growl notification sender for Ruby.
72
+ test_files:
73
+ - test/rowl_test.rb
74
+ - test/test_helper.rb