4

I am making an app in python 2.7 on mac osx 10.8.5 I want to show notification number of times, therefore using NSUserNotificationCenter. Notifications are coming while running code on eclipse. But, the issue is when I made app using py2app, Notifications are not coming. Moreover, the default page of error of open console and Terminate is coming. Please suggest some way, how to include Notification in dist generated by py2app, so that It will work on any other machine. My setup.py is

from setuptools import setup

APP=['CC4Box.py']
DATA_FILES= [('',['config.cfg'])]
OPTIONS={'iconfile':'cc.icns','argv_emulation': True,'plist':{'CFBundleShortVersionString':'1.0'}}

setup(
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app']
    ) 

My notification code is:

def notify(title, subtitle, info_text, delay=0, sound=False, userInfo={}):
    NSUserNotification = objc.lookUpClass('NSUserNotification')
    NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
    notification = NSUserNotification.alloc().init()
    notification.setTitle_(title)
    notification.setSubtitle_(subtitle)
    notification.setInformativeText_(info_text)
    notification.setUserInfo_(userInfo)
    if sound:
        notification.setSoundName_("NSUserNotificationDefaultSoundName")
    notification.setDeliveryDate_(Foundation.NSDate.dateWithTimeInterval_sinceDate_(delay, Foundation.NSDate.date()))
    NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)


def notificationBalloon(title,msg):
    notify(title1, msg1,"", sound=False) 

On eclipse, notifications are coming as expected, however, import error produced in lines:

NSUserNotification = objc.lookUpClass('NSUserNotification')
 NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter') 

but in terminal these lines are nicely run.

imp
  • 1,967
  • 2
  • 28
  • 40
  • do you also get the error message without further information when you launch te application from the terminal (that is run "dist/CC4Box.app/Contents/MacOS/CCBox4" as a command in Terminal.app, with the current working directory set to the directory when you ran py2app) – Ronald Oussoren Oct 30 '13 at 16:18
  • yes, same error occured when run through terminal. But working fine when run code in eclipse as I have added path in $PYTHONPATH. No idea how to give path in py2app for it – imp Oct 30 '13 at 16:42
  • What likely happens is that the $PYTHONPATH setting is not active when you run py2app, and therefore py2app cannot find a module that is needed by the script and hence that module is not copied into the application bundle. – Ronald Oussoren Oct 31 '13 at 07:27
  • yes, in eclipse, we can set the $PYTHONPATH, therefore it is working fine. But, with py2app there is no such thing I guess to include module. Is there any other way to resolve this issue – imp Oct 31 '13 at 07:46
  • You need to set PYTHONPATH in the shell that runs “python setup.py py2app”, PYTHONPATH is a *python* setting, not a *py2app* setting. – Ronald Oussoren Oct 31 '13 at 08:22
  • How to set PYTHONPATH in the shell that runs “python setup.py py2app". Please suggest, it will solve the issue – imp Oct 31 '13 at 08:26

2 Answers2

0

My guess is, .lookUpClass() should be resolved at runtime. Thus you don't actually want to include that class in your py2app. Unless you wrote this class yourself that it.

What you do want to include is objc and related libraries. Make sure it's in your virtualenv when you call py2app. If python -m pydoc objc works, so should python setup.py py2app.

