how to include NSUserNotificationCenter in py2app - python

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.

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.

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

Related

Inno Setup PyInstaller Auto-Update

I'm trying to implement an auto-update functionality, so I'm programmatically downloading the update_myprog.exe (created with Inno Setup), and then I want to close the program immediately and run update_myprog.exe. Currently I am using subprocess.Popen() to run it, but for some reason when the update_myprog.exe runs, I get an error: "Setup was unable to automatically close all applications. It is recommended that you close all applications using files that need to be updated by Setup before continuing.". When I run update_myprog.exe myself (not through the original program), it works just fine.
So, I'm wondering, is it a problem with my Python, with Inno Setup, or something else?
Below is a simplified version of my problem, extracting just the relevant code.
Here is my python code (autoupdate.py):
import wx
import subprocess
import win32process
import tempfile
class Main(wx.Frame):
def __init__(self,*args,**kwargs):
wx.Frame.__init__(self,*args,**kwargs)
self.SetTitle('MyProg v1')
self.updatebutton=wx.Button(self,label='Update')
self.updatebutton.Bind(wx.EVT_BUTTON,self.update)
def update(self,event):
canupdate=True
if(canupdate):
tempdir=tempfile.mkdtemp()
fname=os.path.join(tempdir,'update_myprog.exe')
proc = subprocess.Popen('"update_myprog.exe" /SP- /silent /noicons /nocancel /password="pw"', creationflags=win32process.DETACHED_PROCESS,shell=True)
self.Destroy()
sys.exit()
app = wx.App(False)
Main(parent=None).Show(True)
app.MainLoop()
I then compiled it with:
pyinstaller "autoupdate.py" --distpath="make\dist" --workpath="make\build"
And then I made the installer (update_myprog.exe) with the following Inno Setup Script:
[Setup]
AppId={{7FBA93BE-7DC4-4114-91DF-DD524A078F63}
AppName=My Program
AppVersion=1
AppPublisher=My Company, Inc.
AppPublisherURL=http://www.example.com/
AppSupportURL=http://www.example.com/
AppUpdatesURL=http://www.example.com/
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
AllowNoIcons=yes
OutputDir=make/Installer
OutputBaseFilename=update_myprog
Password=pw
Compression=lzma
SolidCompression=yes
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
[Files]
Source: "C:\Python27\My Projects\Test Update\make\dist\autoupdate\autoupdate2.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\Python27\My Projects\Test Update\make\dist\autoupdate\*"; DestDir: "{app}";
[Icons]
Name: "{group}\My Program"; Filename: "{app}\autoupdate.exe"
Name: "{commondesktop}\My Program"; Filename: "{app}\autoupdate.exe"; Tasks: desktopicon
[Run]
Filename: "{app}\autoupdate.exe"; Description: "{cm:LaunchProgram,My Program}"; Flags: nowait postinstall
Then I run the installer (works fine), and copy the installer into the directory it installed to. Then I run my program, and click the button, and it gives me an error. Why?
It might help me if somebody else could run do the above steps on their computer, and let me know if they have the same problems. All help is appreciated.
Old Question:
So, I basically have the same question as Spawning a non-child process in python but for Windows.
I'm trying to implement an auto-update functionality, so I'm programmatically downloading the update_myprog.exe (created with Inno Setup), and then I want to close the program immediately and run update_myprog.exe. Currently I am using subprocess.Popen() to run it, but it seems like it is still a child of the original program, and thus cannot overwrite the exe file of the original to update it.
Would os.system be what I'm looking for, or is there some other solution?
If you want to completely detach the process you can use:
from win32process import DETACHED_PROCESS
from subprocess import Popen
Popen(["python","xyz.py"],creationflags=DETACHED_PROCESS,shell=True).pid
Update
Compiling it could lead to it's own little nightmare with the use of temporary directories, but that's another question, and god knows how wx is behaving here. Be sure that download is actually finishing and try execfile(filename) instead of Popen. If no luck there, try the following:
from subprocess import Popen, CREATE_NEW_CONSOLE,CREATE_NEW_PROCESS_GROUP
Popen(["python", 'xyz.py'],shell = True | CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE)
Failing that, repost the question and let someone else have a look. Sorry I couldn't be of more help. Let me know how you sussed it in the end.
I implemented auto-update using Inno Setup and PyInstaller over a year ago.
You need to call self.destroy() before the subprocess. This is so that after you call Inno, you can exit immediately. You can also use the /FORCECLOSEAPPLICATIONS flag so that Inno-Setup can close your program in case the sys.exit() was not fast enough.

Using Python pywin32 to send keystrokes to interactive win32 console application

So I have been trying to use Python pywin32 package to send inputs to an interactive console based win32 exe which gives me a bunch of options when executed and based on the input keyed in by the user subsequent menus are displayed. After some reading around on the net I did try to execute the following code but it is still unable to send the input to the program, so if anyone has been able to achieve something similar, please let me know.
the code I have been trying is as follows:
import win32com.client
def main():
shell = win32com.client.Dispatch("WScript.Shell")
shell.run('cmd /K cd "E:\\Documents and Settings\\Owner\\Desktop\\pds\\" && CONVERT.EXE')
shell.AppActivate('E:\\Documents and Settings\\Owner\\Desktop\\pds\\CONVERT.EXE')
print("sending keys...")
shell.SendKeys("trial.bin")
shell.SendKeys("{ENTER}")
if __name__ == '__main__':
main()
I've made small improvement in pywinauto library. Now it can deal with console window like so:
import pywinauto
app = pywinauto.Application.start('cmd.exe', wait_for_idle=False)
app.Window_().TypeKeys('cmd.exe /?{ENTER}', with_spaces=True, pause=0.1)
app.Window_().TypeKeys('{ENTER 7}', pause=0.1)

How to debug python code in OpenERP 6.1

I am working with OpenERP 6.1 and i am not able to debug the python code
by giving print statements in the python code.
This was quite easy/possible with OpenERP 6.0 where we give the server path
followed by module name and database name to debug the code.
How can i achieve this with OpenERP 6.1??
Please help!!
Thanks in advance..
Hi friend you can install ipython. Using ipython you can debug openerp 6.1 at command prompt. kindly make sure that you have installed these packages before hands.
sudo apt-get install python-dateutil python-feedparser python-gdata python-ldap python-libxslt1 python-lxml python-mako python-openid python-psycopg2 python-pybabel python-pychart python-pydot python-pyparsing python-reportlab python-simplejson python-tz python-vatnumber python-vobject python-webdav python-werkzeug python-xlwt python-yaml python-zsi
I took this list from
http://www.theopensourcerer.com/2012/02/22/how-to-install-openerp-6-1-on-ubuntu-10-04-lts/
you can also try pycharm.
To debug your Openerp+python code in eclipse, start eclipse in debug perspective and follow the given steps:
1: Stop your openERP running server by pressing "ctr+c".
2: In eclipse go to Menu "Run/Debug Configurations". In configuration window under "Python Run", create new debug configuration(Double click on 'Python Run').
3: After creating new debug configuration follow the given steps:
3.1: In "Main" tab under "Project", select the "server" project or folder (in which Openerp Server resides) from your workspace.
3.2: Write location of 'openerp-server' under "Main Module".
Ex: ${workspace_loc:server/openerp-server}.
3.3: In "Arguments" tab under "Program Arguments", click on button "Variables" and new window will appear.
3.4: Then create new "Variable" by clicking on "Edit Variables" button and new window will appear.
3.5: Press on "New" button and give your addons path as value.
Ex: --addons ../addons,../your_module_path
3.6: Press Ok in all the opened windows and then "Apply".
4: Now into "PyDev Package Explorer" view go to 6.1/server and right click on "openerp-server" file, Select 'Debug As --> Python Run'.
5: Now in "Console" you can see your server has been started.
6: Now open your .py file which you want to debug and set a break-point.
7: Now start your module's form from 'gtk' or 'web-client' and execution will stop when execution will reach to break-point.
8: Now enjoy by debugging your code by pressing "F5, F6, F7" and you can see value of your variables.
I run the 6.1 server under Eclipse and PyDev without any problems. That lets me add breakpoints and step through the code. Here are the arguments I use:
--addons-path ${workspace_loc:openerp-addons-trunk},${workspace_loc:openerp-web-trunk}/addons --config ${workspace_loc:openerp-config/src/server.config}
The two breakpoints I find most useful are at either end of the RPC call. On the server side, I put a breakpoint on this line in netsvc.dispatch_rpc():
result = ExportService.getService(service_name).dispatch(method, params)
I don't debug the client as often, and not all requests come through the same path, but one useful breakpoint is the first line of rpc.tinySocket_gw.execute().
Of course, both these breakpoints see a lot of traffic, so I only use them if I'm exploring some feature I'm not familiar with, and I don't know where the code will execute. It can also be useful to put a condition on the breakpoint so it only triggers when a request comes through for a specific model or parameter value.
Here is the config file I use:
[options]
debug_mode = False
admin_passwd = ******
db_user = ******
db_password = *******
price_accuracy = 5
smtp_server = **********
ftp_server_port = 8022
ftp_server_passive_ports = 8192:8447
translate_data = False
#log_level = debug_rpc_answer
Check that you have:
logfile = None
in your openerp-server.conf, that gives you the log through the standard output.
Does it helps ?
First: import logging
Then :
def ExampleFunction(self,cr,uid,ids,context):
log = logging.getLogger("ExampleClass -- ExampleFunction")
log.info('test')
return True
And in your openerp folder /server/server/openerp-server.log file
you will see the log.info content here ( ExampleClass -- ExampleFunction: test)

How to show the default beautiful popup message in ubuntu using python?

http://tinypic.com/r/5dv7kj/7
How can i show the message like in the picture(top right)?
I'm new to linux and now tring to use pygtk to make a client application to show/popup some random hint/mems.
Using traditional winodw is OK,but this one is much more friendly to me.I have tried scanning through the pygtk guide but still missing the solution.Other
Is there any body could give me some hint?Any python GUI libs are also OK.
It's an Ubuntu specific thing called NotifyOSD. There are examples of programming for it here.
Quick and Dirty codes in python
import pynotify
# Only Text Notification
pynotify.init('Basic')
pynotify.Notification("Title", "simple text").show()
# Lets try with an image
pynotify.init('Image')
## Use absolute Path of the photo
pynotify.Notification("Title", "My Photo here!!", "/home/nafis/Pictures/me.png").show()
# Try Markup
pynotify.init("markup") ## all smallerCase "markup"
# but in parameter, first letter capital
pynotify.Notification("Markup",
'''
<b>bold</b>, <i>italic</i>, <u>underline</u>
and even links are supported!
'''
).show()
Also You can use it from shell (I use lubuntu, it works here.)
#!/bin/bash
### try it in terminal
notify-send -t 900 "Title" "Message"
A simple method without any additional packages.
you can execute commands via os.system.
import os
def message(title, message):
os.system(f"notify-send '{title}' '{message}'")
message("Title", "Im message")

Basic cocoa application using dock in Python, but not Xcode and all that extras

It seems that if I want to create a very basic Cocoa application with a dock icon and the like, I would have to use Xcode and the GUI builder (w/ PyObjC).
The application I am intending to write is largely concerned with algorithms and basic IO - and thus, not mostly related to Apple specific stuff.
Basically the application is supposed to run periodically (say, every 3 minutes) .. pull some information via AppleScript and write HTML files to a particular directory. I would like to add a Dock icon for this application .. mainly to showing the "status" of the process (for example, if there is an error .. the dock icon would have a red flag on it). Another advantage of the dock icon is that I can make it run on startup.
Additional bonus for defining the dock right-click menu in a simple way (eg: using Python lists of callables).
Can I achieve this without using Xcode or GUI builders but simply using Emacs and Python?
Install the latest py2app, then make a new directory -- cd to it -- in it make a HelloWorld.py file such as:
# generic Python imports
import datetime
import os
import sched
import sys
import tempfile
import threading
import time
# need PyObjC on sys.path...:
for d in sys.path:
if 'Extras' in d:
sys.path.append(d + '/PyObjC')
break
# objc-related imports
import objc
from Foundation import *
from AppKit import *
from PyObjCTools import AppHelper
# all stuff related to the repeating-action
thesched = sched.scheduler(time.time, time.sleep)
def tick(n, writer):
writer(n)
thesched.enter(20.0, 10, tick, (n+1, writer))
fd, name = tempfile.mkstemp('.txt', 'hello', '/tmp');
print 'writing %r' % name
f = os.fdopen(fd, 'w')
f.write(datetime.datetime.now().isoformat())
f.write('\n')
f.close()
def schedule(writer):
pool = NSAutoreleasePool.alloc().init()
thesched.enter(0.0, 10, tick, (1, writer))
thesched.run()
# normally you'd want pool.drain() here, but since this function never
# ends until end of program (thesched.run never returns since each tick
# schedules a new one) that pool.drain would never execute here;-).
# objc-related stuff
class TheDelegate(NSObject):
statusbar = None
state = 'idle'
def applicationDidFinishLaunching_(self, notification):
statusbar = NSStatusBar.systemStatusBar()
self.statusitem = statusbar.statusItemWithLength_(
NSVariableStatusItemLength)
self.statusitem.setHighlightMode_(1)
self.statusitem.setToolTip_('Example')
self.statusitem.setTitle_('Example')
self.menu = NSMenu.alloc().init()
menuitem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(
'Quit', 'terminate:', '')
self.menu.addItem_(menuitem)
self.statusitem.setMenu_(self.menu)
def writer(self, s):
self.badge.setBadgeLabel_(str(s))
if __name__ == "__main__":
# prepare and set our delegate
app = NSApplication.sharedApplication()
delegate = TheDelegate.alloc().init()
app.setDelegate_(delegate)
delegate.badge = app.dockTile()
delegate.writer(0)
# on a separate thread, run the scheduler
t = threading.Thread(target=schedule, args=(delegate.writer,))
t.setDaemon(1)
t.start()
# let her rip!-)
AppHelper.runEventLoop()
Of course, in your real code, you'll be performing your own periodic actions every 3 minutes (rather than writing a temp file every 20 seconds as I'm doing here), doing your own status updates (rather than just showing a counter of the number of files written so far), etc, etc, but I hope this example shows you a viable starting point.
Then in Terminal.App cd to the directory containing this source file, py2applet --make-setup HelloWorld.py, python setup.py py2app -A -p PyObjC.
You now have in subdirectory dist a directory HelloWorld.app; open dist and drag the icon to the Dock, and you're all set (on your own machine -- distributing to other machines may not work due to the -A flag, but I had trouble building without it, probably due to mis-installed egg files laying around this machine;-). No doubt you'll want to customize your icon &c.
This doesn't do the "extra credit" thingy you asked for -- it's already a lot of code and I decided to stop here (the extra credit thingy may warrant a new question). Also, I'm not quite sure that all the incantations I'm performing here are actually necessary or useful; the docs are pretty latitant for making a pyobjc .app without Xcode, as you require, so I hacked this together from bits and pieces of example code found on the net plus a substantial amount of trial and error. Still, I hope it helps!-)
PyObjC, which is included with Mac OS X 10.5 and 10.6, is pretty close to what you're looking for.
Chuck is correct about PyObjC.
You should then read about this NSApplication method to change your icon.
-(void)setApplicationIconImage:(NSImage *)anImage;
For the dock menu, implement the following in an application delegate. You can build an NSMenu programmatically to avoid using InterfaceBuilder.
-(NSMenu *)applicationDockMenu:(NSApplication *)sender;

Categories