2010-06-27 17 views
5

Estoy tratando de usar los enlaces de Growl Python (Growl.py v0.7 desde el repositorio de Growl) para escribir una aplicación pequeña. Una de las características que falta actualmente es la notificación de clic enviada a Python.Growl Python binding with Click feedback?

Sé en Objective-C, cuando un usuario hace clic en la notificación, se enviará un disparador a la aplicación en ejecución. Me gustaría hacer algo similar con las vinculaciones de Python. Cuando un usuario hace clic en una notificación, me gustaría que el programa Python abra una URL en el navegador (o maneje el evento de otra manera).

¿Alguna idea sobre cómo podría lograrlo?

Actualización: Gracias a synthesizerpatel que ofrece una solución prometedora y creo que sus palabras funcionaron en Lion. Desafortunadamente, estoy empezando a desaparecer de Mac, así que ya no hago mucha programación de Mac. Sin embargo, he hecho un poco de depuración, ya que todavía no está trabajando en Snow Leopard, y aquí es por qué:

Discussion Growl PyObjC not working with PyObjC 2.2b3

Source code

+0

¿Alguna suerte aquí? Me encantaría saber también. –

+0

Todavía es una pregunta abierta ~ – Patrick

+0

¿Está buscando esto para captar todas las notificaciones de gruñidos o simplemente una aplicación de Python que tiene la capacidad de enviar notificaciones de gruñidos y de poder hacer clic en el mouse cuando el usuario lo descarta? – synthesizerpatel

Respuesta

1

¿Es esto lo que quieres?

#!/usr/bin/env python 
# 
# pyGrr! 
# 
# This code was originally found @ 
# http://www.cocoaforge.com/viewtopic.php?f=6&t=13359&p=91992&hilit=pyobjc+growl 
# It is (to the best of our knowledge) the work of user 'tooru' on the same 
# website. 
# 
# I make no claim to this code, all I did was get it working with PyObjC on Lion 
# reformatted it a bit and added some more verbose explanations of what the script 
# does. To be honest, I haven't touched pyobjc in a couple years and I was amazed 
# that it still works! Even more amazed that I was able to get this example working 
# in about 20 minutes. 
# 
# Great job tooru! 
# 
# I have verified this code works with the following combination of 
# packages/versions 
# 
# * OSX Lion 10.7.3 
# * Python 2.7 
# * Growl 1.3 
# * Growl SDK 1.3.1 
# 
# 
# - Nathan Ramella [email protected] (http://www.remix.net) 
################################################################################## 

import objc 
from Foundation import * 
from AppKit import * 
from PyObjCTools import AppHelper 
import time 
import sys 
import os 

myGrowlBundle = objc.loadBundle(
    "GrowlApplicationBridge", 
    globals(), 
    bundle_path = objc.pathForFramework(
    '/Library/Frameworks/Growl.framework' 
) 
) 

class MenuMakerDelegate(NSObject): 

    """ 
    This is a delegate for Growl, a required element of using the Growl 
    service. 

    There isn't a requirement that delegates actually 'do' anything, but 
    in this case, it does. We'll make a little menu up on the status bar 
    which will be named 'pyGrr!' 

    Inside the menu will be two options, 'Send a Grr!', and 'Quit'. 

    Send a Grr! will emit a growl notification that when clicked calls back 
    to the Python code so you can take some sort of action - if you're that 
    type of person. 
    """ 

    statusbar = None 
    state = 'idle' 

    def applicationDidFinishLaunching_(self, notification): 

    """ 
    Setup the menu and our menu items. Getting excited yet? 
    """ 

    statusbar = NSStatusBar.systemStatusBar() 
    # Create the statusbar item 
    self.statusitem = statusbar.statusItemWithLength_(NSVariableStatusItemLength) 

    self.statusitem.setHighlightMode_(1) # Let it highlight upon clicking 
    self.statusitem.setToolTip_('pyGrr!') # Set a tooltip 
    self.statusitem.setTitle_('pyGrr!') # Set an initial title 

    # Build a very simple menu 
    self.menu = NSMenu.alloc().init() 
    menuitem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(
     'Send a Grr!', 
     'rcNotification:', 
     '' 
    ) 
    self.menu.addItem_(menuitem) 

    # Default event 
    menuitem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(
     'Quit', 
     'terminate:', 
     '' 
    ) 
    self.menu.addItem_(menuitem) 

    # Bind it to the status item 
    self.statusitem.setMenu_(self.menu) 

    def rcNotification_(self,notification): 

    """ 
    This is run when you select the 'Send a Grr!' menu item. It 
    will lovingly bundle up a Grr and send it Growl's way. 
    """ 

    print "Sending a growl notification at", time.time() 

    GrowlApplicationBridge.notifyWithTitle_description_notificationName_iconData_priority_isSticky_clickContext_(
     "Grr! - I'm a title!", 
     "This is where you put notification information.", 
     "test1", 
     None, 
     0, 
     False, 
     "this ends up being the argument to your context callback" 
    ) 

