#!/usr/bin/env python

'''
Upgrade Sage from a Mirror - Draft

Retrieves official list of active and up-to-date mirrors.
Then selects one of the top 3 mirrors, where pinging
the host for index.html responses fastest.  

@author: harald schilly <harald.schilly@gmail.com>
@created: 2009-07-22
@copyright: Harald Schilly, 2009, Vienna, Austria
@license: GPL v2+
'''

import urllib
import re
import subprocess
import time
import threading
import random
import socket

# everything stalls since timetouts are not part of urllib!                                                                                
# http://viralcontentnetwork.blogspot.com/2007/08/handling-timeouts-with-urllib2-in.html                                                   
import socket                                                                                                                              
socket.setdefaulttimeout(20)   


mirrors = eval(urllib.urlopen('http://www.sagemath.org/mirror_list').read())
timings = []

re_host = re.compile(r'://([^/]*)/')

def pinger_urllib(host):
  """
  helper function timing the retrival of index.html's header 
  TODO: should there be a 1MB bogus file on each mirror?
  """
  t1 = time.time()
  try:
    opener = urllib.FancyURLopener({})
    u = opener.open(host + '/index.html')
    if u.getcode() is not 200:
      return None
    # u.read() to get the actual content
    return (time.time() - t1) * 1000.0
  except IOError:
    # socket timeout
    print '%-30s TIMEOUT' % (host)
    return None

def task(m):
  """
  the actual task of testing a mirror
  """
  host = re_host.search(m).group(1)
  delay = pinger_urllib(m)
  if delay is None:
    return
  global timings
  timings.append((delay, m))
  print '%-30s %5.0f [ms]' % (host, delay)

# parallelization
tasks = []
for m in mirrors:
  t = threading.Thread(target=task, args=(m,))
  t.start()
  tasks.append(t)

# synchronization point
for t in tasks:
  t.join(timeout=30)

# select a random one from the top 3 to be fair
top = sorted(timings)[0:min(len(timings), 3)]
random.shuffle(top)
selected = top[0][1]

# output
print 
print 'now run:'
print '$ sage -upgrade', selected + 'spkg'
