blob: b8591aa5d1a70d3f1d51891e90e4e8e6d30a7ebb [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:
48 # XXX Ought to put up a dialog
Guido van Rossum57128fd1995-02-19 15:49:17 +000049 print "Template", `template`, "not found"
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000050 return
51
Guido van Rossum57128fd1995-02-19 15:49:17 +000052 # Ask for source text if not specified in sys.argv[1:]
Guido van Rossum2d546921995-02-17 14:28:39 +000053
Guido van Rossum57128fd1995-02-19 15:49:17 +000054 if not sys.argv[1:]:
55 srcfss, ok = macfs.StandardGetFile('TEXT')
56 if not ok:
57 return
58 filename = srcfss.as_pathname()
59 if not sys.argv: sys.argv.append('')
60 sys.argv.append(filename)
61
62 # Loop over all files to be processed
63
64 for filename in sys.argv[1:]:
65 process(template, filename)
66
67undefs = ('????', ' ', '\0\0\0\0')
68
69def process(template, filename):
70
71 print "Processing", `filename`, "..."
Guido van Rossum2d546921995-02-17 14:28:39 +000072
73 # Read the source and compile it
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000074 # (there's no point overwriting the destination if it has a syntax error)
Guido van Rossum2d546921995-02-17 14:28:39 +000075
Guido van Rossum2d546921995-02-17 14:28:39 +000076 fp = open(filename)
77 text = fp.read()
78 fp.close()
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000079 try:
80 code = compile(text, filename, "exec")
81 except (SyntaxError, EOFError):
Guido van Rossum57128fd1995-02-19 15:49:17 +000082 print "Syntax error in script", `filename`
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000083 return
Guido van Rossum2d546921995-02-17 14:28:39 +000084
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000085 # Set the destination file name
Guido van Rossum2d546921995-02-17 14:28:39 +000086
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000087 if string.lower(filename[-3:]) == ".py":
88 destname = filename[:-3]
89 else:
90 destname = filename + ".applet"
Guido van Rossum2d546921995-02-17 14:28:39 +000091
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000092 # Copy the data from the template (creating the file as well)
Guido van Rossum2d546921995-02-17 14:28:39 +000093
Guido van Rossum57128fd1995-02-19 15:49:17 +000094 tmpl = open(template, "rb")
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000095 dest = open(destname, "wb")
96 data = tmpl.read()
97 if data:
98 dest.write(data)
99 dest.close()
100 tmpl.close()
Guido van Rossum2d546921995-02-17 14:28:39 +0000101
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000102 # Copy the creator and type of the template to the destination
Guido van Rossum57128fd1995-02-19 15:49:17 +0000103 # unless it already has one
Guido van Rossum2d546921995-02-17 14:28:39 +0000104
Guido van Rossum57128fd1995-02-19 15:49:17 +0000105 tctor, ttype = MacOS.GetCreatorAndType(template)
106 ctor, type = MacOS.GetCreatorAndType(destname)
107 if type in undefs: type = ttype
108 if ctor in undefs: ctor = tctor
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000109 MacOS.SetCreatorAndType(destname, ctor, type)
Guido van Rossum2d546921995-02-17 14:28:39 +0000110
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000111 # Open the input and output resource forks
112
113 input = FSpOpenResFile(template, READ)
114 try:
115 output = FSpOpenResFile(destname, WRITE)
116 except MacOS.Error:
117 print "Creating resource fork..."
118 CreateResFile(destname)
119 output = FSpOpenResFile(destname, WRITE)
120
121 # Copy the resources from the template,
122 # except a 'PYC ' resource named __main__
123
124 UseResFile(input)
125 ntypes = Count1Types()
126 for itype in range(1, 1+ntypes):
127 type = Get1IndType(itype)
128 nresources = Count1Resources(type)
129 for ires in range(1, 1+nresources):
130 res = Get1IndResource(type, ires)
131 id, type, name = res.GetResInfo()
132 if (type, name) == (RESTYPE, RESNAME):
133 continue # Don't copy __main__ from template
134 size = res.SizeResource()
135 attrs = res.GetResAttrs()
136 print id, type, name, size, hex(attrs)
137 res.LoadResource()
138 res.DetachResource()
139 UseResFile(output)
140 try:
141 res2 = Get1Resource(type, id)
142 except MacOS.Error:
143 res2 = None
144 if res2:
145 print "Overwriting..."
146 res2.RmveResource()
147 res.AddResource(type, id, name)
148 #res.SetResAttrs(attrs)
149 res.WriteResource()
150 UseResFile(input)
151 CloseResFile(input)
152
153 # Make sure we're manipulating the output resource file now
154
155 UseResFile(output)
156
157 # Delete any existing 'PYC 'resource named __main__
Guido van Rossum2d546921995-02-17 14:28:39 +0000158
159 try:
160 res = Get1NamedResource(RESTYPE, RESNAME)
161 res.RmveResource()
162 except Error:
163 pass
164
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000165 # Create the raw data for the resource from the code object
166
167 data = marshal.dumps(code)
168 del code
169 data = (MAGIC + '\0\0\0\0') + data
Guido van Rossum2d546921995-02-17 14:28:39 +0000170
171 # Create the resource and write it
172
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000173 id = 0
174 while id < 128:
175 id = Unique1ID(RESTYPE)
Guido van Rossum2d546921995-02-17 14:28:39 +0000176 res = Resource(data)
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000177 res.AddResource(RESTYPE, id, RESNAME)
Guido van Rossum2d546921995-02-17 14:28:39 +0000178 res.WriteResource()
179 res.ReleaseResource()
180
181 # Close the resource file
182
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000183 CloseResFile(output)
Guido van Rossum57128fd1995-02-19 15:49:17 +0000184
185 print "Done with", `filename`, "..."
186
Guido van Rossum2d546921995-02-17 14:28:39 +0000187
188if __name__ == '__main__':
189 main()