Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6a0fb6e

Browse files
committed
fancier version copies template file
1 parent a6da03f commit 6a0fb6e

1 file changed

Lines changed: 111 additions & 34 deletions

File tree

Mac/mkapplet.py

Lines changed: 111 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
1-
"""Add a 'PYC ' resource named "__main__" to a resource file.
1+
"""Create an applet from a Python script.
22
3-
This first puts up a dialog asking for a Python source file ('TEXT'),
4-
then one asking for an existing destination file ('APPL' or 'rsrc').
5-
6-
It compiles the Python source into a code object, marshals it into a string,
7-
prefixes the string with a .pyc header, and turns it into a resource,
8-
which is then written to the destination.
9-
10-
If the destination already contains a resource with the same name and type,
11-
it is overwritten.
3+
This puts up a dialog asking for a Python source file ('TEXT').
4+
The output is a file with the same name but its ".py" suffix dropped.
5+
It is created by copying an applet template and then adding a 'PYC '
6+
resource named __main__ containing the compiled, marshalled script.
127
"""
138

9+
import sys
10+
import string
11+
import os
1412
import marshal
1513
import imp
1614
import macfs
15+
import MacOS
1716
from Res import *
1817

1918
# .pyc file (and 'PYC ' resource magic number)
2019
MAGIC = imp.get_magic()
2120

22-
# Complete specification of our resource
21+
# Template file (searched on sys.path)
22+
TEMPLATE = "PythonApplet"
23+
24+
# Specification of our resource
2325
RESTYPE = 'PYC '
24-
RESID = 128
2526
RESNAME = '__main__'
2627

2728
# OpenResFile mode parameters
@@ -30,60 +31,136 @@
3031

3132
def main():
3233

34+
# 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+
3349
# Ask for source text
3450

3551
srcfss, ok = macfs.StandardGetFile('TEXT')
36-
if not ok: return
52+
if not ok:
53+
tmpl.close()
54+
return
55+
filename = srcfss.as_pathname()
3756

3857
# Read the source and compile it
39-
# (there's no point asking for a destination if it has a syntax error)
58+
# (there's no point overwriting the destination if it has a syntax error)
4059

41-
filename = srcfss.as_pathname()
4260
fp = open(filename)
4361
text = fp.read()
4462
fp.close()
45-
code = compile(text, filename, "exec")
63+
try:
64+
code = compile(text, filename, "exec")
65+
except (SyntaxError, EOFError):
66+
print "Syntax error in script"
67+
tmpl.close()
68+
return
4669

47-
# Ask for destination file
70+
# Set the destination file name
4871

49-
dstfss, ok = macfs.StandardGetFile('APPL', 'rsrc')
50-
if not ok: return
72+
if string.lower(filename[-3:]) == ".py":
73+
destname = filename[:-3]
74+
else:
75+
destname = filename + ".applet"
5176

52-
# Create the raw data for the resource from the code object
77+
# Copy the data from the template (creating the file as well)
5378

54-
data = marshal.dumps(code)
55-
del code
56-
data = (MAGIC + '\0\0\0\0') + data
79+
dest = open(destname, "wb")
80+
data = tmpl.read()
81+
if data:
82+
dest.write(data)
83+
dest.close()
84+
tmpl.close()
5785

58-
# Open the resource file
86+
# Copy the creator and type of the template to the destination
5987

60-
fnum = FSpOpenResFile(dstfss.as_pathname(), WRITE)
88+
ctor, type = MacOS.GetCreatorAndType(template)
89+
MacOS.SetCreatorAndType(destname, ctor, type)
6190

62-
# Delete any existing resource with name __main__ or number 128
91+
# Open the input and output resource forks
6392

93+
input = FSpOpenResFile(template, READ)
6494
try:
65-
res = Get1NamedResource(RESTYPE, RESNAME)
66-
res.RmveResource()
67-
except Error:
68-
pass
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__
69138

70139
try:
71-
res = Get1Resource(RESTYPE, RESID)
140+
res = Get1NamedResource(RESTYPE, RESNAME)
72141
res.RmveResource()
73142
except Error:
74143
pass
75144

145+
# 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
150+
76151
# Create the resource and write it
77152

153+
id = 0
154+
while id < 128:
155+
id = Unique1ID(RESTYPE)
78156
res = Resource(data)
79-
res.AddResource(RESTYPE, RESID, RESNAME)
80-
# XXX Are the following two calls needed?
157+
res.AddResource(RESTYPE, id, RESNAME)
81158
res.WriteResource()
82159
res.ReleaseResource()
83160

84161
# Close the resource file
85162

86-
CloseResFile(fnum)
163+
CloseResFile(output)
87164

88165
if __name__ == '__main__':
89166
main()

0 commit comments

Comments
 (0)