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:
parent
302310c5aa
commit
35bbc96b99
|
@ -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
|
||||
|
|
|
@ -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:
|
|
@ -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:
|
Loading…
Reference in New Issue