2020-09-08 17:49:02 -06:00
|
|
|
package transpile
|
2019-09-02 19:47:24 -06:00
|
|
|
|
2020-09-04 18:28:23 -06:00
|
|
|
import (
|
|
|
|
"archive/zip"
|
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
2020-09-15 16:42:31 -06:00
|
|
|
"os/exec"
|
2020-09-04 18:28:23 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
// Mothball packages a Category up for a production server run.
|
|
|
|
func Mothball(c Category) (*bytes.Reader, error) {
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
zf := zip.NewWriter(buf)
|
|
|
|
|
|
|
|
inv, err := c.Inventory()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
puzzlesTxt, err := zf.Create("puzzles.txt")
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
answersTxt, err := zf.Create("answers.txt")
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, points := range inv {
|
|
|
|
fmt.Fprintln(puzzlesTxt, points)
|
|
|
|
|
|
|
|
puzzlePath := fmt.Sprintf("%d/puzzle.json", points)
|
|
|
|
pw, err := zf.Create(puzzlePath)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
puzzle, err := c.Puzzle(points)
|
|
|
|
if err != nil {
|
2020-09-15 16:42:31 -06:00
|
|
|
return nil, fmt.Errorf("Puzzle %d: %s", points, err)
|
2020-09-04 18:28:23 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// Record answers in answers.txt
|
|
|
|
for _, answer := range puzzle.Answers {
|
|
|
|
fmt.Fprintln(answersTxt, points, answer)
|
|
|
|
}
|
|
|
|
|
2020-09-15 16:42:31 -06:00
|
|
|
// Remove answers and debugging from puzzle object
|
2020-09-04 18:28:23 -06:00
|
|
|
puzzle.Answers = []string{}
|
2020-09-15 16:42:31 -06:00
|
|
|
puzzle.Debug.Errors = []string{}
|
|
|
|
puzzle.Debug.Hints = []string{}
|
|
|
|
puzzle.Debug.Log = []string{}
|
2020-09-04 18:28:23 -06:00
|
|
|
|
|
|
|
// Write out Puzzle object
|
|
|
|
penc := json.NewEncoder(pw)
|
|
|
|
if err := penc.Encode(puzzle); err != nil {
|
2020-09-15 16:42:31 -06:00
|
|
|
return nil, fmt.Errorf("Puzzle %d: %s", points, err)
|
2020-09-04 18:28:23 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// Write out all attachments and scripts
|
|
|
|
attachments := append(puzzle.Pre.Attachments, puzzle.Pre.Scripts...)
|
|
|
|
for _, att := range attachments {
|
|
|
|
attPath := fmt.Sprintf("%d/%s", points, att)
|
|
|
|
aw, err := zf.Create(attPath)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
ar, err := c.Open(points, att)
|
2020-09-15 16:42:31 -06:00
|
|
|
if exerr, ok := err.(*exec.ExitError); ok {
|
|
|
|
return nil, fmt.Errorf("Puzzle %d: %s: %s: %s", points, att, err, string(exerr.Stderr))
|
|
|
|
} else if err != nil {
|
|
|
|
return nil, fmt.Errorf("Puzzle %d: %s: %s", points, att, err)
|
2020-09-04 18:28:23 -06:00
|
|
|
}
|
|
|
|
if _, err := io.Copy(aw, ar); err != nil {
|
2020-09-15 16:42:31 -06:00
|
|
|
return nil, fmt.Errorf("Puzzle %d: %s: %s", points, att, err)
|
2020-09-04 18:28:23 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
zf.Close()
|
|
|
|
|
|
|
|
return bytes.NewReader(buf.Bytes()), nil
|
|
|
|
}
|