PageRenderTime 316ms CodeModel.GetById 133ms app.highlight 12ms RepoModel.GetById 169ms app.codeStats 0ms

/Lib/plat-mac/macresource.py

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