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