blob: 9ddcd0b2bddc424458bbb930f147e2a5cc88808c [file] [log] [blame]
Jack Jansen7571f301995-07-29 13:48:41 +00001"""Create an applet from a Python script.
2
3This puts up a dialog asking for a Python source file ('TEXT').
4The output is a file with the same name but its ".py" suffix dropped.
5It is created by copying an applet template and then adding a 'PYC '
6resource named __main__ containing the compiled, marshalled script.
7"""
8
Jack Jansen0f452fa1995-09-01 11:54:11 +00009
Jack Jansen7571f301995-07-29 13:48:41 +000010import sys
11sys.stdout = sys.stderr
12
Jack Jansen7571f301995-07-29 13:48:41 +000013import os
Jack Jansen7571f301995-07-29 13:48:41 +000014import MacOS
Jack Jansenaf647dd1997-05-13 15:42:26 +000015import EasyDialogs
Jack Jansen015b70e1998-07-31 09:44:23 +000016import buildtools
Jack Jansen388fbf32002-06-09 22:08:52 +000017import getopt
Jack Jansen0f452fa1995-09-01 11:54:11 +000018
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000019if 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 Jansen0f452fa1995-09-01 11:54:11 +000031def main():
Tim Peters182b5ac2004-07-18 06:16:08 +000032 try:
33 buildapplet()
Guido van Rossumb940e112007-01-10 16:19:56 +000034 except buildtools.BuildError as detail:
Tim Peters182b5ac2004-07-18 06:16:08 +000035 EasyDialogs.Message(detail)
Jack Jansen015b70e1998-07-31 09:44:23 +000036
37
38def buildapplet():
Tim Peters182b5ac2004-07-18 06:16:08 +000039 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 Jansenc77f6df2004-12-27 15:51:03 +000068 SHORTOPTS = "o:r:ne:v?PR"
69 LONGOPTS=("output=", "resource=", "noargv", "extra=", "verbose", "help", "python=", "destroot=")
Tim Peters182b5ac2004-07-18 06:16:08 +000070 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 Jansenc77f6df2004-12-27 15:51:03 +000082 destroot = ''
Tim Peters182b5ac2004-07-18 06:16:08 +000083 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 Jansenc77f6df2004-12-27 15:51:03 +0000103 elif opt in ('-d', '--destroot'):
104 destroot = arg
Tim Peters182b5ac2004-07-18 06:16:08 +0000105 # 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 Jansenc77f6df2004-12-27 15:51:03 +0000115 rsrcname=rsrcfilename, others=extras, raw=raw,
116 progress=verbose, destroot=destroot)
Jack Jansen7571f301995-07-29 13:48:41 +0000117
Jack Jansen388fbf32002-06-09 22:08:52 +0000118def usage():
Tim Peters182b5ac2004-07-18 06:16:08 +0000119 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 Jansen388fbf32002-06-09 22:08:52 +0000132
133class Verbose:
Tim Peters182b5ac2004-07-18 06:16:08 +0000134 """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 Jansen7571f301995-07-29 13:48:41 +0000147
148if __name__ == '__main__':
Tim Peters182b5ac2004-07-18 06:16:08 +0000149 main()