Class: Growl
- Inherits:
-
Object
- Object
- Growl
- Defined in:
- lib/autotest/growl/ruby-growl.rb
Overview
ruby-growl allows you to perform Growl notification via UDP from machines without growl installed (for example, non-OSX machines).
What’s Growl? Growl is a really cool “global notification system for Mac OS X”. See growl.info/
You’ll need a Mac to recieve Growl notifications, but you can send Growl notifications from any UDP-capable machine that runs Ruby.
See also the Ruby Growl bindings in Growl’s subversion repository: growl.info/documentation/growl-source-install.php
ruby-growl also contains a command-line notification tool named ‘growl’. It is almost completely option-compatible with growlnotify. (All except for -p is supported, use –priority instead.)
Synopsis
g = Growl.new "127.0.0.1", "ruby-growl",
["ruby-growl Notification"]
g.notify "ruby-growl Notification", "It Came From Ruby-Growl",
"Greetings!"
Constant Summary collapse
- BROKEN_PACK =
The Ruby that ships with Tiger has a broken #pack, so ‘v’ means network byte order instead of ‘n’.
[1].pack("n") != "\000\001"
- VERSION =
ruby-growl Version
"1.0.1"
- GNR_FORMAT =
Growl Network Registration Packet
pack
Format – Format:struct GrowlNetworkRegistration { struct GrowlNetworkPacket { unsigned char version; unsigned char type; } __attribute__((packed)); unsigned short appNameLen; unsigned char numAllNotifications; unsigned char numDefaultNotifications; /* * Variable sized. Format: * <application name><all notifications><default notifications><checksum> * where <all notifications> is of the form (<length><name>){num} and * <default notifications> is an array of indices into the all notifications * array, each index being 8 bits. */ unsigned char data[]; } __attribute__((packed));
"CCnCCa*"
- GNN_FORMAT =
Growl Network Notification Packet
pack
Format – Format:struct GrowlNetworkNotification { struct GrowlNetworkPacket { unsigned char version; unsigned char type; } __attribute__((packed)); struct GrowlNetworkNotificationFlags { unsigned reserved: 12; signed priority: 3; unsigned sticky: 1; } __attribute__((packed)) flags; //size = 16 (12 + 3 + 1) unsigned short nameLen; unsigned short titleLen; unsigned short descriptionLen; unsigned short appNameLen; /* * Variable sized. Format: * <notification name><title><description><application name><checksum> */ unsigned char data[]; } __attribute__((packed));
"CCnnnnna*"
- GROWL_UDP_PORT =
Growl UDP Port
9887
- GROWL_PROTOCOL_VERSION =
Growl Protocol Version
1
- GROWL_TYPE_REGISTRATION =
Growl Registration Packet Id
0
- GROWL_TYPE_NOTIFICATION =
Growl Notification Packet Id
1
Instance Method Summary collapse
-
#initialize(host, app_name, all_notifies, default_notifies = nil, password = nil) ⇒ Growl
constructor
Creates a new Growl notifier and automatically registers any notifications with the remote machine.
-
#notification_packet(name, title, description, priority, sticky) ⇒ Object
Builds a Growl notification packet.
-
#notify(notify_type, title, message, priority = 0, sticky = false) ⇒ Object
Sends a notification.
-
#register ⇒ Object
Registers the notification types with
host
. -
#registration_packet ⇒ Object
Builds a Growl registration packet.
-
#send(packet) ⇒ Object
Sends a Growl packet.
-
#set_sndbuf(length) ⇒ Object
Set the size of the send buffer – Is this truly necessary?.
Constructor Details
#initialize(host, app_name, all_notifies, default_notifies = nil, password = nil) ⇒ Growl
Creates a new Growl notifier and automatically registers any notifications with the remote machine.
host
is the host to contact.
app_name
is the name of the application sending the notifications.
all_notifies
is a list of notification types your application sends.
default_notifies
is a list of notification types that are turned on by default.
I’m not sure about what default_notifies
is supposed to be set to, since there is a comment that says “not a subset of all_notifies” in the code.
password
is the password needed to send notifications to host
.
140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/autotest/growl/ruby-growl.rb', line 140 def initialize(host, app_name, all_notifies, default_notifies = nil, password = nil) @socket = UDPSocket.open # FIXME This goes somewhere else @socket.connect host, GROWL_UDP_PORT @app_name = app_name @all_notifies = all_notifies @default_notifies = default_notifies.nil? ? all_notifies : default_notifies @password = password register end |
Instance Method Details
#notification_packet(name, title, description, priority, sticky) ⇒ Object
Builds a Growl notification packet
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/autotest/growl/ruby-growl.rb', line 241 def notification_packet(name, title, description, priority, sticky) flags = 0 data = [] packet = [ GROWL_PROTOCOL_VERSION, GROWL_TYPE_NOTIFICATION, ] flags = 0 flags |= ((0x7 & priority) << 1) # 3 bits for priority flags |= 1 if sticky # 1 bit for sticky packet << flags packet << name.length packet << title.length packet << description.length packet << @app_name.length data << name data << title data << description data << @app_name packet << data.join packet = packet.pack GNN_FORMAT checksum = MD5.new packet checksum.update @password unless @password.nil? packet << checksum.digest return packet end |
#notify(notify_type, title, message, priority = 0, sticky = false) ⇒ Object
Sends a notification.
notify_type
is the type of notification to send.
title
is a title for the notification.
message
is the body of the notification.
priority
is the priorty of message to send.
sticky
makes the notification stick until clicked.
166 167 168 169 170 171 |
# File 'lib/autotest/growl/ruby-growl.rb', line 166 def notify(notify_type, title, , priority = 0, sticky = false) raise "Unknown Notification" unless @all_notifies.include? notify_type raise "Invalid Priority" unless priority >= -2 and priority <= 2 send notification_packet(notify_type, title, , priority, sticky) end |
#register ⇒ Object
Registers the notification types with host
.
178 179 180 |
# File 'lib/autotest/growl/ruby-growl.rb', line 178 def register send registration_packet end |
#registration_packet ⇒ Object
Builds a Growl registration packet
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/autotest/growl/ruby-growl.rb', line 194 def registration_packet length = 0 data = [] data_format = "" packet = [ GROWL_PROTOCOL_VERSION, GROWL_TYPE_REGISTRATION ] packet << @app_name.length packet << @all_notifies.length packet << @default_notifies.length data << @app_name data_format = "a#{@app_name.length}" @all_notifies.each do |notify| data << notify.length data << notify data_format << "na#{notify.length}" end @default_notifies.each do |notify| data << @all_notifies.index(notify) if @all_notifies.include? notify data_format << "C" end data_format.gsub!(/n/, 'v') if BROKEN_PACK data = data.pack data_format packet << data packet = packet.pack GNR_FORMAT checksum = MD5.new packet checksum.update @password unless @password.nil? packet << checksum.digest return packet end |
#send(packet) ⇒ Object
Sends a Growl packet
185 186 187 188 189 |
# File 'lib/autotest/growl/ruby-growl.rb', line 185 def send(packet) set_sndbuf packet.length @socket.send packet, 0 @socket.flush end |
#set_sndbuf(length) ⇒ Object
Set the size of the send buffer – Is this truly necessary?
281 282 283 |
# File 'lib/autotest/growl/ruby-growl.rb', line 281 def set_sndbuf(length) @socket.setsockopt Socket::SOL_SOCKET, Socket::SO_SNDBUF, length end |