Browse Source

Growl update

pull/84/head
Ruud 13 years ago
parent
commit
e4588a5e7e
  1. 30
      libs/gntp/__init__.py
  2. 21
      libs/gntp/notifier.py

30
libs/gntp/__init__.py

@ -1,8 +1,8 @@
import re
import hashlib import hashlib
import re
import time import time
__version__ = '0.5' __version__ = '0.6'
#GNTP/<version> <messagetype> <encryptionAlgorithmID>[:<ivValue>][ <keyHashAlgorithmID>:<keyHash>.<salt>] #GNTP/<version> <messagetype> <encryptionAlgorithmID>[:<ivValue>][ <keyHashAlgorithmID>:<keyHash>.<salt>]
GNTP_INFO_LINE = re.compile( GNTP_INFO_LINE = re.compile(
@ -50,7 +50,7 @@ class _GNTPBase(object):
:param string version: GNTP Protocol version :param string version: GNTP Protocol version
:param string encription: Encryption protocol :param string encription: Encryption protocol
""" """
def __init__(self, messagetype=None, version='1.0', encryption=None): def __init__(self, messagetype = None, version = '1.0', encryption = None):
self.info = { self.info = {
'version': version, 'version': version,
'messagetype': messagetype, 'messagetype': messagetype,
@ -80,7 +80,7 @@ class _GNTPBase(object):
return info return info
def set_password(self, password, encryptAlgo='MD5'): def set_password(self, password, encryptAlgo = 'MD5'):
"""Set a password for a GNTP Message """Set a password for a GNTP Message
:param string password: Null to clear password :param string password: Null to clear password
@ -217,7 +217,7 @@ class _GNTPBase(object):
else: else:
self.headers[key] = unicode('%s' % value, 'utf8', 'replace') self.headers[key] = unicode('%s' % value, 'utf8', 'replace')
def decode(self, data, password=None): def decode(self, data, password = None):
"""Decode GNTP Message """Decode GNTP Message
:param string data: :param string data:
@ -256,7 +256,7 @@ class GNTPRegister(_GNTPBase):
] ]
_requiredNotificationHeaders = ['Notification-Name'] _requiredNotificationHeaders = ['Notification-Name']
def __init__(self, data=None, password=None): def __init__(self, data = None, password = None):
_GNTPBase.__init__(self, 'REGISTER') _GNTPBase.__init__(self, 'REGISTER')
self.notifications = [] self.notifications = []
@ -301,7 +301,7 @@ class GNTPRegister(_GNTPBase):
#open('register.png','wblol').write(notice['Data']) #open('register.png','wblol').write(notice['Data'])
self.resources[notice.get('Identifier')] = notice self.resources[notice.get('Identifier')] = notice
def add_notification(self, name, enabled=True): def add_notification(self, name, enabled = True):
"""Add new Notification to Registration message """Add new Notification to Registration message
:param string name: Notification Name :param string name: Notification Name
@ -352,7 +352,7 @@ class GNTPNotice(_GNTPBase):
'Notification-Title' 'Notification-Title'
] ]
def __init__(self, data=None, app=None, name=None, title=None, password=None): def __init__(self, data = None, app = None, name = None, title = None, password = None):
_GNTPBase.__init__(self, 'NOTIFY') _GNTPBase.__init__(self, 'NOTIFY')
if data: if data:
@ -415,7 +415,7 @@ class GNTPSubscribe(_GNTPBase):
'Subscriber-Name', 'Subscriber-Name',
] ]
def __init__(self, data=None, password=None): def __init__(self, data = None, password = None):
_GNTPBase.__init__(self, 'SUBSCRIBE') _GNTPBase.__init__(self, 'SUBSCRIBE')
if data: if data:
self.decode(data, password) self.decode(data, password)
@ -431,7 +431,7 @@ class GNTPOK(_GNTPBase):
""" """
_requiredHeaders = ['Response-Action'] _requiredHeaders = ['Response-Action']
def __init__(self, data=None, action=None): def __init__(self, data = None, action = None):
_GNTPBase.__init__(self, '-OK') _GNTPBase.__init__(self, '-OK')
if data: if data:
self.decode(data) self.decode(data)
@ -448,7 +448,7 @@ class GNTPError(_GNTPBase):
""" """
_requiredHeaders = ['Error-Code', 'Error-Description'] _requiredHeaders = ['Error-Code', 'Error-Description']
def __init__(self, data=None, errorcode=None, errordesc=None): def __init__(self, data = None, errorcode = None, errordesc = None):
_GNTPBase.__init__(self, '-ERROR') _GNTPBase.__init__(self, '-ERROR')
if data: if data:
self.decode(data) self.decode(data)
@ -460,7 +460,7 @@ class GNTPError(_GNTPBase):
return self.headers['Error-Code'], self.headers['Error-Description'] return self.headers['Error-Code'], self.headers['Error-Description']
def parse_gntp(data, password=None): def parse_gntp(data, password = None):
"""Attempt to parse a message as a GNTP message """Attempt to parse a message as a GNTP message
:param string data: Message to be parsed :param string data: Message to be parsed
@ -471,11 +471,11 @@ def parse_gntp(data, password=None):
raise ParseError('INVALID_GNTP_INFO') raise ParseError('INVALID_GNTP_INFO')
info = match.groupdict() info = match.groupdict()
if info['messagetype'] == 'REGISTER': if info['messagetype'] == 'REGISTER':
return GNTPRegister(data, password=password) return GNTPRegister(data, password = password)
elif info['messagetype'] == 'NOTIFY': elif info['messagetype'] == 'NOTIFY':
return GNTPNotice(data, password=password) return GNTPNotice(data, password = password)
elif info['messagetype'] == 'SUBSCRIBE': elif info['messagetype'] == 'SUBSCRIBE':
return GNTPSubscribe(data, password=password) return GNTPSubscribe(data, password = password)
elif info['messagetype'] == '-OK': elif info['messagetype'] == '-OK':
return GNTPOK(data) return GNTPOK(data)
elif info['messagetype'] == '-ERROR': elif info['messagetype'] == '-ERROR':

