diff options
author | Brian Dolbec <dolsen@gentoo.org> | 2012-11-11 19:29:16 -0800 |
---|---|---|
committer | Brian Dolbec <dolsen@gentoo.org> | 2012-11-11 23:23:09 -0800 |
commit | 50e5e2dd9972dd7ac0a4eeb79ef43ab8d4101dd6 (patch) | |
tree | cca6ef4363d6e9c264233aa0337ed3186cf0f104 /mirrorselect | |
parent | move the selector classes to their own file (diff) | |
download | mirrorselect-50e5e2dd9972dd7ac0a4eeb79ef43ab8d4101dd6.tar.gz mirrorselect-50e5e2dd9972dd7ac0a4eeb79ef43ab8d4101dd6.tar.bz2 mirrorselect-50e5e2dd9972dd7ac0a4eeb79ef43ab8d4101dd6.zip |
move main's code into a MirrorSelect class, eliminate the global variable 'output'.
Diffstat (limited to 'mirrorselect')
-rwxr-xr-x | mirrorselect/main.py | 523 | ||||
-rw-r--r-- | mirrorselect/output.py | 17 | ||||
-rw-r--r-- | mirrorselect/selectors.py | 97 |
3 files changed, 323 insertions, 314 deletions
diff --git a/mirrorselect/main.py b/mirrorselect/main.py index 25c73ae..2f257a6 100755 --- a/mirrorselect/main.py +++ b/mirrorselect/main.py @@ -32,273 +32,278 @@ import string import sys from optparse import OptionParser from mirrorselect.mirrorparser3 import MIRRORS_3_XML, MIRRORS_RSYNC_DATA -from mirrorselect.output import output, ColoredFormatter +from mirrorselect.output import Output, ColoredFormatter from mirrorselect.selectors import Deep, Shallow, Extractor, Interactive -def _have_bin(name): - """ - Determines whether a particular binary is available on the host system. - """ - for path_dir in os.environ.get("PATH", "").split(":"): - if not path_dir: - continue - file_path = os.path.join(path_dir, name) - if os.path.isfile(file_path) and os.access(file_path, os.X_OK): - return file_path - return None - - -def write_config(hosts, out, path, sync=False): - """ - Writes the make.conf style string to the given file, or to stdout. - """ - if sync: - var = 'SYNC' - else: - var = 'GENTOO_MIRRORS' - - mirror_string = '%s="%s"' % (var, ' '.join(hosts)) - - if out: - print - print mirror_string - sys.exit(0) +class MirrorSelect(object): + '''Main operational class''' + + def __init__(self, output=None): + '''Main class init''' + self.output = output or Output() + + @staticmethod + def _have_bin(name): + """ + Determines whether a particular binary is available on the host system. + """ + for path_dir in os.environ.get("PATH", "").split(":"): + if not path_dir: + continue + file_path = os.path.join(path_dir, name) + if os.path.isfile(file_path) and os.access(file_path, os.X_OK): + return file_path + return None + + + def write_config(self, hosts, out, path, sync=False): + """ + Writes the make.conf style string to the given file, or to stdout. + """ + if sync: + var = 'SYNC' + else: + var = 'GENTOO_MIRRORS' + + mirror_string = '%s="%s"' % (var, ' '.join(hosts)) + + if out: + print + print mirror_string + sys.exit(0) + + + self.output.write('\n') + self.output.print_info('Modifying %s with new mirrors...\n' % path) + try: + config = open(path, 'r') + self.output.write('\tReading make.conf\n') + lines = config.readlines() + config.close() + self.output.write('\tMoving to %s.backup\n' % path) + shutil.move(path, path + '.backup') + except IOError: + lines = [] + + regex = re.compile('^%s=.*' % var) + for line in lines: + if regex.match(line): + lines.remove(line) + + lines.append(mirror_string) + + self.output.write('\tWriting new %s\n' % path) + config = open(path, 'w') + for line in lines: + config.write(line) + config.write('\n') + config.close() + self.output.print_info('Done.\n') + sys.exit(0) - output.write('\n') - output.print_info('Modifying %s with new mirrors...\n' % path) - try: - config = open(path, 'r') - output.write('\tReading make.conf\n') - lines = config.readlines() - config.close() - output.write('\tMoving to %s.backup\n' % path) - shutil.move(path, path + '.backup') - except IOError: - lines = [] - - regex = re.compile('^%s=.*' % var) - for line in lines: - if regex.match(line): - lines.remove(line) - - lines.append(mirror_string) - - output.write('\tWriting new %s\n' % path) - config = open(path, 'w') - for line in lines: - config.write(line) - config.write('\n') - config.close() - - output.print_info('Done.\n') - sys.exit(0) - -def get_filesystem_mirrors(out, path, sync=False): - """ - Read the current mirrors and retain mounted filesystems mirrors - """ - fsmirrors = [] - - if sync: - var = 'SYNC' - else: - var = 'GENTOO_MIRRORS' - - try: - f = open(path,'r') - except IOError: - return fsmirrors + def get_filesystem_mirrors(self, out, path, sync=False): + """ + Read the current mirrors and retain mounted filesystems mirrors + """ + fsmirrors = [] - """ Search for 'var' in make.conf and extract value """ - try: - lex = shlex.shlex(f, posix=True) - lex.wordchars = string.digits+string.letters+"~!@#$%*_\:;?,./-+{}" - lex.quotes = "\"'" - while 1: - key = lex.get_token() - if key == var: - equ = lex.get_token() - - if (equ == ''): + if sync: + var = 'SYNC' + else: + var = 'GENTOO_MIRRORS' + + try: + f = open(path,'r') + except IOError: + return fsmirrors + + """ Search for 'var' in make.conf and extract value """ + try: + lex = shlex.shlex(f, posix=True) + lex.wordchars = string.digits+string.letters+"~!@#$%*_\:;?,./-+{}" + lex.quotes = "\"'" + while 1: + key = lex.get_token() + if key == var: + equ = lex.get_token() + + if (equ == ''): + break + elif (equ != '='): + break + + val = lex.get_token() + if val is None: + break + + """ Look for mounted filesystem in value """ + mirrorlist = val.rsplit() + p = re.compile('rsync://|http://|ftp://', re.IGNORECASE) + for mirror in mirrorlist: + if (p.match(mirror) == None): + fsmirrors.append(mirror) break - elif (equ != '='): + elif key is None: break + except Exception: + fsmirrors = [] - val = lex.get_token() - if val is None: - break + return fsmirrors - """ Look for mounted filesystem in value """ - mirrorlist = val.rsplit() - p = re.compile('rsync://|http://|ftp://', re.IGNORECASE) - for mirror in mirrorlist: - if (p.match(mirror) == None): - fsmirrors.append(mirror) - break - elif key is None: - break - except Exception: - fsmirrors = [] + def parse_args(self, argv, config_path): + """ + Does argument parsing and some sanity checks. + Returns an optparse Options object. + + The descriptions, grouping, and possibly the amount sanity checking + need some finishing touches. + """ + desc = "\n".join(( + self.output.white("examples:"), + "", + self.output.white(" automatic:"), + " # mirrorselect -s5", + " # mirrorselect -s3 -b10 -o >> /mnt/gentoo/etc/portage/make.conf", + " # mirrorselect -D -s4", + "", + self.output.white(" interactive:"), + " # mirrorselect -i -r", + )) + parser = OptionParser( + formatter=ColoredFormatter(self.output), description=desc, + version='Mirrorselect version: %s' % __revision__) + + group = parser.add_option_group("Main modes") + group.add_option( + "-i", "--interactive", action="store_true", default=False, + help="Interactive Mode, this will present a list " + "to make it possible to select mirrors you wish to use.") + group.add_option( + "-D", "--deep", action="store_true", default=False, + help="Deep mode. This is used to give a more accurate " + "speed test. It will download a 100k file from " + "each server. Because of this you should only use " + "this option if you have a good connection.") + + group = parser.add_option_group( + "Server type selection (choose at most one)") + group.add_option( + "-F", "--ftp", action="store_true", default=False, + help="ftp only mode. Will not consider hosts of other " + "types.") + group.add_option( + "-H", "--http", action="store_true", default=False, + help="http only mode. Will not consider hosts of other types") + group.add_option( + "-r", "--rsync", action="store_true", default=False, + help="rsync mode. Allows you to interactively select your" + " rsync mirror. Requires -i to be used.") + group.add_option( + "-4", "--ipv4", action="store_true", default=False, + help="only use IPv4") + group.add_option( + "-6", "--ipv6", action="store_true", default=False, + help="only use IPv6") + + group = parser.add_option_group("Other options") + group.add_option( + "-o", "--output", action="store_true", default=False, + help="Output Only Mode, this is especially useful " + "when being used during installation, to redirect " + "output to a file other than %s" % config_path) + group.add_option( + "-b", "--blocksize", action="store", type="int", + help="This is to be used in automatic mode " + "and will split the hosts into blocks of BLOCKSIZE for " + "use with netselect. This is required for certain " + "routers which block 40+ requests at any given time. " + "Recommended parameters to pass are: -s3 -b10") + group.add_option( + "-t", "--timeout", action="store", type="int", + default="10", help="Timeout for deep mode. Defaults to 10 seconds.") + group.add_option( + "-s", "--servers", action="store", type="int", default=1, + help="Specify Number of servers for Automatic Mode " + "to select. this is only valid for download mirrors. " + "If this is not specified, a default of 1 is used.") + group.add_option( + "-d", "--debug", action="store_const", const=2, dest="verbosity", + default=1, help="debug mode") + group.add_option( + "-q", "--quiet", action="store_const", const=0, dest="verbosity", + help="Quiet mode") + + if len(argv) == 1: + parser.print_help() + sys.exit(1) + + options, args = parser.parse_args(argv[1:]) + + # sanity checks + + # hack: check if more than one of these is set + if options.http + options.ftp + options.rsync > 1: + self.output.print_err('Choose at most one of -H, -f and -r') + + if options.ipv4 and options.ipv6: + self.output.print_err('Choose at most one of --ipv4 and --ipv6') + + if (options.ipv6 and not socket.has_ipv6) and not options.interactive: + options.ipv6 = False + self.output.print_err('The --ipv6 option requires python ipv6 support') + + if options.rsync and not options.interactive: + self.output.print_err('rsync servers can only be selected with -i') + + if options.interactive and ( + options.deep or + options.blocksize or + options.servers > 1): + self.output.print_err('Invalid option combination with -i') + + if (not options.deep) and (not self._have_bin('netselect') ): + self.output.print_err( + 'You do not appear to have netselect on your system. ' + 'You must use the -D flag') + + if (os.getuid() != 0) and not options.output: + self.output.print_err('Must be root to write to %s!\n' % config_path) + + if args: + self.output.print_err('Unexpected arguments passed.') + + # return results + return options + + + def main(self, argv): + """Lets Rock!""" + # start with the new location + config_path = '/etc/portage/make.conf' + if not os.access(config_path, os.F_OK): + # check if the old location is what is used + if os.access('/etc/make.conf', os.F_OK): + config_path = '/etc/make.conf' + + #self.output.print_info("config_path set to :", config_path) + + options = self.parse_args(argv, config_path) + self.output.verbosity = options.verbosity + + fsmirrors = self.get_filesystem_mirrors(options.output, config_path, options.rsync) + if options.rsync: + hosts = Extractor(MIRRORS_RSYNC_DATA, options, self.output).hosts + else: + hosts = Extractor(MIRRORS_3_XML, options, self.output).hosts + + if options.interactive: + selector = Interactive(hosts, options, self.output) + elif options.deep: + selector = Deep(hosts, options, self.output) + else: + selector = Shallow(hosts, options, self.output) + + self.write_config(fsmirrors + selector.urls, options.output, config_path, options.rsync) - return fsmirrors - -def parse_args(argv, config_path): - """ - Does argument parsing and some sanity checks. - Returns an optparse Options object. - - The descriptions, grouping, and possibly the amount sanity checking - need some finishing touches. - """ - desc = "\n".join(( - output.white("examples:"), - "", - output.white(" automatic:"), - " # mirrorselect -s5", - " # mirrorselect -s3 -b10 -o >> /mnt/gentoo/etc/portage/make.conf", - " # mirrorselect -D -s4", - "", - output.white(" interactive:"), - " # mirrorselect -i -r", - )) - parser = OptionParser( - formatter=ColoredFormatter(), description=desc, - version='Mirrorselect version: %s' % __revision__) - - group = parser.add_option_group("Main modes") - group.add_option( - "-i", "--interactive", action="store_true", default=False, - help="Interactive Mode, this will present a list " - "to make it possible to select mirrors you wish to use.") - group.add_option( - "-D", "--deep", action="store_true", default=False, - help="Deep mode. This is used to give a more accurate " - "speed test. It will download a 100k file from " - "each server. Because of this you should only use " - "this option if you have a good connection.") - - group = parser.add_option_group( - "Server type selection (choose at most one)") - group.add_option( - "-F", "--ftp", action="store_true", default=False, - help="ftp only mode. Will not consider hosts of other " - "types.") - group.add_option( - "-H", "--http", action="store_true", default=False, - help="http only mode. Will not consider hosts of other types") - group.add_option( - "-r", "--rsync", action="store_true", default=False, - help="rsync mode. Allows you to interactively select your" - " rsync mirror. Requires -i to be used.") - group.add_option( - "-4", "--ipv4", action="store_true", default=False, - help="only use IPv4") - group.add_option( - "-6", "--ipv6", action="store_true", default=False, - help="only use IPv6") - - group = parser.add_option_group("Other options") - group.add_option( - "-o", "--output", action="store_true", default=False, - help="Output Only Mode, this is especially useful " - "when being used during installation, to redirect " - "output to a file other than %s" % config_path) - group.add_option( - "-b", "--blocksize", action="store", type="int", - help="This is to be used in automatic mode " - "and will split the hosts into blocks of BLOCKSIZE for " - "use with netselect. This is required for certain " - "routers which block 40+ requests at any given time. " - "Recommended parameters to pass are: -s3 -b10") - group.add_option( - "-t", "--timeout", action="store", type="int", - default="10", help="Timeout for deep mode. Defaults to 10 seconds.") - group.add_option( - "-s", "--servers", action="store", type="int", default=1, - help="Specify Number of servers for Automatic Mode " - "to select. this is only valid for download mirrors. " - "If this is not specified, a default of 1 is used.") - group.add_option( - "-d", "--debug", action="store_const", const=2, dest="verbosity", - default=1, help="debug mode") - group.add_option( - "-q", "--quiet", action="store_const", const=0, dest="verbosity", - help="Quiet mode") - - if len(argv) == 1: - parser.print_help() - sys.exit(1) - - options, args = parser.parse_args(argv[1:]) - - # sanity checks - - # hack: check if more than one of these is set - if options.http + options.ftp + options.rsync > 1: - output.print_err('Choose at most one of -H, -f and -r') - - if options.ipv4 and options.ipv6: - output.print_err('Choose at most one of --ipv4 and --ipv6') - - if (options.ipv6 and not socket.has_ipv6) and not options.interactive: - options.ipv6 = False - output.print_err('The --ipv6 option requires python ipv6 support') - - if options.rsync and not options.interactive: - output.print_err('rsync servers can only be selected with -i') - - if options.interactive and ( - options.deep or - options.blocksize or - options.servers > 1): - output.print_err('Invalid option combination with -i') - - if (not options.deep) and (not _have_bin('netselect') ): - output.print_err( - 'You do not appear to have netselect on your system. ' - 'You must use the -D flag') - - if (os.getuid() != 0) and not options.output: - output.print_err('Must be root to write to %s!\n' % config_path) - - if args: - output.print_err('Unexpected arguments passed.') - - # return results - return options - - -def main(argv): - """Lets Rock!""" - # start with the new location - config_path = '/etc/portage/make.conf' - if not os.access(config_path, os.F_OK): - # check if the old location is what is used - if os.access('/etc/make.conf', os.F_OK): - config_path = '/etc/make.conf' - - #output.print_info("config_path set to :", config_path) - - options = parse_args(argv, config_path) - output.verbosity = options.verbosity - - fsmirrors = get_filesystem_mirrors(options.output, config_path, options.rsync) - if options.rsync: - hosts = Extractor(MIRRORS_RSYNC_DATA, options).hosts - else: - hosts = Extractor(MIRRORS_3_XML, options).hosts - - if options.interactive: - selector = Interactive(hosts, options) - elif options.deep: - selector = Deep(hosts, options) - else: - selector = Shallow(hosts, options) - - write_config(fsmirrors + selector.urls, options.output, config_path, options.rsync) - - -if __name__ == '__main__': - main(sys.argv) diff --git a/mirrorselect/output.py b/mirrorselect/output.py index b00226a..a9d49bb 100644 --- a/mirrorselect/output.py +++ b/mirrorselect/output.py @@ -27,7 +27,6 @@ Distributed under the terms of the GNU General Public License v2 """ -from __future__ import print_function import sys import re @@ -106,9 +105,12 @@ class ColoredFormatter(IndentedHelpFormatter): Overrides format_heading. """ + def __init__(self, output): + self.output = output + def format_heading(self, heading): """Return a colorful heading.""" - return "%*s%s:\n" % (self.current_indent, "", output.white(heading)) + return "%*s%s:\n" % (self.current_indent, "", self.output.white(heading)) def format_option(self, option): """Return colorful formatted help for an option.""" @@ -116,17 +118,18 @@ class ColoredFormatter(IndentedHelpFormatter): # long options with args option = re.sub( r"--([a-zA-Z]*)=([a-zA-Z]*)", - lambda m: "-%s %s" % (output.green(m.group(1)), - output.blue(m.group(2))), + lambda m: "-%s %s" % (self.output.green(m.group(1)), + self.output.blue(m.group(2))), option) # short options with args option = re.sub( r"-([a-zA-Z]) ?([0-9A-Z]+)", - lambda m: " -" + output.green(m.group(1)) + ' ' + output.blue(m.group(2)), + lambda m: " -" + self.output.green(m.group(1)) + ' ' + \ + self.output.blue(m.group(2)), option) # options without args option = re.sub( - r"-([a-zA-Z\d]+)", lambda m: "-" + output.green(m.group(1)), + r"-([a-zA-Z\d]+)", lambda m: "-" + self.output.green(m.group(1)), option) return option @@ -134,5 +137,3 @@ class ColoredFormatter(IndentedHelpFormatter): """Do not wrap.""" return description + '\n' - -output = Output() #the only FUCKING global. Damnit. diff --git a/mirrorselect/selectors.py b/mirrorselect/selectors.py index d2e7e63..9593848 100644 --- a/mirrorselect/selectors.py +++ b/mirrorselect/selectors.py @@ -38,7 +38,6 @@ import urllib import urlparse import hashlib from mirrorselect.mirrorparser3 import MirrorParser3 -from mirrorselect.output import output import codecs @@ -48,12 +47,13 @@ class Extractor(object): mirrors, and then filters them. Only the mirrors that should be tested, based on user input are saved. They will be in the hosts attribute.""" - def __init__(self, list_url, options): + def __init__(self, list_url, options, output): + self.output = output parser = MirrorParser3() self.hosts = [] hosts = self.getlist(parser, list_url) - output.write('Extractor(): fetched mirrors.xml,' + self.output.write('Extractor(): fetched mirrors.xml,' ' %s hosts before filtering\n' % len(hosts), 2) if not options.rsync: @@ -71,13 +71,13 @@ class Extractor(object): """ myhosts = [] - output.print_info('Limiting test to %s hosts. ' % prot ) + self.output.print_info('Limiting test to %s hosts. ' % prot ) for host in hosts: if host[0].startswith(prot): myhosts.append(host) - output.write('%s of %s removed.\n' % (len(hosts) - len(myhosts), + self.output.write('%s of %s removed.\n' % (len(hosts) - len(myhosts), len(hosts)) ) return myhosts @@ -89,9 +89,9 @@ class Extractor(object): Takes a parser object, url, and filering options. """ - output.write('getlist(): fetching ' + url + '\n', 2) + self.output.write('getlist(): fetching ' + url + '\n', 2) - output.print_info('Downloading a list of mirrors...') + self.output.print_info('Downloading a list of mirrors...') try: parser.parse(urllib.urlopen(url).read()) @@ -99,10 +99,10 @@ class Extractor(object): pass if len(parser.tuples()) == 0: - output.print_err('Could not get mirror list. Check your internet' + self.output.print_err('Could not get mirror list. Check your internet' ' connection.') - output.write(' Got %d mirrors.\n' % len(parser.tuples())) + self.output.write(' Got %d mirrors.\n' % len(parser.tuples())) return parser.tuples() @@ -110,7 +110,8 @@ class Extractor(object): class Shallow(object): """handles rapid server selection via netselect""" - def __init__(self, hosts, options): + def __init__(self, hosts, options, output): + self.output = output self.urls = [] if options.blocksize is not None: @@ -120,7 +121,7 @@ class Shallow(object): self.netselect(hosts, options.servers) if len(self.urls) == 0: - output.print_err('Netselect failed to return any mirrors.' + self.output.print_err('Netselect failed to return any mirrors.' ' Try again using block mode.') @@ -134,12 +135,12 @@ class Shallow(object): top_hosts = [] if not quiet: - output.print_info('Using netselect to choose the top %d mirrors...' \ + self.output.print_info('Using netselect to choose the top %d mirrors...' \ % number) host_string = ' '.join(hosts) - output.write('\nnetselect(): running "netselect -s%d %s"\n' % (int(number), + self.output.write('\nnetselect(): running "netselect -s%d %s"\n' % (int(number), host_string), 2) proc = subprocess.Popen( ['netselect', '-s%d' % (number,)] + hosts, @@ -148,7 +149,7 @@ class Shallow(object): out, err = proc.communicate() if err: - output.write('netselect(): netselect stderr: %s\n' % err, 2) + self.output.write('netselect(): netselect stderr: %s\n' % err, 2) for line in out.splitlines(): line = line.split() @@ -158,9 +159,9 @@ class Shallow(object): top_host_dict[line[0]] = line[1] if not quiet: - output.write('Done.\n') + self.output.write('Done.\n') - output.write('\nnetselect(): returning %s and %s\n' % (top_hosts, + self.output.write('\nnetselect(): returning %s and %s\n' % (top_hosts, top_host_dict), 2) if quiet: @@ -176,24 +177,24 @@ class Shallow(object): """ hosts = [host[0] for host in hosts] - output.write('netselect_split() got %s hosts.\n' % len(hosts), 2) + self.output.write('netselect_split() got %s hosts.\n' % len(hosts), 2) host_blocks = self.host_blocks(hosts, block_size) - output.write(' split into %s blocks\n' % len(host_blocks), 2) + self.output.write(' split into %s blocks\n' % len(host_blocks), 2) top_hosts = [] ret_hosts = {} block_index = 0 for block in host_blocks: - output.print_info('Using netselect to choose the top ' + self.output.print_info('Using netselect to choose the top ' '%d hosts, in blocks of %s. %s of %s blocks complete.' % (number, block_size, block_index, len(host_blocks))) host_dict = self.netselect(block, len(block), quiet=True)[1] - output.write('ran netselect(%s, %s), and got %s\n' % (block, len(block), + self.output.write('ran netselect(%s, %s), and got %s\n' % (block, len(block), host_dict), 2) for key in host_dict.keys(): @@ -210,7 +211,7 @@ class Shallow(object): for rank in host_ranking_keys[:number]: top_hosts.append(ret_hosts[rank]) - output.write('netselect_split(): returns %s\n' % top_hosts, 2) + self.output.write('netselect_split(): returns %s\n' % top_hosts, 2) self.urls = top_hosts @@ -230,7 +231,7 @@ class Shallow(object): mylist = [] host_array.append(hosts) - output.write('\n_host_blocks(): returns %s blocks, each about %s in size\n' + self.output.write('\n_host_blocks(): returns %s blocks, each about %s in size\n' % (len(host_array), len(host_array[0])), 2) return host_array @@ -239,7 +240,8 @@ class Shallow(object): class Deep(object): """handles deep mode mirror selection.""" - def __init__(self, hosts, options): + def __init__(self, hosts, options, output): + self.output = output self.urls = [] self._hosts = hosts self._number = options.servers @@ -276,7 +278,7 @@ class Deep(object): for host in hosts: prog += 1 - output.print_info('Downloading 100k files from each mirror... [%s of %s]'\ + self.output.print_info('Downloading 100k files from each mirror... [%s of %s]'\ % (prog, num_hosts) ) mytime, ignore = self.deeptime(host, maxtime) @@ -287,10 +289,10 @@ class Deep(object): else: continue - output.write('deeptest(): got %s hosts, and returned %s\n' % (num_hosts, \ + self.output.write('deeptest(): got %s hosts, and returned %s\n' % (num_hosts, \ str(top_hosts.values())), 2) - output.write('\n') #this just makes output nicer + self.output.write('\n') #this just makes output nicer #can't just return the dict.valuse, because we want the fastest mirror first... keys = top_hosts.keys() @@ -309,7 +311,7 @@ class Deep(object): Can be given an optional timeout, for use with a clever algorithm. Like mine. """ - output.write('\n_deeptime(): maxtime is %s\n' % maxtime, 2) + self.output.write('\n_deeptime(): maxtime is %s\n' % maxtime, 2) if url.endswith('/'): #append the path to the testfile to the URL url = url + 'distfiles/mirrorselect-test' @@ -342,14 +344,14 @@ class Deep(object): finally: signal.alarm(0) except socket.error, e: - output.write('deeptime(): dns error for host %s: %s\n' % \ + self.output.write('deeptime(): dns error for host %s: %s\n' % \ (url_parts.hostname, e), 2) except TimeoutException: - output.write('deeptime(): dns timeout for host %s\n' % \ + self.output.write('deeptime(): dns timeout for host %s\n' % \ (url_parts.hostname,), 2) if not ips: - output.write('deeptime(): unable to resolve ip for host %s\n' % \ + self.output.write('deeptime(): unable to resolve ip for host %s\n' % \ (url_parts.hostname,), 2) return (None, True) @@ -365,16 +367,16 @@ class Deep(object): finally: signal.alarm(0) except EnvironmentError, e: - output.write(('deeptime(): connection to host %s ' + \ + self.output.write(('deeptime(): connection to host %s ' + \ 'failed for ip %s: %s\n') % \ (url_parts.hostname, ip, e), 2) except TimeoutException: - output.write(('deeptime(): connection to host %s ' + \ + self.output.write(('deeptime(): connection to host %s ' + \ 'timed out for ip %s\n') % \ (url_parts.hostname, ip), 2) if f is None: - output.write('deeptime(): unable to ' + \ + self.output.write('deeptime(): unable to ' + \ 'connect to host %s\n' % \ (url_parts.hostname,), 2) return (None, True) @@ -387,11 +389,11 @@ class Deep(object): finally: signal.alarm(0) except EnvironmentError, e: - output.write(('deeptime(): close connection to host %s ' + \ + self.output.write(('deeptime(): close connection to host %s ' + \ 'failed for ip %s: %s\n') % \ (url_parts.hostname, ip, e), 2) except TimeoutException: - output.write(('deeptime(): close connection to host %s ' + \ + self.output.write(('deeptime(): close connection to host %s ' + \ 'timed out for ip %s\n') % \ (url_parts.hostname, ip), 2) @@ -413,20 +415,20 @@ class Deep(object): signal.alarm(0) except EnvironmentError, e: - output.write(('deeptime(): download from host %s ' + \ + self.output.write(('deeptime(): download from host %s ' + \ 'failed for ip %s: %s\n') % \ (url_parts.hostname, ip, e), 2) return (None, True) except TimeoutException: - output.write(('deeptime(): download from host %s ' + \ + self.output.write(('deeptime(): download from host %s ' + \ 'timed out for ip %s\n') % \ (url_parts.hostname, ip), 2) return (None, True) signal.signal(signal.SIGALRM, signal.SIG_DFL) - output.write('deeptime(): download completed.\n', 2) - output.write('deeptime(): %s seconds for host %s\n' % (delta, url), 2) + self.output.write('deeptime(): download completed.\n', 2) + self.output.write('deeptime(): %s seconds for host %s\n' % (delta, url), 2) return (delta, False) def _list_add(self, time_host, maxtime, host_dict, maxlen): @@ -438,7 +440,7 @@ class Deep(object): """ if len(host_dict) < maxlen: #still have room, and host is fast. add it. - output.write('_list_add(): added host %s. with a time of %s\n' % + self.output.write('_list_add(): added host %s. with a time of %s\n' % (time_host[1], time_host[0]), 2) host_dict.update(dict([time_host])) @@ -446,11 +448,11 @@ class Deep(object): times.sort() else: #We need to make room in the dict before we add. Kill the slowest. - output.write('_list_add(): Adding host %s with a time of %s\n' % + self.output.write('_list_add(): Adding host %s with a time of %s\n' % (time_host[1], time_host[0]), 2) times = host_dict.keys() times.sort() - output.write('_list_add(): removing %s\n' % host_dict[times[-1]], + self.output.write('_list_add(): removing %s\n' % host_dict[times[-1]], 2) del host_dict[times[-1]] host_dict.update(dict([time_host])) @@ -459,18 +461,18 @@ class Deep(object): times.sort() if len(host_dict) < maxlen: #check again to choose new timeout - output.write('_list_add(): host_dict is not full yet.' + self.output.write('_list_add(): host_dict is not full yet.' ' reusing timeout of %s sec.\n' % maxtime, 2) retval = maxtime else: - output.write('_list_add(): host_dict is full. Selecting the best' + self.output.write('_list_add(): host_dict is full. Selecting the best' ' timeout\n', 2) if times[-1] < maxtime: retval = times[-1] else: retval = maxtime - output.write('_list_add(): new max time is %s seconds,' + self.output.write('_list_add(): new max time is %s seconds,' ' and now len(host_dict)= %s\n' % (retval, len(host_dict)), 2) return retval, host_dict @@ -479,11 +481,12 @@ class Deep(object): class Interactive(object): """Handles interactive host selection.""" - def __init__(self, hosts, options): + def __init__(self, hosts, options, output): + self.output = output self.urls = [] self.interactive(hosts, options) - output.write('Interactive.interactive(): self.urls = %s\n' % self.urls, 2) + self.output.write('Interactive.interactive(): self.urls = %s\n' % self.urls, 2) if len(self.urls[0]) == 0: sys.exit(1) |