speedtest/src/Speedtest.ts

128 lines
3.1 KiB
TypeScript

import * as Excel from "exceljs";
import * as moment from "moment";
import * as speedtest from "speedtest-net";
import { existsSync } from "fs";
/**
* Speedtest class
*/
export default class Speedtest {
private path: string;
constructor (path?: string) {
this.path = path ? path : "./data.xlsx";
if (!this._checks) return;
};
/**
* Run a speedtest and save the results
* @returns {void}
*/
run (): void {
let test = speedtest({
maxTime: 5000
});
if (!this._checks) return;
test.on("data", (data: SpeedtestResults) => {
const { download, upload } = data.speeds;
let date: string = moment().format("YYYY-MM-DD H:mm:ss");
console.log(`[${date}] Upload: ${upload}, Download: ${download}`);
this._save(data);
});
test.on("error", (err: Error) => {
throw err;
});
}
/**
* Save the results to the file
* @param {SpeedtestResults} results - The test results to save
* @param {string} path - Where to save the results
* @private
*/
private _save (results: SpeedtestResults, path?: string) {
if (path) this.path = path;
if (!(this._checks)) return;
let workbook = new Excel.Workbook();
workbook
.xlsx
.readFile(this.path)
.then((): Promise<void> => {
let worksheet = workbook.getWorksheet("speedtest") || workbook.addWorksheet("speedtest");
let date = moment().format("YYYY-MM-DD H:mm:ss");
worksheet.columns = [
{ header: "Date", key: "date" },
{ header: "Download", key: "down_speed" },
{ header: "Upload", key: "up_speed" },
{ header: "Ping", key: "ping" },
{ header: "Full Results", key: "full_results", hidden: true }
];
worksheet.addRow(
{
date: date,
down_speed: results.speeds.download,
up_speed: results.speeds.upload,
ping: results.server.ping,
full_results: results
}
);
return workbook.xlsx.writeFile(this.path);
});
}
/**
* Checks if the file exists and can be edited.
* @return {boolean} - The file exists
* @private
*/
private get _checks (): boolean {
let tempPrefix = "~$";
let path: string[] = this.path.split("/");
let tempFile = tempPrefix + path[path.length - 1];
let fileExt = tempFile.split(".").pop();
let tempPath = path.slice(0, -1).join("/");
if (existsSync(`${tempPath}/${tempFile}`)) {
console.error("A temp file is present, meaning the log file cannot be edited. This is most likely caused by the file being used by another program.");
return false;
}
if (!existsSync(this.path)) throw new Error(`There is no file located at ${require("path").resolve(this.path)}`);
if (fileExt !== "xlsx") throw new Error("The log file must be an xlsx file.");
return true;
}
}
interface SpeedtestResults {
speeds: {
download: number;
upload: number;
originalDownload: number;
},
client: {
ip: string;
lat: number;
lon: number;
isp: string;
isprating: number;
rating: number;
ispdlavg: number;
ispulavg: number;
country: string;
},
server: {
host: string;
lat: number;
lon: number;
location: string;
country: string;
cc: string;
sponsor: string;
distance: number;
distanceMi: number;
ping: number;
id: number;
}
}