blob: 7e99c00a695694d72eecc79c38ea0c7767e96831 [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__'):
Just van Rossum077c5822003-01-06 11:15:05 +000052 searchdirs = [os.path.dirname(mod.__file__)]
53 searchdirs.extend(sys.path)
Jack Jansende3226f2001-08-27 21:21:07 +000054
55 # And look for the file
56 for dir in searchdirs:
57 pathname = os.path.join(dir, filename)
58 if os.path.exists(pathname):
59 break
60 else:
61 raise ResourceFileNotFoundError, filename
62
Jack Jansen562baab2002-03-21 22:38:32 +000063 refno = open_pathname(pathname)
64
65 # And check that the resource exists now
66 if type(resid) is type(1):
67 h = Res.GetResource(restype, resid)
68 else:
69 h = Res.GetNamedResource(restype, resid)
70 return refno
71
Jack Jansenccd8e8d2002-08-09 13:44:03 +000072def open_pathname(pathname, verbose=0):
Jack Jansen562baab2002-03-21 22:38:32 +000073 """Open a resource file given by pathname, possibly decoding an
74 AppleSingle file"""
Jack Jansen32d1a3b2002-01-13 23:18:00 +000075 try:
76 refno = Res.FSpOpenResFile(pathname, 1)
77 except Res.Error, arg:
78 if arg[0] in (-37, -39):
Jack Jansen5053b702002-03-29 14:29:35 +000079 # No resource fork. We may be on OSX, and this may be either
80 # a data-fork based resource file or a AppleSingle file
81 # from the CVS repository.
82 try:
Jack Jansen32d1a3b2002-01-13 23:18:00 +000083 refno = Res.FSOpenResourceFile(pathname, u'', 1)
Jack Jansen5053b702002-03-29 14:29:35 +000084 except Res.Error, arg:
85 if arg[0] != -199:
86 # -199 is "bad resource map"
87 raise
Jack Jansen32d1a3b2002-01-13 23:18:00 +000088 else:
Jack Jansen5053b702002-03-29 14:29:35 +000089 return refno
90 # Finally try decoding an AppleSingle file
Jack Jansenccd8e8d2002-08-09 13:44:03 +000091 pathname = _decode(pathname, verbose=verbose)
Jack Jansen5053b702002-03-29 14:29:35 +000092 refno = Res.FSOpenResourceFile(pathname, u'', 1)
Jack Jansend21c9f42002-03-29 21:17:57 +000093 else:
94 raise
Jack Jansen32d1a3b2002-01-13 23:18:00 +000095 return refno
96
Jack Jansendde800e2002-11-07 23:07:05 +000097def open_error_resource():
98 """Open the resource file containing the error code to error message
99 mapping."""
100 need('Estr', 1, filename="errors.rsrc", modname=__name__)
101
Jack Jansenccd8e8d2002-08-09 13:44:03 +0000102def _decode(pathname, verbose=0):
Jack Jansen32d1a3b2002-01-13 23:18:00 +0000103 # Decode an AppleSingle resource file, return the new pathname.
104 newpathname = pathname + '.df.rsrc'
Jack Jansenccd8e8d2002-08-09 13:44:03 +0000105 if os.path.exists(newpathname) and \
106 os.stat(newpathname).st_mtime >= os.stat(pathname).st_mtime:
Jack Jansen32d1a3b2002-01-13 23:18:00 +0000107 return newpathname
Jack Jansenccd8e8d2002-08-09 13:44:03 +0000108 if verbose:
109 print 'Decoding', pathname
Jack Jansen32d1a3b2002-01-13 23:18:00 +0000110 import applesingle
111 applesingle.decode(pathname, newpathname, resonly=1)
112 return newpathname
113
114