[pacman-dev] [PATCH] replace rankmirrors by bash clone
matthewbruenig at gmail.com
matthewbruenig at gmail.com
Wed Aug 19 14:40:36 EDT 2009
woot!
On Aug 19, 2009 1:01pm, Xavier Chantry <shiningxc at gmail.com> wrote:
> This removes python optdepends in pacman package \o/
> This bash clone is a courtesy of
> Matthew Bruenig matthewbruenig at gmail.com>
> Signed-off-by: Xavier Chantry shiningxc at gmail.com>
> ---
> scripts/Makefile.am | 4 +-
> scripts/rankmirrors.py.in | 189
> -------------------------------------------
> scripts/rankmirrors.sh.in | 196
> +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 198 insertions(+), 191 deletions(-)
> delete mode 100644 scripts/rankmirrors.py.in
> create mode 100644 scripts/rankmirrors.sh.in
> diff --git a/scripts/Makefile.am b/scripts/Makefile.am
> index 5d65653..330acb9 100644
> --- a/scripts/Makefile.am
> +++ b/scripts/Makefile.am
> @@ -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
> diff --git a/scripts/rankmirrors.py.in b/scripts/rankmirrors.py.in
> deleted file mode 100644
> index 4b253b6..0000000
> --- a/scripts/rankmirrors.py.in
> +++ /dev/null
> @@ -1,189 +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 at archlinux.org>
> -# Copyright (c) 2002-2006 by Judd Vinet jvinet at 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 at archlinux.org>.\n" \
> - "Copyright (C) 2002-2006 Judd Vinet jvinet at 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]
> - 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')
> -
> - # 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:
> diff --git a/scripts/rankmirrors.sh.in b/scripts/rankmirrors.sh.in
> new file mode 100644
> index 0000000..e1878a0
> --- /dev/null
> +++ b/scripts/rankmirrors.sh.in
> @@ -0,0 +1,196 @@
> +#!/bin/bash
> +#
> +# rankmirrors - read a list of mirrors from a file and rank them by speed
> +# @configure_input@
> +#
> +# Copyright (c) 2009 Matthew Bruenig matthewbruenig at 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 at 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 (eg 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 (eg getturl http://foo.com/core/os/i686)
> +# if $repo is in the line, then assumes core
> +# returns a fetchurl (eg http://foo.com/core/os/i686/core.db.tar.gz)
> +getfetchurl() {
> + strippedurl="${1%/}"
> + replacedurl="${strippedurl//'$repo'/core}"
> + tmp1="${replacedurl%/*}"
> + tmp2="${tmp1%/*}"
> + reponame="${tmp2##*/}"
> + if [[ -z $reponame || $reponame = $replacedurl ]]; then
> + echo "fail"
> + else
> + fetchurl="${replacedurl}/$reponame at 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=( $(
> + STDIN=1
> + shift
> + else
> + snum=1
> + for ((i=1 ; i
> + 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=( $(
> + [[ $linearray ]] || err "File is empty."
> + shift
More information about the pacman-dev
mailing list