1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | Mac/scripts/BuildApplet.py
"""Create an applet from a Python script. This puts up a dialog asking for a Python source file ('TEXT'). The output is a file with the same name but its ".py" suffix dropped. It is created by copying an applet template and then adding a 'PYC ' resource named __main__ containing the compiled, marshalled script. """ import sys sys.stdout = sys.stderr import os import MacOS try: import EasyDialogs except ImportError: EasyDialogs = None import buildtools import getopt if not sys.executable.startswith(sys.exec_prefix): # Oh, the joys of using a python script to bootstrap applicatin bundles # sys.executable points inside the current application bundle. Because this # path contains blanks (two of them actually) this path isn't usable on # #! lines. Reset sys.executable to point to the embedded python interpreter sys.executable = os.path.join(sys.prefix, 'Resources/Python.app/Contents/MacOS/Python') # Just in case we're not in a framework: if not os.path.exists(sys.executable): sys.executable = os.path.join(sys.exec_prefix, 'bin/python') def main(): try: buildapplet() except buildtools.BuildError, detail: if EasyDialogs is None: print detail else: EasyDialogs.Message(detail) def buildapplet(): buildtools.DEBUG=1 # Find the template # (there's no point in proceeding if we can't find it) template = buildtools.findtemplate() # Ask for source text if not specified in sys.argv[1:] if not sys.argv[1:]: if EasyDialogs is None: usage() sys.exit(1) filename = EasyDialogs.AskFileForOpen(message='Select Python source or applet:', typeList=('TEXT', 'APPL')) if not filename: return tp, tf = os.path.split(filename) if tf[-3:] == '.py': tf = tf[:-3] else: tf = tf + '.applet' dstfilename = EasyDialogs.AskFileForSave(message='Save application as:', savedFileName=tf) if not dstfilename: return cr, tp = MacOS.GetCreatorAndType(filename) if tp == 'APPL': buildtools.update(template, filename, dstfilename) else: buildtools.process(template, filename, dstfilename, 1) else: SHORTOPTS = "o:r:ne:v?PR" LONGOPTS=("output=", "resource=", "noargv", "extra=", "verbose", "help", "python=", "destroot=") try: options, args = getopt.getopt(sys.argv[1:], SHORTOPTS, LONGOPTS) except getopt.error: usage() if options and len(args) > 1: sys.stderr.write("Cannot use options when specifying multiple input files") sys.exit(1) dstfilename = None rsrcfilename = None raw = 0 extras = [] verbose = None destroot = '' for opt, arg in options: if opt in ('-o', '--output'): dstfilename = arg elif opt in ('-r', '--resource'): rsrcfilename = arg elif opt in ('-n', '--noargv'): raw = 1 elif opt in ('-e', '--extra'): if ':' in arg: arg = arg.split(':') extras.append(arg) elif opt in ('-P', '--python'): # This is a very dirty trick. We set sys.executable # so that bundlebuilder will use this in the #! line # for the applet bootstrap. sys.executable = arg elif opt in ('-v', '--verbose'): verbose = Verbose() elif opt in ('-?', '--help'): usage() elif opt in ('-d', '--destroot'): destroot = arg # Loop over all files to be processed for filename in args: cr, tp = MacOS.GetCreatorAndType(filename) if tp == 'APPL': buildtools.update(template, filename, dstfilename) else: buildtools.process(template, filename, dstfilename, 1, rsrcname=rsrcfilename, others=extras, raw=raw, progress=verbose, destroot=destroot) def usage(): print "BuildApplet creates an application from a Python source file" print "Usage:" print " BuildApplet interactive, single file, no options" print " BuildApplet src1.py src2.py ... non-interactive multiple file" print " BuildApplet [options] src.py non-interactive single file" print "Options:" print " --output o Output file; default based on source filename, short -o" print " --resource r Resource file; default based on source filename, short -r" print " --noargv Build applet without drag-and-drop sys.argv emulation, short -n, OSX only" print " --extra src[:dst] Extra file to put in .app bundle, short -e, OSX only" print " --verbose Verbose, short -v" print " --help This message, short -?" sys.exit(1) class Verbose: """This class mimics EasyDialogs.ProgressBar but prints to stderr""" def __init__(self, *args): if args and args[0]: self.label(args[0]) def set(self, *args): pass def inc(self, *args): pass def label(self, str): sys.stderr.write(str+'\n') if __name__ == '__main__': main() |