summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRené 'Necoro' Neumann <necoro@necoro.eu>2022-01-22 22:32:10 +0100
committerRené 'Necoro' Neumann <necoro@necoro.eu>2022-01-22 22:32:10 +0100
commit3c5c4758fb2540eb3db667b376d2dbce9e8187a2 (patch)
treee5c5fc070df918737e13a6da659815ec8a2c27a1
parentf6c165150e4bdfbd76414faac1c8be54eeae564c (diff)
downloadengarde-importer-3c5c4758fb2540eb3db667b376d2dbce9e8187a2.tar.gz
engarde-importer-3c5c4758fb2540eb3db667b376d2dbce9e8187a2.tar.bz2
engarde-importer-3c5c4758fb2540eb3db667b376d2dbce9e8187a2.zip
First setup: Parse CSV content
-rw-r--r--encoding.go40
-rw-r--r--go.mod6
-rw-r--r--go.sum6
-rw-r--r--main.go70
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
+}
diff --git a/go.mod b/go.mod
index 522b283..1ba569a 100644
--- a/go.mod
+++ b/go.mod
@@ -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
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..3e88ccb
--- /dev/null
+++ b/go.sum
@@ -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=
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..29593db
--- /dev/null
+++ b/main.go
@@ -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)
+ }
+}