]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
A new home for scripts/applets
authorJack Jansen <jack.jansen@cwi.nl>
Sat, 29 Jul 1995 13:48:41 +0000 (13:48 +0000)
committerJack Jansen <jack.jansen@cwi.nl>
Sat, 29 Jul 1995 13:48:41 +0000 (13:48 +0000)
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..

Mac/scripts/BuildApplet.py [new file with mode: 0644]
Mac/scripts/EditPythonPrefs.py [new file with mode: 0644]
Mac/scripts/PackLibDir.py [new file with mode: 0644]
Mac/scripts/RunLibScript.py [new file with mode: 0644]

diff --git a/Mac/scripts/BuildApplet.py b/Mac/scripts/BuildApplet.py
new file mode 100644 (file)
index 0000000..cf90901
--- /dev/null
@@ -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()
+
diff --git a/Mac/scripts/EditPythonPrefs.py b/Mac/scripts/EditPythonPrefs.py
new file mode 100644 (file)
index 0000000..3e14ff3
--- /dev/null
@@ -0,0 +1,168 @@
+"""Edit the Python Preferences file."""
+import addpack
+addpack.addpack('Tools')
+addpack.addpack('bgen')
+addpack.addpack('evt')
+
+from Dlg import *
+from Events import *
+from Res import *
+import string
+import struct
+import macfs
+import MacOS
+import os
+import sys
+import Res # For Res.Error
+
+# resource IDs in our own resources (dialogs, etc)
+MESSAGE_ID = 256
+
+DIALOG_ID = 131
+TEXT_ITEM = 1
+OK_ITEM = 2
+CANCEL_ITEM = 3
+REVERT_ITEM = 4
+DIR_ITEM = 5
+
+# Resource IDs in the preferences file
+PATH_STRINGS_ID = 128
+DIRECTORY_ID = 128
+
+WRITE = 2
+smAllScripts = -3
+kOnSystemDisk = 0x8000
+
+def restolist(data):
+       """Convert STR# resource data to a list of strings"""
+       if not data:
+               return []
+       num, = struct.unpack('h', data[:2])
+       data = data[2:]
+       rv = []
+       for i in range(num):
+               strlen = ord(data[0])
+               if strlen < 0: strlen = strlen + 256
+               str = data[1:strlen+1]
+               data = data[strlen+1:]
+               rv.append(str)
+       return rv
+       
+def listtores(list):
+       """Convert a list of strings to STR# resource data"""
+       rv = struct.pack('h', len(list))
+       for str in list:
+               rv = rv + chr(len(str)) + str
+       return rv
+
+def message(str = "Hello, world!", id = MESSAGE_ID):
+       """Show a simple alert with a text message"""
+       d = GetNewDialog(id, -1)
+       print 'd=', d
+       tp, h, rect = d.GetDialogItem(2)
+       SetDialogItemText(h, str)
+       while 1:
+               n = ModalDialog(None)
+               if n == 1: break
+               
+def interact(list, pythondir):
+       """Let the user interact with the dialog"""
+       opythondir = pythondir
+       try:
+               # Try to go to the "correct" dir for GetDirectory
+               os.chdir(pythondir.as_pathname())
+       except os.error:
+               pass
+       d = GetNewDialog(DIALOG_ID, -1)
+       tp, h, rect = d.GetDialogItem(1)
+       SetDialogItemText(h, string.joinfields(list, '\r'))
+       while 1:
+               n = ModalDialog(None)
+               if n == OK_ITEM:
+                       break
+               if n == CANCEL_ITEM:
+                       return None
+               if n == REVERT_ITEM:
+                       return [], pythondir
+               if n == DIR_ITEM:
+                       fss, ok = macfs.GetDirectory()
+                       if ok:
+                               pythondir = fss
+       tmp = string.splitfields(GetDialogItemText(h), '\r')
+       rv = []
+       for i in tmp:
+               if i:
+                       rv.append(i)
+       return rv, pythondir
+       
+def main():
+       try:
+               h = OpenResFile('EditPythonPrefs.rsrc')
+       except Res.Error:
+               pass    # Assume we already have acces to our own resource
+       
+       # Find the preferences folder and our prefs file, create if needed.     
+       vrefnum, dirid = macfs.FindFolder(kOnSystemDisk, 'pref', 0)
+       preff_fss = macfs.FSSpec((vrefnum, dirid, 'Python Preferences'))
+       try:
+               preff_handle = FSpOpenResFile(preff_fss, WRITE)
+       except Res.Error:
+               # Create it
+               message('No preferences file, creating one...')
+               FSpCreateResFile(preff_fss, 'PYTH', 'pref', smAllScripts)
+               preff_handle = FSpOpenResFile(preff_fss, WRITE)
+               
+       # Load the path and directory resources
+       try:
+               sr = GetResource('STR#', PATH_STRINGS_ID)
+       except (MacOS.Error, Res.Error):
+               message('Cannot find any sys.path resource! (Old python?)')
+               sys.exit(0)
+       d = sr.data
+       l = restolist(d)
+       
+       try:
+               dr = GetResource('alis', DIRECTORY_ID)
+               fss, fss_changed = macfs.RawAlias(dr.data).Resolve()
+       except (MacOS.Error, Res.Error):
+               dr = None
+               fss = macfs.FSSpec(os.getcwd())
+               fss_changed = 1
+       
+       # Let the user play away
+       result = interact(l, fss)
+       
+       # See what we have to update, and how
+       if result == None:
+               sys.exit(0)
+               
+       pathlist, nfss = result
+       if nfss != fss:
+               fss_changed = 1
+               
+       if fss_changed or pathlist != l:
+               if fss_changed:
+                       alias = nfss.NewAlias()
+                       if dr:
+                               dr.data = alias.data
+                               dr.ChangedResource()
+                       else:
+                               dr = Resource(alias.data)
+                               dr.AddResource('alis', DIRECTORY_ID, '')
+                               
+               if pathlist != l:
+                       if pathlist == []:
+                               if sr.HomeResFile() == preff_handle:
+                                       sr.RemoveResource()
+                       elif sr.HomeResFile() == preff_handle:
+                               sr.data = listtores(pathlist)
+                               sr.ChangedResource()
+                       else:
+                               sr = Resource(listtores(pathlist))
+                               sr.AddResource('STR#', PATH_STRINGS_ID, '')
+                               
+       CloseResFile(preff_handle)
+
+if __name__ == '__main__':
+       print # Stupid, to init toolboxes...
+       main()
diff --git a/Mac/scripts/PackLibDir.py b/Mac/scripts/PackLibDir.py
new file mode 100644 (file)
index 0000000..cdda87d
--- /dev/null
@@ -0,0 +1,93 @@
+#
+# Turn a pyc file into a resource file containing it in 'PYC ' resource form
+import addpack
+addpack.addpack('Tools')
+addpack.addpack('bgen')
+addpack.addpack('res')
+from Res import *
+import Res
+from Resources import *
+import os
+import macfs
+import sys
+
+READ = 1
+WRITE = 2
+smAllScripts = -3
+
+error = 'mkpycresourcefile.error'
+
+def Pstring(str):
+       if len(str) > 255:
+               raise ValueError, 'String too large'
+       return chr(len(str))+str
+       
+def createoutput(dst):
+       """Create output file. Return handle and first id to use."""
+       
+
+       FSpCreateResFile(dst, 'PYTH', 'rsrc', smAllScripts)
+       output = FSpOpenResFile(dst, WRITE)
+       UseResFile(output)
+       num = 128
+       return output, num
+       
+def writemodule(name, id, data):
+       """Write pyc code to a PYC resource with given name and id."""
+       # XXXX Check that it doesn't exist
+       res = Resource(data)
+       res.AddResource('PYC ', id, name)
+       res.WriteResource()
+       res.ReleaseResource()
+               
+def mkpycresourcefile(src, dst):
+       """Copy pyc file/dir src to resource file dst."""
+       
+       if not os.path.isdir(src) and src[-4:] <> '.pyc':
+                       raise error, 'I can only handle .pyc files or directories'
+       handle, oid = createoutput(dst)
+       if os.path.isdir(src):
+               id = handlesubdir(handle, oid, src)
+       else:
+               id = handleonepycfile(handle, oid, src)
+       print 'Wrote',id-oid,'PYC resources to', dst
+       CloseResFile(handle)
+                       
+def handleonepycfile(handle, id, file):
+       """Copy one pyc file to the open resource file"""
+       d, name = os.path.split(file)
+       name = name[:-4]
+       print '  module', name
+       writemodule(name, id, open(file, 'rb').read())
+       return id+1
+       
+def handlesubdir(handle, id, srcdir):
+       """Recursively scan a directory for pyc files and copy to resources"""
+       print 'Directory', srcdir
+       src = os.listdir(srcdir)
+       for file in src:
+               file = os.path.join(srcdir, file)
+               if os.path.isdir(file):
+                       id = handlesubdir(handle, id, file)
+               elif file[-4:] == '.pyc':
+                       id = handleonepycfile(handle, id, file)
+       return id
+                               
+       
+if __name__ == '__main__':
+       args = sys.argv[1:]
+       if not args:
+               ifss, ok = macfs.StandardGetFile('PYC ')
+               if ok:
+                       args = [ifss.as_pathname()]
+               else:
+                       ifss, ok = macfs.GetDirectory()
+                       if not ok:
+                               sys.exit(0)
+                       args = [ifss.as_pathname()]
+       for ifn in args:
+               ofss, ok = macfs.StandardPutFile('Output for '+os.path.split(ifn)[1])
+               if not ok:
+                       sys.exit(0)
+               mkpycresourcefile(ifn, ofss.as_pathname())
+       sys.exit(1)                     # So we can see something...
diff --git a/Mac/scripts/RunLibScript.py b/Mac/scripts/RunLibScript.py
new file mode 100644 (file)
index 0000000..36787d9
--- /dev/null
@@ -0,0 +1,108 @@
+"""Import a module while pretending its name is __main__. This
+can be used to run scripts from the PackedLib resource file while pretending
+they have been double-clicked."""
+
+import imp
+import sys
+import os
+import string
+import Dlg
+import macfs
+
+DIALOG_ID = 140
+OK = 1
+CANCEL = 2
+SCRIPTNAME=3
+ARGV=4
+STDIN_CONS=5
+STDIN_FILE=6
+STDOUT_CONS=7
+STDOUT_FILE=8
+WORKING_DIR=9
+PAUSE=10
+
+def import_as_main(name):
+       fp, path, (suffix, mode, type) = imp.find_module(name)
+       if type == imp.PY_SOURCE:
+               imp.load_source('__main__', path)
+       elif type == imp.PY_COMPILED:
+               imp.load_compiled('__main__', path)
+       elif type == imp.PY_RESOURCE:
+               imp.load_resource('__main__', path)
+               
+def interact():
+       d = Dlg.GetNewDialog(DIALOG_ID, -1)
+       wdir = stdin = stdout = None
+       pause = 0
+
+       tp, in_c_h, rect = d.GetDialogItem(STDIN_CONS)
+       tp, in_f_h, rect = d.GetDialogItem(STDIN_FILE)
+       tp, out_c_h, rect = d.GetDialogItem(STDOUT_CONS)
+       tp, out_f_h, rect = d.GetDialogItem(STDOUT_FILE)
+       tp, pause_h, rect = d.GetDialogItem(PAUSE)
+       in_c_h = in_c_h.as_Control()
+       in_f_h = in_f_h.as_Control()
+       out_c_h = out_c_h.as_Control()
+       out_f_h = out_f_h.as_Control()
+       pause_h = pause_h.as_Control()
+
+       while 1:
+               in_c_h.SetControlValue(not stdin)
+               in_f_h.SetControlValue(not not stdin)
+               out_c_h.SetControlValue(not stdout)
+               out_f_h.SetControlValue(not not stdout)
+               pause_h.SetControlValue(pause)
+               
+               n = Dlg.ModalDialog(None)
+               if n == OK:
+                       break
+               elif n == CANCEL:
+                       sys.exit(0)
+               elif n == STDIN_CONS:
+                       stdin = None
+               elif n == STDIN_FILE:
+                       fss, ok = macfs.StandardGetFile('TEXT')
+                       if ok:
+                               stdin = fss
+               elif n == STDOUT_FILE:
+                       fss, ok = macfs.StandardPutFile('stdout:')
+                       if ok:
+                               stdout = fss
+               elif n == WORKING_DIR:
+                       fss, ok = macfs.GetDirectory()
+                       if ok:
+                               wdir = fss
+               elif n == PAUSE:
+                       pause = (not pause)
+               
+       tp, h, rect = d.GetDialogItem(SCRIPTNAME)
+       name = Dlg.GetDialogItemText(h)
+       tp, h, rect = d.GetDialogItem(ARGV)
+       argv = Dlg.GetDialogItemText(h)
+       return name, argv, stdin, stdout, wdir, pause
+       
+def main():
+       curdir = os.getcwd()
+       import Res
+       Res.OpenResFile('RunLibScript.rsrc')
+       name, argv, stdin, stdout, wdir, pause = interact()
+       if not name:
+               sys.exit(0)
+       sys.argv = [name] + string.split(argv)
+       if stdin:
+               sys.stdin = open(stdin.as_pathname())
+       if stdout:
+               sys.stdout = open(stdout.as_pathname(), 'w')
+       if wdir:
+               os.chdir(wdir.as_pathname())
+       else:
+               os.chdir(curdir)
+
+       import_as_main(name)
+
+       if pause:
+               sys.exit(1)
+       
+if __name__ == '__main__':
+       main()
+