blob: be20ecb75ac83552ae40c210e77294e6e8dc305a [file] [log] [blame]
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +00001"""Create an applet from a Python script.
Guido van Rossum2d546921995-02-17 14:28:39 +00002
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +00003This 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.
Guido van Rossum2d546921995-02-17 14:28:39 +00007"""
8
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +00009import sys
Guido van Rossum57128fd1995-02-19 15:49:17 +000010sys.stdout = sys.stderr
11
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000012import string
13import os
Guido van Rossum2d546921995-02-17 14:28:39 +000014import marshal
15import imp
16import macfs
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000017import MacOS
Guido van Rossum2d546921995-02-17 14:28:39 +000018from Res import *
19
20# .pyc file (and 'PYC ' resource magic number)
21MAGIC = imp.get_magic()
22
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000023# Template file (searched on sys.path)
24TEMPLATE = "PythonApplet"
25
26# Specification of our resource
Guido van Rossum2d546921995-02-17 14:28:39 +000027RESTYPE = 'PYC '
Guido van Rossum2d546921995-02-17 14:28:39 +000028RESNAME = '__main__'
29
30# OpenResFile mode parameters
31READ = 1
32WRITE = 2
33
34def main():
35
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000036 # Find the template
37 # (there's no point in proceeding if we can't find it)
38
39 for p in sys.path:
40 template = os.path.join(p, TEMPLATE)
41 try:
42 tmpl = open(template, "rb")
Guido van Rossum57128fd1995-02-19 15:49:17 +000043 tmpl.close()
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000044 break
45 except IOError:
46 continue
47 else:
Guido van Rossum42a69c81995-02-20 23:44:14 +000048 die("Template %s not found" % `template`)
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000049 return
50
Guido van Rossum57128fd1995-02-19 15:49:17 +000051 # Ask for source text if not specified in sys.argv[1:]
Guido van Rossum2d546921995-02-17 14:28:39 +000052
Guido van Rossum57128fd1995-02-19 15:49:17 +000053 if not sys.argv[1:]:
54 srcfss, ok = macfs.StandardGetFile('TEXT')
55 if not ok:
56 return
57 filename = srcfss.as_pathname()
58 if not sys.argv: sys.argv.append('')
59 sys.argv.append(filename)
60
61 # Loop over all files to be processed
62
63 for filename in sys.argv[1:]:
64 process(template, filename)
65
66undefs = ('????', ' ', '\0\0\0\0')
67
68def process(template, filename):
69
70 print "Processing", `filename`, "..."
Guido van Rossum2d546921995-02-17 14:28:39 +000071
72 # Read the source and compile it
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000073 # (there's no point overwriting the destination if it has a syntax error)
Guido van Rossum2d546921995-02-17 14:28:39 +000074
Guido van Rossum2d546921995-02-17 14:28:39 +000075 fp = open(filename)
76 text = fp.read()
77 fp.close()
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000078 try:
79 code = compile(text, filename, "exec")
80 except (SyntaxError, EOFError):
Guido van Rossum42a69c81995-02-20 23:44:14 +000081 die("Syntax error in script %s" % `filename`)
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000082 return
Guido van Rossum2d546921995-02-17 14:28:39 +000083
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000084 # Set the destination file name
Guido van Rossum2d546921995-02-17 14:28:39 +000085
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000086 if string.lower(filename[-3:]) == ".py":
87 destname = filename[:-3]
Guido van Rossum42a69c81995-02-20 23:44:14 +000088 rsrcname = destname + '.rsrc'
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000089 else:
90 destname = filename + ".applet"
Guido van Rossum42a69c81995-02-20 23:44:14 +000091 rsrcname = filename + '.rsrc'
Guido van Rossum2d546921995-02-17 14:28:39 +000092
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000093 # Copy the data from the template (creating the file as well)
Guido van Rossum2d546921995-02-17 14:28:39 +000094
Guido van Rossum57128fd1995-02-19 15:49:17 +000095 tmpl = open(template, "rb")
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000096 dest = open(destname, "wb")
97 data = tmpl.read()
98 if data:
99 dest.write(data)
100 dest.close()
101 tmpl.close()
Guido van Rossum2d546921995-02-17 14:28:39 +0000102
Jack Jansen77b58281995-02-20 15:49:27 +0000103 # Copy the creator of the template to the destination
Guido van Rossum42a69c81995-02-20 23:44:14 +0000104 # unless it already got one. Set type to APPL
105
Guido van Rossum57128fd1995-02-19 15:49:17 +0000106 tctor, ttype = MacOS.GetCreatorAndType(template)
107 ctor, type = MacOS.GetCreatorAndType(destname)
Jack Jansen77b58281995-02-20 15:49:27 +0000108 if type in undefs: type = 'APPL'
Guido van Rossum57128fd1995-02-19 15:49:17 +0000109 if ctor in undefs: ctor = tctor
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000110 MacOS.SetCreatorAndType(destname, ctor, type)
Guido van Rossum2d546921995-02-17 14:28:39 +0000111
Guido van Rossum42a69c81995-02-20 23:44:14 +0000112 # Open the output resource fork
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000113
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000114 try:
115 output = FSpOpenResFile(destname, WRITE)
116 except MacOS.Error:
117 print "Creating resource fork..."
118 CreateResFile(destname)
119 output = FSpOpenResFile(destname, WRITE)
120
Guido van Rossum42a69c81995-02-20 23:44:14 +0000121 # Copy the resources from the template
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000122
Guido van Rossum42a69c81995-02-20 23:44:14 +0000123 input = FSpOpenResFile(template, READ)
124 copyres(input, output)
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000125 CloseResFile(input)
126
Guido van Rossum42a69c81995-02-20 23:44:14 +0000127 # Copy the resources from the target specific resource template, if any
128
129 try:
130 input = FSpOpenResFile(rsrcname, READ)
131 except MacOS.Error:
132 pass
133 else:
134 copyres(input, output)
135 CloseResFile(input)
136
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000137 # Make sure we're manipulating the output resource file now
138
139 UseResFile(output)
140
141 # Delete any existing 'PYC 'resource named __main__
Guido van Rossum2d546921995-02-17 14:28:39 +0000142
143 try:
144 res = Get1NamedResource(RESTYPE, RESNAME)
145 res.RmveResource()
146 except Error:
147 pass
148
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000149 # Create the raw data for the resource from the code object
150
151 data = marshal.dumps(code)
152 del code
153 data = (MAGIC + '\0\0\0\0') + data
Guido van Rossum2d546921995-02-17 14:28:39 +0000154
155 # Create the resource and write it
156
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000157 id = 0
158 while id < 128:
159 id = Unique1ID(RESTYPE)
Guido van Rossum2d546921995-02-17 14:28:39 +0000160 res = Resource(data)
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000161 res.AddResource(RESTYPE, id, RESNAME)
Guido van Rossum2d546921995-02-17 14:28:39 +0000162 res.WriteResource()
163 res.ReleaseResource()
164
Guido van Rossum42a69c81995-02-20 23:44:14 +0000165 # Close the output file
Guido van Rossum2d546921995-02-17 14:28:39 +0000166
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000167 CloseResFile(output)
Guido van Rossum57128fd1995-02-19 15:49:17 +0000168
Guido van Rossum42a69c81995-02-20 23:44:14 +0000169 # Give positive feedback
170
171 message("Applet %s created." % `destname`)
172
173
174# Copy resources between two resource file descriptors
175# Exception: don't copy a __main__ resource
176
177def copyres(input, output):
178 UseResFile(input)
179 ntypes = Count1Types()
180 for itype in range(1, 1+ntypes):
181 type = Get1IndType(itype)
182 nresources = Count1Resources(type)
183 for ires in range(1, 1+nresources):
184 res = Get1IndResource(type, ires)
185 id, type, name = res.GetResInfo()
186 if (type, name) == (RESTYPE, RESNAME):
187 continue # Don't copy __main__ from template
188 size = res.SizeResource()
189 attrs = res.GetResAttrs()
190 print id, type, name, size, hex(attrs)
191 res.LoadResource()
192 res.DetachResource()
193 UseResFile(output)
194 try:
195 res2 = Get1Resource(type, id)
196 except MacOS.Error:
197 res2 = None
198 if res2:
199 print "Overwriting..."
200 res2.RmveResource()
201 res.AddResource(type, id, name)
202 #res.SetResAttrs(attrs)
203 res.WriteResource()
204 UseResFile(input)
205
206
207# Show a message and exit
208
209def die(str):
210 message(str)
211 sys.exit(1)
212
213
214# Show a message
215
216def message(str, id = 256):
217 from Dlg import *
218 d = GetNewDialog(id, -1)
219 if not d:
220 print "Error:", `str`
221 print "DLOG id =", id, "not found."
222 return
223 tp, h, rect = d.GetDItem(2)
224 SetIText(h, str)
225 while 1:
226 n = ModalDialog(None)
227 if n == 1: break
228 del d
Guido van Rossum57128fd1995-02-19 15:49:17 +0000229
Guido van Rossum2d546921995-02-17 14:28:39 +0000230
231if __name__ == '__main__':
232 main()