1# Copyright 2009 Google Inc. All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Little utility functions.""" 16 17__author__ = 'tstromberg@google.com (Thomas Stromberg)' 18 19import datetime 20import math 21import os.path 22import sys 23import tempfile 24 25 26def CalculateListAverage(values): 27 """Computes the arithmetic mean of a list of numbers.""" 28 if not values: 29 return 0 30 return sum(values) / float(len(values)) 31 32 33def DrawTextBar(value, max_value, max_width=53): 34 """Return a simple ASCII bar graph, making sure it fits within max_width. 35 36 Args: 37 value: integer or float representing the value of this bar. 38 max_value: integer or float representing the largest bar. 39 max_width: How many characters this graph can use (int) 40 41 Returns: 42 string 43 """ 44 45 hash_width = max_value / max_width 46 return int(math.ceil(value/hash_width)) * '#' 47 48 49def SecondsToMilliseconds(seconds): 50 return seconds * 1000 51 52 53def SplitSequence(seq, size): 54 """Split a list. 55 56 Args: 57 seq: sequence 58 size: int 59 60 Returns: 61 New list. 62 63 Recipe From http://code.activestate.com/recipes/425397/ (Modified to not return blank values) 64 """ 65 newseq = [] 66 splitsize = 1.0/size*len(seq) 67 for i in range(size): 68 newseq.append(seq[int(round(i*splitsize)):int(round((i+1)*splitsize))]) 69 70 return [x for x in newseq if x] 71 72 73def FindDataFile(filename): 74 """Find a datafile, searching various relative and OS paths.""" 75 filename = os.path.expanduser(filename) 76 if os.path.exists(filename): 77 return filename 78 79 # If it's not a relative path, we can't do anything useful. 80 if os.path.isabs(filename): 81 return filename 82 83 other_places = [os.getcwd(), 84 os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'Contents', 'Resources'), 85 os.path.join(os.getcwd(), 'namebench.app', 'Contents', 'Resources'), 86 os.path.join(os.getcwd(), '..'), 87 os.path.join(sys.prefix, 'namebench'), 88 '/usr/local/share/namebench', 89 '/usr/local/etc/namebench', 90 '/usr/local/namebench', 91 '/etc/namebench', 92 '/usr/share/namebench', 93 '/usr/namebench'] 94 for directory in reversed(sys.path): 95 other_places.append(directory) 96 other_places.append(os.path.join(directory, 'namebench')) 97 98 for place in other_places: 99 path = os.path.join(place, filename) 100 if os.path.exists(path): 101 return path 102 103 print 'I could not find "%s". Tried:' % filename 104 for path in other_places: 105 print ' %s' % path 106 return filename 107 108def GenerateOutputFilename(extension): 109 """Generate a decent default output filename for a given extensio.""" 110 111 # used for resolv.conf 112 if '.' in extension: 113 filename = extension 114 else: 115 output_base = 'namebench_%s' % datetime.datetime.strftime(datetime.datetime.now(), 116 '%Y-%m-%d %H%M') 117 output_base = output_base.replace(':', '').replace(' ', '_') 118 filename = '.'.join((output_base, extension)) 119 120 output_dir = tempfile.gettempdir() 121 return os.path.join(output_dir, filename) 122 123 124 125def GetLastExceptionString(): 126 """Get the last exception and return a good looking string for it.""" 127 (exc, error) = sys.exc_info()[0:2] 128 exc_msg = str(exc) 129 if '<class' in exc_msg: 130 exc_msg = exc_msg.split("'")[1] 131 132 exc_msg = exc_msg.replace('dns.exception.', '') 133 error = '%s %s' % (exc_msg, error) 134 # We need to remove the trailing space at some point. 135 return error.rstrip() 136