diff --git a/report/csv.go b/report/csv.go deleted file mode 100644 index 946a275..0000000 --- a/report/csv.go +++ /dev/null @@ -1,18 +0,0 @@ -package report - -import ( - "time" -) - -// CSVReport represents the output data fields in a CSV file -type CSVReport struct { - Timestamp time.Time `csv:"Timestamp"` - Name string `csv:"Server Name"` - Address string `csv:"Address"` - Ping float64 `csv:"Ping"` - Jitter float64 `csv:"Jitter"` - Download float64 `csv:"Download"` - Upload float64 `csv:"Upload"` - Share string `csv:"Share"` - IP string `csv:"IP"` -} diff --git a/report/json.go b/report/json.go deleted file mode 100644 index fee05b3..0000000 --- a/report/json.go +++ /dev/null @@ -1,32 +0,0 @@ -package report - -import ( - "time" - - "github.com/librespeed/speedtest-cli/defs" -) - -// JSONReport represents the output data fields in a JSON file -type JSONReport struct { - Timestamp time.Time `json:"timestamp"` - Server Server `json:"server"` - Client Client `json:"client"` - BytesSent int `json:"bytes_sent"` - BytesReceived int `json:"bytes_received"` - Ping float64 `json:"ping"` - Jitter float64 `json:"jitter"` - Upload float64 `json:"upload"` - Download float64 `json:"download"` - Share string `json:"share"` -} - -// Server represents the speed test server's information -type Server struct { - Name string `json:"name"` - URL string `json:"url"` -} - -// Client represents the speed test client's information -type Client struct { - defs.IPInfoResponse -} diff --git a/report/testreport.go b/report/testreport.go new file mode 100644 index 0000000..2f086d8 --- /dev/null +++ b/report/testreport.go @@ -0,0 +1,61 @@ +package report + +import ( + "time" + + "github.com/librespeed/speedtest-cli/defs" +) + +// Report represents the output data fields in a nestable file data such as JSON. +type Report struct { + Timestamp time.Time `json:"timestamp"` + Server Server `json:"server"` + Client Client `json:"client"` + BytesSent int `json:"bytes_sent"` + BytesReceived int `json:"bytes_received"` + Ping float64 `json:"ping"` + Jitter float64 `json:"jitter"` + Upload float64 `json:"upload"` + Download float64 `json:"download"` + Share string `json:"share"` +} + +// FlatReport represents the output data fields in a flat file data such as CSV. +type FlatReport struct { + Timestamp time.Time `csv:"Timestamp"` + Name string `csv:"Server Name"` + Address string `csv:"Address"` + Ping float64 `csv:"Ping"` + Jitter float64 `csv:"Jitter"` + Download float64 `csv:"Download"` + Upload float64 `csv:"Upload"` + Share string `csv:"Share"` + IP string `csv:"IP"` +} + +// Server represents the speed test server's information +type Server struct { + Name string `json:"name"` + URL string `json:"url"` +} + +// Client represents the speed test client's information +type Client struct { + defs.IPInfoResponse +} + +func (r Report) GetFlatReport() FlatReport { + var rep FlatReport + + rep.Timestamp = r.Timestamp + rep.Name = r.Server.Name + rep.Address = r.Server.URL + rep.Ping = r.Ping + rep.Jitter = r.Jitter + rep.Download = r.Download + rep.Upload = r.Upload + rep.Share = r.Share + rep.IP = r.Client.IP + + return rep +} diff --git a/speedtest/helper.go b/speedtest/helper.go index ddc9bc1..3d81683 100644 --- a/speedtest/helper.go +++ b/speedtest/helper.go @@ -8,7 +8,6 @@ import ( "math" "mime/multipart" "net/http" - "os" "strconv" "strings" "time" @@ -33,8 +32,7 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel log.Infof("Testing against %d servers", serverCount) } - var reps_json []report.JSONReport - var reps_csv []report.CSVReport + var reps []report.Report // fetch current user's IP info for _, currentServer := range servers { @@ -141,43 +139,24 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel } } - // check for --csv or --json. the program prioritize the --csv before the --json. this is the same behavior as speedtest-cli - if c.Bool(defs.OptionCSV) { - // print csv if --csv is given - var rep report.CSVReport - rep.Timestamp = time.Now() - - rep.Name = currentServer.Name - rep.Address = u.String() - rep.Ping = math.Round(p*100) / 100 - rep.Jitter = math.Round(jitter*100) / 100 - rep.Download = math.Round(downloadValue*100) / 100 - rep.Upload = math.Round(uploadValue*100) / 100 - rep.Share = shareLink - rep.IP = ispInfo.RawISPInfo.IP - - reps_csv = append(reps_csv, rep) - } else if c.Bool(defs.OptionJSON) { - // print json if --json is given - var rep report.JSONReport - rep.Timestamp = time.Now() - - rep.Ping = math.Round(p*100) / 100 - rep.Jitter = math.Round(jitter*100) / 100 - rep.Download = math.Round(downloadValue*100) / 100 - rep.Upload = math.Round(uploadValue*100) / 100 - rep.BytesReceived = bytesRead - rep.BytesSent = bytesWritten - rep.Share = shareLink - - rep.Server.Name = currentServer.Name - rep.Server.URL = u.String() - - rep.Client = report.Client{ispInfo.RawISPInfo} - rep.Client.Readme = "" - - reps_json = append(reps_json, rep) - } + var rep report.Report + rep.Timestamp = time.Now() + + rep.Ping = math.Round(p*100) / 100 + rep.Jitter = math.Round(jitter*100) / 100 + rep.Download = math.Round(downloadValue*100) / 100 + rep.Upload = math.Round(uploadValue*100) / 100 + rep.BytesReceived = bytesRead + rep.BytesSent = bytesWritten + rep.Share = shareLink + + rep.Server.Name = currentServer.Name + rep.Server.URL = u.String() + + rep.Client = report.Client{IPInfoResponse: ispInfo.RawISPInfo} + rep.Client.Readme = "" + + reps = append(reps, rep) } else { log.Infof("Selected server %s (%s) is not responding at the moment, try again later", currentServer.Name, u.Hostname()) } @@ -190,17 +169,20 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel // check for --csv or --json. the program prioritize the --csv before the --json. this is the same behavior as speedtest-cli if c.Bool(defs.OptionCSV) { - var buf bytes.Buffer - if err := gocsv.MarshalWithoutHeaders(&reps_csv, &buf); err != nil { + var reps_csv []report.FlatReport + for _, rep := range reps { + reps_csv = append(reps_csv, rep.GetFlatReport()) + } + if resultStrig, err := gocsv.MarshalStringWithoutHeaders(&reps_csv); err != nil { log.Errorf("Error generating CSV report: %s", err) } else { - os.Stdout.WriteString(buf.String()) + fmt.Print(resultStrig) } } else if c.Bool(defs.OptionJSON) { - if b, err := json.Marshal(&reps_json); err != nil { + if jsonBytes, err := json.Marshal(&reps); err != nil { log.Errorf("Error generating JSON report: %s", err) } else { - os.Stdout.Write(b[:]) + fmt.Println(string(jsonBytes)) } } diff --git a/speedtest/speedtest.go b/speedtest/speedtest.go index 8a68092..8ef69f3 100644 --- a/speedtest/speedtest.go +++ b/speedtest/speedtest.go @@ -79,9 +79,9 @@ func SpeedTest(c *cli.Context) error { // if --csv-header is given, print the header and exit (same behavior speedtest-cli) if c.Bool(defs.OptionCSVHeader) { - var rep []report.CSVReport - b, _ := gocsv.MarshalBytes(&rep) - os.Stdout.WriteString(string(b)) + var rep []report.FlatReport + header, _ := gocsv.MarshalString(&rep) + fmt.Print(header) return nil }