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