From 0f785dd2156351179983e43f3da099c3da607ffd Mon Sep 17 00:00:00 2001 From: kuzh Date: Tue, 2 Jan 2024 18:54:42 +0100 Subject: [PATCH] Added debug options, possibility to save as csv files. --- .vs/ProjectSettings.json | 3 + .vs/PythonSettings.json | 3 + .vs/VSWorkspaceState.json | 6 + .vs/slnx.sqlite | Bin 0 -> 90112 bytes ...52ea1fff-b95a-4a8a-b802-2ddc4ac591f9.vsidx | Bin 0 -> 88495 bytes .vs/speedtest-cli/v17/.wsuo | Bin 0 -> 29696 bytes .vscode/launch.json | 32 ++++++ output.csv | 2 + speedtest.py | 6 + tmp/speedtest.log | 1 + utilities.py | 103 ++++++++++++++++++ 11 files changed, 156 insertions(+) create mode 100644 .vs/ProjectSettings.json create mode 100644 .vs/PythonSettings.json create mode 100644 .vs/VSWorkspaceState.json create mode 100644 .vs/slnx.sqlite create mode 100644 .vs/speedtest-cli/FileContentIndex/52ea1fff-b95a-4a8a-b802-2ddc4ac591f9.vsidx create mode 100644 .vs/speedtest-cli/v17/.wsuo create mode 100644 .vscode/launch.json create mode 100644 output.csv create mode 100644 tmp/speedtest.log create mode 100644 utilities.py diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json new file mode 100644 index 0000000..f8b4888 --- /dev/null +++ b/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": null +} \ No newline at end of file diff --git a/.vs/PythonSettings.json b/.vs/PythonSettings.json new file mode 100644 index 0000000..40738ec --- /dev/null +++ b/.vs/PythonSettings.json @@ -0,0 +1,3 @@ +{ + "Interpreter": "Global|PythonCore|3.11" +} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..6b61141 --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,6 @@ +{ + "ExpandedNodes": [ + "" + ], + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..20c232f1bc6efd85ebd663e372b466aacecaca09 GIT binary patch literal 90112 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 literal 0 HcmV?d00001 diff --git a/.vs/speedtest-cli/FileContentIndex/52ea1fff-b95a-4a8a-b802-2ddc4ac591f9.vsidx b/.vs/speedtest-cli/FileContentIndex/52ea1fff-b95a-4a8a-b802-2ddc4ac591f9.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..7ea946785112dfd97a3e69991630d1b0ecf93b8f GIT binary patch literal 88495 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 literal 0 HcmV?d00001 diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..a15689b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,32 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: downloade single", + "type": "python", + "request": "launch", + "program": "${workspaceFolder}/speedtest.py", + "console": "integratedTerminal", + "args": [ + "--csv", + "--json" + ], + // "linux": { + // "MIMode": "gdb", + // "miDebuggerPath": "/usr/bin/gdb" + // }, + // "osx": { + // "MIMode": "lldb" + // }, + // "windows": { + // "MIMode": "gdb", + // "miDebuggerPath": "C:\\MinGw\\bin\\gdb.exe" + // } + // "cwd": "${workspaceFolder}", + "justMyCode": false + } + ] +} \ No newline at end of file diff --git a/output.csv b/output.csv new file mode 100644 index 0000000..ea7b55c --- /dev/null +++ b/output.csv @@ -0,0 +1,2 @@ +download,upload,ping,server_url,server_lat,server_lon,server_name,server_country,server_cc,server_sponsor,server_id,server_host,server_d,server_latency,timestamp,bytes_sent,bytes_received,share,client_ip,client_lat,client_lon,client_isp,client_isprating,client_rating,client_ispdlavg,client_ispulavg,client_loggedin,client_country +0,0,6.93,http://ookla-osl.net.avur.no:8080/speedtest/upload.php,59.9494,10.7564,Oslo,Norway,NO,AVUR AS,18967,ookla-osl.net.avur.no:8080,5.7463776547060155,6.93,2024-01-01T21:26:53.963606Z,0,0,,84.215.59.36,59.955,10.859,Telia Norge AS,3.7,0,0,0,0,NO diff --git a/speedtest.py b/speedtest.py index 186b529..ff7207a 100755 --- a/speedtest.py +++ b/speedtest.py @@ -28,6 +28,8 @@ import sys import threading import timeit import xml.parsers.expat +import utilities + try: import gzip @@ -1830,6 +1832,7 @@ def printer(string, quiet=False, debug=False, error=False, **kwargs): if not quiet: print_(out, **kwargs) + # return str(out) def shell(): @@ -1940,6 +1943,9 @@ def shell(): speedtest.get_best_server(speedtest.set_mini_server(args.mini)) results = speedtest.results + # print(dict(str(results))) + # os.makedirs('tmp', exist_ok=True) + utilities.write_to_csv(str(results)) printer('Hosted by %(sponsor)s (%(name)s) [%(d)0.2f km]: ' '%(latency)s ms' % results.server, quiet) diff --git a/tmp/speedtest.log b/tmp/speedtest.log new file mode 100644 index 0000000..93c2de5 --- /dev/null +++ b/tmp/speedtest.log @@ -0,0 +1 @@ +{'download': 0, 'upload': 0, 'ping': 9.319, 'server': {'url': 'http://speedtest.nextgentel.no:8080/speedtest/upload.php', 'lat': '59.9494', 'lon': '10.7564', 'name': 'Oslo', 'country': 'Norway', 'cc': 'NO', 'sponsor': 'NextGenTel AS', 'id': '8018', 'host': 'speedtest.nextgentel.no:8080', 'd': 5.7463776547060155, 'latency': 9.319}, 'timestamp': '2024-01-01T20:06:56.839888Z', 'bytes_sent': 0, 'bytes_received': 0, 'share': None, 'client': {'ip': '84.215.59.36', 'lat': '59.955', 'lon': '10.859', 'isp': 'Telia Norge AS', 'isprating': '3.7', 'rating': '0', 'ispdlavg': '0', 'ispulavg': '0', 'loggedin': '0', 'country': 'NO'}} diff --git a/utilities.py b/utilities.py new file mode 100644 index 0000000..37ca76b --- /dev/null +++ b/utilities.py @@ -0,0 +1,103 @@ +import logging +import os +import shutil +import time +import csv +import json + + +def remove_directory(directory_path, n=100): + directory_path = str(directory_path) + if os.path.islink(directory_path): + os.unlink(directory_path) + elif os.path.exists(directory_path): + deleted = False + for i in range(0, n - 1): + try: + shutil.rmtree(directory_path, onerror=on_error) + deleted = True + break + + except OSError as err: + logging.error( + "Error while deleting directory {}, on attempt number {}: {}. Retrying...".format( + directory_path, i, err.strerror + ) + ) + time.sleep(1) + + if not deleted: + shutil.rmtree(directory_path, onerror=on_error) + + +def on_error(func, path, exc_info): + """ + Error handler for ``shutil.rmtree``. + + If the error is due to an access error (read only file) + it attempts to add write permission and then retries. + + If the error is for another reason it re-raises the error. + + Usage : ``shutil.rmtree(path, onerror=on_error)`` + """ + import stat + + if not os.access(path, os.W_OK): + # Is the error an access error ? + os.chmod(path, stat.S_IWUSR) + func(path) + else: + raise + + +def make_directory(directory_path): + directory_path = str(directory_path) + if not os.path.exists(directory_path): + os.makedirs(directory_path) + + +def make_clean_directory(directory_path): + directory_path = str(directory_path) + remove_directory(directory_path) + while os.path.exists(directory_path): + pass + make_directory(directory_path) + while not os.path.exists(directory_path): + pass + + +def delete_file(file): + file = str(file) + if os.path.exists(file): + os.remove(file) + + +def write_to_csv(input_str): + # Convert single quotes to double quotes for valid JSON + input_str = input_str.replace("'", "\"") + + # Convert the input string to a dictionary + input_dict = eval(input_str) + + # Extract keys for the header row + header = [] + for key, value in input_dict.items(): + if isinstance(value, dict): + header.extend([f"{key}_{subkey}" for subkey in value.keys()]) + else: + header.append(key) + + # Extract values for the data row + values = [] + for key, value in input_dict.items(): + if isinstance(value, dict): + values.extend(value.values()) + else: + values.append(value) + + # Write to CSV + with open('output.csv', 'w', newline='') as csvfile: + csv_writer = csv.writer(csvfile) + csv_writer.writerow(header) + csv_writer.writerow(values)