package sync import ( "bufio" "crypto" "encoding/hex" "fmt" "io" "os" "path" "strings" "srs.epita.fr/fic-server/libfic" _ "golang.org/x/crypto/blake2b" ) func SyncExerciceHints(i Importer, exercice fic.Exercice) (errs []string) { params, err := parseExerciceParams(i, exercice.Path) if err != nil { errs = append(errs, fmt.Sprintf("%q: defines.txt: %s", path.Base(exercice.Path), err)) } if _, err := exercice.WipeHints(); err != nil { errs = append(errs, err.Error()) } else if ! i.exists(path.Join(exercice.Path, "hints")) { return } else if hints, err := i.listDir(path.Join(exercice.Path, "hints")); err != nil { errs = append(errs, err.Error()) } else { for n, hfile := range hints { // Find corresponding parameters var hint_title = fmt.Sprintf("Astuce #%d", n + 1) var hint_cost = exercice.Gain / 4 for _, hp := range params.Hints { if hp.Filename == hfile { if hp.Cost > 0 { hint_cost = hp.Cost } if hp.Title != "" { hint_title = hp.Title } break } } // Extract hint content var hint_cnt string if fi, err := i.stat(path.Join(exercice.Path, "hints", hfile)); err != nil { errs = append(errs, fmt.Sprintf("%q: unable to add hint %q: %s", path.Base(exercice.Path), hfile, err)) } else if ! fi.IsDir() && fi.Size() > 512 { // Handle big files as downloadable content if res, err := i.importFile(path.Join(exercice.Path, "hints", hfile), func(filePath string, origin string) (interface{}, error) { // Calculate hash hash512 := crypto.BLAKE2b_512.New() if fd, err := os.Open(filePath); err != nil { return nil, err } else { defer fd.Close() reader := bufio.NewReader(fd) if _, err := io.Copy(hash512, reader); err != nil { return nil, err } } result512 := hash512.Sum(nil) return "$FILES" + hex.EncodeToString(result512) + strings.TrimPrefix(filePath, fic.FilesDir), nil }); err != nil { errs = append(errs, fmt.Sprintf("%q: unable to import hint file %q: %s", path.Base(exercice.Path), hfile, err)) continue } else if s, ok := res.(string); !ok { errs = append(errs, fmt.Sprintf("%q: unable to import hint file %q: invalid string returned as filename", path.Base(exercice.Path), hfile)) continue } else { hint_cnt = s } } else if hint_cnt, err = getFileContent(i, path.Join(exercice.Path, "hints", hfile)); err != nil { errs = append(errs, fmt.Sprintf("%q: unable to read hint file %q: %s", path.Base(exercice.Path), hfile, err)) continue } // Import hint if _, err := exercice.AddHint(hint_title, hint_cnt, hint_cost); err != nil { errs = append(errs, fmt.Sprintf("%q: unable to add hint %q: %s", path.Base(exercice.Path), hfile, err)) } } } return }