| 1 | n/a | """macresource - Locate and open the resources needed for a script.""" |
|---|
| 2 | n/a | |
|---|
| 3 | n/a | from warnings import warnpy3k |
|---|
| 4 | n/a | warnpy3k("In 3.x, the macresource module is removed.", stacklevel=2) |
|---|
| 5 | n/a | |
|---|
| 6 | n/a | from Carbon import Res |
|---|
| 7 | n/a | import os |
|---|
| 8 | n/a | import sys |
|---|
| 9 | n/a | import MacOS |
|---|
| 10 | n/a | import macostools |
|---|
| 11 | n/a | |
|---|
| 12 | n/a | class ArgumentError(TypeError): pass |
|---|
| 13 | n/a | class ResourceFileNotFoundError(ImportError): pass |
|---|
| 14 | n/a | |
|---|
| 15 | n/a | def need(restype, resid, filename=None, modname=None): |
|---|
| 16 | n/a | """Open a resource file, if needed. restype and resid |
|---|
| 17 | n/a | are required parameters, and identify the resource for which to test. If it |
|---|
| 18 | n/a | is available we are done. If it is not available we look for a file filename |
|---|
| 19 | n/a | (default: modname with .rsrc appended) either in the same folder as |
|---|
| 20 | n/a | where modname was loaded from, or otherwise across sys.path. |
|---|
| 21 | n/a | |
|---|
| 22 | n/a | Returns the refno of the resource file opened (or None)""" |
|---|
| 23 | n/a | |
|---|
| 24 | n/a | if modname is None and filename is None: |
|---|
| 25 | n/a | raise ArgumentError, "Either filename or modname argument (or both) must be given" |
|---|
| 26 | n/a | |
|---|
| 27 | n/a | if type(resid) is type(1): |
|---|
| 28 | n/a | try: |
|---|
| 29 | n/a | h = Res.GetResource(restype, resid) |
|---|
| 30 | n/a | except Res.Error: |
|---|
| 31 | n/a | pass |
|---|
| 32 | n/a | else: |
|---|
| 33 | n/a | return None |
|---|
| 34 | n/a | else: |
|---|
| 35 | n/a | try: |
|---|
| 36 | n/a | h = Res.GetNamedResource(restype, resid) |
|---|
| 37 | n/a | except Res.Error: |
|---|
| 38 | n/a | pass |
|---|
| 39 | n/a | else: |
|---|
| 40 | n/a | return None |
|---|
| 41 | n/a | |
|---|
| 42 | n/a | # Construct a filename if we don't have one |
|---|
| 43 | n/a | if not filename: |
|---|
| 44 | n/a | if '.' in modname: |
|---|
| 45 | n/a | filename = modname.split('.')[-1] + '.rsrc' |
|---|
| 46 | n/a | else: |
|---|
| 47 | n/a | filename = modname + '.rsrc' |
|---|
| 48 | n/a | |
|---|
| 49 | n/a | # Now create a list of folders to search |
|---|
| 50 | n/a | searchdirs = [] |
|---|
| 51 | n/a | if modname == '__main__': |
|---|
| 52 | n/a | # If we're main we look in the current directory |
|---|
| 53 | n/a | searchdirs = [os.curdir] |
|---|
| 54 | n/a | if modname in sys.modules: |
|---|
| 55 | n/a | mod = sys.modules[modname] |
|---|
| 56 | n/a | if hasattr(mod, '__file__'): |
|---|
| 57 | n/a | searchdirs = [os.path.dirname(mod.__file__)] |
|---|
| 58 | n/a | searchdirs.extend(sys.path) |
|---|
| 59 | n/a | |
|---|
| 60 | n/a | # And look for the file |
|---|
| 61 | n/a | for dir in searchdirs: |
|---|
| 62 | n/a | pathname = os.path.join(dir, filename) |
|---|
| 63 | n/a | if os.path.exists(pathname): |
|---|
| 64 | n/a | break |
|---|
| 65 | n/a | else: |
|---|
| 66 | n/a | raise ResourceFileNotFoundError, filename |
|---|
| 67 | n/a | |
|---|
| 68 | n/a | refno = open_pathname(pathname) |
|---|
| 69 | n/a | |
|---|
| 70 | n/a | # And check that the resource exists now |
|---|
| 71 | n/a | if type(resid) is type(1): |
|---|
| 72 | n/a | h = Res.GetResource(restype, resid) |
|---|
| 73 | n/a | else: |
|---|
| 74 | n/a | h = Res.GetNamedResource(restype, resid) |
|---|
| 75 | n/a | return refno |
|---|
| 76 | n/a | |
|---|
| 77 | n/a | def open_pathname(pathname, verbose=0): |
|---|
| 78 | n/a | """Open a resource file given by pathname, possibly decoding an |
|---|
| 79 | n/a | AppleSingle file""" |
|---|
| 80 | n/a | # No resource fork. We may be on OSX, and this may be either |
|---|
| 81 | n/a | # a data-fork based resource file or a AppleSingle file |
|---|
| 82 | n/a | # from the CVS repository. |
|---|
| 83 | n/a | try: |
|---|
| 84 | n/a | refno = Res.FSOpenResourceFile(pathname, u'', 1) |
|---|
| 85 | n/a | except Res.Error, arg: |
|---|
| 86 | n/a | if arg[0] != -199: |
|---|
| 87 | n/a | # -199 is "bad resource map" |
|---|
| 88 | n/a | raise |
|---|
| 89 | n/a | else: |
|---|
| 90 | n/a | return refno |
|---|
| 91 | n/a | # Finally try decoding an AppleSingle file |
|---|
| 92 | n/a | pathname = _decode(pathname, verbose=verbose) |
|---|
| 93 | n/a | refno = Res.FSOpenResourceFile(pathname, u'', 1) |
|---|
| 94 | n/a | |
|---|
| 95 | n/a | def resource_pathname(pathname, verbose=0): |
|---|
| 96 | n/a | """Return the pathname for a resource file (either DF or RF based). |
|---|
| 97 | n/a | If the pathname given already refers to such a file simply return it, |
|---|
| 98 | n/a | otherwise first decode it.""" |
|---|
| 99 | n/a | # No resource fork. We may be on OSX, and this may be either |
|---|
| 100 | n/a | # a data-fork based resource file or a AppleSingle file |
|---|
| 101 | n/a | # from the CVS repository. |
|---|
| 102 | n/a | try: |
|---|
| 103 | n/a | refno = Res.FSOpenResourceFile(pathname, u'', 1) |
|---|
| 104 | n/a | except Res.Error, arg: |
|---|
| 105 | n/a | if arg[0] != -199: |
|---|
| 106 | n/a | # -199 is "bad resource map" |
|---|
| 107 | n/a | raise |
|---|
| 108 | n/a | else: |
|---|
| 109 | n/a | return refno |
|---|
| 110 | n/a | # Finally try decoding an AppleSingle file |
|---|
| 111 | n/a | pathname = _decode(pathname, verbose=verbose) |
|---|
| 112 | n/a | return pathname |
|---|
| 113 | n/a | |
|---|
| 114 | n/a | def open_error_resource(): |
|---|
| 115 | n/a | """Open the resource file containing the error code to error message |
|---|
| 116 | n/a | mapping.""" |
|---|
| 117 | n/a | need('Estr', 1, filename="errors.rsrc", modname=__name__) |
|---|
| 118 | n/a | |
|---|
| 119 | n/a | def _decode(pathname, verbose=0): |
|---|
| 120 | n/a | # Decode an AppleSingle resource file, return the new pathname. |
|---|
| 121 | n/a | newpathname = pathname + '.df.rsrc' |
|---|
| 122 | n/a | if os.path.exists(newpathname) and \ |
|---|
| 123 | n/a | os.stat(newpathname).st_mtime >= os.stat(pathname).st_mtime: |
|---|
| 124 | n/a | return newpathname |
|---|
| 125 | n/a | if hasattr(os, 'access') and not \ |
|---|
| 126 | n/a | os.access(os.path.dirname(pathname), os.W_OK|os.X_OK): |
|---|
| 127 | n/a | # The destination directory isn't writeable. Create the file in |
|---|
| 128 | n/a | # a temporary directory |
|---|
| 129 | n/a | import tempfile |
|---|
| 130 | n/a | fd, newpathname = tempfile.mkstemp(".rsrc") |
|---|
| 131 | n/a | if verbose: |
|---|
| 132 | n/a | print 'Decoding', pathname, 'to', newpathname |
|---|
| 133 | n/a | import applesingle |
|---|
| 134 | n/a | applesingle.decode(pathname, newpathname, resonly=1) |
|---|
| 135 | n/a | return newpathname |
|---|