class Growl::UDP
Implements the UDP growl protocol used in growl 1.2 and older.
Constants
- GNN_FORMAT
Growl Network Notification Packet
pack
Format- GNR_FORMAT
Growl Network Registration Packet
pack
Format- GROWL_PROTOCOL_VERSION
Growl Protocol Version
- GROWL_TYPE_NOTIFICATION
Growl Notification Packet Id
- GROWL_TYPE_REGISTRATION
Growl Registration Packet Id
- LITTLE_ENDIAN
Endianness of this machine
- PORT
Public Class Methods
Creates a new Growl UDP 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
.
# File lib/ruby-growl/udp.rb, line 120 def initialize(host, app_name, all_notifies, default_notifies = nil, password = nil) @socket = socket host @app_name = app_name @all_notifies = all_notifies @default_notifies = default_notifies.nil? ? all_notifies : default_notifies @password = password register end
Public Instance Methods
Builds a Growl notification packet
# File lib/ruby-growl/udp.rb, line 219 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.bytesize packet << title.length packet << description.bytesize packet << @app_name.bytesize data << name data << title data << description data << @app_name packet << data.join packet = packet.pack GNN_FORMAT checksum = Digest::MD5.new << packet checksum.update @password unless @password.nil? packet << checksum.digest return packet end
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.
# File lib/ruby-growl/udp.rb, line 144 def notify(notify_type, title, message, priority = 0, sticky = false) raise Growl::Error, "Unknown Notification" unless @all_notifies.include? notify_type raise Growl::Error, "Invalid Priority" unless priority >= -2 and priority <= 2 send notification_packet(notify_type, title, message, priority, sticky) end
Registers the notification types with host
.
# File lib/ruby-growl/udp.rb, line 157 def register send registration_packet end
Builds a Growl registration packet
# File lib/ruby-growl/udp.rb, line 173 def registration_packet data = [] data_format = "" packet = [ GROWL_PROTOCOL_VERSION, GROWL_TYPE_REGISTRATION ] packet << @app_name.bytesize packet << @all_notifies.length packet << @default_notifies.length data << @app_name data_format = "a#{@app_name.bytesize}" @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 = Digest::MD5.new << packet checksum.update @password unless @password.nil? packet << checksum.digest return packet end
Sends a Growl packet
# File lib/ruby-growl/udp.rb, line 164 def send(packet) set_sndbuf packet.length @socket.send packet, 0 @socket.flush end
Set the size of the send buffer
# File lib/ruby-growl/udp.rb, line 259 def set_sndbuf(length) @socket.setsockopt Socket::SOL_SOCKET, Socket::SO_SNDBUF, length end
# File lib/ruby-growl/udp.rb, line 263 def socket host addrinfo = Addrinfo.udp host, PORT socket = Socket.new addrinfo.pfamily, addrinfo.socktype, addrinfo.protocol if addrinfo.ip_address == '255.255.255.255' then socket.setsockopt :SOL_SOCKET, :SO_BROADCAST, true elsif Socket.respond_to?(:getifaddrs) and Socket.getifaddrs.any? do |ifaddr| ifaddr.broadaddr and ifaddr.broadaddr.ip_address == addrinfo.ip_address end then socket.setsockopt :SOL_SOCKET, :SO_BROADCAST, true end socket.connect addrinfo socket end