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
157
158
159
|
"""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
# On OS9 always be verbose
if sys.platform == 'mac' and not verbose:
verbose = 'default'
# 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()
|