⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gopherli.py

📁 minimal python variant for small footprint apps like embedded apps
💻 PY
字号:
# Gopher protocol client interfaceimport string# Default selector, host and portDEF_SELECTOR = '1/'DEF_HOST     = 'gopher.micro.umn.edu'DEF_PORT     = 70# Recognized file typesA_TEXT       = '0'A_MENU       = '1'A_CSO        = '2'A_ERROR      = '3'A_MACBINHEX  = '4'A_PCBINHEX   = '5'A_UUENCODED  = '6'A_INDEX      = '7'A_TELNET     = '8'A_BINARY     = '9'A_DUPLICATE  = '+'A_SOUND      = 's'A_EVENT      = 'e'A_CALENDAR   = 'c'A_HTML       = 'h'A_TN3270     = 'T'A_MIME       = 'M'A_IMAGE      = 'I'A_WHOIS      = 'w'A_QUERY      = 'q'A_GIF        = 'g'A_HTML       = 'h'			# HTML fileA_WWW        = 'w'			# WWW addressA_PLUS_IMAGE = ':'A_PLUS_MOVIE = ';'A_PLUS_SOUND = '<'# Function mapping all file types to strings; unknown types become TYPE='x'_names = dir()_type_to_name_map = {}def type_to_name(gtype):	global _type_to_name_map	if _type_to_name_map=={}:		for name in _names:			if name[:2] == 'A_':				_type_to_name_map[eval(name)] = name[2:]	if _type_to_name_map.has_key(gtype):		return _type_to_name_map[gtype]	return 'TYPE=' + `gtype`# Names for characters and stringsCRLF = '\r\n'TAB = '\t'# Send a selector to a given host and port, return a file with the replydef send_selector(selector, host, port = 0):	import socket	import string	if not port:		i = string.find(host, ':')		if i >= 0:			host, port = host[:i], string.atoi(host[i+1:])	if not port:		port = DEF_PORT	elif type(port) == type(''):		port = string.atoi(port)	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)	s.connect(host, port)	s.send(selector + CRLF)	s.shutdown(1)	return s.makefile('rb')# Send a selector and a query stringdef send_query(selector, query, host, port = 0):	return send_selector(selector + '\t' + query, host, port)# Takes a path as returned by urlparse and returns the appropriate selectordef path_to_selector(path):	if path=="/":		return "/"	else:		return path[2:] # Cuts initial slash and data type identifier# Takes a path as returned by urlparse and maps it to a string# See section 3.4 of RFC 1738 for detailsdef path_to_datatype_name(path):	if path=="/":		# No way to tell, although "INDEX" is likely		return "TYPE='unknown'"	else:		return type_to_name(path[1])# The following functions interpret the data returned by the gopher# server according to the expected type, e.g. textfile or directory# Get a directory in the form of a list of entriesdef get_directory(f):	import string	list = []	while 1:		line = f.readline()		if not line:			print '(Unexpected EOF from server)'			break		if line[-2:] == CRLF:			line = line[:-2]		elif line[-1:] in CRLF:			line = line[:-1]		if line == '.':			break		if not line:			print '(Empty line from server)'			continue		gtype = line[0]		parts = string.splitfields(line[1:], TAB)		if len(parts) < 4:			print '(Bad line from server:', `line`, ')'			continue		if len(parts) > 4:			if parts[4:] != ['+']:				print '(Extra info from server:',				print parts[4:], ')'		else:			parts.append('')		parts.insert(0, gtype)		list.append(parts)	return list# Get a text file as a list of lines, with trailing CRLF strippeddef get_textfile(f):	list = []	get_alt_textfile(f, list.append)	return list# Get a text file and pass each line to a function, with trailing CRLF strippeddef get_alt_textfile(f, func):	while 1:		line = f.readline()		if not line:			print '(Unexpected EOF from server)'			break		if line[-2:] == CRLF:			line = line[:-2]		elif line[-1:] in CRLF:			line = line[:-1]		if line == '.':			break		if line[:2] == '..':			line = line[1:]		func(line)# Get a binary file as one solid data blockdef get_binary(f):	data = f.read()	return data# Get a binary file and pass each block to a functiondef get_alt_binary(f, func, blocksize):	while 1:		data = f.read(blocksize)		if not data:			break		func(data)# Trivial test programdef test():	import sys	import getopt	opts, args = getopt.getopt(sys.argv[1:], '')	selector = DEF_SELECTOR	type = selector[0]	host = DEF_HOST	port = DEF_PORT	if args:		host = args[0]		args = args[1:]	if args:		type = args[0]		args = args[1:]		if len(type) > 1:			type, selector = type[0], type		else:			selector = ''			if args:				selector = args[0]				args = args[1:]		query = ''		if args:			query = args[0]			args = args[1:]	if type == A_INDEX:		f = send_query(selector, query, host)	else:		f = send_selector(selector, host)	if type == A_TEXT:		list = get_textfile(f)		for item in list: print item	elif type in (A_MENU, A_INDEX):		list = get_directory(f)		for item in list: print item	else:		data = get_binary(f)		print 'binary data:', len(data), 'bytes:', `data[:100]`[:40]# Run the test when run as scriptif __name__ == '__main__':	test()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -