Changeset 4754 for trunk/makeMacApp.py


Ignore:
Timestamp:
Jan 9, 2021 7:34:21 PM (9 months ago)
Author:
toby
Message:

new approach for MacOS AppleScripting?

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/makeMacApp.py

    r4749 r4754  
    55
    66This script creates an AppleScript app bundle to launch GSAS-II. The app is
    7 created in the directory where the GSAS-II script (.../GSASII/GSASII.py)
     7usually created in the directory where the GSAS-II script (.../GSASII/GSASII.py)
    88is located. A softlink to Python is created inside that app bundle,
    99but the softlink name is GSAS-II so that "GSAS-II" shows up as the name
     
    1313alas).
    1414
     15This can be used two different ways.
     16
     17 1. In the usual way, for conda-type installations
     18    where Python is in <condaroot>/bin and GSAS-II is in <condaroot>/GSASII, a premade
     19    app is restored from a tar file. This works best for 11.0 (Big Sur) where there are security
     20    constraints in place.
     21
     22 2. If python is not in that location or a name/location is specified
     23    for the app that will be created, this script creates an app (AppleScript) with the GSAS-II
     24    and the python locations hard coded. When an AppleScript is created, 
     25    this script tests to make sure that a wxpython script will run inside the
     26    app and if not, it searches for a pythonw image and tries that.
     27
    1528This has been tested with several versions of Python interpreters
    16 from Anaconda and does not require pythonw (Python.app). It tests to
    17 make sure that a wxpython script will run inside the app but if not,
    18 it searches for a pythonw image and tries that.
     29from Anaconda and does not require pythonw (Python.app).
    1930
    2031Run this script with no arguments or with one or two arguments.
     32
    2133The first argument, if supplied, is a reference to the GSASII.py script,
    22 which can have a relative or absolute path (the absolute path is determined). 
     34which can have a relative or absolute path (the absolute path is determined).
    2335If not supplied, the GSASII.py script will be used from the directory where
    24 this (makeMacApp.py) script is found. The second argument, if supplied,
    25 provides the name for the app to be created. This can be used to create
    26 multiple copies of the app using different Python versions (likely use for
    27 development only).
     36this (makeMacApp.py) script is found.
     37
     38The second argument, if supplied,
     39provides the name/location for the app to be created. This can be used to create
     40multiple app copies using different Python versions (likely use for
     41development only). If the second argument is used, the AppleScript is created rather than
     42restored from g2app.tar.gz
    2843'''
    2944
    3045from __future__ import division, print_function
    3146import sys, os, os.path, stat, shutil, subprocess, plistlib
     47import platform
    3248def Usage():
    3349    print("\n\tUsage: python "+sys.argv[0]+" [<GSAS-II script>] [project]\n")
     
    4864AppleScript = ''
    4965'''Contains an AppleScript to start GSAS-II, launching Python and the
    50 GSAS-II python script
    51 '''
    52 
    53 if __name__ == '__main__' and sys.platform == "darwin":
     66GSAS-II python script.
     67'''
     68
     69if __name__ == '__main__':
    5470    project="GSAS-II"
    55 
    56     # set scriptdir: find the main GSAS-II script if not on command line
     71    # set GSAS-II location (path2GSAS): find the main GSAS-II script
     72    # from this file, if not on command line
    5773    if len(sys.argv) == 1:
    58         script = os.path.abspath(os.path.join(
    59                 os.path.split(__file__)[0],
    60                 "GSASII.py"
    61                 ))
     74        path2GSAS = os.path.split(__file__)[0]
     75        script = os.path.abspath(os.path.join(path2GSAS,"GSASII.py"))
    6276    elif len(sys.argv) == 2:
    6377        script = os.path.abspath(sys.argv[1])
     78        path2GSAS = os.path.split(script)[0]
    6479    elif len(sys.argv) == 3:
    6580        script = os.path.abspath(sys.argv[1])
     81        path2GSAS = os.path.split(script)[0]
    6682        project = sys.argv[2]
    6783    else:
    6884        Usage()
    69         raise Exception
    70     # make sure we found it
    7185    if not os.path.exists(script):
    7286        print("\nFile "+script+" not found")
     
    7589        print("\nScript "+script+" does not have extension .py")
    7690        Usage()
    77     # where the app will be created
    78     scriptdir = os.path.split(script)[0]
    79    
    80     appPath = os.path.abspath(os.path.join(scriptdir,project+".app"))
    81     iconfile = os.path.join(scriptdir,'gsas2.icns') # optional icon file
     91    projectname = os.path.split(project)[1]
     92    if os.path.split(project)[0] != '':
     93        appPath = os.path.abspath(project+".app")
     94    else:
     95        appPath = os.path.abspath(os.path.join(path2GSAS,project+".app"))
     96
     97# new approach, if possible use previously created file
     98if __name__ == '__main__' and sys.platform == "darwin" and os.path.exists(
     99                os.path.join(path2GSAS,"g2app.tar.gz")) and project =="GSAS-II":
     100    if os.path.exists(os.path.join(path2GSAS,'../bin/python')):
     101        print('found python, found g2app.tar.gz')
     102        subprocess.call(["rm","-rf",appPath])
     103        subprocess.call(["mkdir","-p",appPath])
     104        subprocess.call(["tar","xzvf",os.path.join(path2GSAS,"g2app.tar.gz"),'-C',appPath])
     105        print("\nCreated "+projectname+" app ("+str(appPath)+
     106          ").\nViewing app in Finder so you can drag it to the dock if, you wish.")
     107        subprocess.call(["open","-R",appPath])
     108        sys.exit()
     109    else:
     110        print('found g2app.tar.gz, but python not in expected location')       
     111
     112if __name__ == '__main__' and sys.platform == "darwin":
     113    iconfile = os.path.join(path2GSAS,'gsas2.icns') # optional icon file
    82114   
    83115    AppleScript = '''(*   GSAS-II AppleScript by B. Toby (brian.toby@anl.gov)
     
    145177'''
    146178    # create a link named GSAS-II.py to the script
    147     newScript = os.path.join(scriptdir,'GSAS-II.py')
     179    newScript = os.path.join(path2GSAS,'GSAS-II.py')
    148180    if os.path.exists(newScript): # cleanup
    149181        print("\nRemoving sym link",newScript)
     
    155187    # inside the app that will be created
    156188    pythonExe = os.path.realpath(sys.executable)
    157     newpython =  os.path.join(appPath,"Contents","MacOS",project)
    158 
     189    newpython =  os.path.join(appPath,"Contents","MacOS",projectname)
     190   
    159191    # create an app using this python and if that fails to run wx, look for a
    160192    # pythonw and try that with wx
    161193    for i in 1,2,3:
    162194        if os.path.exists(appPath): # cleanup
    163             print("\nRemoving old "+project+" app ("+str(appPath)+")")
     195            print("\nRemoving old "+projectname+" app ("+str(appPath)+")")
    164196            shutil.rmtree(appPath)
    165197       
     
    180212
    181213        # test if newpython can run wx
    182         testout,errout = RunPython(newpython,'import numpy; import wx; wx.App(); print("-OK-")')
     214        testout,errout = RunPython(newpython,'import numpy; import wx; wx.App(); print("-"+"OK-")')
    183215        if isinstance(testout,bytes): testout = testout.decode()
    184216        if "-OK-" in testout:
     217            print('wxpython app ran',testout)
    185218            break
    186219        elif i == 1:
     
    223256        plistlib.writePlist(d,os.path.join(appPath,"Contents",'Info.plist'))
    224257
    225     # open & save the file in the editor to help set authorization levels
     258    # Big Sur: open & save the file in the editor to set authorization levels
    226259    osascript = '''
    227260    tell application "Script Editor"
    228261       set MyName to open "{}"
    229262       save MyName
    230        close MyName
    231        quit
    232     end tell   
     263       (* close MyName *)
     264       (* quit *)
     265    end tell
    233266'''.format(appPath)
    234     print(script)
    235     subprocess.Popen(["osascript","-e",osascript])
    236        
    237     print("\nCreated "+project+" app ("+str(appPath)+
     267    # detect MacOS 11 (11.0 == 10.16!)
     268    if platform.mac_ver()[0].split('.')[0] == '11' or platform.mac_ver()[0][:5] == '10.16':
     269        print("\nFor Big Sur and later, save the app in Script Editor before using it\n")
     270        subprocess.Popen(["osascript","-e",osascript])
     271    print("\nCreated "+projectname+" app ("+str(appPath)+
    238272          ").\nViewing app in Finder so you can drag it to the dock if, you wish.")
    239273    subprocess.call(["open","-R",appPath])
Note: See TracChangeset for help on using the changeset viewer.