main.go - randomcrap - random crap programs of varying quality
(HTM) git clone git://git.codemadness.org/randomcrap
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
main.go (2337B)
---
1 package main
2
3 import (
4 "encoding/csv"
5 "flag"
6 "fmt"
7 "io"
8 "io/ioutil"
9 "log"
10 "os"
11 "strings"
12 "text/template"
13 "unicode"
14 )
15
16 // only allow a-zA-Z0-9 and '_', rest is removed.
17 func normalizeheader(s string) string {
18 return strings.Map(func(r rune) rune {
19 switch {
20 case unicode.IsLetter(r):
21 return unicode.ToLower(r)
22 case unicode.IsDigit(r):
23 return r
24 case r == '_':
25 return r
26 }
27 return -1
28 }, s)
29 }
30
31 func main() {
32 config_templatefile := ""
33 config_separator := ";"
34
35 flag.StringVar(&config_templatefile, "template", config_templatefile, "Text template file")
36 flag.StringVar(&config_separator, "separator", config_separator, "Field separator")
37 flag.Parse()
38
39 if config_templatefile == "" {
40 fmt.Fprint(os.Stderr, "Usage: ", os.Args[0], "\n")
41 flag.PrintDefaults()
42 os.Exit(1)
43 }
44 templatedata, err := ioutil.ReadFile(config_templatefile)
45 if err != nil {
46 log.Fatalf("reading template file \"%s\" failed: %s", config_templatefile, err)
47 }
48
49 t := template.New(config_templatefile)
50 t = AddTemplateFuncs(t)
51 // parse template.
52 t, err = t.Parse(string(templatedata))
53 if err != nil {
54 log.Fatalf("template parsing failed: %s", err)
55 }
56
57 r := csv.NewReader(os.Stdin)
58 // if set: use first rune as separator.
59 if len(config_separator) > 0 {
60 r.Comma = rune(config_separator[0])
61 }
62
63 var errset error
64 c := make(chan map[string]string, 0)
65 go func() {
66 var headers []string
67 headerslen := 0
68 recordlen := 0
69 linecount := 0
70 keepreading := true
71 for keepreading {
72 record, err := r.Read()
73 if err != nil {
74 keepreading = false
75 if err != io.EOF {
76 errset = err
77 }
78 break
79 }
80 recordlen = len(record)
81 // first line are the headers.
82 if linecount == 0 {
83 headers = record
84 for i := 0; i < recordlen; i++ {
85 headers[i] = normalizeheader(record[i])
86 }
87 headerslen = recordlen
88 } else {
89 // ... rest are items.
90 item := make(map[string]string)
91 i := 0
92 for i = 0; i < recordlen && i < headerslen; i++ {
93 item[headers[i]] = record[i]
94 }
95 // set remaining fields to empty string.
96 for ; i < headerslen; i++ {
97 item[headers[i]] = ""
98 }
99 c <- item
100 }
101 linecount++
102 }
103 close(c)
104 }()
105 if err = t.Execute(os.Stdout, map[string]interface{}{"rows": c}); err != nil {
106 log.Fatalln(err)
107 }
108 if errset != nil {
109 log.Fatalln(errset)
110 }
111 }