diff options
Diffstat (limited to 'Demo/sockets/gopher.py')
-rwxr-xr-x | Demo/sockets/gopher.py | 498 |
1 files changed, 249 insertions, 249 deletions
diff --git a/Demo/sockets/gopher.py b/Demo/sockets/gopher.py index 4e1cb30..cd76659 100755 --- a/Demo/sockets/gopher.py +++ b/Demo/sockets/gopher.py @@ -30,8 +30,8 @@ T_SOUND = 's' # Dictionary mapping types to strings typename = {'0': '<TEXT>', '1': '<DIR>', '2': '<CSO>', '3': '<ERROR>', \ - '4': '<BINHEX>', '5': '<DOS>', '6': '<UUENCODE>', '7': '<SEARCH>', \ - '8': '<TELNET>', '9': '<BINARY>', '+': '<REDUNDANT>', 's': '<SOUND>'} + '4': '<BINHEX>', '5': '<DOS>', '6': '<UUENCODE>', '7': '<SEARCH>', \ + '8': '<TELNET>', '9': '<BINARY>', '+': '<REDUNDANT>', 's': '<SOUND>'} # Oft-used characters and strings CRLF = '\r\n' @@ -39,309 +39,309 @@ TAB = '\t' # Open a TCP connection to a given host and port def open_socket(host, port): - 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)) - return s + 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)) + return s # Send a selector to a given host and port, return a file with the reply def send_request(selector, host, port): - s = open_socket(host, port) - s.send(selector + CRLF) - s.shutdown(1) - return s.makefile('r') + s = open_socket(host, port) + s.send(selector + CRLF) + s.shutdown(1) + return s.makefile('r') # Get a menu in the form of a list of entries def get_menu(selector, host, port): - f = send_request(selector, host, port) - 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 - typechar = line[0] - parts = string.splitfields(line[1:], TAB) - if len(parts) < 4: - print '(Bad line from server: %r)' % (line,) - continue - if len(parts) > 4: - print '(Extra info from server: %r)' % (parts[4:],) - parts.insert(0, typechar) - list.append(parts) - f.close() - return list + f = send_request(selector, host, port) + 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 + typechar = line[0] + parts = string.splitfields(line[1:], TAB) + if len(parts) < 4: + print '(Bad line from server: %r)' % (line,) + continue + if len(parts) > 4: + print '(Extra info from server: %r)' % (parts[4:],) + parts.insert(0, typechar) + list.append(parts) + f.close() + return list # Get a text file as a list of lines, with trailing CRLF stripped def get_textfile(selector, host, port): - list = [] - get_alt_textfile(selector, host, port, list.append) - return list + list = [] + get_alt_textfile(selector, host, port, list.append) + return list # Get a text file and pass each line to a function, with trailing CRLF stripped def get_alt_textfile(selector, host, port, func): - f = send_request(selector, host, port) - 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) - f.close() + f = send_request(selector, host, port) + 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) + f.close() # Get a binary file as one solid data block def get_binary(selector, host, port): - f = send_request(selector, host, port) - data = f.read() - f.close() - return data + f = send_request(selector, host, port) + data = f.read() + f.close() + return data # Get a binary file and pass each block to a function def get_alt_binary(selector, host, port, func, blocksize): - f = send_request(selector, host, port) - while 1: - data = f.read(blocksize) - if not data: - break - func(data) + f = send_request(selector, host, port) + while 1: + data = f.read(blocksize) + if not data: + break + func(data) # A *very* simple interactive browser # Browser main command, has default arguments def browser(*args): - 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: - raise RuntimeError, 'too many args' - try: - browse_menu(selector, host, port) - except socket.error, msg: - print 'Socket error:', msg - sys.exit(1) - except KeyboardInterrupt: - print '\n[Goodbye]' + 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: + raise RuntimeError, 'too many args' + try: + browse_menu(selector, host, port) + except socket.error, msg: + print 'Socket error:', msg + sys.exit(1) + except KeyboardInterrupt: + print '\n[Goodbye]' # Browse a menu def browse_menu(selector, host, port): - list = get_menu(selector, host, port) - while 1: - print '----- MENU -----' - print 'Selector:', repr(selector) - print 'Host:', host, ' Port:', port - print - for i in range(len(list)): - item = list[i] - typechar, description = item[0], item[1] - print string.rjust(repr(i+1), 3) + ':', description, - if typename.has_key(typechar): - print typename[typechar] - else: - print '<TYPE=' + repr(typechar) + '>' - print - while 1: - try: - str = raw_input('Choice [CR == up a level]: ') - except EOFError: - print - return - if not str: - return - try: - choice = string.atoi(str) - except string.atoi_error: - print 'Choice must be a number; try again:' - continue - if not 0 < choice <= len(list): - print 'Choice out of range; try again:' - continue - break - item = list[choice-1] - typechar = item[0] - [i_selector, i_host, i_port] = item[2:5] - if typebrowser.has_key(typechar): - browserfunc = typebrowser[typechar] - try: - browserfunc(i_selector, i_host, i_port) - except (IOError, socket.error): - print '***', sys.exc_type, ':', sys.exc_value - else: - print 'Unsupported object type' + list = get_menu(selector, host, port) + while 1: + print '----- MENU -----' + print 'Selector:', repr(selector) + print 'Host:', host, ' Port:', port + print + for i in range(len(list)): + item = list[i] + typechar, description = item[0], item[1] + print string.rjust(repr(i+1), 3) + ':', description, + if typename.has_key(typechar): + print typename[typechar] + else: + print '<TYPE=' + repr(typechar) + '>' + print + while 1: + try: + str = raw_input('Choice [CR == up a level]: ') + except EOFError: + print + return + if not str: + return + try: + choice = string.atoi(str) + except string.atoi_error: + print 'Choice must be a number; try again:' + continue + if not 0 < choice <= len(list): + print 'Choice out of range; try again:' + continue + break + item = list[choice-1] + typechar = item[0] + [i_selector, i_host, i_port] = item[2:5] + if typebrowser.has_key(typechar): + browserfunc = typebrowser[typechar] + try: + browserfunc(i_selector, i_host, i_port) + except (IOError, socket.error): + print '***', sys.exc_type, ':', sys.exc_value + else: + print 'Unsupported object type' # Browse a text file def browse_textfile(selector, host, port): - x = None - try: - p = os.popen('${PAGER-more}', 'w') - x = SaveLines(p) - get_alt_textfile(selector, host, port, x.writeln) - except IOError, msg: - print 'IOError:', msg - if x: - x.close() - f = open_savefile() - if not f: - return - x = SaveLines(f) - try: - get_alt_textfile(selector, host, port, x.writeln) - print 'Done.' - except IOError, msg: - print 'IOError:', msg - x.close() + x = None + try: + p = os.popen('${PAGER-more}', 'w') + x = SaveLines(p) + get_alt_textfile(selector, host, port, x.writeln) + except IOError, msg: + print 'IOError:', msg + if x: + x.close() + f = open_savefile() + if not f: + return + x = SaveLines(f) + try: + get_alt_textfile(selector, host, port, x.writeln) + print 'Done.' + except IOError, msg: + print 'IOError:', msg + x.close() # Browse a search index def browse_search(selector, host, port): - while 1: - print '----- SEARCH -----' - print 'Selector:', repr(selector) - print 'Host:', host, ' Port:', port - print - try: - query = raw_input('Query [CR == up a level]: ') - except EOFError: - print - break - query = string.strip(query) - if not query: - break - if '\t' in query: - print 'Sorry, queries cannot contain tabs' - continue - browse_menu(selector + TAB + query, host, port) + while 1: + print '----- SEARCH -----' + print 'Selector:', repr(selector) + print 'Host:', host, ' Port:', port + print + try: + query = raw_input('Query [CR == up a level]: ') + except EOFError: + print + break + query = string.strip(query) + if not query: + break + if '\t' in query: + print 'Sorry, queries cannot contain tabs' + continue + browse_menu(selector + TAB + query, host, port) # "Browse" telnet-based information, i.e. open a telnet session def browse_telnet(selector, host, port): - if selector: - print 'Log in as', repr(selector) - if type(port) <> type(''): - port = repr(port) - sts = os.system('set -x; exec telnet ' + host + ' ' + port) - if sts: - print 'Exit status:', sts + if selector: + print 'Log in as', repr(selector) + if type(port) <> type(''): + port = repr(port) + sts = os.system('set -x; exec telnet ' + host + ' ' + port) + if sts: + print 'Exit status:', sts # "Browse" a binary file, i.e. save it to a file def browse_binary(selector, host, port): - f = open_savefile() - if not f: - return - x = SaveWithProgress(f) - get_alt_binary(selector, host, port, x.write, 8*1024) - x.close() + f = open_savefile() + if not f: + return + x = SaveWithProgress(f) + get_alt_binary(selector, host, port, x.write, 8*1024) + x.close() # "Browse" a sound file, i.e. play it or save it def browse_sound(selector, host, port): - browse_binary(selector, host, port) + browse_binary(selector, host, port) # Dictionary mapping types to browser functions typebrowser = {'0': browse_textfile, '1': browse_menu, \ - '4': browse_binary, '5': browse_binary, '6': browse_textfile, \ - '7': browse_search, \ - '8': browse_telnet, '9': browse_binary, 's': browse_sound} + '4': browse_binary, '5': browse_binary, '6': browse_textfile, \ + '7': browse_search, \ + '8': browse_telnet, '9': browse_binary, 's': browse_sound} # Class used to save lines, appending a newline to each line class SaveLines: - 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: - print 'Exit status:', sts + 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: + print 'Exit status:', sts # Class used to save data while showing progress class SaveWithProgress: - def __init__(self, f): - self.f = f - def write(self, data): - sys.stdout.write('#') - sys.stdout.flush() - self.f.write(data) - def close(self): - print - sts = self.f.close() - if sts: - print 'Exit status:', sts + def __init__(self, f): + self.f = f + def write(self, data): + sys.stdout.write('#') + sys.stdout.flush() + self.f.write(data) + def close(self): + print + sts = self.f.close() + if sts: + print 'Exit status:', sts # Ask for and open a save file, or return None if not to save def open_savefile(): - try: - savefile = raw_input( \ - 'Save as file [CR == don\'t save; |pipeline or ~user/... OK]: ') - except EOFError: - print - return None - savefile = string.strip(savefile) - if not savefile: - return None - if savefile[0] == '|': - cmd = string.strip(savefile[1:]) - try: - p = os.popen(cmd, 'w') - except IOError, msg: - print repr(cmd), ':', msg - return None - print 'Piping through', repr(cmd), '...' - return p - if savefile[0] == '~': - savefile = os.path.expanduser(savefile) - try: - f = open(savefile, 'w') - except IOError, msg: - print repr(savefile), ':', msg - return None - print 'Saving to', repr(savefile), '...' - return f + try: + savefile = raw_input( \ + 'Save as file [CR == don\'t save; |pipeline or ~user/... OK]: ') + except EOFError: + print + return None + savefile = string.strip(savefile) + if not savefile: + return None + if savefile[0] == '|': + cmd = string.strip(savefile[1:]) + try: + p = os.popen(cmd, 'w') + except IOError, msg: + print repr(cmd), ':', msg + return None + print 'Piping through', repr(cmd), '...' + return p + if savefile[0] == '~': + savefile = os.path.expanduser(savefile) + try: + f = open(savefile, 'w') + except IOError, msg: + print repr(savefile), ':', msg + return None + print 'Saving to', repr(savefile), '...' + return f # Test program def test(): - if sys.argv[4:]: - print 'usage: gopher [ [selector] host [port] ]' - sys.exit(2) - elif sys.argv[3:]: - browser(sys.argv[1], sys.argv[2], sys.argv[3]) - elif sys.argv[2:]: - try: - port = string.atoi(sys.argv[2]) - selector = '' - host = sys.argv[1] - except string.atoi_error: - selector = sys.argv[1] - host = sys.argv[2] - port = '' - browser(selector, host, port) - elif sys.argv[1:]: - browser('', sys.argv[1]) - else: - browser() + if sys.argv[4:]: + print 'usage: gopher [ [selector] host [port] ]' + sys.exit(2) + elif sys.argv[3:]: + browser(sys.argv[1], sys.argv[2], sys.argv[3]) + elif sys.argv[2:]: + try: + port = string.atoi(sys.argv[2]) + selector = '' + host = sys.argv[1] + except string.atoi_error: + selector = sys.argv[1] + host = sys.argv[2] + port = '' + browser(selector, host, port) + elif sys.argv[1:]: + browser('', sys.argv[1]) + else: + browser() # Call the test program as a main program test() |