summaryrefslogtreecommitdiffstats
path: root/Mac/scripts/BuildApplet.py
diff options
context:
space:
mode:
authorJack Jansen <jack.jansen@cwi.nl>1995-07-29 13:48:41 (GMT)
committerJack Jansen <jack.jansen@cwi.nl>1995-07-29 13:48:41 (GMT)
commit7571f30efe935bfddd2be3a8e716f2dda2e55f9e (patch)
tree9df641c104c73ec7a319e150ca2ae07613bd8f88 /Mac/scripts/BuildApplet.py
parent0db1ef96aca3f8ba369080021974ccc1436d395a (diff)
downloadcpython-7571f30efe935bfddd2be3a8e716f2dda2e55f9e.zip
cpython-7571f30efe935bfddd2be3a8e716f2dda2e55f9e.tar.gz
cpython-7571f30efe935bfddd2be3a8e716f2dda2e55f9e.tar.bz2
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..
Diffstat (limited to 'Mac/scripts/BuildApplet.py')
-rw-r--r--Mac/scripts/BuildApplet.py260
1 files changed, 260 insertions, 0 deletions
diff --git a/Mac/scripts/BuildApplet.py b/Mac/scripts/BuildApplet.py
new file mode 100644
index 0000000..cf90901
--- /dev/null
+++ b/Mac/scripts/BuildApplet.py
@@ -0,0 +1,260 @@
+"""Create an applet from a Python script.
+
+This puts up a dialog asking for a Python source file ('TEXT').
+The output is a file with the same name but its ".py" suffix dropped.
+It is created by copying an applet template and then adding a 'PYC '
+resource named __main__ containing the compiled, marshalled script.
+"""
+
+import sys
+sys.stdout = sys.stderr
+
+import string
+import os
+import marshal
+import imp
+import macfs
+import MacOS
+from Res import *
+
+# .pyc file (and 'PYC ' resource magic number)
+MAGIC = imp.get_magic()
+
+# Template file (searched on sys.path)
+TEMPLATE = "PythonApplet"
+
+# Specification of our resource
+RESTYPE = 'PYC '
+RESNAME = '__main__'
+
+# A resource with this name sets the "owner" (creator) of the destination
+OWNERNAME = "owner resource"
+
+# OpenResFile mode parameters
+READ = 1
+WRITE = 2
+
+def main():
+
+ # Find the template
+ # (there's no point in proceeding if we can't find it)
+
+ for p in sys.path:
+ template = os.path.join(p, TEMPLATE)
+ try:
+ tmpl = open(template, "rb")
+ tmpl.close()
+ break
+ except IOError:
+ continue
+ else:
+ die("Template %s not found" % `template`)
+ return
+
+ # Convert to full pathname
+ template = macfs.FSSpec(template).as_pathname()
+
+ # Ask for source text if not specified in sys.argv[1:]
+
+ if not sys.argv[1:]:
+ srcfss, ok = macfs.StandardGetFile('TEXT')
+ if not ok:
+ return
+ filename = srcfss.as_pathname()
+ tp, tf = os.path.split(filename)
+ if tf[-3:] == '.py':
+ tf = tf[:-3]
+ else:
+ tf = tf + '.applet'
+ dstfss, ok = macfs.StandardPutFile('Save application as:', tf)
+ if not ok: return
+ process(template, filename, dstfss.as_pathname())
+ else:
+
+ # Loop over all files to be processed
+ for filename in sys.argv[1:]:
+ process(template, filename, '')
+
+undefs = ('Atmp', '????', ' ', '\0\0\0\0', 'BINA')
+
+def process(template, filename, output):
+
+ print "Processing", `filename`, "..."
+
+ # Read the source and compile it
+ # (there's no point overwriting the destination if it has a syntax error)
+
+ fp = open(filename)
+ text = fp.read()
+ fp.close()
+ try:
+ code = compile(text, filename, "exec")
+ except (SyntaxError, EOFError):
+ die("Syntax error in script %s" % `filename`)
+ return
+
+ # Set the destination file name
+
+ if string.lower(filename[-3:]) == ".py":
+ destname = filename[:-3]
+ rsrcname = destname + '.rsrc'
+ else:
+ destname = filename + ".applet"
+ rsrcname = filename + '.rsrc'
+
+ if output:
+ destname = output
+ # Copy the data from the template (creating the file as well)
+
+ tmpl = open(template, "rb")
+ dest = open(destname, "wb")
+ data = tmpl.read()
+ if data:
+ dest.write(data)
+ dest.close()
+ tmpl.close()
+
+ # Copy the creator of the template to the destination
+ # unless it already got one. Set type to APPL
+
+ tctor, ttype = MacOS.GetCreatorAndType(template)
+ ctor, type = MacOS.GetCreatorAndType(destname)
+ if type in undefs: type = 'APPL'
+ if ctor in undefs: ctor = tctor
+
+ # Open the output resource fork
+
+ try:
+ output = FSpOpenResFile(destname, WRITE)
+ except MacOS.Error:
+ print "Creating resource fork..."
+ CreateResFile(destname)
+ output = FSpOpenResFile(destname, WRITE)
+
+ # Copy the resources from the template
+
+ input = FSpOpenResFile(template, READ)
+ newctor = copyres(input, output)
+ CloseResFile(input)
+ if newctor: ctor = newctor
+
+ # Copy the resources from the target specific resource template, if any
+
+ try:
+ input = FSpOpenResFile(rsrcname, READ)
+ except MacOS.Error:
+ pass
+ else:
+ newctor = copyres(input, output)
+ CloseResFile(input)
+ if newctor: ctor = newctor
+
+ # Now set the creator and type of the destination
+
+ MacOS.SetCreatorAndType(destname, ctor, type)
+
+ # Make sure we're manipulating the output resource file now
+
+ UseResFile(output)
+
+ # Delete any existing 'PYC 'resource named __main__
+
+ try:
+ res = Get1NamedResource(RESTYPE, RESNAME)
+ res.RemoveResource()
+ except Error:
+ pass
+
+ # Create the raw data for the resource from the code object
+
+ data = marshal.dumps(code)
+ del code
+ data = (MAGIC + '\0\0\0\0') + data
+
+ # Create the resource and write it
+
+ id = 0
+ while id < 128:
+ id = Unique1ID(RESTYPE)
+ res = Resource(data)
+ res.AddResource(RESTYPE, id, RESNAME)
+ res.WriteResource()
+ res.ReleaseResource()
+
+ # Close the output file
+
+ CloseResFile(output)
+
+ # Give positive feedback
+
+ message("Applet %s created." % `destname`)
+
+
+# Copy resources between two resource file descriptors.
+# Exception: don't copy a __main__ resource.
+# If a resource's name is "owner resource", its type is returned
+# (so the caller can use it to set the destination's creator)
+
+def copyres(input, output):
+ ctor = None
+ UseResFile(input)
+ ntypes = Count1Types()
+ for itype in range(1, 1+ntypes):
+ type = Get1IndType(itype)
+ nresources = Count1Resources(type)
+ for ires in range(1, 1+nresources):
+ res = Get1IndResource(type, ires)
+ id, type, name = res.GetResInfo()
+ lcname = string.lower(name)
+ if (type, lcname) == (RESTYPE, RESNAME):
+ continue # Don't copy __main__ from template
+ if lcname == OWNERNAME: ctor = type
+ size = res.size
+ attrs = res.GetResAttrs()
+ print id, type, name, size, hex(attrs)
+ res.LoadResource()
+ res.DetachResource()
+ UseResFile(output)
+ try:
+ res2 = Get1Resource(type, id)
+ except MacOS.Error:
+ res2 = None
+ if res2:
+ print "Overwriting..."
+ res2.RemoveResource()
+ res.AddResource(type, id, name)
+ res.WriteResource()
+ attrs = attrs | res.GetResAttrs()
+ print "New attrs =", hex(attrs)
+ res.SetResAttrs(attrs)
+ UseResFile(input)
+ return ctor
+
+
+# Show a message and exit
+
+def die(str):
+ message(str)
+ sys.exit(1)
+
+
+# Show a message
+
+def message(str, id = 256):
+ from Dlg import *
+ d = GetNewDialog(id, -1)
+ if not d:
+ print "Error:", `str`
+ print "DLOG id =", id, "not found."
+ return
+ tp, h, rect = d.GetDialogItem(2)
+ SetDialogItemText(h, str)
+ while 1:
+ n = ModalDialog(None)
+ if n == 1: break
+ del d
+
+
+if __name__ == '__main__':
+ main()
+