Skip to content

Commit

Permalink
Added Python argparser.
Browse files Browse the repository at this point in the history
Made it print most of the output to STDERR (so that CSV output could
later be printed to STDOUT).
Added some error catching.
  • Loading branch information
Janhouse committed Nov 10, 2012
1 parent 72739f7 commit ed592da
Showing 1 changed file with 80 additions and 42 deletions.
122 changes: 80 additions & 42 deletions tespeed.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Copyright 2012 Janis Jansons ([email protected])
#

import argparse
import urllib
import urllib2
import gzip
Expand Down Expand Up @@ -43,11 +44,11 @@ def read(self, n=10240):
if self.num==0:
percent = float(down) / (self.total)
percent = round(percent*100, 2)
sys.stdout.write("Uploaded %d of %d bytes (%0.2f%%) in %d threads\r" %
sys.stderr.write("Uploaded %d of %d bytes (%0.2f%%) in %d threads\r" %
(down, self.total, percent, self.th))

#if down >= self.total:
# sys.stdout.write('\n')
# sys.stderr.write('\n')
# self.d['done']=1

return next
Expand All @@ -58,21 +59,24 @@ def __len__(self):

class TeSpeed:

def __init__(self, server = "", numTop = 0):
def __init__(self, server = "", numTop = 0, store = False):

self.headers = {
'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'User-Agent' : 'Mozilla/5.0 (X11; Linux x86_64; rv:11.0) Gecko/20100101 Firefox/11.0',
'Accept-Language' : 'en-us,en;q=0.5',
'Connection' : 'keep-alive',
'Accept-Encoding' : 'gzip, deflate',
#'Referer' : 'http://c.speedtest.net/flash/speedtest.swf?v=301256',
'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'User-Agent' : 'Mozilla/5.0 (X11; Linux x86_64; rv:11.0) Gecko/20100101 Firefox/11.0',
'Accept-Language' : 'en-us,en;q=0.5',
'Connection' : 'keep-alive',
'Accept-Encoding' : 'gzip, deflate',
#'Referer' : 'http://c.speedtest.net/flash/speedtest.swf?v=301256',
}

self.server=server
print "Getting ready"
#print >> sys.stderr, "Getting ready"
self.latencycount=10
self.bestServers=5
self.store=store
if store:
print >> sys.stderr, "Printing CSV formated results to STDOUT."
self.numTop=int(numTop)
self.downList=['350x350', '500x500', '750x750', '1000x1000',
'1500x1500', '2000x2000', '2000x2000', '2500x2500', '3000x3000',
Expand Down Expand Up @@ -125,21 +129,21 @@ def Closest(self, center, points, num=5):

def TestLatency(self, servers):
# Finding the server with lowest latency
print "Testing latency..."
print >> sys.stderr, "Testing latency..."
shortest = -1.0
po = []
for server in servers:
now=self.TestSingleLatency(server['url']+"latency.txt?x=" + str( time.time() ))*1000
now=now/2 # Evil hack or just pure stupidity? Nobody knows...
if now == -1 or now == 0:
continue
print "%0.0f ms latency for %s (%s, %s, %s) [%0.2f km]" % (now, server['url'], server['sponsor'], server['name'], server['country'], server['distance'])
print >> sys.stderr, "%0.0f ms latency for %s (%s, %s, %s) [%0.2f km]" % (now, server['url'], server['sponsor'], server['name'], server['country'], server['distance'])

if (now < shortest and shortest > 0) or shortest < 0:
shortest = now
po = server

print "Best server with average latency %0.0fms - %s, %s, %s" % (shortest, po['sponsor'], po['name'], po['country'])
print >> sys.stderr, "Best server with average latency %0.0fms - %s, %s, %s" % (shortest, po['sponsor'], po['name'], po['country'])

return po

Expand Down Expand Up @@ -196,15 +200,15 @@ def ChunkReport(self, bytes_so_far, chunk_size, total_size, num, th, d, w):
percent = float(down) / (total_size*th)
percent = round(percent*100, 2)

sys.stdout.write("Downloaded %d of %d bytes (%0.2f%%) in %d threads\r" %
sys.stderr.write("Downloaded %d of %d bytes (%0.2f%%) in %d threads\r" %
(down, total_size*th, percent, th))

#if down >= total_size*th:
# sys.stdout.write('\n')
# sys.stderr.write('\n')


def ChunkRead(self, response, num, th, d, w=0, chunk_size=10240, report_hook=None):
#print "Thread num ", th, num, d, " starting to report\n"
#print >> sys.stderr, "Thread num ", th, num, d, " starting to report\n"
if(w==1):
return [0,0,0]

Expand All @@ -216,7 +220,7 @@ def ChunkRead(self, response, num, th, d, w=0, chunk_size=10240, report_hook=Non
while 1:
chunk=0
if start == 0:
#print "Started receiving data"
#print >> sys.stderr, "Started receiving data"
chunk = response.read(1)
start = time.time()

Expand All @@ -235,8 +239,22 @@ def ChunkRead(self, response, num, th, d, w=0, chunk_size=10240, report_hook=Non
def AsyncGet(self, conn, uri, num, th, d):

request=self.GetRequest(uri)
response = urllib2.urlopen(request, timeout = 30);
size, start, end=self.ChunkRead(response, num, th, d, report_hook=self.ChunkReport)

start=0
end=0
size=0

try:
response = urllib2.urlopen(request, timeout = 30);
size, start, end=self.ChunkRead(response, num, th, d, report_hook=self.ChunkReport)
#except urllib2.URLError, e:
# print >> sys.stderr, "Failed downloading."
except:
sys.stderr.write(' \r')
print >> sys.stderr, "Failed downloading."
conn.send([0, 0, False])
conn.close()
return

conn.send([size, start, end])
conn.close()
Expand All @@ -253,16 +271,22 @@ def AsyncPost(self, conn, uri, num, th, d):
try:
response = urllib2.urlopen(request, timeout = 30);
size, start, end=self.ChunkRead(response, num, th, d, 1, report_hook=self.ChunkReport)
except urllib2.URLError, e:
print "Failed uploading..."
#except urllib2.URLError, e:
# print >> sys.stderr, "Failed uploading."
except:
sys.stderr.write(' \r')
print >> sys.stderr, "Failed uploading."
conn.send([0, 0, False])
conn.close()
return

conn.send([postlen, start, end])
conn.close()


def LoadConfig(self):
# Load the configuration file
print "Loading speedtest configuration..."
print >> sys.stderr, "Loading speedtest configuration..."
uri = "http://speedtest.net/speedtest-config.php?x=" + str( time.time() )
request=self.GetRequest(uri)
response = urllib2.urlopen(request)
Expand All @@ -276,14 +300,14 @@ def LoadConfig(self):
lat=float(config.find("client").attrib['lat'])
lon=float(config.find("client").attrib['lon'])

print "IP: %s; Lat: %f; Lon: %f; ISP: %s" % (ip, lat, lon, isp)
print >> sys.stderr, "IP: %s; Lat: %f; Lon: %f; ISP: %s" % (ip, lat, lon, isp)

return { 'ip': ip, 'lat': lat, 'lon': lon, 'isp': isp }


def LoadServers(self):
# Load server list
print "Loading server list..."
print >> sys.stderr, "Loading server list..."
uri = "http://speedtest.net/speedtest-servers.php?x=" + str( time.time() )
request=self.GetRequest(uri)
response = urllib2.urlopen(request);
Expand Down Expand Up @@ -316,10 +340,10 @@ def DecompressResponse(sefl, response):


def FindBestServer(self):
print "Looking for closest and best server..."
print >> sys.stderr, "Looking for closest and best server..."
best=self.TestLatency(self.Closest([self.config['lat'], self.config['lon']], self.server_list, self.bestServers))
self.server=best['url']
print "\033[94mBest server: ", self.server, "\033[0m"
print >> sys.stderr, "\033[94mBest server: ", self.server, "\033[0m"


def AsyncRequest(self, url, num, upload=0):
Expand All @@ -343,7 +367,7 @@ def AsyncRequest(self, url, num, upload=0):

end=time.time()

sys.stdout.write(' \r')
sys.stderr.write(' \r')

sizes=0
#tspeed=0
Expand Down Expand Up @@ -376,37 +400,40 @@ def TestUpload(self):
data=""
for i in range(0, len(self.upSizes)):
if len(data) == 0 or self.upSizes[i] != self.upSizes[i-1]:
#print "Generating new string to upload. Length: ", self.upSizes[i]
#print >> sys.stderr, "Generating new string to upload. Length: ", self.upSizes[i]
data=''.join("1" for x in xrange(self.upSizes[i]))
self.postData=urllib.urlencode({'upload6': data })

sizes, took=self.AsyncRequest(url, (i<4 and 1 or (i<6 and 2 or (i<6 and 4 or 8))), 1)
print "Upload size: %0.2f MiB; Uploaded in %0.2f s" % (float(sizes)/1024/1024, took)
print "\033[92mUpload speed: %0.2f MiB/s\033[0m" % ((float(sizes)/1024/1024)/took)
if sizes==0:
continue
print >> sys.stderr, "Upload size: %0.2f MiB; Uploaded in %0.2f s" % (float(sizes)/1024/1024, took)
print >> sys.stderr, "\033[92mUpload speed: %0.2f MiB/s\033[0m" % ((float(sizes)/1024/1024)/took)

if took>5:
break

#print "Upload size: %0.2f MiB; Uploaded in %0.2f s" % (float(sizes)/1024/1024, took)
#print "Upload speed: %0.2f MiB/s" % ((float(sizes)/1024/1024)/took)
#print >> sys.stderr, "Upload size: %0.2f MiB; Uploaded in %0.2f s" % (float(sizes)/1024/1024, took)
#print >> sys.stderr, "Upload speed: %0.2f MiB/s" % ((float(sizes)/1024/1024)/took)


def TestDownload(self):
# Testing download speed
sizes, took=[0,0]
for i in range(0, len(self.downList)):
url=self.server+"random"+self.downList[i]+".jpg?x=" + str( time.time() ) + "&y=3"
#print url
#print >> sys.stderr, url
sizes, took=self.AsyncRequest(url, (i<1 and 2 or (i<6 and 4 or (i<10 and 6 or 8))) )

print("Download size: %0.2f MiB; Downloaded in %0.2f s") % (float(sizes)/1024/1024, took)
print("\033[91mDownload speed: %0.2f MiB/s\033[0m") % ((float(sizes)/1024/1024)/took)
if sizes==0:
continue
print >> sys.stderr, ("Download size: %0.2f MiB; Downloaded in %0.2f s") % (float(sizes)/1024/1024, took)
print >> sys.stderr, ("\033[91mDownload speed: %0.2f MiB/s\033[0m") % ((float(sizes)/1024/1024)/took)

if took>5:
break

#print "Download size: %0.2f MiB; Downloaded in %0.2f s" % (float(sizes)/1024/1024, took)
#print "Download speed: %0.2f MiB/s" % ((float(sizes)/1024/1024)/took)
#print >> sys.stderr, "Download size: %0.2f MiB; Downloaded in %0.2f s" % (float(sizes)/1024/1024, took)
#print >> sys.stderr, "Download speed: %0.2f MiB/s" % ((float(sizes)/1024/1024)/took)

def TestSpeed(self):

Expand All @@ -431,12 +458,23 @@ def ListServers(self, num=0):
for i in range(0, len(allSorted)):
print "%s. %s (%s, %s, %s) [%0.2f km]" % (i+1, allSorted[i]['url'], allSorted[i]['sponsor'], allSorted[i]['name'], allSorted[i]['country'], allSorted[i]['distance'])

def main(argv):
def main(args):
if args.listservers!=True and args.server=='' and args.store!=True:
print >> sys.stderr, "Getting ready. Use parameter -h or --help to see available features."
else:
print >> sys.stderr, "Getting ready"
try:
t=TeSpeed(len(argv)>1 and argv[1] or '', len(argv)>2 and argv[2])
t=TeSpeed(args.listservers and 'list-servers' or args.server, args.listservers, args.store and True or False)
except (KeyboardInterrupt, SystemExit):
print "\nTesting stopped."
print >> sys.stderr, "\nTesting stopped."
#raise

if __name__ == '__main__':
main(sys.argv)
parser = argparse.ArgumentParser(description='TeSpeed, CLI SpeedTest.net')

parser.add_argument('server', nargs='?', type=str, default='', help='Use the specified server for testing (skip checking for location and closest server).')
parser.add_argument('-ls', '--list-servers', dest='listservers', nargs='?', default=0, const=10, help='List the servers sorted by distance, nearest first. Optionally specify number of servers to show.')
parser.add_argument('-w', '--csv', dest='store', action='store_const', const=True, help='Print CSV formated output to STDOUT')

args = parser.parse_args()
main(args)

0 comments on commit ed592da

Please sign in to comment.