source: trunk/makeMacApp.py @ 1356

Last change on this file since 1356 was 1356, checked in by toby, 9 years ago

revised for Canopy

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 7.5 KB
Line 
1#!/usr/bin/env python
2'''
3*makeMacApp: Create Mac Applet*
4===============================
5
6This script creates an AppleScript app to launch GSAS-II. The app is
7created in the directory where the GSAS-II script is located.
8A softlink to Python is created, but is named GSAS-II, so that
9GSAS-II shows up as the name of the app rather than Python in the
10menu bar, etc. Note that this requires finding an app version of Python
11(expected name .../Resources/Python.app/Contents/MacOS/Python in
12directory tree of the calling python interpreter).
13
14Run this script with one optional argument, the path to the GSASII.py
15The script path may be specified relative to the current path or given
16an absolute path, but will be accessed via an absolute path.
17If no arguments are supplied, the GSASII.py script is assumed to be in the
18same directory as this file.
19
20'''
21import sys, os, os.path, stat, shutil, subprocess, plistlib
22def Usage():
23    print("\n\tUsage: python "+sys.argv[0]+" [<GSAS-II script>]\n")
24    sys.exit()
25
26def RunPython(image,cmd):
27    'Run a command in a python image'
28    try:
29        err=None
30        p = subprocess.Popen([image,'-c',cmd],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
31        out = p.stdout.read()
32        err = p.stderr.read()
33        p.communicate()
34        return out,err
35    except Exception(err):
36        return '','Exception = '+err
37
38project="GSAS-II"
39AppleScript = ''
40'''Contains an AppleScript to start GSAS-II launching python and the
41GSAS-II python script
42'''
43
44AppleScript += '''(*   GSAS-II AppleScript by B. Toby (brian.toby@anl.gov)
45     It can launch GSAS-II by double clicking or by dropping a data file
46     or folder over the app.
47     It runs GSAS-II in a terminal window.
48*)
49
50(* test if a file is present and exit with an error message if it is not  *)
51on TestFilePresent(appwithpath)
52        tell application "System Events"
53                if (file appwithpath exists) then
54                else
55                        display dialog "Error: file " & appwithpath & " not found. If you have moved this file recreate the AppleScript with bootstrap.py." with icon caution buttons {{"Quit"}}
56                        return
57                end if
58        end tell
59end TestFilePresent
60
61(*
62------------------------------------------------------------------------
63this section responds to a double-click. No file is supplied to GSAS-II
64------------------------------------------------------------------------
65*)
66on run
67        set python to "{:s}"
68        set appwithpath to "{:s}"
69        set env to "{:s}"
70        TestFilePresent(appwithpath)
71        TestFilePresent(python)
72        tell application "Terminal"
73                activate
74                do script env & python & " " & appwithpath & "; exit"
75        end tell
76end run
77
78(*
79-----------------------------------------------------------------------------------------------
80this section handles starting with files dragged into the AppleScript
81 o it goes through the list of file(s) dragged in
82 o then it converts the colon-delimited macintosh file location to a POSIX filename
83 o for every non-directory file dragged into the icon, it starts GSAS-II, passing the file name
84------------------------------------------------------------------------------------------------
85*)
86
87on open names
88        set python to "{:s}"
89        set appwithpath to "{:s}"
90        set env to "{:s}"
91 
92        TestFilePresent(appwithpath)
93        repeat with filename in names
94                set filestr to (filename as string)
95                if filestr ends with ":" then
96                        (* should not happen, skip directories *)
97                else
98                        (* if this is an input file, open it *)
99                        set filename to the quoted form of the POSIX path of filename
100                        tell application "Terminal"
101                                activate
102                                do script env & python & " " & appwithpath & " " & filename & "; exit"
103                        end tell
104                end if
105        end repeat
106end open
107'''
108
109if __name__ == '__main__':
110    # find the main GSAS-II script if not on command line
111    if len(sys.argv) == 1:
112        script = os.path.abspath(os.path.join(
113            os.path.split(__file__)[0],
114            "GSASII.py"
115            ))
116    elif len(sys.argv) == 2:
117        script = os.path.abspath(sys.argv[1])
118    else:
119        Usage()
120
121    # make sure we found it
122    if not os.path.exists(script):
123        print("\nFile "+script+" not found")
124        Usage()
125    if os.path.splitext(script)[1].lower() != '.py':
126        print("\nScript "+script+" does not have extension .py")
127        Usage()
128    # where the app will be created
129    scriptdir = os.path.split(script)[0]
130    # name of app
131    apppath = os.path.abspath(os.path.join(scriptdir,project+".app"))
132    iconfile = os.path.join(scriptdir,'gsas2.icns') # optional icon file
133
134    # find the python application; must be an OS X app
135    pythonpath,top = os.path.split(os.path.realpath(sys.executable))
136    while top:
137        if 'Resources' in pythonpath:
138            pass
139        elif os.path.exists(os.path.join(pythonpath,'Resources')):
140            break
141        pythonpath,top = os.path.split(pythonpath)
142        pythonapp = os.path.join(pythonpath,'Resources','Python.app','Contents','MacOS','Python')
143        if not os.path.exists(pythonapp): 
144            print("\nSorry, failed to find a Python app in "+str(pythonapp))
145            pythonapp = sys.executable
146    else:
147        print("\nSorry, failed to find a Resources directory associated with "+str(sys.executable))
148        pythonapp = sys.executable
149
150    # create a link to the python app, but named to match the project
151    if os.path.exists('/tmp/testpython'): os.remove('/tmp/testpython')
152    os.symlink(pythonapp,'/tmp/testpython')
153    # test if it runs
154    testout,errout = RunPython('/tmp/testpython','import numpy; import wx; print("OK")')
155    os.remove('/tmp/testpython')
156    #print testout,errout
157    if testout.strip() != "OK":
158        print 'Run of python app failed, assuming Canopy <=1.4'
159        pythonapp = sys.executable
160        # switch to pythonw
161        if os.path.split(pythonapp)[1].lower() == 'python':
162            pythonapp = os.path.join(os.path.split(pythonapp)[0],'pythonw')
163        newpython = pythonapp
164    else:
165        # new name to call python
166        newpython =  os.path.join(apppath,"Contents","MacOS",project)
167
168    print sys.executable
169    print newpython
170    print pythonapp
171    #sys.exit()
172   
173    if os.path.exists(apppath): # cleanup
174        print("\nRemoving old "+project+" app ("+str(apppath)+")")
175        shutil.rmtree(apppath)
176
177    shell = os.path.join("/tmp/","appscrpt.script")
178    f = open(shell, "w")
179    f.write(AppleScript.format(newpython,script,'',newpython,script,''))
180    f.close()
181
182    try: 
183        subprocess.check_output(["osacompile","-o",apppath,shell],stderr=subprocess.STDOUT)
184    except subprocess.CalledProcessError, msg:
185        print '''Error compiling AppleScript.
186        Report the next message along with details about your Mac to toby@anl.gov'''
187        print msg.output
188        sys.exit()
189
190    # create a link to the python app, but named to match the project
191    if pythonapp != newpython: os.symlink(pythonapp,newpython)
192
193    # change the icon
194    oldicon = os.path.join(apppath,"Contents","Resources","droplet.icns")
195    if os.path.exists(iconfile) and os.path.exists(oldicon):
196        shutil.copyfile(iconfile,oldicon)
197
198    # Edit the app plist file to restrict the type of files that can be dropped
199    d = plistlib.readPlist(os.path.join(apppath,"Contents",'Info.plist'))
200    d['CFBundleDocumentTypes'] = [{
201        'CFBundleTypeExtensions': ['gpx'],
202        'CFBundleTypeName': 'GSAS-II project',
203        'CFBundleTypeRole': 'Editor'}]
204   
205    plistlib.writePlist(d,os.path.join(apppath,"Contents",'Info.plist'))
206
207    print("\nCreated "+project+" app ("+str(apppath)+
208          ").\nViewing app in Finder so you can drag it to the dock if, you wish.")
209    subprocess.call(["open","-R",apppath])
Note: See TracBrowser for help on using the repository browser.