replace rankmirrors by bash clone

This removes python optdepends in pacman package

This bash clone is a courtesy of
Matthew Bruenig <matthewbruenig@gmail.com>

Signed-off-by: Xavier Chantry <shiningxc@gmail.com>
This commit is contained in:
Xavier Chantry 2009-08-09 20:27:40 +02:00 committed by Dan McGee
parent 302310c5aa
commit 35bbc96b99
3 changed files with 204 additions and 193 deletions

View File

@ -16,7 +16,7 @@ EXTRA_DIST = \
makepkg.sh.in \
pacman-optimize.sh.in \
pkgdelta.sh.in \
rankmirrors.py.in \
rankmirrors.sh.in \
repo-add.sh.in
# Files that should be removed, but which Automake does not know.
@ -62,7 +62,7 @@ $(OURSCRIPTS): Makefile
makepkg: $(srcdir)/makepkg.sh.in
pacman-optimize: $(srcdir)/pacman-optimize.sh.in
pkgdelta: $(srcdir)/pkgdelta.sh.in
rankmirrors: $(srcdir)/rankmirrors.py.in
rankmirrors: $(srcdir)/rankmirrors.sh.in
repo-add: $(srcdir)/repo-add.sh.in
repo-remove: $(srcdir)/repo-add.sh.in
rm -f repo-remove

View File

@ -1,191 +0,0 @@
#! /usr/bin/python
#
# rankmirrors - read a list of mirrors from a file and rank them by speed
# @configure_input@
#
# Copyright (c) 2006-2009 Pacman Development Team <pacman-dev@archlinux.org>
# Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import os, sys, datetime, time, socket, urllib2
from optparse import OptionParser
from string import Template
def createOptParser():
usage = "usage: %prog [options] MIRRORFILE | URL"
version = "%prog (pacman) @PACKAGE_VERSION@\n" \
"Copyright (c) 2006-2009 Pacman Development Team <pacman-dev@archlinux.org>.\n" \
"Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n" \
"This is free software; see the source for copying conditions.\n" \
"There is NO WARRANTY, to the extent permitted by law."
description = "Ranks pacman mirrors by their connection and opening " \
"speed. Pacman mirror files are located in /etc/pacman.d/. It " \
"can also rank one mirror if the URL is provided."
parser = OptionParser(usage = usage, version = version,
description = description)
parser.add_option("-n", type = "int", dest = "num", default = 0,
help = "number of servers to output, 0 for all")
parser.add_option("-t", "--times", action = "store_true",
dest = "times", default = False,
help = "only output mirrors and their response times")
parser.add_option("-u", "--url", action = "store_true", dest = "url",
default = False, help = "test a specific url")
parser.add_option("-v", "--verbose", action = "store_true",
dest = "verbose", default = False,
help = "be verbose in ouptut")
# The following two options should be automatic
#parser.add_option("-h", "--help", action = "help")
#parser.add_option("-V", "--version", action = "version")
return parser
def timeCmd(cmd):
before = time.time()
try:
cmd()
except KeyboardInterrupt, ki:
raise ki
except socket.timeout, ioe:
return 'timeout'
except Exception, e:
return 'unreachable'
return time.time() - before
def talkToServer(serverUrl):
opener = urllib2.build_opener()
# retrieve first 50,000 bytes only
tmp = opener.open(serverUrl).read(50000)
def getFuncToTime(serverUrl):
return lambda : talkToServer(serverUrl)
def cmpPairBySecond(p1, p2):
if p1[1] == p2[1]:
return 0
if p1[1] < p2[1]:
return -1
return 1
def printResults(servers, time, verbose, num):
items = servers.items()
items.sort(cmpPairBySecond)
itemsLen = len(items)
numToShow = num
if numToShow > itemsLen or numToShow == 0:
numToShow = itemsLen
if itemsLen > 0:
if time:
print
print ' Servers sorted by time (seconds):'
for i in items[0:numToShow]:
if i[1] == 'timeout' or i[1] == 'unreachable':
print i[0], ':', i[1]
else:
print i[0], ':', "%.2f" % i[1]
else:
for i in items[0:numToShow]:
print 'Server =', i[0]
if __name__ == "__main__":
parser = createOptParser()
(options, args) = parser.parse_args()
if len(args) != 1:
parser.print_help(sys.stderr)
sys.exit(0)
# allows connections to time out if they take too long
socket.setdefaulttimeout(10)
if options.url:
if options.verbose:
print 'Testing', args[0] + '...'
try:
serverToTime = timeCmd(getFuncToTime(args[0]))
except KeyboardInterrupt, ki:
sys.exit(1)
if serverToTime == 'timeout' or serverToTime == 'unreachable':
print args[0], ':', serverToTime
else:
print args[0], ':', "%.2f" % serverToTime
sys.exit(0)
if not os.path.isfile(args[0]) and args[0] != "-":
print >>sys.stderr, 'rankmirrors: file', args[0], 'does not exist.'
sys.exit(1)
if args[0] == "-":
fl = sys.stdin
else:
fl = open(args[0], 'r')
serverToTime = {}
if options.times:
print 'Querying servers, this may take some time...'
else:
print "# Server list generated by rankmirrors on",
print datetime.date.today()
for ln in fl.readlines():
splitted = ln.split('=')
if splitted[0].strip() != 'Server':
if not options.times:
print ln,
continue
serverUrl = splitted[1].strip()
if serverUrl[-1] == '\n':
serverUrl = serverUrl[0:-1]
if options.verbose and options.times:
print serverUrl, '...',
elif options.verbose:
print '#', serverUrl, '...',
elif options.times:
print ' * ',
sys.stdout.flush()
# if the $repo var is used in the url, replace it by core
tempUrl = Template(serverUrl).safe_substitute(repo='core')
# if the $arch var is used in the url, replace it by i686
tempUrl = Template(tempUrl).safe_substitute(arch='i686')
# add @DBEXT@ to server name. the repo name is parsed
# from the mirror url; it is the third (or fourth) dir
# from the end, where the url is http://foo/bar/REPO/os/arch
try:
splitted2 = tempUrl.split('/')
if tempUrl[-1] != '/':
repoName = splitted2[-3]
dbFileName = '/' + repoName + '@DBEXT@'
else:
repoName = splitted2[-4]
dbFileName = repoName + '@DBEXT@'
except:
dbFileName = ''
try:
serverToTime[serverUrl] = timeCmd(getFuncToTime(tempUrl + dbFileName))
if options.verbose:
try:
print "%.2f" % serverToTime[serverUrl]
except:
print serverToTime[serverUrl]
except:
print
printResults(serverToTime, options.times, options.verbose,
options.num)
sys.exit(0)
printResults(serverToTime, options.times, options.verbose, options.num)
# vim: set ts=4 sw=4 et:

