blob: 4bd40bcca9d90715374407c5c91e8b12943b1458 [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 Jansen562baab2002-03-21 22:38:32 +000064 refno = open_pathname(pathname)
65
66 # And check that the resource exists now
67 if type(resid) is type(1):
68 h = Res.GetResource(restype, resid)
69 else:
70 h = Res.GetNamedResource(restype, resid)
71 return refno
72
73def open_pathname(pathname):
74 """Open a resource file given by pathname, possibly decoding an
75 AppleSingle file"""
Jack Jansen32d1a3b2002-01-13 23:18:00 +000076 try:
77 refno = Res.FSpOpenResFile(pathname, 1)
78 except Res.Error, arg:
79 if arg[0] in (-37, -39):
80 # No resource fork. We may be on OSX, try to decode
81 # the applesingle file.
82 pathname = _decode(pathname)
83 if pathname:
84 refno = Res.FSOpenResourceFile(pathname, u'', 1)
85 else:
86 raise
Jack Jansen32d1a3b2002-01-13 23:18:00 +000087 return refno
88
89def _decode(pathname):
90 # Decode an AppleSingle resource file, return the new pathname.
91 newpathname = pathname + '.df.rsrc'
92 if os.path.exists(newpathname):
93 return newpathname
94 import applesingle
95 applesingle.decode(pathname, newpathname, resonly=1)
96 return newpathname
97
98