3 # rankmirrors : read a list of mirrors from a file and rank them by speed
5 # Original Idea copyright (c) 2006 R.G. <chesercat>
6 # Modified 2006 by Dan McGee <dan@archlinux.org>
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
23 import os
, sys
, datetime
, time
, socket
, urllib2
24 from optparse
import OptionParser
26 def createOptParser():
27 usage
= "usage: %prog [options] MIRRORFILE | URL"
28 description
= "Ranks pacman mirrors by their connection and opening " \
29 "speed. Pacman mirror files are located in /etc/pacman.d/. It " \
30 "can also rank one mirror if the URL is provided."
31 parser
= OptionParser(usage
= usage
, description
= description
)
32 parser
.add_option("-n", type = "int", dest
= "num", default
= 0,
33 help = "number of servers to output, 0 for all")
34 parser
.add_option("-t", "--times", action
= "store_true",
35 dest
= "times", default
= False,
36 help = "only output mirrors and their response times")
37 parser
.add_option("-u", "--url", action
= "store_true", dest
= "url",
38 default
= False, help = "test a specific url")
39 parser
.add_option("-v", "--verbose", action
= "store_true",
40 dest
= "verbose", default
= False,
41 help = "be verbose in ouptut")
48 except KeyboardInterrupt, ki
:
50 except socket
.timeout
, ioe
:
54 return time
.time() - before
56 def talkToServer(serverUrl
):
57 opener
= urllib2
.build_opener()
58 tmp
= opener
.open(serverUrl
).read()
60 def getFuncToTime(serverUrl
):
61 return lambda : talkToServer(serverUrl
)
63 def cmpPairBySecond(p1
, p2
):
70 def printResults(servers
, time
, verbose
, num
):
71 items
= servers
.items()
72 items
.sort(cmpPairBySecond
)
75 if numToShow
> itemsLen
or numToShow
== 0:
80 print ' Servers sorted by time (seconds):'
81 for i
in items
[0:numToShow
]:
82 if i
[1] == 'timeout' or i
[1] == 'unreachable':
85 print i
[0], ':', "%.2f" % i
[1]
87 for i
in items
[0:numToShow
]:
88 print 'Server =', i
[0]
90 if __name__
== "__main__":
91 parser
= createOptParser()
92 (options
, args
) = parser
.parse_args()
95 parser
.print_help(sys
.stderr
)
98 # allows connections to time out if they take too long
99 socket
.setdefaulttimeout(10)
103 print 'Testing', args
[0] + '...'
105 serverToTime
= timeCmd(getFuncToTime(args
[0]))
106 except KeyboardInterrupt, ki
:
108 if serverToTime
== 'timeout' or serverToTime
== 'unreachable':
109 print args
[0], ':', serverToTime
111 print args
[0], ':', "%.2f" % serverToTime
114 if not os
.path
.isfile(args
[0]):
115 print >>sys
.stderr
, 'rankmirrors: file', args
[0], 'does not exist.'
118 fl
= open(args
[0], 'r')
121 print 'Querying servers, this may take some time...'
123 print "# Server list generated by rankmirrors on",
124 print datetime
.date
.today()
125 for ln
in fl
.readlines():
126 splitted
= ln
.split('=')
127 if splitted
[0].strip() != 'Server':
128 if not options
.times
:
132 serverUrl
= splitted
[1].strip()
133 if serverUrl
[-1] == '\n':
134 serverUrl
= serverUrl
[0:-1]
135 if options
.verbose
and options
.times
:
136 print serverUrl
, '...',
137 elif options
.verbose
:
138 print '#', serverUrl
, '...',
143 serverToTime
[serverUrl
] = timeCmd(getFuncToTime(serverUrl
))
146 print "%.2f" % serverToTime
[serverUrl
]
148 print serverToTime
[serverUrl
]
151 printResults(serverToTime
, options
.times
, options
.verbose
,
155 printResults(serverToTime
, options
.times
, options
.verbose
, options
.num
)
157 # vim: set ts=4 sw=4 et: