handle input json in formats other than utf8
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
72
main.go
72
main.go
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
@@ -15,6 +16,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/xuri/excelize/v2"
|
||||
"golang.org/x/text/encoding/unicode"
|
||||
"golang.org/x/text/transform"
|
||||
"golang.org/x/text/unicode/norm"
|
||||
)
|
||||
|
||||
type Input struct {
|
||||
@@ -232,7 +236,7 @@ func AvgChart(f *excelize.File, worksheetName string, location string, avgCpuCol
|
||||
chartSeries = append(chartSeries, thisChartSeries)
|
||||
}
|
||||
|
||||
if err := f.AddChart("Report", location, &excelize.Chart{
|
||||
chart := excelize.Chart{
|
||||
Type: excelize.Line,
|
||||
Series: chartSeries,
|
||||
Format: excelize.GraphicOptions{
|
||||
@@ -278,14 +282,19 @@ func AvgChart(f *excelize.File, worksheetName string, location string, avgCpuCol
|
||||
Font: excelize.Font{
|
||||
Color: "000000",
|
||||
},
|
||||
Maximum: &yMaxValue,
|
||||
Minimum: &yMinValue,
|
||||
},
|
||||
Dimension: excelize.ChartDimension{
|
||||
Height: 500,
|
||||
Width: 800,
|
||||
},
|
||||
}); err != nil {
|
||||
}
|
||||
|
||||
if yMaxValue > 0 || yMinValue > 0 {
|
||||
chart.YAxis.Maximum = &yMaxValue
|
||||
chart.YAxis.Minimum = &yMinValue
|
||||
}
|
||||
|
||||
if err := f.AddChart("Report", location, &chart); err != nil {
|
||||
fmt.Printf("Error adding chart to workbook %s at location %s: %s\n", worksheetName, location, err)
|
||||
return
|
||||
}
|
||||
@@ -293,6 +302,7 @@ func AvgChart(f *excelize.File, worksheetName string, location string, avgCpuCol
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
var data Input
|
||||
|
||||
inputFile := flag.String("input", "input.json", "The filename from which to load historical data")
|
||||
outputFile := flag.String("output", "book1.xlsx", "The filename to use when writing excel workbook")
|
||||
@@ -322,9 +332,19 @@ func main() {
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
byteValue, _ := io.ReadAll(file)
|
||||
var data Input
|
||||
if err := json.Unmarshal(byteValue, &data); err != nil {
|
||||
byteValue, err := io.ReadAll(file)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read input json: %v", err)
|
||||
}
|
||||
|
||||
// Detect encoding and convert to UTF-8 if necessary
|
||||
utf8Data, err := ensureUTF8(byteValue)
|
||||
if err != nil {
|
||||
fmt.Printf("Error ensuring UTF-8 encoding: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(utf8Data, &data); err != nil {
|
||||
fmt.Printf("Error reading json input: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
@@ -366,6 +386,44 @@ func sortDates(dates []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ensureUTF8 checks if the data is UTF-8, and if not, converts it to UTF-8.
|
||||
// It also removes BOM from UTF-8 if present.
|
||||
func ensureUTF8(data []byte) ([]byte, error) {
|
||||
// Detect and strip UTF-8 BOM if present
|
||||
if hasUTF8BOM(data) {
|
||||
data = stripUTF8BOM(data)
|
||||
}
|
||||
|
||||
// If data is already UTF-8 (without BOM), return as is
|
||||
if isUTF8(data) {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// Detect and decode UTF-16 (either UTF-16LE or UTF-16BE)
|
||||
decoder := unicode.UTF16(unicode.LittleEndian, unicode.UseBOM).NewDecoder()
|
||||
utf8Data, _, err := transform.Bytes(decoder, data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error converting to UTF-8: %v", err)
|
||||
}
|
||||
|
||||
return utf8Data, nil
|
||||
}
|
||||
|
||||
// isUTF8 checks if the byte slice is already encoded in UTF-8
|
||||
func isUTF8(data []byte) bool {
|
||||
return bytes.Equal(data, norm.NFC.Bytes(data)) // UTF-8 normalization check
|
||||
}
|
||||
|
||||
// hasUTF8BOM checks if the data has a UTF-8 BOM
|
||||
func hasUTF8BOM(data []byte) bool {
|
||||
return len(data) >= 3 && data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF
|
||||
}
|
||||
|
||||
// stripUTF8BOM removes the UTF-8 BOM if it exists
|
||||
func stripUTF8BOM(data []byte) []byte {
|
||||
return data[3:]
|
||||
}
|
||||
|
||||
func fetchValue(value interface{}) {
|
||||
switch value.(type) {
|
||||
case string:
|
||||
|
Reference in New Issue
Block a user