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

Skip to content

Commit 7571f30

Browse files
committed
A new home for scripts/applets
EditPythonPrefs - Edit the preferences file (sys.path, python home) PackLibDir - Convert a sys.path directory to a resource file RunLibScript - import a module and run as __main__ mkapplet - Create a python applet The resource files belonging to these should also be stored here, somehow..
1 parent 0db1ef9 commit 7571f30

4 files changed

Lines changed: 629 additions & 0 deletions

File tree

Mac/scripts/BuildApplet.py

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
"""Create an applet from a Python script.
2+
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.
7+
"""
8+
9+
import sys
10+
sys.stdout = sys.stderr
11+
12+
import string
13+
import os
14+
import marshal
15+
import imp
16+
import macfs
17+
import MacOS
18+
from Res import *
19+
20+
# .pyc file (and 'PYC ' resource magic number)
21+
MAGIC = imp.get_magic()
22+
23+
# Template file (searched on sys.path)
24+
TEMPLATE = "PythonApplet"
25+
26+
# Specification of our resource
27+
RESTYPE = 'PYC '
28+
RESNAME = '__main__'
29+
30+
# A resource with this name sets the "owner" (creator) of the destination
31+
OWNERNAME = "owner resource"
32+
33+
# OpenResFile mode parameters
34+
READ = 1
35+
WRITE = 2
36+
37+
def main():
38+
39+
# Find the template
40+
# (there's no point in proceeding if we can't find it)
41+
42+
for p in sys.path:
43+
template = os.path.join(p, TEMPLATE)
44+
try:
45+
tmpl = open(template, "rb")
46+
tmpl.close()
47+
break
48+
except IOError:
49+
continue
50+
else:
51+
die("Template %s not found" % `template`)
52+
return
53+
54+
# Convert to full pathname
55+
template = macfs.FSSpec(template).as_pathname()
56+
57+
# Ask for source text if not specified in sys.argv[1:]
58+
59+
if not sys.argv[1:]:
60+
srcfss, ok = macfs.StandardGetFile('TEXT')
61+
if not ok:
62+
return
63+
filename = srcfss.as_pathname()
64+
tp, tf = os.path.split(filename)
65+
if tf[-3:] == '.py':
66+
tf = tf[:-3]
67+
else:
68+
tf = tf + '.applet'
69+
dstfss, ok = macfs.StandardPutFile('Save application as:', tf)
70+
if not ok: return
71+
process(template, filename, dstfss.as_pathname())
72+
else:
73+
74+
# Loop over all files to be processed
75+
for filename in sys.argv[1:]:
76+
process(template, filename, '')
77+
78+
undefs = ('Atmp', '????', ' ', '\0\0\0\0', 'BINA')
79+
80+
def process(template, filename, output):
81+
82+
print "Processing", `filename`, "..."
83+
84+
# Read the source and compile it
85+
# (there's no point overwriting the destination if it has a syntax error)
86+
87+
fp = open(filename)
88+
text = fp.read()
89+
fp.close()
90+
try:
91+
code = compile(text, filename, "exec")
92+
except (SyntaxError, EOFError):
93+
die("Syntax error in script %s" % `filename`)
94+
return
95+
96+
# Set the destination file name
97+
98+
if string.lower(filename[-3:]) == ".py":
99+
destname = filename[:-3]
100+
rsrcname = destname + '.rsrc'
101+
else:
102+
destname = filename + ".applet"
103+
rsrcname = filename + '.rsrc'
104+
105+
if output:
106+
destname = output
107+
# Copy the data from the template (creating the file as well)
108+
109+
tmpl = open(template, "rb")
110+
dest = open(destname, "wb")
111+
data = tmpl.read()
112+
if data:
113+
dest.write(data)
114+
dest.close()
115+
tmpl.close()
116+
117+
# Copy the creator of the template to the destination
118+
# unless it already got one. Set type to APPL
119+
120+
tctor, ttype = MacOS.GetCreatorAndType(template)
121+
ctor, type = MacOS.GetCreatorAndType(destname)
122+
if type in undefs: type = 'APPL'
123+
if ctor in undefs: ctor = tctor
124+
125+
# Open the output resource fork
126+
127+
try:
128+
output = FSpOpenResFile(destname, WRITE)
129+
except MacOS.Error:
130+
print "Creating resource fork..."
131+
CreateResFile(destname)
132+
output = FSpOpenResFile(destname, WRITE)
133+
134+
# Copy the resources from the template
135+
136+
input = FSpOpenResFile(template, READ)
137+
newctor = copyres(input, output)
138+
CloseResFile(input)
139+
if newctor: ctor = newctor
140+
141+
# Copy the resources from the target specific resource template, if any
142+
143+
try:
144+
input = FSpOpenResFile(rsrcname, READ)
145+
except MacOS.Error:
146+
pass
147+
else:
148+
newctor = copyres(input, output)
149+
CloseResFile(input)
150+
if newctor: ctor = newctor
151+
152+
# Now set the creator and type of the destination
153+
154+
MacOS.SetCreatorAndType(destname, ctor, type)
155+
156+
# Make sure we're manipulating the output resource file now
157+
158+
UseResFile(output)
159+
160+
# Delete any existing 'PYC 'resource named __main__
161+
162+
try:
163+
res = Get1NamedResource(RESTYPE, RESNAME)
164+
res.RemoveResource()
165+
except Error:
166+
pass
167+
168+
# Create the raw data for the resource from the code object
169+
170+
data = marshal.dumps(code)
171+
del code
172+
data = (MAGIC + '\0\0\0\0') + data
173+
174+
# Create the resource and write it
175+
176+
id = 0
177+
while id < 128:
178+
id = Unique1ID(RESTYPE)
179+
res = Resource(data)
180+
res.AddResource(RESTYPE, id, RESNAME)
181+
res.WriteResource()
182+
res.ReleaseResource()
183+
184+
# Close the output file
185+
186+
CloseResFile(output)
187+
188+
# Give positive feedback
189+
190+
message("Applet %s created." % `destname`)
191+
192+
193+
# Copy resources between two resource file descriptors.
194+
# Exception: don't copy a __main__ resource.
195+
# If a resource's name is "owner resource", its type is returned
196+
# (so the caller can use it to set the destination's creator)
197+
198+
def copyres(input, output):
199+
ctor = None
200+
UseResFile(input)
201+
ntypes = Count1Types()
202+
for itype in range(1, 1+ntypes):
203+
type = Get1IndType(itype)
204+
nresources = Count1Resources(type)
205+
for ires in range(1, 1+nresources):
206+
res = Get1IndResource(type, ires)
207+
id, type, name = res.GetResInfo()
208+
lcname = string.lower(name)
209+
if (type, lcname) == (RESTYPE, RESNAME):
210+
continue # Don't copy __main__ from template
211+
if lcname == OWNERNAME: ctor = type
212+
size = res.size
213+
attrs = res.GetResAttrs()
214+
print id, type, name, size, hex(attrs)
215+
res.LoadResource()
216+
res.DetachResource()
217+
UseResFile(output)
218+
try:
219+
res2 = Get1Resource(type, id)
220+
except MacOS.Error:
221+
res2 = None
222+
if res2:
223+
print "Overwriting..."
224+
res2.RemoveResource()
225+
res.AddResource(type, id, name)
226+
res.WriteResource()
227+
attrs = attrs | res.GetResAttrs()
228+
print "New attrs =", hex(attrs)
229+
res.SetResAttrs(attrs)
230+
UseResFile(input)
231+
return ctor
232+
233+
234+
# Show a message and exit
235+
236+
def die(str):
237+
message(str)
238+
sys.exit(1)
239+
240+
241+
# Show a message
242+
243+
def message(str, id = 256):
244+
from Dlg import *
245+
d = GetNewDialog(id, -1)
246+
if not d:
247+
print "Error:", `str`
248+
print "DLOG id =", id, "not found."
249+
return
250+
tp, h, rect = d.GetDialogItem(2)
251+
SetDialogItemText(h, str)
252+
while 1:
253+
n = ModalDialog(None)
254+
if n == 1: break
255+
del d
256+
257+
258+
if __name__ == '__main__':
259+
main()
260+

0 commit comments

Comments
 (0)