| 
									
										
										
										
											1996-11-27 19:52:01 +00:00
										 |  |  | #! /usr/bin/env python | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # A simple gopher client. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Usage: gopher [ [selector] host [port] ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import socket | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Default selector, host and port | 
					
						
							|  |  |  | DEF_SELECTOR = '' | 
					
						
							|  |  |  | DEF_HOST     = 'gopher.micro.umn.edu' | 
					
						
							|  |  |  | DEF_PORT     = 70 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Recognized file types | 
					
						
							|  |  |  | T_TEXTFILE  = '0' | 
					
						
							|  |  |  | T_MENU      = '1' | 
					
						
							|  |  |  | T_CSO       = '2' | 
					
						
							|  |  |  | T_ERROR     = '3' | 
					
						
							|  |  |  | T_BINHEX    = '4' | 
					
						
							|  |  |  | T_DOS       = '5' | 
					
						
							|  |  |  | T_UUENCODE  = '6' | 
					
						
							|  |  |  | T_SEARCH    = '7' | 
					
						
							|  |  |  | T_TELNET    = '8' | 
					
						
							|  |  |  | T_BINARY    = '9' | 
					
						
							|  |  |  | T_REDUNDANT = '+' | 
					
						
							|  |  |  | T_SOUND     = 's' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Dictionary mapping types to strings | 
					
						
							|  |  |  | typename = {'0': '<TEXT>', '1': '<DIR>', '2': '<CSO>', '3': '<ERROR>', \ | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         '4': '<BINHEX>', '5': '<DOS>', '6': '<UUENCODE>', '7': '<SEARCH>', \ | 
					
						
							|  |  |  |         '8': '<TELNET>', '9': '<BINARY>', '+': '<REDUNDANT>', 's': '<SOUND>'} | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Oft-used characters and strings | 
					
						
							|  |  |  | CRLF = '\r\n' | 
					
						
							|  |  |  | TAB = '\t' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Open a TCP connection to a given host and port | 
					
						
							|  |  |  | def open_socket(host, port): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     if not port: | 
					
						
							|  |  |  |         port = DEF_PORT | 
					
						
							|  |  |  |     elif type(port) == type(''): | 
					
						
							| 
									
										
										
										
											2006-03-17 06:49:51 +00:00
										 |  |  |         port = int(port) | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | 
					
						
							|  |  |  |     s.connect((host, port)) | 
					
						
							|  |  |  |     return s | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Send a selector to a given host and port, return a file with the reply | 
					
						
							|  |  |  | def send_request(selector, host, port): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     s = open_socket(host, port) | 
					
						
							|  |  |  |     s.send(selector + CRLF) | 
					
						
							|  |  |  |     s.shutdown(1) | 
					
						
							|  |  |  |     return s.makefile('r') | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Get a menu in the form of a list of entries | 
					
						
							|  |  |  | def get_menu(selector, host, port): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     f = send_request(selector, host, port) | 
					
						
							|  |  |  |     list = [] | 
					
						
							|  |  |  |     while 1: | 
					
						
							|  |  |  |         line = f.readline() | 
					
						
							|  |  |  |         if not line: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |             print('(Unexpected EOF from server)') | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |             break | 
					
						
							|  |  |  |         if line[-2:] == CRLF: | 
					
						
							|  |  |  |             line = line[:-2] | 
					
						
							|  |  |  |         elif line[-1:] in CRLF: | 
					
						
							|  |  |  |             line = line[:-1] | 
					
						
							|  |  |  |         if line == '.': | 
					
						
							|  |  |  |             break | 
					
						
							|  |  |  |         if not line: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |             print('(Empty line from server)') | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |             continue | 
					
						
							|  |  |  |         typechar = line[0] | 
					
						
							| 
									
										
										
										
											2006-03-17 06:49:51 +00:00
										 |  |  |         parts = line[1:].split(TAB) | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         if len(parts) < 4: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |             print('(Bad line from server: %r)' % (line,)) | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |             continue | 
					
						
							|  |  |  |         if len(parts) > 4: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |             print('(Extra info from server: %r)' % (parts[4:],)) | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         parts.insert(0, typechar) | 
					
						
							|  |  |  |         list.append(parts) | 
					
						
							|  |  |  |     f.close() | 
					
						
							|  |  |  |     return list | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Get a text file as a list of lines, with trailing CRLF stripped | 
					
						
							|  |  |  | def get_textfile(selector, host, port): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     list = [] | 
					
						
							|  |  |  |     get_alt_textfile(selector, host, port, list.append) | 
					
						
							|  |  |  |     return list | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Get a text file and pass each line to a function, with trailing CRLF stripped | 
					
						
							|  |  |  | def get_alt_textfile(selector, host, port, func): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     f = send_request(selector, host, port) | 
					
						
							|  |  |  |     while 1: | 
					
						
							|  |  |  |         line = f.readline() | 
					
						
							|  |  |  |         if not line: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |             print('(Unexpected EOF from server)') | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |             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) | 
					
						
							|  |  |  |     f.close() | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Get a binary file as one solid data block | 
					
						
							|  |  |  | def get_binary(selector, host, port): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     f = send_request(selector, host, port) | 
					
						
							|  |  |  |     data = f.read() | 
					
						
							|  |  |  |     f.close() | 
					
						
							|  |  |  |     return data | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Get a binary file and pass each block to a function | 
					
						
							|  |  |  | def get_alt_binary(selector, host, port, func, blocksize): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     f = send_request(selector, host, port) | 
					
						
							|  |  |  |     while 1: | 
					
						
							|  |  |  |         data = f.read(blocksize) | 
					
						
							|  |  |  |         if not data: | 
					
						
							|  |  |  |             break | 
					
						
							|  |  |  |         func(data) | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # A *very* simple interactive browser | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Browser main command, has default arguments | 
					
						
							|  |  |  | def browser(*args): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     selector = DEF_SELECTOR | 
					
						
							|  |  |  |     host = DEF_HOST | 
					
						
							|  |  |  |     port = DEF_PORT | 
					
						
							|  |  |  |     n = len(args) | 
					
						
							|  |  |  |     if n > 0 and args[0]: | 
					
						
							|  |  |  |         selector = args[0] | 
					
						
							|  |  |  |     if n > 1 and args[1]: | 
					
						
							|  |  |  |         host = args[1] | 
					
						
							|  |  |  |     if n > 2 and args[2]: | 
					
						
							|  |  |  |         port = args[2] | 
					
						
							|  |  |  |     if n > 3: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         raise RuntimeError('too many args') | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     try: | 
					
						
							|  |  |  |         browse_menu(selector, host, port) | 
					
						
							| 
									
										
										
										
											2007-01-10 16:19:56 +00:00
										 |  |  |     except socket.error as msg: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         print('Socket error:', msg) | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         sys.exit(1) | 
					
						
							|  |  |  |     except KeyboardInterrupt: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         print('\n[Goodbye]') | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Browse a menu | 
					
						
							|  |  |  | def browse_menu(selector, host, port): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     list = get_menu(selector, host, port) | 
					
						
							|  |  |  |     while 1: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         print('----- MENU -----') | 
					
						
							|  |  |  |         print('Selector:', repr(selector)) | 
					
						
							|  |  |  |         print('Host:', host, ' Port:', port) | 
					
						
							|  |  |  |         print() | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         for i in range(len(list)): | 
					
						
							|  |  |  |             item = list[i] | 
					
						
							|  |  |  |             typechar, description = item[0], item[1] | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |             print(repr(i+1).rjust(3) + ':', description, end=' ') | 
					
						
							|  |  |  |             if typechar in typename: | 
					
						
							|  |  |  |                 print(typename[typechar]) | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |                 print('<TYPE=' + repr(typechar) + '>') | 
					
						
							|  |  |  |         print() | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         while 1: | 
					
						
							|  |  |  |             try: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |                 str = input('Choice [CR == up a level]: ') | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |             except EOFError: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |                 print() | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |                 return | 
					
						
							|  |  |  |             if not str: | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             try: | 
					
						
							| 
									
										
										
										
											2006-03-17 06:49:51 +00:00
										 |  |  |                 choice = int(str) | 
					
						
							|  |  |  |             except ValueError: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |                 print('Choice must be a number; try again:') | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |                 continue | 
					
						
							|  |  |  |             if not 0 < choice <= len(list): | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |                 print('Choice out of range; try again:') | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |                 continue | 
					
						
							|  |  |  |             break | 
					
						
							|  |  |  |         item = list[choice-1] | 
					
						
							|  |  |  |         typechar = item[0] | 
					
						
							|  |  |  |         [i_selector, i_host, i_port] = item[2:5] | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         if typechar in typebrowser: | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |             browserfunc = typebrowser[typechar] | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 browserfunc(i_selector, i_host, i_port) | 
					
						
							|  |  |  |             except (IOError, socket.error): | 
					
						
							| 
									
										
										
										
											2006-03-17 05:49:33 +00:00
										 |  |  |                 t, v, tb = sys.exc_info() | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |                 print('***', t, ':', v) | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |             print('Unsupported object type') | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Browse a text file | 
					
						
							|  |  |  | def browse_textfile(selector, host, port): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     x = None | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         p = os.popen('${PAGER-more}', 'w') | 
					
						
							|  |  |  |         x = SaveLines(p) | 
					
						
							|  |  |  |         get_alt_textfile(selector, host, port, x.writeln) | 
					
						
							| 
									
										
										
										
											2007-01-10 16:19:56 +00:00
										 |  |  |     except IOError as msg: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         print('IOError:', msg) | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     if x: | 
					
						
							|  |  |  |         x.close() | 
					
						
							|  |  |  |     f = open_savefile() | 
					
						
							|  |  |  |     if not f: | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     x = SaveLines(f) | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         get_alt_textfile(selector, host, port, x.writeln) | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         print('Done.') | 
					
						
							| 
									
										
										
										
											2007-01-10 16:19:56 +00:00
										 |  |  |     except IOError as msg: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         print('IOError:', msg) | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     x.close() | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-17 06:49:51 +00:00
										 |  |  | def raw_input(prompt): | 
					
						
							|  |  |  |     sys.stdout.write(prompt) | 
					
						
							|  |  |  |     sys.stdout.flush() | 
					
						
							|  |  |  |     return sys.stdin.readline() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | # Browse a search index | 
					
						
							|  |  |  | def browse_search(selector, host, port): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     while 1: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         print('----- SEARCH -----') | 
					
						
							|  |  |  |         print('Selector:', repr(selector)) | 
					
						
							|  |  |  |         print('Host:', host, ' Port:', port) | 
					
						
							|  |  |  |         print() | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |             query = input('Query [CR == up a level]: ') | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         except EOFError: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |             print() | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |             break | 
					
						
							| 
									
										
										
										
											2006-03-17 06:49:51 +00:00
										 |  |  |         query = query.strip() | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         if not query: | 
					
						
							|  |  |  |             break | 
					
						
							|  |  |  |         if '\t' in query: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |             print('Sorry, queries cannot contain tabs') | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |             continue | 
					
						
							|  |  |  |         browse_menu(selector + TAB + query, host, port) | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # "Browse" telnet-based information, i.e. open a telnet session | 
					
						
							|  |  |  | def browse_telnet(selector, host, port): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     if selector: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         print('Log in as', repr(selector)) | 
					
						
							| 
									
										
										
										
											2006-08-29 04:39:12 +00:00
										 |  |  |     if type(port) != type(''): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         port = repr(port) | 
					
						
							|  |  |  |     sts = os.system('set -x; exec telnet ' + host + ' ' + port) | 
					
						
							|  |  |  |     if sts: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         print('Exit status:', sts) | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # "Browse" a binary file, i.e. save it to a file | 
					
						
							|  |  |  | def browse_binary(selector, host, port): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     f = open_savefile() | 
					
						
							|  |  |  |     if not f: | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     x = SaveWithProgress(f) | 
					
						
							|  |  |  |     get_alt_binary(selector, host, port, x.write, 8*1024) | 
					
						
							|  |  |  |     x.close() | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # "Browse" a sound file, i.e. play it or save it | 
					
						
							|  |  |  | def browse_sound(selector, host, port): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     browse_binary(selector, host, port) | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Dictionary mapping types to browser functions | 
					
						
							|  |  |  | typebrowser = {'0': browse_textfile, '1': browse_menu, \ | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         '4': browse_binary, '5': browse_binary, '6': browse_textfile, \ | 
					
						
							|  |  |  |         '7': browse_search, \ | 
					
						
							|  |  |  |         '8': browse_telnet, '9': browse_binary, 's': browse_sound} | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Class used to save lines, appending a newline to each line | 
					
						
							|  |  |  | class SaveLines: | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     def __init__(self, f): | 
					
						
							|  |  |  |         self.f = f | 
					
						
							|  |  |  |     def writeln(self, line): | 
					
						
							|  |  |  |         self.f.write(line + '\n') | 
					
						
							|  |  |  |     def close(self): | 
					
						
							|  |  |  |         sts = self.f.close() | 
					
						
							|  |  |  |         if sts: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |             print('Exit status:', sts) | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Class used to save data while showing progress | 
					
						
							|  |  |  | class SaveWithProgress: | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     def __init__(self, f): | 
					
						
							|  |  |  |         self.f = f | 
					
						
							|  |  |  |     def write(self, data): | 
					
						
							|  |  |  |         sys.stdout.write('#') | 
					
						
							|  |  |  |         sys.stdout.flush() | 
					
						
							|  |  |  |         self.f.write(data) | 
					
						
							|  |  |  |     def close(self): | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         print() | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         sts = self.f.close() | 
					
						
							|  |  |  |         if sts: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |             print('Exit status:', sts) | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Ask for and open a save file, or return None if not to save | 
					
						
							|  |  |  | def open_savefile(): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         savefile = input( \ | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     'Save as file [CR == don\'t save; |pipeline or ~user/... OK]: ') | 
					
						
							|  |  |  |     except EOFError: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         print() | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2006-03-17 06:49:51 +00:00
										 |  |  |     savefile = savefile.strip() | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     if not savefile: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  |     if savefile[0] == '|': | 
					
						
							| 
									
										
										
										
											2006-03-17 06:49:51 +00:00
										 |  |  |         cmd = savefile[1:].strip() | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             p = os.popen(cmd, 'w') | 
					
						
							| 
									
										
										
										
											2007-01-10 16:19:56 +00:00
										 |  |  |         except IOError as msg: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |             print(repr(cmd), ':', msg) | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |             return None | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         print('Piping through', repr(cmd), '...') | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         return p | 
					
						
							|  |  |  |     if savefile[0] == '~': | 
					
						
							|  |  |  |         savefile = os.path.expanduser(savefile) | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         f = open(savefile, 'w') | 
					
						
							| 
									
										
										
										
											2007-01-10 16:19:56 +00:00
										 |  |  |     except IOError as msg: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         print(repr(savefile), ':', msg) | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |     print('Saving to', repr(savefile), '...') | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     return f | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Test program | 
					
						
							|  |  |  | def test(): | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     if sys.argv[4:]: | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         print('usage: gopher [ [selector] host [port] ]') | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         sys.exit(2) | 
					
						
							|  |  |  |     elif sys.argv[3:]: | 
					
						
							|  |  |  |         browser(sys.argv[1], sys.argv[2], sys.argv[3]) | 
					
						
							|  |  |  |     elif sys.argv[2:]: | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2006-03-17 06:49:51 +00:00
										 |  |  |             port = int(sys.argv[2]) | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |             selector = '' | 
					
						
							|  |  |  |             host = sys.argv[1] | 
					
						
							| 
									
										
										
										
											2006-03-17 06:49:51 +00:00
										 |  |  |         except ValueError: | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |             selector = sys.argv[1] | 
					
						
							|  |  |  |             host = sys.argv[2] | 
					
						
							|  |  |  |             port = '' | 
					
						
							|  |  |  |         browser(selector, host, port) | 
					
						
							|  |  |  |     elif sys.argv[1:]: | 
					
						
							|  |  |  |         browser('', sys.argv[1]) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         browser() | 
					
						
							| 
									
										
										
										
											1992-10-25 19:18:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Call the test program as a main program | 
					
						
							|  |  |  | test() |