Dima Tisnek
  • 11,241
  • 4
  • 68
  • 120
  • NSUserNotification = objc._objc.lookUpClass('NSUserNotification') NSUserNotificationCenter = objc._objc.lookUpClass('NSUserNotificationCenter') I am using. It shows no error. But, in other mac system, it is showing apple.lauched.error 501[128] – imp Nov 18 '13 at 16:51
  • same osx versions or different? – Dima Tisnek Nov 18 '13 at 17:09
  • perhaps you also need `import Foundation` to get foundation services python wrapper? – Dima Tisnek Nov 18 '13 at 17:13
  • Same osx version. I am importing Foundation, AppKit,objc. Is there any other way for popup notification that I can implement in python and can be packaged through py2app effectively. – imp Nov 18 '13 at 17:45
  • In the old days, `Growl` was required. Nowadays, I think you should be able to get by without. – Dima Tisnek Nov 19 '13 at 10:55
  • http://stackoverflow.com/questions/16021330/nsusernotificationcenter-defaultusernotificationcenter-returns-none-in-python read through comments re 32/64 bit and bundle/plugin – Dima Tisnek Nov 19 '13 at 10:58
  • Growl is not free. I install objc through easy_install pyobjc. Can you suggest some other library/module in python for pop-up – imp Nov 19 '13 at 11:04
  • growl is AFAIK the only option that supports older osx versions. alloy's terminal-notifier referred in someone-or-other's answer only supports 10.8 and newer, but is unencumbered. readme includes build tweaks/limitations. there's https://pypi.python.org/pypi/pync that user the latter too. take your pick. – Dima Tisnek Nov 19 '13 at 11:14
  • pync will work only when terminal-notifier is installed in system. terminal-notifier uses Ruby gem which is installed in /Library/Ruby. So issue with that is how to include it while packaging of app like though py2app. – imp Nov 19 '13 at 11:53
0

If you are trying to create a pop-up window to notify the user of certain information, there are plenty of python modules for this purpose. Wx python is a good choice. Here is the documentation for pop-up windows:

http://wxpython.org/docs/api/wx.PopupWindow-class.html

EDIT: That won't get an apple notification in the way you want. Try this code. It uses a downloadable command line tool called terminal-notifier to make notifications, accessed through python via sub process:

import subprocess

def notification(title, subtitle, message):
    subprocess.Popen(['terminal-notifier','-message',message,'-title',title,'-subtitle',subtitle])

notification(title = 'notification title', subtitle = 'subtitle', message  = 'Hello World')

This should get the results you want, although to install it automatically you need to run a build in ruby. You could also get it to play sounds, change some ID parameters, and even tell it to run a shell command when you click on it. For more information go here, this is where you can get the source and the docs:

https://github.com/julienXX/terminal-notifier

Cœur
  • 37,241
  • 25
  • 195
  • 267
trevorKirkby
  • 1,886
  • 20
  • 47
  • I don't want window asking for 'OK' press for exiting of message. The pop-up should come and go automatically. I want to call pop-up function many times. Working on python on mac – imp Nov 19 '13 at 04:18
  • There are lower level WX windows. You could use a timer to make it automatically close. However, if your looking for the notification rectangles that pop up in the side of the screen on a mac with a newer operating system, WX probably isn't the best solution. – trevorKirkby Nov 19 '13 at 04:30
  • how to achieve that pop-up. PLease suggest. – imp Nov 19 '13 at 04:47
  • this should be what you are looking for – trevorKirkby Nov 19 '13 at 05:13
  • I want to achieve simple pop-up to display text message to user which can be easily bundled through py2app. Not like window which asks for clicking on OK to exit. Please suggest. – imp Nov 19 '13 at 05:27
  • That shouldn't have an OK button on it... It could be difficult to use with py2app though. I believe you can specify it to include file resources like that in the compiler program. I know you can do that on py2exe, the windows version. – trevorKirkby Nov 19 '13 at 05:42
  • Interesting suggestion. I think it's worth following code flow and build in the linked github ruby solution. Perhaps OP missed something in his environment, e.g. application needs to be installed, some link, etc? – Dima Tisnek Nov 19 '13 at 10:57
  • @someone-or-other I tried with terminal-notifier. It worked properly. However, issue with it is how to bundle it through py2app. As i want to distribute it. Can you suggest some other methods/libraries for it. – imp Nov 19 '13 at 10:59
  • I don't know of any other tools to do this. However, because it is a shell command you should be able to use "python setup.py py2app --resources " in your compiler to include the program in the exe bundle. – trevorKirkby Nov 20 '13 at 03:07