Welcome to mirror list, hosted at ThFree Co, Russian Federation.

dev.gajim.org/gajim/gajim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYann Leboulanger <asterix@lagaule.org>2007-11-14 22:47:52 +0300
committerYann Leboulanger <asterix@lagaule.org>2007-11-14 22:47:52 +0300
commit1f7a462788b27a83ea7e0660273e6864ed71e17f (patch)
tree2e7a2846876588d3a8f5cf9302e982fc38530b74 /src/osx/growl/Growl.py
parent819b3c733520c23127d00c47ea932c3d2271191a (diff)
[James Newton] osx port for Gajim. a GREAT thanks!!!
Diffstat (limited to 'src/osx/growl/Growl.py')
-rw-r--r--src/osx/growl/Growl.py247
1 files changed, 247 insertions, 0 deletions
diff --git a/src/osx/growl/Growl.py b/src/osx/growl/Growl.py
new file mode 100644
index 000000000..15e037673
--- /dev/null
+++ b/src/osx/growl/Growl.py
@@ -0,0 +1,247 @@
+"""
+A Python module that enables posting notifications to the Growl daemon.
+See <http://growl.info/> for more information.
+"""
+__version__ = "0.7"
+__author__ = "Mark Rowe <bdash@users.sourceforge.net>"
+__copyright__ = "(C) 2003 Mark Rowe <bdash@users.sourceforge.net>. Released under the BSD license."
+__contributors__ = ["Ingmar J Stein (Growl Team)",
+ "Rui Carmo (http://the.taoofmac.com)",
+ "Jeremy Rossi <jeremy@jeremyrossi.com>"
+ ]
+
+try:
+ import _growl
+except:
+ _growl = False
+import types
+import struct
+import md5
+import socket
+
+GROWL_UDP_PORT=9887
+GROWL_PROTOCOL_VERSION=1
+GROWL_TYPE_REGISTRATION=0
+GROWL_TYPE_NOTIFICATION=1
+
+GROWL_APP_NAME="ApplicationName"
+GROWL_APP_ICON="ApplicationIcon"
+GROWL_NOTIFICATIONS_DEFAULT="DefaultNotifications"
+GROWL_NOTIFICATIONS_ALL="AllNotifications"
+GROWL_NOTIFICATIONS_USER_SET="AllowedUserNotifications"
+
+GROWL_NOTIFICATION_NAME="NotificationName"
+GROWL_NOTIFICATION_TITLE="NotificationTitle"
+GROWL_NOTIFICATION_DESCRIPTION="NotificationDescription"
+GROWL_NOTIFICATION_ICON="NotificationIcon"
+GROWL_NOTIFICATION_APP_ICON="NotificationAppIcon"
+GROWL_NOTIFICATION_PRIORITY="NotificationPriority"
+
+GROWL_NOTIFICATION_STICKY="NotificationSticky"
+GROWL_NOTIFICATION_CLICK_CONTEXT="NotificationClickContext"
+
+GROWL_APP_REGISTRATION="GrowlApplicationRegistrationNotification"
+GROWL_APP_REGISTRATION_CONF="GrowlApplicationRegistrationConfirmationNotification"
+GROWL_NOTIFICATION="GrowlNotification"
+GROWL_SHUTDOWN="GrowlShutdown"
+GROWL_PING="Honey, Mind Taking Out The Trash"
+GROWL_PONG="What Do You Want From Me, Woman"
+GROWL_IS_READY="Lend Me Some Sugar; I Am Your Neighbor!"
+
+GROWL_NOTIFICATION_CLICKED="GrowlClicked!"
+GROWL_NOTIFICATION_TIMED_OUT="GrowlTimedOut!"
+GROWL_KEY_CLICKED_CONTEXT="ClickedContext"
+
+
+growlPriority = {"Very Low":-2,"Moderate":-1,"Normal":0,"High":1,"Emergency":2}
+
+class netgrowl:
+ """Builds a Growl Network Registration packet.
+ Defaults to emulating the command-line growlnotify utility."""
+
+ __notAllowed__ = [GROWL_APP_ICON, GROWL_NOTIFICATION_ICON, GROWL_NOTIFICATION_APP_ICON]
+
+ def __init__(self, hostname, password ):
+ self.hostname = hostname
+ self.password = password
+ self.socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
+
+ def send(self, data):
+ self.socket.sendto(data, (self.hostname, GROWL_UDP_PORT))
+
+ def PostNotification(self, userInfo):
+ if userInfo.has_key(GROWL_NOTIFICATION_PRIORITY):
+ priority = userInfo[GROWL_NOTIFICATION_PRIORITY]
+ else:
+ priority = 0
+ if userInfo.has_key(GROWL_NOTIFICATION_STICKY):
+ sticky = userInfo[GROWL_NOTIFICATION_STICKY]
+ else:
+ priority = False
+ data = self.encodeNotify(userInfo[GROWL_APP_NAME],
+ userInfo[GROWL_NOTIFICATION_NAME],
+ userInfo[GROWL_NOTIFICATION_TITLE],
+ userInfo[GROWL_NOTIFICATION_DESCRIPTION],
+ priority,
+ sticky)
+ return self.send(data)
+
+ def PostRegistration(self, userInfo):
+ data = self.encodeRegistration(userInfo[GROWL_APP_NAME],
+ userInfo[GROWL_NOTIFICATIONS_ALL],
+ userInfo[GROWL_NOTIFICATIONS_DEFAULT])
+ return self.send(data)
+
+ def encodeRegistration(self, application, notifications, defaultNotifications):
+ data = struct.pack("!BBH",
+ GROWL_PROTOCOL_VERSION,
+ GROWL_TYPE_REGISTRATION,
+ len(application) )
+ data += struct.pack("BB",
+ len(notifications),
+ len(defaultNotifications) )
+ data += application
+ for i in notifications:
+ encoded = i.encode("utf-8")
+ data += struct.pack("!H", len(encoded))
+ data += encoded
+ for i in defaultNotifications:
+ data += struct.pack("B", i)
+ return self.encodePassword(data)
+
+ def encodeNotify(self, application, notification, title, description,
+ priority = 0, sticky = False):
+
+ application = application.encode("utf-8")
+ notification = notification.encode("utf-8")
+ title = title.encode("utf-8")
+ description = description.encode("utf-8")
+ flags = (priority & 0x07) * 2
+ if priority < 0:
+ flags |= 0x08
+ if sticky:
+ flags = flags | 0x0001
+ data = struct.pack("!BBHHHHH",
+ GROWL_PROTOCOL_VERSION,
+ GROWL_TYPE_NOTIFICATION,
+ flags,
+ len(notification),
+ len(title),
+ len(description),
+ len(application) )
+ data += notification
+ data += title
+ data += description
+ data += application
+ return self.encodePassword(data)
+
+ def encodePassword(self, data):
+ checksum = md5.new()
+ checksum.update(data)
+ if self.password:
+ checksum.update(self.password)
+ data += checksum.digest()
+ return data
+
+class _ImageHook(type):
+ def __getattribute__(self, attr):
+ global Image
+ if Image is self:
+ from _growlImage import Image
+
+ return getattr(Image, attr)
+
+class Image(object):
+ __metaclass__ = _ImageHook
+
+class _RawImage(object):
+ def __init__(self, data): self.rawImageData = data
+
+class GrowlNotifier(object):
+ """
+ A class that abstracts the process of registering and posting
+ notifications to the Growl daemon.
+
+ You can either pass `applicationName', `notifications',
+ `defaultNotifications' and `applicationIcon' to the constructor
+ or you may define them as class-level variables in a sub-class.
+
+ `defaultNotifications' is optional, and defaults to the value of
+ `notifications'. `applicationIcon' is also optional but defaults
+ to a pointless icon so is better to be specified.
+ """
+
+ applicationName = 'GrowlNotifier'
+ notifications = []
+ defaultNotifications = []
+ applicationIcon = None
+ _notifyMethod = _growl
+ _notify_cb = None
+
+ def __init__(self, applicationName=None, notifications=None, defaultNotifications=None, applicationIcon=None, hostname=None, password=None, notify_cb=None):
+ assert(applicationName is not None, 'an application name is required')
+ self.applicationName = applicationName
+
+ assert(notifications, 'a sequence of one or more notification names is required')
+ self.notifications = list(notifications)
+ if defaultNotifications is not None:
+ self.defaultNotifications = list(defaultNotifications)
+ else:
+ self.defaultNotifications = list(self.notifications)
+
+ if applicationIcon is not None:
+ self.applicationIcon = self._checkIcon(applicationIcon)
+
+ if hostname is not None and password is not None:
+ self._notifyMethod = netgrowl(hostname, password)
+ elif hostname is not None or password is not None:
+ raise KeyError, "Hostname and Password are both required for a network notification"
+
+ if notify_cb is not None:
+ self._notify_cb = notify_cb
+ else:
+ self._notify_cb = self.notifyCB
+
+ if hostname is None and password is None:
+ self._notifyMethod.Init(applicationName, self._notify_cb)
+
+ def _checkIcon(self, data):
+ if isinstance(data, str):
+ return _RawImage(data)
+ else:
+ return data
+
+ def register(self):
+ if self.applicationIcon is not None:
+ self.applicationIcon = self._checkIcon(self.applicationIcon)
+
+ regInfo = {GROWL_APP_NAME: self.applicationName,
+ GROWL_NOTIFICATIONS_ALL: self.notifications,
+ GROWL_NOTIFICATIONS_DEFAULT: self.defaultNotifications,
+ GROWL_APP_ICON:self.applicationIcon,
+ }
+ self._notifyMethod.PostRegistration(regInfo)
+
+ def notify(self, noteType, title, description, icon=None, sticky=False, priority=None, context=None):
+ assert noteType in self.notifications
+ notifyInfo = {GROWL_NOTIFICATION_NAME: noteType,
+ GROWL_APP_NAME: self.applicationName,
+ GROWL_NOTIFICATION_TITLE: title,
+ GROWL_NOTIFICATION_DESCRIPTION: description,
+ }
+ if sticky:
+ notifyInfo[GROWL_NOTIFICATION_STICKY] = 1
+
+ if priority is not None:
+ notifyInfo[GROWL_NOTIFICATION_PRIORITY] = priority
+
+ if icon:
+ notifyInfo[GROWL_NOTIFICATION_ICON] = self._checkIcon(icon)
+
+ if context:
+ notifyInfo[GROWL_NOTIFICATION_CLICK_CONTEXT] = context
+
+ self._notifyMethod.PostNotification(notifyInfo)
+
+ def notifyCB(self, userdata):
+ print "Got notify in pyland", userdata