Skip to content
Snippets Groups Projects
Commit 5a090485 authored by Jeffrey Tolar's avatar Jeffrey Tolar
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
main.go 0 → 100644
package main
import (
"encoding/csv"
"encoding/json"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"path"
"regexp"
"strings"
)
var (
csvFile = flag.String("csv", "", "Path to CSV to parse")
qidPattern = flag.String("qid", ".*", "Regex to filter QIDs (should match only one per student)")
outputPath = flag.String("output", "files/$netid/", "Output directory; should contain $netid, can contain $qid")
fileTransform = flag.String("transform", "_cpp,.cpp,_h,.h", "Transformations to file names; format: search1,replace1,search2,replace2,... You can't escape commas.")
)
func main() {
flag.Parse()
f, err := os.Open(*csvFile)
if err != nil {
log.Fatal(err)
}
defer f.Close()
cr := csv.NewReader(f)
// chop the header row
row, err := cr.Read()
if err != nil {
log.Fatal(err)
}
colMapping := make(map[string]int)
for i, v := range row {
colMapping[v] = i
}
for _, c := range []string{"uid", "qid", "submittedAnswer"} {
if _, ok := colMapping[c]; !ok {
log.Fatal(fmt.Errorf("missing %q column", c))
}
}
netidRegexp := regexp.MustCompile(`^(\w+)@illinois\.edu.*$`)
qidRegexp, err := regexp.Compile(*qidPattern)
if err != nil {
log.Fatal(err)
}
transformer := func(s string) string { return s }
patterns := strings.Split(*fileTransform, ",")
if len(patterns) > 0 {
transformer = strings.NewReplacer(patterns...).Replace
}
for row, err = cr.Read(); err == nil; row, err = cr.Read() {
qid := row[colMapping["qid"]]
if !qidRegexp.MatchString(qid) {
continue
}
uid := row[colMapping["uid"]]
ans := row[colMapping["submittedAnswer"]]
var netid string
if match := netidRegexp.FindStringSubmatch(uid); len(match) > 1 {
netid = match[1]
} else {
continue
}
var files map[string][]byte
// json decodes a string into a []byte as base64-decoded data
if ans != "" {
if err := json.NewDecoder(strings.NewReader(ans)).Decode(&files); err != nil {
log.Fatal(err)
}
}
root := os.Expand(*outputPath, func(s string) string {
switch s {
case "netid":
return netid
case "qid":
return qid
}
return os.Getenv(s)
})
err = os.MkdirAll(root, 0700)
if err != nil {
log.Fatal(err)
}
for name, contents := range files {
name = transformer(name)
p := path.Join(root, name)
err = ioutil.WriteFile(p, contents, 0600)
if err != nil {
log.Fatal(err)
}
}
p := path.Join(root, "qid")
err = ioutil.WriteFile(p, []byte(qid), 0600)
if err != nil {
log.Fatal(err)
}
}
if err != nil && err != io.EOF {
log.Fatal(err)
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment