-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSpeedTester.py
More file actions
144 lines (120 loc) · 4.88 KB
/
SpeedTester.py
File metadata and controls
144 lines (120 loc) · 4.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
"""
Runs a speed test to test internet speed.
Results are written to a file called "speedresults.json".
This script is best used with a cronjob, windows schedule or included runner script.
pip install speedtest-cli
"""
__author__ = "Paul Pfeffer"
import json
import os
import re
import subprocess
import time
def live_communicate(process, logger):
"""Execute subprocess printing data when available."""
data_received = ""
while True:
line = process.stdout.readline()
if line != '':
logger.info(line.rstrip())
data_received += line.rstrip()
else:
break
return data_received
class SpeedTester(object):
"""Get the speed of Internet."""
def __init__(self, logger, results_file):
"""Define needed regex and main results dictionary.
@param logger
@param results_file
"""
super(SpeedTester, self).__init__()
self.ipv4_regex = r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
self.results = {}
self.logger = logger
self.results_file = results_file
if os.name == "nt":
self.speedtest_cmd = "speedtest.exe"
else:
# assume nix
self.speedtest_cmd = "speedtest-cli"
def __del__(self):
"""Alert that class is being torn down."""
self.logger.debug("Called __del__ method of SpeedTester")
def get_previous_results(self):
"""Add previous results from json."""
with open(self.results_file) as f:
try:
self.results = json.load(f)
except ValueError:
self.logger.critical("No json was loaded from speedresults.json")
def run_test(self):
"""Execute speed test process and save results."""
self.logger.info("Running Test..........")
speedtest_process = subprocess.Popen(
self.speedtest_cmd,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
speedtest_out = live_communicate(speedtest_process, logger=self.logger)
if os.name == "nt":
speedtest_process = subprocess.Popen(
["NETSH", "WLAN", "SHOW", "INTERFACE", "|", "findstr", "/r", "'^....SSID'"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
wlan_info_out, err = speedtest_process.communicate()
speedtest_out += wlan_info_out
self.logger.info("Running Test Complete.")
self.logger.info("Saving Results")
self.parse_and_save_results(speedtest_out)
self.logger.info("Saving Results Complete")
def parse_and_save_results(self, output):
"""
Parse results into the available keys.
@param output the raw output from running speedtest.exe
"""
from_regex = r"Testing from (.+) \((%s)" % self.ipv4_regex
from_addr = re.search(from_regex, output)
provider = from_addr.group(1)
ip_addr = from_addr.group(2)
ping_regex = r"Hosted by.+?(\d+?.\d+?\sms)"
ping_time = re.search(ping_regex, output).group(1)
download_regex = "Download: (.+?/s)"
download_speed = re.search(download_regex, output).group(1)
upload_regex = "Upload: (.+?/s)"
upload_speed = re.search(upload_regex, output).group(1)
try:
ssid_regex = r"SSID\s+: (.+\s)"
ssid_name = re.search(ssid_regex, output).group(1).strip()
except AttributeError:
self.logger.info("You have a wired connection")
ssid_name = "wired"
result = {
"Provider": provider,
"ip_address": ip_addr,
"ping": ping_time,
"download": download_speed,
"upload": upload_speed,
"ssid": ssid_name,
"all_info": output
}
self.results[time.strftime("%Y-%m-%d %H:%M:%S")] = result
def write_results_to_file(self, pretty=False):
"""
Write the gathered results to a text file.
@param pretty should be True if you want to read the result file yourself. (default=False)
"""
with open(self.results_file, 'w') as f:
if pretty:
f.write(json.dumps(self.results, f, sort_keys=True, indent=4, separators=(',', ': ')))
else:
f.write(json.dumps(self.results, f))
def main():
"""Example of how to use the class."""
import logging
logging.basicConfig(level=logging.DEBUG) # Create a logger
logger = logging.getLogger(__name__) # Any logger should do
tester = SpeedTester(logger, "speedresults.json") # Create instance of class
tester.get_previous_results() # Optionally load previous results
tester.run_test() # Run the tests
tester.write_results_to_file(pretty=True) # Save results
if __name__ == '__main__':
main()