diff options
Diffstat (limited to '')
-rw-r--r-- | encoding.go | 40 | ||||
-rw-r--r-- | go.mod | 6 | ||||
-rw-r--r-- | go.sum | 6 | ||||
-rw-r--r-- | main.go | 70 |
4 files changed, 122 insertions, 0 deletions
diff --git a/encoding.go b/encoding.go new file mode 100644 index 0000000..d77cd65 --- /dev/null +++ b/encoding.go @@ -0,0 +1,40 @@ +package main + +import ( + "bytes" + "io" + + "github.com/gogs/chardet" + "golang.org/x/text/encoding/ianaindex" +) + +// getEncodedReader tries to determine the encoding of the content of `r`. +// It returns a new reader that returns UTF-8 content. +func getEncodedReader(r io.Reader) (io.Reader, error) { + buf := make([]byte, 128) + + n, err := io.ReadFull(r, buf) + switch { + case err == io.ErrUnexpectedEOF: + buf = buf[:n] + // as `buf` holds the whole content, we can use it as the underlying reader + r = bytes.NewReader(buf) + case err != nil: + return nil, err + default: + // re-append `buf` + r = io.MultiReader(bytes.NewReader(buf), r) + } + + res, err := chardet.NewTextDetector().DetectBest(buf) + if err != nil { + return nil, err + } + + enc, err := ianaindex.IANA.Encoding(res.Charset) + if err != nil { + return nil, err + } + + return enc.NewDecoder().Reader(r), nil +} @@ -1,3 +1,9 @@ module github.com/Necoro/enguarde-importer go 1.17 + +require ( + github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f + github.com/jszwec/csvutil v1.6.0 + golang.org/x/text v0.3.7 +) @@ -0,0 +1,6 @@ +github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f h1:3BSP1Tbs2djlpprl7wCLuiqMaUh5SJkkzI2gDs+FgLs= +github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14= +github.com/jszwec/csvutil v1.6.0 h1:QORXquCT0t8nUKD7utAD4HDmQMgG0Ir9WieZXzpa7ms= +github.com/jszwec/csvutil v1.6.0/go.mod h1:Rpu7Uu9giO9subDyMCIQfHVDuLrcaC36UA4YcJjGBkg= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -0,0 +1,70 @@ +package main + +import ( + "encoding/csv" + "errors" + "fmt" + "log" + "os" + + "github.com/jszwec/csvutil" +) + +type Participant struct { + LastName string `csv:"lastname"` + FirstName string `csv:"firstname"` + DateOfBirth string `csv:"dateofbirth"` + Gender string `csv:"gender"` + Nation string `csv:"nation"` + Region string `csv:"region"` + Club string `csv:"club"` +} + +func parseOphardtInput(fileName string) ([]Participant, error) { + f, err := os.Open(fileName) + if err != nil { + return nil, fmt.Errorf("opening input file '%s': %w", fileName, err) + } + + encReader, err := getEncodedReader(f) + if err != nil { + return nil, fmt.Errorf("cannot determine encoding of file '%s': %w", fileName, err) + } + + csvReader := csv.NewReader(encReader) + csvReader.Comma = ';' + + dec, err := csvutil.NewDecoder(csvReader) + if err != nil { + return nil, fmt.Errorf("reading from file '%s': %w", fileName, err) + } + dec.DisallowMissingColumns = true + + var participants []Participant + if err = dec.Decode(&participants); err != nil { + return nil, fmt.Errorf("decoding file '%s': %w", fileName, err) + } + + return participants, nil +} + +func run() error { + if len(os.Args) <= 1 { + return errors.New("need filename to start with") + } + fileName := os.Args[1] + + p, err := parseOphardtInput(fileName) + if err != nil { + return err + } + + fmt.Print(p) + return nil +} + +func main() { + if err := run(); err != nil { + log.Fatalf("An error occured: %v", err) + } +} |