Home | History | Annotate | Download | only in plat-mac
      1 """macresource - Locate and open the resources needed for a script."""
      2 
      3 from warnings import warnpy3k
      4 warnpy3k("In 3.x, the macresource module is removed.", stacklevel=2)
      5 
      6 from Carbon import Res
      7 import os
      8 import sys
      9 import MacOS
     10 import macostools
     11 
     12 class ArgumentError(TypeError): pass
     13 class ResourceFileNotFoundError(ImportError): pass
     14 
     15 def 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 modname in sys.modules:
     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 
     77 def open_pathname(pathname, verbose=0):
     78     """Open a resource file given by pathname, possibly decoding an
     79     AppleSingle file"""
     80     # No resource fork. We may be on OSX, and this may be either
     81     # a data-fork based resource file or a AppleSingle file
     82     # from the CVS repository.
     83     try:
     84         refno = Res.FSOpenResourceFile(pathname, u'', 1)
     85     except Res.Error, arg:
     86         if arg[0] != -199:
     87             # -199 is "bad resource map"
     88             raise
     89     else:
     90         return refno
     91     # Finally try decoding an AppleSingle file
     92     pathname = _decode(pathname, verbose=verbose)
     93     refno = Res.FSOpenResourceFile(pathname, u'', 1)
     94 
     95 def resource_pathname(pathname, verbose=0):
     96     """Return the pathname for a resource file (either DF or RF based).
     97     If the pathname given already refers to such a file simply return it,
     98     otherwise first decode it."""
     99     # No resource fork. We may be on OSX, and this may be either
    100     # a data-fork based resource file or a AppleSingle file
    101     # from the CVS repository.
    102     try:
    103         refno = Res.FSOpenResourceFile(pathname, u'', 1)
    104     except Res.Error, arg:
    105         if arg[0] != -199:
    106             # -199 is "bad resource map"
    107             raise
    108     else:
    109         return refno
    110     # Finally try decoding an AppleSingle file
    111     pathname = _decode(pathname, verbose=verbose)
    112     return pathname
    113 
    114 def open_error_resource():
    115     """Open the resource file containing the error code to error message
    116     mapping."""
    117     need('Estr', 1, filename="errors.rsrc", modname=__name__)
    118 
    119 def _decode(pathname, verbose=0):
    120     # Decode an AppleSingle resource file, return the new pathname.
    121     newpathname = pathname + '.df.rsrc'
    122     if os.path.exists(newpathname) and \
    123         os.stat(newpathname).st_mtime >= os.stat(pathname).st_mtime:
    124         return newpathname
    125     if hasattr(os, 'access') and not \
    126         os.access(os.path.dirname(pathname), os.W_OK|os.X_OK):
    127         # The destination directory isn't writeable. Create the file in
    128         # a temporary directory
    129         import tempfile
    130         fd, newpathname = tempfile.mkstemp(".rsrc")
    131     if verbose:
    132         print 'Decoding', pathname, 'to', newpathname
    133     import applesingle
    134     applesingle.decode(pathname, newpathname, resonly=1)
    135     return newpathname
    136