summaryrefslogtreecommitdiffstats
path: root/Mac/scripts/BuildApplet.py
blob: e954854b819a1adce242c16a4d5779fbcafb726e (plain)
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
"""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
import EasyDialogs
import buildtools
import getopt

def main():
	try:
		buildapplet()
	except buildtools.BuildError, detail:
		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:]:
		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?P"
		LONGOPTS=("output=", "resource=", "noargv", "extra=", "verbose", "help", "python=")
		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
		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()
		# 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)

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()