blob: 23713a58aee367be3fd16712e5d4129e014e322c [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):
Jack Jansen5053b702002-03-29 14:29:35 +000080 # 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:
Jack Jansen32d1a3b2002-01-13 23:18:00 +000084 refno = Res.FSOpenResourceFile(pathname, u'', 1)
Jack Jansen5053b702002-03-29 14:29:35 +000085 except Res.Error, arg:
86 if arg[0] != -199:
87 # -199 is "bad resource map"
88 raise
Jack Jansen32d1a3b2002-01-13 23:18:00 +000089 else:
Jack Jansen5053b702002-03-29 14:29:35 +000090 return refno
91 # Finally try decoding an AppleSingle file
92 pathname = _decode(pathname)
93 refno = Res.FSOpenResourceFile(pathname, u'', 1)
Jack Jansend21c9f42002-03-29 21:17:57 +000094 else:
95 raise
Jack Jansen32d1a3b2002-01-13 23:18:00 +000096 return refno
97
98def _decode(pathname):
99 # Decode an AppleSingle resource file, return the new pathname.
100 newpathname = pathname + '.df.rsrc'
101 if os.path.exists(newpathname):
102 return newpathname
103 import applesingle
104 applesingle.decode(pathname, newpathname, resonly=1)
105 return newpathname
106
107