Added static option for static server list
This commit is contained in:
parent
c58ad3367b
commit
67985db684
206
speedtest.py
206
speedtest.py
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import json
|
||||||
import csv
|
import csv
|
||||||
import sys
|
import sys
|
||||||
import math
|
import math
|
||||||
|
@ -1224,132 +1225,139 @@ class Speedtest(object):
|
||||||
|
|
||||||
return self.config
|
return self.config
|
||||||
|
|
||||||
def get_servers(self, servers=None, exclude=None):
|
def get_servers(self, servers=None, exclude=None, servers_json=None):
|
||||||
"""Retrieve a the list of speedtest.net servers, optionally filtered
|
"""Retrieve a the list of speedtest.net servers, optionally filtered
|
||||||
to servers matching those specified in the ``servers`` argument
|
to servers matching those specified in the ``servers`` argument
|
||||||
"""
|
"""
|
||||||
if servers is None:
|
|
||||||
servers = []
|
|
||||||
|
|
||||||
if exclude is None:
|
if servers_json is None:
|
||||||
exclude = []
|
if servers is None:
|
||||||
|
servers = []
|
||||||
|
|
||||||
self.servers.clear()
|
if exclude is None:
|
||||||
|
exclude = []
|
||||||
|
|
||||||
for server_list in (servers, exclude):
|
self.servers.clear()
|
||||||
for i, s in enumerate(server_list):
|
|
||||||
|
for server_list in (servers, exclude):
|
||||||
|
for i, s in enumerate(server_list):
|
||||||
|
try:
|
||||||
|
server_list[i] = int(s)
|
||||||
|
except ValueError:
|
||||||
|
raise InvalidServerIDType(
|
||||||
|
'%s is an invalid server type, must be int' % s
|
||||||
|
)
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
'://www.speedtest.net/speedtest-servers-static.php',
|
||||||
|
'http://c.speedtest.net/speedtest-servers-static.php',
|
||||||
|
'://www.speedtest.net/speedtest-servers.php',
|
||||||
|
'http://c.speedtest.net/speedtest-servers.php',
|
||||||
|
]
|
||||||
|
|
||||||
|
headers = {}
|
||||||
|
if gzip:
|
||||||
|
headers['Accept-Encoding'] = 'gzip'
|
||||||
|
|
||||||
|
errors = []
|
||||||
|
for url in urls:
|
||||||
try:
|
try:
|
||||||
server_list[i] = int(s)
|
request = build_request(
|
||||||
except ValueError:
|
'%s?threads=%s' % (url,
|
||||||
raise InvalidServerIDType(
|
self.config['threads']['download']),
|
||||||
'%s is an invalid server type, must be int' % s
|
headers=headers,
|
||||||
|
secure=self._secure
|
||||||
)
|
)
|
||||||
|
uh, e = catch_request(request, opener=self._opener)
|
||||||
|
if e:
|
||||||
|
errors.append('%s' % e)
|
||||||
|
raise ServersRetrievalError()
|
||||||
|
|
||||||
urls = [
|
stream = get_response_stream(uh)
|
||||||
'://www.speedtest.net/speedtest-servers-static.php',
|
|
||||||
'http://c.speedtest.net/speedtest-servers-static.php',
|
|
||||||
'://www.speedtest.net/speedtest-servers.php',
|
|
||||||
'http://c.speedtest.net/speedtest-servers.php',
|
|
||||||
]
|
|
||||||
|
|
||||||
headers = {}
|
serversxml_list = []
|
||||||
if gzip:
|
while 1:
|
||||||
headers['Accept-Encoding'] = 'gzip'
|
try:
|
||||||
|
serversxml_list.append(stream.read(1024))
|
||||||
|
except (OSError, EOFError):
|
||||||
|
raise ServersRetrievalError(get_exception())
|
||||||
|
if len(serversxml_list[-1]) == 0:
|
||||||
|
break
|
||||||
|
|
||||||
errors = []
|
stream.close()
|
||||||
for url in urls:
|
uh.close()
|
||||||
try:
|
|
||||||
request = build_request(
|
|
||||||
'%s?threads=%s' % (url,
|
|
||||||
self.config['threads']['download']),
|
|
||||||
headers=headers,
|
|
||||||
secure=self._secure
|
|
||||||
)
|
|
||||||
uh, e = catch_request(request, opener=self._opener)
|
|
||||||
if e:
|
|
||||||
errors.append('%s' % e)
|
|
||||||
raise ServersRetrievalError()
|
|
||||||
|
|
||||||
stream = get_response_stream(uh)
|
if int(uh.code) != 200:
|
||||||
|
raise ServersRetrievalError()
|
||||||
|
|
||||||
serversxml_list = []
|
serversxml = ''.encode().join(serversxml_list)
|
||||||
while 1:
|
|
||||||
try:
|
|
||||||
serversxml_list.append(stream.read(1024))
|
|
||||||
except (OSError, EOFError):
|
|
||||||
raise ServersRetrievalError(get_exception())
|
|
||||||
if len(serversxml_list[-1]) == 0:
|
|
||||||
break
|
|
||||||
|
|
||||||
stream.close()
|
printer('Servers XML:\n%s' % serversxml, debug=True)
|
||||||
uh.close()
|
|
||||||
|
|
||||||
if int(uh.code) != 200:
|
|
||||||
raise ServersRetrievalError()
|
|
||||||
|
|
||||||
serversxml = ''.encode().join(serversxml_list)
|
|
||||||
|
|
||||||
printer('Servers XML:\n%s' % serversxml, debug=True)
|
|
||||||
|
|
||||||
try:
|
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
root = ET.fromstring(serversxml)
|
try:
|
||||||
except ET.ParseError:
|
root = ET.fromstring(serversxml)
|
||||||
e = get_exception()
|
except ET.ParseError:
|
||||||
raise SpeedtestServersError(
|
e = get_exception()
|
||||||
'Malformed speedtest.net server list: %s' % e
|
raise SpeedtestServersError(
|
||||||
)
|
'Malformed speedtest.net server list: %s' % e
|
||||||
elements = etree_iter(root, 'server')
|
)
|
||||||
except AttributeError:
|
elements = etree_iter(root, 'server')
|
||||||
|
except AttributeError:
|
||||||
|
try:
|
||||||
|
root = DOM.parseString(serversxml)
|
||||||
|
except ExpatError:
|
||||||
|
e = get_exception()
|
||||||
|
raise SpeedtestServersError(
|
||||||
|
'Malformed speedtest.net server list: %s' % e
|
||||||
|
)
|
||||||
|
elements = root.getElementsByTagName('server')
|
||||||
|
except (SyntaxError, xml.parsers.expat.ExpatError):
|
||||||
|
raise ServersRetrievalError()
|
||||||
|
|
||||||
|
for server in elements:
|
||||||
try:
|
try:
|
||||||
root = DOM.parseString(serversxml)
|
attrib = server.attrib
|
||||||
except ExpatError:
|
except AttributeError:
|
||||||
e = get_exception()
|
attrib = dict(list(server.attributes.items()))
|
||||||
raise SpeedtestServersError(
|
|
||||||
'Malformed speedtest.net server list: %s' % e
|
|
||||||
)
|
|
||||||
elements = root.getElementsByTagName('server')
|
|
||||||
except (SyntaxError, xml.parsers.expat.ExpatError):
|
|
||||||
raise ServersRetrievalError()
|
|
||||||
|
|
||||||
for server in elements:
|
if servers and int(attrib.get('id')) not in servers:
|
||||||
try:
|
continue
|
||||||
attrib = server.attrib
|
|
||||||
except AttributeError:
|
|
||||||
attrib = dict(list(server.attributes.items()))
|
|
||||||
|
|
||||||
if servers and int(attrib.get('id')) not in servers:
|
if (int(attrib.get('id')) in self.config['ignore_servers']
|
||||||
continue
|
or int(attrib.get('id')) in exclude):
|
||||||
|
continue
|
||||||
|
|
||||||
if (int(attrib.get('id')) in self.config['ignore_servers']
|
try:
|
||||||
or int(attrib.get('id')) in exclude):
|
d = distance(self.lat_lon,
|
||||||
continue
|
(float(attrib.get('lat')),
|
||||||
|
float(attrib.get('lon'))))
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
|
||||||
try:
|
attrib['d'] = d
|
||||||
d = distance(self.lat_lon,
|
|
||||||
(float(attrib.get('lat')),
|
|
||||||
float(attrib.get('lon'))))
|
|
||||||
except Exception:
|
|
||||||
continue
|
|
||||||
|
|
||||||
attrib['d'] = d
|
try:
|
||||||
|
self.servers[d].append(attrib)
|
||||||
|
except KeyError:
|
||||||
|
self.servers[d] = [attrib]
|
||||||
|
|
||||||
try:
|
break
|
||||||
self.servers[d].append(attrib)
|
|
||||||
except KeyError:
|
|
||||||
self.servers[d] = [attrib]
|
|
||||||
|
|
||||||
break
|
except ServersRetrievalError:
|
||||||
|
continue
|
||||||
|
|
||||||
except ServersRetrievalError:
|
if (servers or exclude) and not self.servers:
|
||||||
continue
|
raise NoMatchedServers()
|
||||||
|
else:
|
||||||
if (servers or exclude) and not self.servers:
|
printer('Loading Servers from:\n%s' % servers_json, debug=True)
|
||||||
raise NoMatchedServers()
|
with open(servers_json) as json_file:
|
||||||
|
self.servers = json.load(json_file)
|
||||||
|
|
||||||
return self.servers
|
return self.servers
|
||||||
|
|
||||||
|
|
||||||
def set_mini_server(self, server):
|
def set_mini_server(self, server):
|
||||||
"""Instead of querying for a list of servers, set a link to a
|
"""Instead of querying for a list of servers, set a link to a
|
||||||
speedtest mini server
|
speedtest mini server
|
||||||
|
@ -1744,6 +1752,8 @@ def parse_args():
|
||||||
help='Suppress verbose output, only show basic '
|
help='Suppress verbose output, only show basic '
|
||||||
'information in JSON format. Speeds listed in '
|
'information in JSON format. Speeds listed in '
|
||||||
'bit/s and not affected by --bytes')
|
'bit/s and not affected by --bytes')
|
||||||
|
parser.add_argument('--load-servers-from-json', dest='servers_json', type=PARSER_TYPE_STR,
|
||||||
|
help='Serverlist for static testing in json Format')
|
||||||
parser.add_argument('--list', action='store_true',
|
parser.add_argument('--list', action='store_true',
|
||||||
help='Display a list of speedtest.net servers '
|
help='Display a list of speedtest.net servers '
|
||||||
'sorted by distance')
|
'sorted by distance')
|
||||||
|
@ -1903,7 +1913,7 @@ def shell():
|
||||||
if not args.mini:
|
if not args.mini:
|
||||||
printer('Retrieving speedtest.net server list...', quiet)
|
printer('Retrieving speedtest.net server list...', quiet)
|
||||||
try:
|
try:
|
||||||
speedtest.get_servers(servers=args.server, exclude=args.exclude)
|
speedtest.get_servers(servers=args.server, exclude=args.exclude, servers_json=args.servers_json)
|
||||||
except NoMatchedServers:
|
except NoMatchedServers:
|
||||||
raise SpeedtestCLIError(
|
raise SpeedtestCLIError(
|
||||||
'No matched servers: %s' %
|
'No matched servers: %s' %
|
||||||
|
|
Loading…
Reference in New Issue