blob: 1cd14332a8be6944ef8da6e932093d2471f2dc2a [file] [log] [blame]
Jack Jansende3226f2001-08-27 21:21:07 +00001"""macresource - Locate and open the resources needed for a script."""
2
3from Carbon import Res
4import os
5import sys
6
7class ArgumentError(TypeError): pass
8class ResourceFileNotFoundError(ImportError): pass
9
10def need(restype, resid, filename=None, modname=None):
11 """Open a resource file, if needed. restype and resid
12 are required parameters, and identify the resource for which to test. If it
13 is available we are done. If it is not available we look for a file filename
14 (default: modname with .rsrc appended) either in the same folder as
Jack Jansena5d7da52001-08-27 21:37:45 +000015 where modname was loaded from, or otherwise across sys.path.
16
17 Returns the refno of the resource file opened (or None)"""
Jack Jansende3226f2001-08-27 21:21:07 +000018
19 if modname is None and filename is None:
20 raise ArgumentError, "Either filename or modname argument (or both) must be given"
21
22 if type(resid) is type(1):
23 try:
24 h = Res.GetResource(restype, resid)
25 except Res.Error:
26 pass
27 else:
Jack Jansena5d7da52001-08-27 21:37:45 +000028 return None
Jack Jansende3226f2001-08-27 21:21:07 +000029 else:
30 try:
31 h = Res.GetNamedResource(restype, resid)
32 except Res.Error:
33 pass
34 else:
Jack Jansena5d7da52001-08-27 21:37:45 +000035 return None
Jack Jansende3226f2001-08-27 21:21:07 +000036
37 # Construct a filename if we don't have one
38 if not filename:
39 if '.' in modname:
40 filename = modname.split('.')[-1] + '.rsrc'
41 else:
42 filename = modname + '.rsrc'
43
44 # Now create a list of folders to search
45 searchdirs = []
46 if modname == '__main__':
47 # If we're main we look in the current directory
48 searchdirs = [os.curdir]
49 if sys.modules.has_key(modname):
50 mod = sys.modules[modname]
51 if hasattr(mod, '__file__'):
Jack Jansenb214c362001-08-30 21:19:42 +000052 searchdirs = [os.path.split(mod.__file__)[0]]
Jack Jansende3226f2001-08-27 21:21:07 +000053 if not searchdirs:
54 searchdirs = sys.path
55
56 # And look for the file
57 for dir in searchdirs:
58 pathname = os.path.join(dir, filename)
59 if os.path.exists(pathname):
60 break
61 else:
62 raise ResourceFileNotFoundError, filename
63
Jack Jansen32d1a3b2002-01-13 23:18:00 +000064 try:
65 refno = Res.FSpOpenResFile(pathname, 1)
66 except Res.Error, arg:
67 if arg[0] in (-37, -39):
68 # No resource fork. We may be on OSX, try to decode
69 # the applesingle file.
70 pathname = _decode(pathname)
71 if pathname:
72 refno = Res.FSOpenResourceFile(pathname, u'', 1)
73 else:
74 raise
75
Jack Jansende3226f2001-08-27 21:21:07 +000076
77 # And check that the resource exists now
78 if type(resid) is type(1):
79 h = Res.GetResource(restype, resid)
80 else:
81 h = Res.GetNamedResource(restype, resid)
Jack Jansen32d1a3b2002-01-13 23:18:00 +000082 return refno
83
84def _decode(pathname):
85 # Decode an AppleSingle resource file, return the new pathname.
86 newpathname = pathname + '.df.rsrc'
87 if os.path.exists(newpathname):
88 return newpathname
89 import applesingle
90 applesingle.decode(pathname, newpathname, resonly=1)
91 return newpathname
92
93