/plugins/growl.py
https://github.com/ozamosi/river · Python · 150 lines · 101 code · 25 blank · 24 comment · 7 complexity · a394d084a2b61ef4c1050ae4b32590fd MD5 · raw file
- #!/usr/bin/env python
- ###
- ### netgrowl
- ###
- """Growl 0.6 Network Protocol Client for Python"""
- __version__ = "0.6.1" # will always match Growl version
- __author__ = "Rui Carmo (http://the.taoofmac.com)"
- __copyright__ = "(C) 2004 Rui Carmo. Code under BSD License."
- __contributors__ = "Ingmar J Stein (Growl Team)"
- import struct
- import md5
- from socket import AF_INET, SOCK_DGRAM, socket
- GROWL_UDP_PORT=9887
- GROWL_PROTOCOL_VERSION=1
- GROWL_TYPE_REGISTRATION=0
- GROWL_TYPE_NOTIFICATION=1
- class GrowlRegistrationPacket:
- """Builds a Growl Network Registration packet.
- Defaults to emulating the command-line growlnotify utility."""
- def __init__(self, application="growlnotify", password = None ):
- self.notifications = []
- self.defaults = [] # array of indexes into notifications
- self.application = application.encode("utf-8")
- self.password = password
- # end def
- def addNotification(self, notification="Command-Line Growl Notification", enabled=True):
- """Adds a notification type and sets whether it is enabled on the GUI"""
- self.notifications.append(notification)
- if enabled:
- self.defaults.append(len(self.notifications)-1)
- # end def
- def payload(self):
- """Returns the packet payload."""
- self.data = struct.pack( "!BBH",
- GROWL_PROTOCOL_VERSION,
- GROWL_TYPE_REGISTRATION,
- len(self.application) )
- self.data += struct.pack( "BB",
- len(self.notifications),
- len(self.defaults) )
- self.data += self.application
- for notification in self.notifications:
- encoded = notification.encode("utf-8")
- self.data += struct.pack("!H", len(encoded))
- self.data += encoded
- for default in self.defaults:
- self.data += struct.pack("B", default)
- self.checksum = md5.new()
- self.checksum.update(self.data)
- if self.password:
- self.checksum.update(self.password)
- self.data += self.checksum.digest()
- return self.data
- # end def
- # end class
- class GrowlNotificationPacket:
- """Builds a Growl Network Notification packet.
- Defaults to emulating the command-line growlnotify utility."""
- def __init__(self, application="growlnotify",
- notification="Command-Line Growl Notification", title="Title",
- description="Description", priority = 0, sticky = False, password = None ):
- self.application = application.encode("utf-8")
- self.notification = notification.encode("utf-8")
- self.title = title.encode("utf-8")
- self.description = description.encode("utf-8")
- flags = (priority & 0x07) * 2
- if priority < 0:
- flags |= 0x08
- if sticky:
- flags = flags | 0x0100
- self.data = struct.pack( "!BBHHHHH",
- GROWL_PROTOCOL_VERSION,
- GROWL_TYPE_NOTIFICATION,
- flags,
- len(self.notification),
- len(self.title),
- len(self.description),
- len(self.application) )
- self.data += self.notification
- self.data += self.title
- self.data += self.description
- self.data += self.application
- self.checksum = md5.new()
- self.checksum.update(self.data)
- if password:
- self.checksum.update(password)
- self.data += self.checksum.digest()
- # end def
- def payload(self):
- """Returns the packet payload."""
- return self.data
- # end def
- # end class
- ###
- ### End netgrowl
- ###
- # Actual plugin
- # config: str: ip; str: password;
- def notify(pdata, notif_type, title, message):
- p = GrowlNotificationPacket (application=pdata['app'], notification=notif_type,
- title=title, description=message, priority=1,
- sticky=True, password=pdata['config']['password'])
- pdata['socket'].sendto (p.payload (), pdata['addr'])
- def new_entry (pdata, dl, item): # not of interest for this plugin, but needs to be implemented
- pass
- def download_complete (pdata, dl, item):
- notify (pdata, "Download Complete", 'Download Complete', item['title'])
- def download_started (pdata, dl, item):
- notify (pdata, "Download Started", 'Download Started', item['title'])
- def download_update (pdata, dl, downloaded, length, item):
- pass
- def download_error (pdata, dl, error, item):
- pass
- def init (pdata):
- pdata['app'] = 'river'
- pdata['addr'] = (pdata['config']['ip'], GROWL_UDP_PORT)
- pdata['socket'] = socket (AF_INET, SOCK_DGRAM)
- p = GrowlRegistrationPacket (application=pdata['app'], password=pdata['config']['password'])
- p.addNotification ("Download Started", enabled=True)
- p.addNotification ("Download Complete", enabled=True)
- pdata['socket'].sendto (p.payload (), pdata['addr'])
- print 'Loaded growl plugin'
- def shutdown (pdata):
- pdata['socket'].close ()
- print 'Unloaded growl plugin'