21
libs/gntp/notifier.py

@ -24,12 +24,17 @@ logger = logging.getLogger(__name__)
def mini(description, applicationName = 'PythonMini', noteType = "Message", def mini(description, applicationName = 'PythonMini', noteType = "Message",
title = "Mini Message", applicationIcon = None, hostname = 'localhost', title = "Mini Message", applicationIcon = None, hostname = 'localhost',
password = None, port = 23053, sticky = False, priority = None): password = None, port = 23053, sticky = False, priority = None,
callback = None):
"""Single notification function """Single notification function
Simple notification function in one line. Has only one required parameter Simple notification function in one line. Has only one required parameter
and attempts to use reasonable defaults for everything else and attempts to use reasonable defaults for everything else
:param string description: Notification message :param string description: Notification message
.. warning::
For now, only URL callbacks are supported. In the future, the
callback argument will also support a function
""" """
growl = GrowlNotifier( growl = GrowlNotifier(
applicationName = applicationName, applicationName = applicationName,
@ -50,6 +55,7 @@ def mini(description, applicationName = 'PythonMini', noteType = "Message",
icon = applicationIcon, icon = applicationIcon,
sticky = sticky, sticky = sticky,
priority = priority, priority = priority,
callback = callback,
) )
@ -66,6 +72,7 @@ class GrowlNotifier(object):
""" """
passwordHash = 'MD5' passwordHash = 'MD5'
socketTimeout = 3
def __init__(self, applicationName = 'Python GNTP', notifications = [], def __init__(self, applicationName = 'Python GNTP', notifications = [],
defaultNotifications = None, applicationIcon = None, hostname = 'localhost', defaultNotifications = None, applicationIcon = None, hostname = 'localhost',
@ -112,7 +119,8 @@ class GrowlNotifier(object):
self.register_hook(register) self.register_hook(register)
return self._send('register', register) return self._send('register', register)
def notify(self, noteType, title, description, icon = None, sticky = False, priority = None): def notify(self, noteType, title, description, icon = None, sticky = False,
priority = None, callback = None):
"""Send a GNTP notifications """Send a GNTP notifications
.. warning:: .. warning::
@ -124,6 +132,11 @@ class GrowlNotifier(object):
:param string icon: Icon URL path :param string icon: Icon URL path
:param boolean sticky: Sticky notification :param boolean sticky: Sticky notification
:param integer priority: Message priority level from -2 to 2 :param integer priority: Message priority level from -2 to 2
:param string callback: URL callback
.. warning::
For now, only URL callbacks are supported. In the future, the
callback argument will also support a function
""" """
logger.info('Sending notification [%s] to %s:%s', noteType, self.hostname, self.port) logger.info('Sending notification [%s] to %s:%s', noteType, self.hostname, self.port)
assert noteType in self.notifications assert noteType in self.notifications
@ -141,6 +154,8 @@ class GrowlNotifier(object):
notice.add_header('Notification-Icon', self._checkIcon(icon)) notice.add_header('Notification-Icon', self._checkIcon(icon))
if description: if description:
notice.add_header('Notification-Text', description) notice.add_header('Notification-Text', description)
if callback:
notice.add_header('Notification-Callback-Target', callback)
self.add_origin_info(notice) self.add_origin_info(notice)
self.notify_hook(notice) self.notify_hook(notice)
@ -186,7 +201,7 @@ class GrowlNotifier(object):
logger.debug('To : %s:%s <%s>\n%s', self.hostname, self.port, packet.__class__, data) logger.debug('To : %s:%s <%s>\n%s', self.hostname, self.port, packet.__class__, data)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(3) s.settimeout(self.socketTimeout)
s.connect((self.hostname, self.port)) s.connect((self.hostname, self.port))
s.send(data.encode('utf8', 'replace')) s.send(data.encode('utf8', 'replace'))
recv_data = s.recv(1024) recv_data = s.recv(1024)

Loading…
Cancel
Save