class rcGrowl(NSObject): 

    """ 
    rcGrowl registers us with Growl to send out Grrs on behalf 
    of the user and do 'something' with the results when a 
    Grr has been clicked. 

    For additional information on what the what is going on 
    please refer to the growl dox @ 

    http://growl.info/documentation/developer/implementing-growl.php 
    """ 

    def rcSetDelegate(self): 
    GrowlApplicationBridge.setGrowlDelegate_(self) 

    def registrationDictionaryForGrowl(self): 

    """ 
    http://growl.info/documentation/developer/implementing-growl.php#registration 
    """ 

    return { 
     u'ApplicationName' : 'rcGrowlMacTidy', 
     u'AllNotifications' : ['test1'], 
     u'DefaultNotifications' : ['test1'], 
     u'NotificationIcon' : None, 
    } 

    # don't know if it is working or not 
    def applicationNameForGrowl(self): 
    """ 
    Identifies the application. 
    """ 
    return 'rcGrowlMacTidy' 

    #def applicationIconDataForGrowl(self): 
    """ 
    If you wish to include a custom icon with the Grr, 
    you can do so here. Disabled by default since I didn't 
    want to bloat up this up 
    """ 
    #icon = NSImage.alloc().init() 
    #icon = icon.initWithContentsOfFile_(u'remix_icon.tiff') 
    #return icon 

    def growlNotificationWasClicked_(self, ctx): 

    """ 
    callback for onClick event 
    """ 
    print "we got a click! " + str(time.time()) + " >>> " + str(ctx) + " <<<\n" 

    def growlNotificationTimedOut_(self, ctx): 

    """ 
    callback for timing out 
    """ 
    print "We timed out" + str(ctx) + "\n" 

    def growlIsReady(self): 

    """ 
    Informs the delegate that GrowlHelperApp was launched 
    successfully. Presumably if it's already running it 
    won't need to run it again? 
    """ 
    print "growl IS READY" 


if __name__ == "__main__": 

    # Both 'growlnotify' and this script seem to have the following 
    # error after emitting a Grr! 
    # 
    # Error Domain=GCDAsyncSocketErrorDomain Code=4 "Read operation timed out" 
    # UserInfo=0x7fa444e00070 {NSLocalizedDescription=Read operation timed out} 
    # 
    # So, we redirect stderr to /dev/null so that it doesn't muck up 
    # the output of this script. Some folks say upgrading Growl fixes it, 
    # others still have the problem. Doesn't seem to make much of a difference 
    # one way or another, things still seem to work regardless. 

    fp = os.open('/dev/null', os.O_RDWR|os.O_CREAT, 0o666) 
    dupped = os.dup(2) 
    os.dup2(fp, 2) 

    # set up system statusbar GUI 
    app = NSApplication.sharedApplication() 
    delegate = MenuMakerDelegate.alloc().init() 
    app.setDelegate_(delegate) 

    # set up growl delegate 
    rcGrowlDelegate=rcGrowl.new() 
    rcGrowlDelegate.rcSetDelegate() 
    AppHelper.runEventLoop() 
+0

Hola, gracias por el guion. Lamentablemente, no funcionó para mí, ya que tengo leopardo de las nieves con gruñido 1.2.2 – Patrick

+0

En todo caso, deberías tener menos problemas en ese caso. : D Pero, tal como es, esto es exactamente lo que estás buscando. Me gustaría saber qué mensajes de error recibes. – synthesizerpatel

+0

Sí, debería haber proporcionado más detalles ... El guión sonaba prometedor como lo que quería. Después de ejecutar el programa, creó el menú de estado con dos opciones. Sin embargo, después de hacer clic en "Send a Grr!", Solo recibí un mensaje en la consola con "Enviando una notificación de gruñido a ..." sin una notificación de Growl real. – Patrick