#!/usr/bin/python -O
# Copyright 1999-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id: /var/cvsroot/gentoo-src/portage/bin/mirror.py,v 1.3 2004/10/10 10:07:20 carpaski Exp $

# Defines the number of threads carrying out the downloading.
maxsems=5

import os,sys,string
os.environ["PORTAGE_CALLER"]="mirror"
os.environ["FEATURES"]="mirror cvs"
sys.path = ["/usr/lib/portage/pym"]+sys.path

import portage
from threading import *
from output import red,green,blue,bold
from random import shuffle
from time import sleep


def cstrip(mystr,mychars):
	newstr = ""
	for x in mystr:
		if x not in mychars:
			newstr += x
	return newstr

class fetcher(Thread):
	def __init__(self, filename, urilist, dest, md5sum):
		self.filename = filename
		self.myurilist = urilist
		self.myuri = None
		self.mydest = dest
		self.destpath = self.mydest+"/"+self.filename
		self.md5sum = md5sum
		self.result = None
		Thread.__init__(self)
	
	def fetch(self):
		#print "Started",self.filename
		sys.stderr.write(".")
		sys.stderr.flush()
		portage.spawn("wget -q -P "+str(self.mydest)+" "+self.myuri, free=1)

	def finished(self):
		if os.path.exists(self.destpath) and self.md5sum:
			ok,reason = portage_checksum.verify_all(self.destpath, md5sum)
			if not ok:
				portage_util.writemsg("Failed verification:"+reason[0]+" (got "+reason[1]+", expected "+reason[2]+"\n")
				return 1
		return 0
	
	def delete(self):
		if os.path.exists(self.destpath):
			#print "Unlink:",self.destpath
			os.unlink(self.destpath)

	def run(self):
		if not self.finished():
			self.delete()

		while not self.finished():
			if self.myurilist:
				self.myuri = self.myurilist.pop(0)+"/"+self.filename
				self.fetch()
			else:
				self.delete()
				self.result = 0
				#print "Failed:",self.filename
				return 1

		#print "Finished:",self.filename
		self.result = 1
		return 0
	
	
uri_list = {}
fetchers = []
fetcher_sem = BoundedSemaphore(value=maxsems)
failures  = 0
successes = 0

def clean_fetchers():
	global fetcher_sem,fetchers,uri_list,failures,successes,maxsems
	while len(fetchers) == maxsems:
		for x in fetchers:
			if not x.isAlive():
				failures  += (x.result == 0)
				successes += (x.result == 1)
				if x.filename in uri_list.keys():
					del uri_list[x.filename]
				del fetchers[fetchers.index(x)]
				fetcher_sem.release()
		if len(fetchers) == maxsems:
			sleep(1)
		

def start_fetcher(fname, urilist, dest, md5sum):
	global fetcher_sem,fetchers,uri_list,failures,successes
	fetcher_sem.acquire()
	fetchers.append(fetcher(fname, urilist, dest, md5sum))
	fetchers[-1].start()


tpm     = portage.thirdpartymirrors
destdir = portage.settings["DISTDIR"][:]

hugelist = []
for mycp in portage.db["/"]["porttree"].dbapi.cp_all():
	hugelist += portage.db["/"]["porttree"].dbapi.cp_list(mycp)
shuffle(hugelist)

mycount = -1
for mycpv in hugelist:
	pv = string.split(mycpv, "/")[-1]

	clean_fetchers()

	mycount += 1
	if ((mycount % 20) == 0):
		sys.stdout.write("\nCompleted: %s\n" % mycount)
		sys.stdout.flush()
	newuri = portage.db["/"]["porttree"].dbapi.aux_get(mycpv,["SRC_URI"])[0]
	newuri = string.split(newuri)

	digestpath = portage.db["/"]["porttree"].dbapi.findname(mycpv)
	digestpath = os.path.dirname(digestpath)+"/files/digest-"+pv
	md5sums    = portage.digestParseFile(digestpath)
	
	for x in newuri:
		clean_fetchers()
		if not x:
			continue
		if (x in [")","(",":","||"]) or (x[-1] == "?"):
			# ignore it. :)
			continue
		x = cstrip(x,"()|?")
		if not x:
			continue
		mybn = os.path.basename(x)
		mydn = os.path.dirname(x)
		if mybn not in uri_list.keys():
			if (len(mybn) > len("mirror://")) and (mybn[:len("mirror://")] == "mirror://"):
				mysite = string.split(x[len("mirror://"):], "/")[0]
				shuffle(tpm[mysite])
				uri_list[mybn] = tpm[mysite][:]
			else:
				uri_list[mybn] = [os.path.dirname(x)]
			clean_fetchers()
			if (not md5sums) or (mybn not in md5sums.keys()):
				start_fetcher(mybn, uri_list[mybn], destdir, None)
			else:
				start_fetcher(mybn, uri_list[mybn], destdir, md5sums[mybn])
		else:
			break

sys.stderr.write("\n\nWaiting last set\n")
sys.stderr.flush()
while fetchers:
	if fetchers[0].isAlive():
		fetchers[0].join()
	clean_fetchers()

print
print
print "Successes:",successes
print "Failures: ",failures
