blob: a76ed90872d9b7a1dcf269245e28bd5bd6f81b72 [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
Ronald Oussoren25967582009-09-06 10:00:26 +000015try:
16 import EasyDialogs
17except ImportError:
18 EasyDialogs = None
Jack Jansen015b70e1998-07-31 09:44:23 +000019import buildtools
Jack Jansen388fbf32002-06-09 22:08:52 +000020import getopt
Jack Jansen0f452fa1995-09-01 11:54:11 +000021
Ronald Oussoren4b7a6c82006-06-07 20:18:44 +000022if not sys.executable.startswith(sys.exec_prefix):
23 # Oh, the joys of using a python script to bootstrap applicatin bundles
24 # sys.executable points inside the current application bundle. Because this
25 # path contains blanks (two of them actually) this path isn't usable on
26 # #! lines. Reset sys.executable to point to the embedded python interpreter
Tim Petersae6a5a72006-06-07 20:40:06 +000027 sys.executable = os.path.join(sys.prefix,
Ronald Oussoren4b7a6c82006-06-07 20:18:44 +000028 'Resources/Python.app/Contents/MacOS/Python')
29
30 # Just in case we're not in a framework:
31 if not os.path.exists(sys.executable):
32 sys.executable = os.path.join(sys.exec_prefix, 'bin/python')
33
Jack Jansen0f452fa1995-09-01 11:54:11 +000034def main():
Tim Peters182b5ac2004-07-18 06:16:08 +000035 try:
36 buildapplet()
37 except buildtools.BuildError, detail:
Ronald Oussoren25967582009-09-06 10:00:26 +000038 if EasyDialogs is None:
39 print detail
40 else:
41 EasyDialogs.Message(detail)
Jack Jansen015b70e1998-07-31 09:44:23 +000042
43
44def buildapplet():
Tim Peters182b5ac2004-07-18 06:16:08 +000045 buildtools.DEBUG=1
46
47 # Find the template
48 # (there's no point in proceeding if we can't find it)
49
50 template = buildtools.findtemplate()
51
52 # Ask for source text if not specified in sys.argv[1:]
53
54 if not sys.argv[1:]:
Ronald Oussoren25967582009-09-06 10:00:26 +000055 if EasyDialogs is None:
56 usage()
57 sys.exit(1)
58
Tim Peters182b5ac2004-07-18 06:16:08 +000059 filename = EasyDialogs.AskFileForOpen(message='Select Python source or applet:',
60 typeList=('TEXT', 'APPL'))
61 if not filename:
62 return
63 tp, tf = os.path.split(filename)
64 if tf[-3:] == '.py':
65 tf = tf[:-3]
66 else:
67 tf = tf + '.applet'
68 dstfilename = EasyDialogs.AskFileForSave(message='Save application as:',
69 savedFileName=tf)
70 if not dstfilename: return
71 cr, tp = MacOS.GetCreatorAndType(filename)
72 if tp == 'APPL':
73 buildtools.update(template, filename, dstfilename)
74 else:
75 buildtools.process(template, filename, dstfilename, 1)
76 else:
77
Jack Jansenc77f6df2004-12-27 15:51:03 +000078 SHORTOPTS = "o:r:ne:v?PR"
79 LONGOPTS=("output=", "resource=", "noargv", "extra=", "verbose", "help", "python=", "destroot=")
Tim Peters182b5ac2004-07-18 06:16:08 +000080 try:
81 options, args = getopt.getopt(sys.argv[1:], SHORTOPTS, LONGOPTS)
82 except getopt.error:
83 usage()
84 if options and len(args) > 1:
85 sys.stderr.write("Cannot use options when specifying multiple input files")
86 sys.exit(1)
87 dstfilename = None
88 rsrcfilename = None
89 raw = 0
90 extras = []
91 verbose = None
Jack Jansenc77f6df2004-12-27 15:51:03 +000092 destroot = ''
Tim Peters182b5ac2004-07-18 06:16:08 +000093 for opt, arg in options:
94 if opt in ('-o', '--output'):
95 dstfilename = arg
96 elif opt in ('-r', '--resource'):
97 rsrcfilename = arg
98 elif opt in ('-n', '--noargv'):
99 raw = 1
100 elif opt in ('-e', '--extra'):
101 if ':' in arg:
102 arg = arg.split(':')
103 extras.append(arg)
104 elif opt in ('-P', '--python'):
105 # This is a very dirty trick. We set sys.executable
106 # so that bundlebuilder will use this in the #! line
107 # for the applet bootstrap.
108 sys.executable = arg
109 elif opt in ('-v', '--verbose'):
110 verbose = Verbose()
111 elif opt in ('-?', '--help'):
112 usage()
Jack Jansenc77f6df2004-12-27 15:51:03 +0000113 elif opt in ('-d', '--destroot'):
114 destroot = arg
Tim Peters182b5ac2004-07-18 06:16:08 +0000115 # Loop over all files to be processed
116 for filename in args:
117 cr, tp = MacOS.GetCreatorAndType(filename)
118 if tp == 'APPL':
119 buildtools.update(template, filename, dstfilename)
120 else:
121 buildtools.process(template, filename, dstfilename, 1,
Jack Jansenc77f6df2004-12-27 15:51:03 +0000122 rsrcname=rsrcfilename, others=extras, raw=raw,
123 progress=verbose, destroot=destroot)
Jack Jansen7571f301995-07-29 13:48:41 +0000124
Jack Jansen388fbf32002-06-09 22:08:52 +0000125def usage():
Tim Peters182b5ac2004-07-18 06:16:08 +0000126 print "BuildApplet creates an application from a Python source file"
127 print "Usage:"
128 print " BuildApplet interactive, single file, no options"
129 print " BuildApplet src1.py src2.py ... non-interactive multiple file"
130 print " BuildApplet [options] src.py non-interactive single file"
131 print "Options:"
132 print " --output o Output file; default based on source filename, short -o"
133 print " --resource r Resource file; default based on source filename, short -r"
134 print " --noargv Build applet without drag-and-drop sys.argv emulation, short -n, OSX only"
135 print " --extra src[:dst] Extra file to put in .app bundle, short -e, OSX only"
136 print " --verbose Verbose, short -v"
137 print " --help This message, short -?"
138 sys.exit(1)
Jack Jansen388fbf32002-06-09 22:08:52 +0000139
140class Verbose:
Tim Peters182b5ac2004-07-18 06:16:08 +0000141 """This class mimics EasyDialogs.ProgressBar but prints to stderr"""
142 def __init__(self, *args):
143 if args and args[0]:
144 self.label(args[0])
145
146 def set(self, *args):
147 pass
148
149 def inc(self, *args):
150 pass
151
152 def label(self, str):
153 sys.stderr.write(str+'\n')
Jack Jansen7571f301995-07-29 13:48:41 +0000154
155if __name__ == '__main__':
Tim Peters182b5ac2004-07-18 06:16:08 +0000156 main()