202
scripts/rankmirrors.sh.in Normal file
View File

@ -0,0 +1,202 @@
#!/bin/bash
#
# rankmirrors - read a list of mirrors from a file and rank them by speed
# @configure_input@
#
# Copyright (c) 2009 Matthew Bruenig <matthewbruenig@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# traps interrupt key to spit out pre-interrupt info
trap finaloutput INT
usage() {
echo "Usage: rankmirrors [options] MIRRORFILE | URL"
echo
echo "Ranks pacman mirrors by their connection and opening speed. Pacman mirror"
echo "files are located in /etc/pacman.d/. It can also rank one mirror if the URL is"
echo "provided."
echo
echo "Options:"
echo " --version show program's version number and exit"
echo " -h, --help show this help message and exit"
echo " -n NUM number of servers to output, 0 for all"
echo " -t, --times only output mirrors and their response times"
echo " -u, --url test a specific url"
echo " -v, --verbose be verbose in ouptut"
exit 0
}
version() {
echo "rankmirrors (pacman) @PACKAGE_VERSION@"
echo "Copyright (c) 2009 Matthew Bruenig <matthewbruenig@gmail.com>."
echo
echo "This is free software; see the source for copying conditions."
echo "There is NO WARRANTY, to the extent permitted by law."
exit 0
}
err() {
echo "$1"
exit 1
}
# gettime fetchurl (e.g gettime http://foo.com/core/os/i686/core.db.tar.gz)
# returns the fetching time, or timeout, or unreachable
gettime() {
IFS=' ' output=( $(curl -s -m 10 -w "%{time_total} %{http_code}" "$1" -o/dev/null) )
[[ $? = 28 ]] && echo timeout && return
[[ ${output[1]} -ge 400 || ${output[1]} -eq 0 ]] && echo unreachable && return
echo "${output[0]}"
}
# getfetchurl serverurl (e.g. getturl http://foo.com/core/os/i686)
# if $repo is in the line, then assumes core
# if $arch is in the line, then assumes $(uname -m)
# returns a fetchurl (e.g. http://foo.com/core/os/i686/core.db.tar.gz)
ARCH="$(uname -m)"
getfetchurl() {
local strippedurl="${1%/}"
local replacedurl="${strippedurl//'$repo'/core}"
replacedurl="${replacedurl//'$arch'/$ARCH}"
local tmp="${replacedurl%/*}"
tmp="${tmp%/*}"
local reponame="${tmp##*/}"
if [[ -z $reponame || $reponame = $replacedurl ]]; then
echo "fail"
else
local fetchurl="${replacedurl}/$reponame@DBEXT@"
echo "$fetchurl"
fi
}
# This exists to remove the need for a separate interrupt function
finaloutput() {
IFS=$'\n' sortedarray=( $(LC_COLLATE=C printf "%s\n" "${timesarray[@]}" | sort) )
# Final output for mirrorfile
numiterator="0"
if [[ $TIMESONLY ]]; then
echo
echo " Servers sorted by time (seconds):"
for line in "${sortedarray[@]}"; do
echo "${line#* } : ${line% *}"
((numiterator++))
[[ $NUM -ne 0 && $numiterator -ge $NUM ]] && break
done
else
for line in "${sortedarray[@]}"; do
echo "Server = ${line#* }"
((numiterator++))
[[ $NUM -ne 0 && $numiterator -ge $NUM ]] && break
done
fi
exit 0
}
# Argument parsing
[[ $1 ]] || usage
while [[ $1 ]]; do
if [[ "${1:0:2}" = -- ]]; then
case "${1:2}" in
help) usage ;;
version) version ;;
times) TIMESONLY=1 ; shift ;;
verbose) VERBOSE=1 ; shift ;;
url) CHECKURL=1; [[ $2 ]] || err "Must specify url."; URL="$2"; shift 2;;
*) err "\`$1' is an invalid argument."
esac
elif [[ ${1:0:1} = - ]]; then
if [[ ! ${1:1:1} ]]; then
[[ -t 0 ]] && err "Stdin is empty."
IFS=$'\n' linearray=( $(</dev/stdin) )
STDIN=1
shift
else
snum=1
for ((i=1 ; i<${#1}; i++)); do
case ${1:$i:1} in
h) usage ;;
t) TIMESONLY=1 ;;
v) VERBOSE=1 ;;
u) CHECKURL=1; [[ $2 ]] || err "Must specify url."; URL="$2"; snum=2;;
n) [[ $2 ]] || err "Must specify number." ; NUM="$2" ; snum=2;;
*) err "\`-$1' is an invald argument." ;;
esac
done
shift $snum
fi
elif [[ -f "$1" ]]; then
FILE="1"
IFS=$'\n' linearray=( $(<$1) )
[[ $linearray ]] || err "File is empty."
shift
else
err "\`$1' does not exist."
fi
done
# Some sanity checks
[[ $NUM ]] || NUM=0
[[ $FILE && $CHECKURL ]] && err "Cannot specify a url and mirrorfile."
[[ $FILE || $CHECKURL || $STDIN ]] || err "Must specify url, mirrorfile, or stdin."
# Single url handling
if [[ $CHECKURL ]]; then
url="$(getfetchurl "$URL")"
[[ $url = fail ]] && err "url \`$URL' is malformed."
[[ $VERBOSE ]] && echo "Testing $url..."
time=$(gettime "$url")
echo "$URL : $time"
exit 0
fi
# Get url results from mirrorfile, fill up the array, and so on
if [[ $TIMESONLY ]]; then
echo "Querying servers, this may take some time..."
elif [[ $FILE ]]; then
echo "# Server list generated by rankmirrors on $(date +%Y-%m-%d)"
fi
timesarray=()
for line in "${linearray[@]}"; do
if [[ $line =~ ^# ]]; then
[[ $TIMESONLY ]] || echo $line
elif [[ $line =~ ^Server ]]; then
# Getting values and times and such
server="${line#*= }"
url="$(getfetchurl "$server")"
[[ $url = fail ]] && err "url \`$URL' is malformed."
time=$(gettime "$url")
timesarray+=("$time $server")
# Output
if [[ $VERBOSE && $TIMESONLY ]]; then
echo "$server ... $time"
elif [[ $VERBOSE ]]; then
echo "# $server ... $time"
elif [[ $TIMESONLY ]]; then
echo -n " *"
fi
fi
done
finaloutput
# vim: set ts=2 sw=2 noet: