blob: c6c7c6b7509c9e6dc712c34a9391008a833d0abd [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
10import string
11import os
Guido van Rossum2d546921995-02-17 14:28:39 +000012import marshal
13import imp
14import macfs
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000015import MacOS
Guido van Rossum2d546921995-02-17 14:28:39 +000016from Res import *
17
18# .pyc file (and 'PYC ' resource magic number)
19MAGIC = imp.get_magic()
20
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000021# Template file (searched on sys.path)
22TEMPLATE = "PythonApplet"
23
24# Specification of our resource
Guido van Rossum2d546921995-02-17 14:28:39 +000025RESTYPE = 'PYC '
Guido van Rossum2d546921995-02-17 14:28:39 +000026RESNAME = '__main__'
27
28# OpenResFile mode parameters
29READ = 1
30WRITE = 2
31
32def main():
33
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000034 # Find the template
35 # (there's no point in proceeding if we can't find it)
36
37 for p in sys.path:
38 template = os.path.join(p, TEMPLATE)
39 try:
40 tmpl = open(template, "rb")
41 break
42 except IOError:
43 continue
44 else:
45 # XXX Ought to put up a dialog
46 print "Template not found. Exit."
47 return
48
Guido van Rossum2d546921995-02-17 14:28:39 +000049 # Ask for source text
50
51 srcfss, ok = macfs.StandardGetFile('TEXT')
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000052 if not ok:
53 tmpl.close()
54 return
55 filename = srcfss.as_pathname()
Guido van Rossum2d546921995-02-17 14:28:39 +000056
57 # Read the source and compile it
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000058 # (there's no point overwriting the destination if it has a syntax error)
Guido van Rossum2d546921995-02-17 14:28:39 +000059
Guido van Rossum2d546921995-02-17 14:28:39 +000060 fp = open(filename)
61 text = fp.read()
62 fp.close()
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000063 try:
64 code = compile(text, filename, "exec")
65 except (SyntaxError, EOFError):
66 print "Syntax error in script"
67 tmpl.close()
68 return
Guido van Rossum2d546921995-02-17 14:28:39 +000069
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000070 # Set the destination file name
Guido van Rossum2d546921995-02-17 14:28:39 +000071
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000072 if string.lower(filename[-3:]) == ".py":
73 destname = filename[:-3]
74 else:
75 destname = filename + ".applet"
Guido van Rossum2d546921995-02-17 14:28:39 +000076
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000077 # Copy the data from the template (creating the file as well)
Guido van Rossum2d546921995-02-17 14:28:39 +000078
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000079 dest = open(destname, "wb")
80 data = tmpl.read()
81 if data:
82 dest.write(data)
83 dest.close()
84 tmpl.close()
Guido van Rossum2d546921995-02-17 14:28:39 +000085
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000086 # Copy the creator and type of the template to the destination
Guido van Rossum2d546921995-02-17 14:28:39 +000087
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000088 ctor, type = MacOS.GetCreatorAndType(template)
89 MacOS.SetCreatorAndType(destname, ctor, type)
Guido van Rossum2d546921995-02-17 14:28:39 +000090
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +000091 # Open the input and output resource forks
92
93 input = FSpOpenResFile(template, READ)
94 try:
95 output = FSpOpenResFile(destname, WRITE)
96 except MacOS.Error:
97 print "Creating resource fork..."
98 CreateResFile(destname)
99 output = FSpOpenResFile(destname, WRITE)
100
101 # Copy the resources from the template,
102 # except a 'PYC ' resource named __main__
103
104 UseResFile(input)
105 ntypes = Count1Types()
106 for itype in range(1, 1+ntypes):
107 type = Get1IndType(itype)
108 nresources = Count1Resources(type)
109 for ires in range(1, 1+nresources):
110 res = Get1IndResource(type, ires)
111 id, type, name = res.GetResInfo()
112 if (type, name) == (RESTYPE, RESNAME):
113 continue # Don't copy __main__ from template
114 size = res.SizeResource()
115 attrs = res.GetResAttrs()
116 print id, type, name, size, hex(attrs)
117 res.LoadResource()
118 res.DetachResource()
119 UseResFile(output)
120 try:
121 res2 = Get1Resource(type, id)
122 except MacOS.Error:
123 res2 = None
124 if res2:
125 print "Overwriting..."
126 res2.RmveResource()
127 res.AddResource(type, id, name)
128 #res.SetResAttrs(attrs)
129 res.WriteResource()
130 UseResFile(input)
131 CloseResFile(input)
132
133 # Make sure we're manipulating the output resource file now
134
135 UseResFile(output)
136
137 # Delete any existing 'PYC 'resource named __main__
Guido van Rossum2d546921995-02-17 14:28:39 +0000138
139 try:
140 res = Get1NamedResource(RESTYPE, RESNAME)
141 res.RmveResource()
142 except Error:
143 pass
144
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000145 # Create the raw data for the resource from the code object
146
147 data = marshal.dumps(code)
148 del code
149 data = (MAGIC + '\0\0\0\0') + data
Guido van Rossum2d546921995-02-17 14:28:39 +0000150
151 # Create the resource and write it
152
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000153 id = 0
154 while id < 128:
155 id = Unique1ID(RESTYPE)
Guido van Rossum2d546921995-02-17 14:28:39 +0000156 res = Resource(data)
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000157 res.AddResource(RESTYPE, id, RESNAME)
Guido van Rossum2d546921995-02-17 14:28:39 +0000158 res.WriteResource()
159 res.ReleaseResource()
160
161 # Close the resource file
162
Guido van Rossum6a0fb6e1995-02-18 15:05:39 +0000163 CloseResFile(output)
Guido van Rossum2d546921995-02-17 14:28:39 +0000164
165if __name__ == '__main__':
166 main()