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 an 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 an 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