| 
									
										
										
										
											1997-01-09 16:26:23 +00:00
										 |  |  | """IC wrapper module, based on Internet Config 1.3""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import icglue | 
					
						
							|  |  |  | import string | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import Res | 
					
						
							|  |  |  | import macfs | 
					
						
							|  |  |  | import macostools | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | error=icglue.error | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # From ictypes.h: | 
					
						
							|  |  |  | icPrefNotFoundErr = -666		# preference not found (duh!) | 
					
						
							|  |  |  | icPermErr = -667				# cannot set preference | 
					
						
							|  |  |  | icPrefDataErr = -668			# problem with preference data | 
					
						
							|  |  |  | icInternalErr = -669			# hmm, this is not good | 
					
						
							|  |  |  | icTruncatedErr = -670			# more data was present than was returned | 
					
						
							|  |  |  | icNoMoreWritersErr = -671		# you cannot begin a write session because someone else is already doing it */ | 
					
						
							|  |  |  | icNothingToOverrideErr = -672	# no component for the override component to capture | 
					
						
							|  |  |  | icNoURLErr = -673				# no URL found | 
					
						
							|  |  |  | icConfigNotFoundErr = -674		# no configuration was found | 
					
						
							|  |  |  | icConfigInappropriateErr = -675	# incorrect manufacturer code | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ICattr_no_change = -1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | icNoPerm = 0 | 
					
						
							|  |  |  | icReadOnlyPerm = 1 | 
					
						
							|  |  |  | icReadWritePerm = 2 | 
					
						
							|  |  |  | # End of ictypes.h | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-01-10 15:25:47 +00:00
										 |  |  | class ICOpaqueData: | 
					
						
							|  |  |  | 	"""An unparseable IC entry""" | 
					
						
							|  |  |  | 	def __init__(self, data): | 
					
						
							|  |  |  | 		self.data = data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def __repr__(self): | 
					
						
							|  |  |  | 		return "ICOpaqueData(%s)"%`self.data` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _ICOpaqueDataType=type(ICOpaqueData('')) | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											1997-01-09 16:26:23 +00:00
										 |  |  | def _decode_default(data, key): | 
					
						
							|  |  |  | 	if len(data) == 0: | 
					
						
							|  |  |  | 		return data | 
					
						
							|  |  |  | 	if ord(data[0]) == len(data)-1: | 
					
						
							|  |  |  | 		# Assume Pstring | 
					
						
							|  |  |  | 		return data[1:] | 
					
						
							| 
									
										
										
										
											1997-01-10 15:25:47 +00:00
										 |  |  | 	return ICOpaqueData(data) | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1997-01-09 16:26:23 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | def _decode_multistr(data, key): | 
					
						
							|  |  |  | 	numstr = ord(data[0]) << 8 | ord(data[1]) | 
					
						
							|  |  |  | 	rv = [] | 
					
						
							|  |  |  | 	ptr = 2 | 
					
						
							|  |  |  | 	for i in range(numstr): | 
					
						
							|  |  |  | 		strlen = ord(data[ptr]) | 
					
						
							|  |  |  | 		str = data[ptr+1:ptr+strlen+1] | 
					
						
							|  |  |  | 		rv.append(str) | 
					
						
							|  |  |  | 		ptr = ptr + strlen + 1 | 
					
						
							|  |  |  | 	return rv | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | def _decode_fontrecord(data, key): | 
					
						
							|  |  |  | 	size = ord(data[0]) << 8 | ord(data[1]) | 
					
						
							|  |  |  | 	face = ord(data[2]) | 
					
						
							|  |  |  | 	namelen = ord(data[4]) | 
					
						
							|  |  |  | 	return size, face, data[5:5+namelen] | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | def _decode_boolean(data, key): | 
					
						
							|  |  |  | 	return ord(data[0]) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | def _decode_text(data, key): | 
					
						
							|  |  |  | 	return data | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | def _decode_charset(data, key): | 
					
						
							|  |  |  | 	return data[:256], data[256:] | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | def _decode_appspec(data, key): | 
					
						
							|  |  |  | 	namelen = ord(data[4]) | 
					
						
							|  |  |  | 	return data[0:4], data[5:5+namelen] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _code_default(data, key): | 
					
						
							|  |  |  | 	return chr(len(data)) + data | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | def _code_multistr(data, key): | 
					
						
							|  |  |  | 	numstr = len(data) | 
					
						
							|  |  |  | 	rv = chr((numstr>>8) & 0xff) + chr(numstr & 0xff) | 
					
						
							|  |  |  | 	for i in data: | 
					
						
							|  |  |  | 		rv = rv + _code_default(i) | 
					
						
							|  |  |  | 	return rv | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | def _code_fontrecord(data, key): | 
					
						
							|  |  |  | 	size, face, name = data | 
					
						
							|  |  |  | 	return chr((size>>8) & 0xff) + chr(size & 0xff) + chr(face & 0xff) + \ | 
					
						
							|  |  |  | 		chr(0) + _code_default(name) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | def _code_boolean(data, key): | 
					
						
							|  |  |  | 	print 'XXXX boolean:', `data` | 
					
						
							|  |  |  | 	return chr(data) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | def _code_text(data, key): | 
					
						
							|  |  |  | 	return data | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | def _code_charset(data, key): | 
					
						
							|  |  |  | 	return data[0] + data[1] | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | def _code_appspec(data, key): | 
					
						
							|  |  |  | 	return data[0] + _code_default(data[1]) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | _decoder_table = { | 
					
						
							|  |  |  | 	"ArchieAll" : (_decode_multistr , _code_multistr), | 
					
						
							|  |  |  | 	"UMichAll" : (_decode_multistr , _code_multistr), | 
					
						
							|  |  |  | 	"InfoMacAll" : (_decode_multistr , _code_multistr), | 
					
						
							|  |  |  | 	"ListFont" : (_decode_fontrecord , _code_fontrecord), | 
					
						
							|  |  |  | 	"ScreenFont" : (_decode_fontrecord , _code_fontrecord), | 
					
						
							|  |  |  | 	"PrinterFont" : (_decode_fontrecord , _code_fontrecord), | 
					
						
							|  |  |  | #	"DownloadFolder" : (_decode_filespec , _code_filespec), | 
					
						
							|  |  |  | 	"Signature": (_decode_text , _code_text), | 
					
						
							|  |  |  | 	"Plan" : (_decode_text , _code_text), | 
					
						
							|  |  |  | 	"MailHeaders" : (_decode_text , _code_text), | 
					
						
							|  |  |  | 	"NewsHeaders" : (_decode_text , _code_text), | 
					
						
							|  |  |  | #	"Mapping"  | 
					
						
							|  |  |  | 	"CharacterSet" : (_decode_charset , _code_charset), | 
					
						
							|  |  |  | 	"Helper\245" : (_decode_appspec , _code_appspec), | 
					
						
							|  |  |  | #	"Services" : (_decode_services, ????), | 
					
						
							|  |  |  | 	"NewMailFlashIcon" : (_decode_boolean , _code_boolean), | 
					
						
							|  |  |  | 	"NewMailDialog" : (_decode_boolean , _code_boolean), | 
					
						
							|  |  |  | 	"NewMailPlaySound" : (_decode_boolean , _code_boolean), | 
					
						
							|  |  |  | #	"WebBackgroundColor" : _decode_color, | 
					
						
							|  |  |  | 	"NoProxyDomains" : (_decode_multistr , _code_multistr), | 
					
						
							|  |  |  | 	"UseHTTPProxy" : (_decode_boolean , _code_boolean), | 
					
						
							|  |  |  | 	"UseGopherProxy": (_decode_boolean , _code_boolean), | 
					
						
							|  |  |  | 	"UseFTPProxy" : (_decode_boolean , _code_boolean), | 
					
						
							|  |  |  | 	"UsePassiveFTP" : (_decode_boolean , _code_boolean), | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _decode(data, key): | 
					
						
							|  |  |  | 	if '\245' in key: | 
					
						
							|  |  |  | 		key2 = key[:string.index(key, '\245')+1] | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		key2 = key | 
					
						
							|  |  |  | 	if _decoder_table.has_key(key2): | 
					
						
							|  |  |  | 		decoder = _decoder_table[key2][0] | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		decoder = _decode_default | 
					
						
							|  |  |  | 	return decoder(data, key) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _code(data, key): | 
					
						
							| 
									
										
										
										
											1997-01-10 15:25:47 +00:00
										 |  |  | 	if type(data) == _ICOpaqueDataType: | 
					
						
							|  |  |  | 		return data.data | 
					
						
							| 
									
										
										
										
											1997-01-09 16:26:23 +00:00
										 |  |  | 	if '\245' in key: | 
					
						
							|  |  |  | 		key2 = key[:string.index(key, '\245')+1] | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		key2 = key | 
					
						
							|  |  |  | 	if _decoder_table.has_key(key2): | 
					
						
							|  |  |  | 		coder = _decoder_table[key2][1] | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		coder = _code_default | 
					
						
							|  |  |  | 	return coder(data, key) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | class IC: | 
					
						
							|  |  |  | 	def __init__(self, signature='Pyth', ic=None): | 
					
						
							|  |  |  | 		if ic: | 
					
						
							|  |  |  | 			self.ic = ic | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			self.ic = icglue.ICStart(signature) | 
					
						
							|  |  |  | 			self.ic.ICFindConfigFile() | 
					
						
							|  |  |  | 		self.h = Res.Resource('') | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 	def keys(self): | 
					
						
							|  |  |  | 		rv = [] | 
					
						
							|  |  |  | 		self.ic.ICBegin(icReadOnlyPerm) | 
					
						
							|  |  |  | 		num = self.ic.ICCountPref() | 
					
						
							|  |  |  | 		for i in range(num): | 
					
						
							|  |  |  | 			rv.append(self.ic.ICGetIndPref(i+1)) | 
					
						
							|  |  |  | 		self.ic.ICEnd() | 
					
						
							|  |  |  | 		return rv | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											1998-07-31 09:39:28 +00:00
										 |  |  | 	def has_key(self, key): | 
					
						
							|  |  |  | 		try: | 
					
						
							|  |  |  | 			dummy = self.ic.ICFindPrefHandle(key, self.h) | 
					
						
							|  |  |  | 		except icglue.error: | 
					
						
							|  |  |  | 			return 0 | 
					
						
							|  |  |  | 		return 1 | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											1997-01-09 16:26:23 +00:00
										 |  |  | 	def __getitem__(self, key): | 
					
						
							|  |  |  | 		attr = self.ic.ICFindPrefHandle(key, self.h) | 
					
						
							|  |  |  | 		return _decode(self.h.data, key) | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def __setitem__(self, key, value): | 
					
						
							|  |  |  | 		value = _code(value, key) | 
					
						
							|  |  |  | 		self.ic.ICSetPref(key, ICattr_no_change, value) | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def launchurl(self, url, hint=""): | 
					
						
							|  |  |  | 		self.ic.ICLaunchURL(hint, url, 0, len(url)) | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def parseurl(self, data, start=None, end=None, hint=""): | 
					
						
							|  |  |  | 		if start == None: | 
					
						
							|  |  |  | 			selStart = 0 | 
					
						
							|  |  |  | 			selEnd = len(data) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			selStart = selEnd = start | 
					
						
							|  |  |  | 		if end != None: | 
					
						
							|  |  |  | 			selEnd = end | 
					
						
							|  |  |  | 		selStart, selEnd = self.ic.ICParseURL(hint, data, selStart, selEnd, self.h) | 
					
						
							|  |  |  | 		return self.h.data, selStart, selEnd | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def mapfile(self, file): | 
					
						
							|  |  |  | 		if type(file) != type(''): | 
					
						
							|  |  |  | 			file = file.as_tuple()[2] | 
					
						
							|  |  |  | 		return self.ic.ICMapFilename(file) | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def maptypecreator(self, type, creator, filename=""): | 
					
						
							|  |  |  | 		return self.ic.ICMapTypeCreator(type, creator, filename) | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	def settypecreator(self, file): | 
					
						
							|  |  |  | 		if type(file) == type(''): | 
					
						
							|  |  |  | 			fss = macfs.FSSpec(file) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			fss = file | 
					
						
							|  |  |  | 		name = fss.as_tuple()[2] | 
					
						
							|  |  |  | 		record = self.mapfile(name) | 
					
						
							|  |  |  | 		fss.SetCreatorType(record[2], record[1]) | 
					
						
							|  |  |  | 		macostools.touched(fss) | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | # Convenience routines | 
					
						
							|  |  |  | _dft_ic = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def launchurl(url, hint=""): | 
					
						
							|  |  |  | 	global _dft_ic | 
					
						
							|  |  |  | 	if _dft_ic == None: _dft_ic = IC() | 
					
						
							|  |  |  | 	return _dft_ic.launchurl(url, hint) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | def parseurl(data, start=None, end=None, hint=""): | 
					
						
							|  |  |  | 	global _dft_ic | 
					
						
							|  |  |  | 	if _dft_ic == None: _dft_ic = IC() | 
					
						
							|  |  |  | 	return _dft_ic.parseurl(data, start, end, hint) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | def mapfile(filename): | 
					
						
							|  |  |  | 	global _dft_ic | 
					
						
							|  |  |  | 	if _dft_ic == None: _dft_ic = IC() | 
					
						
							|  |  |  | 	return _dft_ic.mapfile(filename) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | def maptypecreator(type, creator, filename=""): | 
					
						
							|  |  |  | 	global _dft_ic | 
					
						
							|  |  |  | 	if _dft_ic == None: _dft_ic = IC() | 
					
						
							|  |  |  | 	return _dft_ic.maptypecreator(type, creator, filename) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | def settypecreator(file): | 
					
						
							|  |  |  | 	global _dft_ic | 
					
						
							|  |  |  | 	if _dft_ic == None: _dft_ic = IC() | 
					
						
							|  |  |  | 	return _dft_ic.settypecreator(file) | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | def _test(): | 
					
						
							|  |  |  | 	ic = IC() | 
					
						
							|  |  |  | 	for k in ic.keys(): | 
					
						
							|  |  |  | 		try: | 
					
						
							|  |  |  | 			v = ic[k] | 
					
						
							|  |  |  | 		except error: | 
					
						
							|  |  |  | 			v = '????' | 
					
						
							|  |  |  | 		print k, '\t', v | 
					
						
							|  |  |  | 	sys.exit(1) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  | 	_test() | 
					
						
							|  |  |  | 	 |