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 => { 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; } }