| 
									
										
										
										
											2001-08-27 21:21:07 +00:00
										 |  |  | """macresource - Locate and open the resources needed for a script.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from Carbon import Res | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ArgumentError(TypeError): pass | 
					
						
							|  |  |  | class ResourceFileNotFoundError(ImportError): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def need(restype, resid, filename=None, modname=None): | 
					
						
							|  |  |  | 	"""Open a resource file, if needed. restype and resid
 | 
					
						
							|  |  |  | 	are required parameters, and identify the resource for which to test. If it | 
					
						
							|  |  |  | 	is available we are done. If it is not available we look for a file filename | 
					
						
							|  |  |  | 	(default: modname with .rsrc appended) either in the same folder as | 
					
						
							| 
									
										
										
										
											2001-08-27 21:37:45 +00:00
										 |  |  | 	where modname was loaded from, or otherwise across sys.path. | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	Returns the refno of the resource file opened (or None)"""
 | 
					
						
							| 
									
										
										
										
											2001-08-27 21:21:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if modname is None and filename is None: | 
					
						
							|  |  |  | 		raise ArgumentError, "Either filename or modname argument (or both) must be given" | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if type(resid) is type(1): | 
					
						
							|  |  |  | 		try: | 
					
						
							|  |  |  | 			h = Res.GetResource(restype, resid) | 
					
						
							|  |  |  | 		except Res.Error: | 
					
						
							|  |  |  | 			pass | 
					
						
							|  |  |  | 		else: | 
					
						
							| 
									
										
										
										
											2001-08-27 21:37:45 +00:00
										 |  |  | 			return None | 
					
						
							| 
									
										
										
										
											2001-08-27 21:21:07 +00:00
										 |  |  | 	else: | 
					
						
							|  |  |  | 		try: | 
					
						
							|  |  |  | 			h = Res.GetNamedResource(restype, resid) | 
					
						
							|  |  |  | 		except Res.Error: | 
					
						
							|  |  |  | 			pass | 
					
						
							|  |  |  | 		else: | 
					
						
							| 
									
										
										
										
											2001-08-27 21:37:45 +00:00
										 |  |  | 			return None | 
					
						
							| 
									
										
										
										
											2001-08-27 21:21:07 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 	# Construct a filename if we don't have one | 
					
						
							|  |  |  | 	if not filename: | 
					
						
							|  |  |  | 		if '.' in modname: | 
					
						
							|  |  |  | 			filename = modname.split('.')[-1] + '.rsrc' | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			filename = modname + '.rsrc' | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	# Now create a list of folders to search | 
					
						
							|  |  |  | 	searchdirs = [] | 
					
						
							|  |  |  | 	if modname == '__main__': | 
					
						
							|  |  |  | 		# If we're main we look in the current directory | 
					
						
							|  |  |  | 		searchdirs = [os.curdir] | 
					
						
							|  |  |  | 	if sys.modules.has_key(modname): | 
					
						
							|  |  |  | 		mod = sys.modules[modname] | 
					
						
							|  |  |  | 		if hasattr(mod, '__file__'): | 
					
						
							| 
									
										
										
										
											2003-01-06 11:15:05 +00:00
										 |  |  | 			searchdirs = [os.path.dirname(mod.__file__)] | 
					
						
							|  |  |  | 	searchdirs.extend(sys.path) | 
					
						
							| 
									
										
										
										
											2001-08-27 21:21:07 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	# And look for the file | 
					
						
							|  |  |  | 	for dir in searchdirs: | 
					
						
							|  |  |  | 		pathname = os.path.join(dir, filename) | 
					
						
							|  |  |  | 		if os.path.exists(pathname): | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		raise ResourceFileNotFoundError, filename | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2002-03-21 22:38:32 +00:00
										 |  |  | 	refno = open_pathname(pathname) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	# And check that the resource exists now | 
					
						
							|  |  |  | 	if type(resid) is type(1): | 
					
						
							|  |  |  | 		h = Res.GetResource(restype, resid) | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		h = Res.GetNamedResource(restype, resid) | 
					
						
							|  |  |  | 	return refno | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2002-08-09 13:44:03 +00:00
										 |  |  | def open_pathname(pathname, verbose=0): | 
					
						
							| 
									
										
										
										
											2002-03-21 22:38:32 +00:00
										 |  |  | 	"""Open a resource file given by pathname, possibly decoding an
 | 
					
						
							|  |  |  | 	AppleSingle file"""
 | 
					
						
							| 
									
										
										
										
											2002-01-13 23:18:00 +00:00
										 |  |  | 	try: | 
					
						
							|  |  |  | 		refno = Res.FSpOpenResFile(pathname, 1) | 
					
						
							|  |  |  | 	except Res.Error, arg: | 
					
						
							|  |  |  | 		if arg[0] in (-37, -39): | 
					
						
							| 
									
										
										
										
											2002-03-29 14:29:35 +00:00
										 |  |  | 			# No resource fork. We may be on OSX, and this may be either | 
					
						
							|  |  |  | 			# a data-fork based resource file or a AppleSingle file | 
					
						
							|  |  |  | 			# from the CVS repository. | 
					
						
							|  |  |  | 			try: | 
					
						
							| 
									
										
										
										
											2002-01-13 23:18:00 +00:00
										 |  |  | 				refno = Res.FSOpenResourceFile(pathname, u'', 1) | 
					
						
							| 
									
										
										
										
											2002-03-29 14:29:35 +00:00
										 |  |  | 			except Res.Error, arg: | 
					
						
							|  |  |  | 				if arg[0] != -199: | 
					
						
							|  |  |  | 					# -199 is "bad resource map" | 
					
						
							|  |  |  | 					raise | 
					
						
							| 
									
										
										
										
											2002-01-13 23:18:00 +00:00
										 |  |  | 			else: | 
					
						
							| 
									
										
										
										
											2002-03-29 14:29:35 +00:00
										 |  |  | 				return refno | 
					
						
							|  |  |  | 			# Finally try decoding an AppleSingle file | 
					
						
							| 
									
										
										
										
											2002-08-09 13:44:03 +00:00
										 |  |  | 			pathname = _decode(pathname, verbose=verbose) | 
					
						
							| 
									
										
										
										
											2002-03-29 14:29:35 +00:00
										 |  |  | 			refno = Res.FSOpenResourceFile(pathname, u'', 1) | 
					
						
							| 
									
										
										
										
											2002-03-29 21:17:57 +00:00
										 |  |  | 		else: | 
					
						
							|  |  |  | 			raise | 
					
						
							| 
									
										
										
										
											2002-01-13 23:18:00 +00:00
										 |  |  | 	return refno | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2002-11-07 23:07:05 +00:00
										 |  |  | def open_error_resource(): | 
					
						
							|  |  |  | 	"""Open the resource file containing the error code to error message
 | 
					
						
							|  |  |  | 	mapping."""
 | 
					
						
							|  |  |  | 	need('Estr', 1, filename="errors.rsrc", modname=__name__) | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2002-08-09 13:44:03 +00:00
										 |  |  | def _decode(pathname, verbose=0): | 
					
						
							| 
									
										
										
										
											2002-01-13 23:18:00 +00:00
										 |  |  | 	# Decode an AppleSingle resource file, return the new pathname. | 
					
						
							|  |  |  | 	newpathname = pathname + '.df.rsrc' | 
					
						
							| 
									
										
										
										
											2002-08-09 13:44:03 +00:00
										 |  |  | 	if os.path.exists(newpathname) and \ | 
					
						
							|  |  |  | 			os.stat(newpathname).st_mtime >= os.stat(pathname).st_mtime: | 
					
						
							| 
									
										
										
										
											2002-01-13 23:18:00 +00:00
										 |  |  | 		return newpathname | 
					
						
							| 
									
										
										
										
											2002-08-09 13:44:03 +00:00
										 |  |  | 	if verbose: | 
					
						
							|  |  |  | 		print 'Decoding', pathname | 
					
						
							| 
									
										
										
										
											2002-01-13 23:18:00 +00:00
										 |  |  | 	import applesingle | 
					
						
							|  |  |  | 	applesingle.decode(pathname, newpathname, resonly=1) | 
					
						
							|  |  |  | 	return newpathname | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	 |