sync: Extract function that import files from importer
This commit is contained in:
parent
3104bf4e65
commit
3f55845374
3 changed files with 136 additions and 90 deletions
|
@ -1,6 +1,7 @@
|
|||
package sync
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"path"
|
||||
|
@ -10,76 +11,104 @@ import (
|
|||
"srs.epita.fr/fic-server/libfic"
|
||||
)
|
||||
|
||||
// SyncExerciceFiles reads the content of files/ directory and import it as EFile for the given challenge.
|
||||
// It takes care of DIGESTS.txt and ensure imported files match.
|
||||
func SyncExerciceFiles(i Importer, exercice fic.Exercice) (errs []string) {
|
||||
func buildFilesListInto(i Importer, exercice fic.Exercice, into string) (files []string, digests map[string][]byte, errs []string) {
|
||||
// If no files directory, don't display error
|
||||
if ! i.exists(path.Join(exercice.Path, "files")) {
|
||||
if !i.exists(path.Join(exercice.Path, into)) {
|
||||
return
|
||||
}
|
||||
|
||||
if digs, err := getFileContent(i, path.Join(exercice.Path, "files", "DIGESTS.txt")); err != nil {
|
||||
// Parse DIGESTS.txt
|
||||
if digs, err := getFileContent(i, path.Join(exercice.Path, into, "DIGESTS.txt")); err != nil {
|
||||
errs = append(errs, fmt.Sprintf("%q: unable to read DIGESTS.txt: %s", path.Base(exercice.Path), err))
|
||||
} else if _, err := exercice.WipeFiles(); err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
} else if files, err := i.listDir(path.Join(exercice.Path, "files")); err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
} else {
|
||||
// Parse DIGESTS.txt
|
||||
digests := map[string][]byte{}
|
||||
digests = map[string][]byte{}
|
||||
for nline, d := range strings.Split(digs, "\n") {
|
||||
if dsplt := strings.SplitN(d, " ", 2); len(dsplt) < 2 {
|
||||
errs = append(errs, fmt.Sprintf("%q: unable to parse DIGESTS.txt line %d: invalid format", path.Base(exercice.Path), nline + 1))
|
||||
errs = append(errs, fmt.Sprintf("%q: unable to parse DIGESTS.txt line %d: invalid format", path.Base(exercice.Path), nline+1))
|
||||
continue
|
||||
} else if hash, err := hex.DecodeString(dsplt[0]); err != nil {
|
||||
errs = append(errs, fmt.Sprintf("%q: unable to parse DIGESTS.txt line %d: %s", path.Base(exercice.Path), nline + 1, err))
|
||||
errs = append(errs, fmt.Sprintf("%q: unable to parse DIGESTS.txt line %d: %s", path.Base(exercice.Path), nline+1, err))
|
||||
continue
|
||||
} else {
|
||||
digests[strings.TrimFunc(dsplt[1], unicode.IsSpace)] = hash
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Import splitted files
|
||||
var splittedFiles []string
|
||||
for _, fname := range files {
|
||||
if matched, _ := path.Match("*.00", fname); matched {
|
||||
fname = fname[:len(fname)-3]
|
||||
splittedFiles = append(splittedFiles, fname + ".[0-9][0-9]")
|
||||
files = append(files, fname)
|
||||
} else if matched, _ := path.Match("*00", fname); matched {
|
||||
fname = fname[:len(fname)-2]
|
||||
splittedFiles = append(splittedFiles, fname + "[0-9][0-9]")
|
||||
files = append(files, fname)
|
||||
} else if matched, _ := path.Match("*_MERGED", fname); matched {
|
||||
splittedFiles = append(splittedFiles, fname)
|
||||
}
|
||||
}
|
||||
|
||||
// Import standard files
|
||||
for _, fname := range files {
|
||||
// Read file list
|
||||
if flist, err := i.listDir(path.Join(exercice.Path, into)); err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
} else {
|
||||
for _, fname := range flist {
|
||||
if fname == "DIGESTS.txt" {
|
||||
continue
|
||||
}
|
||||
|
||||
foundSplitted := false
|
||||
for _, sf := range splittedFiles {
|
||||
if matched, _ := path.Match(sf, fname); matched {
|
||||
foundSplitted = true
|
||||
}
|
||||
}
|
||||
if foundSplitted {
|
||||
if matched, _ := path.Match("*.00", fname); matched {
|
||||
fname = fname[:len(fname)-3]
|
||||
} else if matched, _ := path.Match("*00", fname); matched {
|
||||
fname = fname[:len(fname)-2]
|
||||
} else if matched, _ := path.Match("*_MERGED", fname); matched {
|
||||
continue
|
||||
}
|
||||
|
||||
if f, err := i.importFile(path.Join(exercice.Path, "files", fname),
|
||||
func(filePath string, origin string) (interface{}, error) {
|
||||
return exercice.ImportFile(filePath, origin, digests[fname])
|
||||
}); err != nil {
|
||||
errs = append(errs, fmt.Sprintf("%q: unable to import file %q: %s", path.Base(exercice.Path), fname, err))
|
||||
continue
|
||||
} else if f.(fic.EFile).Size == 0 {
|
||||
errs = append(errs, fmt.Sprintf("%q: WARNING imported file %q is empty!", path.Base(exercice.Path), fname))
|
||||
fileFound := false
|
||||
for _, f := range files {
|
||||
if fname == f {
|
||||
fileFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !fileFound {
|
||||
files = append(files, fname)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CheckExerciceFiles checks that remote files have the right digest.
|
||||
func CheckExerciceFiles(i Importer, exercice fic.Exercice) (files []fic.EFile, errs []string) {
|
||||
flist, digests, berrs := buildFilesListInto(i, exercice, "files")
|
||||
errs = append(errs, berrs...)
|
||||
|
||||
for _, fname := range flist {
|
||||
w, hash160, hash512 := fic.CreateHashBuffers()
|
||||
|
||||
if err := i.getFile(path.Join(exercice.Path, "files", fname), bufio.NewWriter(w)); err != nil {
|
||||
errs = append(errs, fmt.Sprintf("%q: unable to read file %q: %s", path.Base(exercice.Path), fname, err))
|
||||
continue
|
||||
} else if _, err := fic.CheckBufferHash(hash160, hash512, digests[fname]); err != nil {
|
||||
errs = append(errs, fmt.Sprintf("%q: %s: %s", path.Base(exercice.Path), fname, err))
|
||||
}
|
||||
|
||||
files = append(files, fic.EFile{Name: fname})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SyncExerciceFiles reads the content of files/ directory and import it as EFile for the given challenge.
|
||||
// It takes care of DIGESTS.txt and ensure imported files match.
|
||||
func SyncExerciceFiles(i Importer, exercice fic.Exercice) (errs []string) {
|
||||
if _, err := exercice.WipeFiles(); err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
}
|
||||
|
||||
files, digests, berrs := buildFilesListInto(i, exercice, "files")
|
||||
errs = append(errs, berrs...)
|
||||
|
||||
// Import standard files
|
||||
for _, fname := range files {
|
||||
if f, err := i.importFile(path.Join(exercice.Path, "files", fname),
|
||||
func(filePath string, origin string) (interface{}, error) {
|
||||
return exercice.ImportFile(filePath, origin, digests[fname])
|
||||
}); err != nil {
|
||||
errs = append(errs, fmt.Sprintf("%q: unable to import file %q: %s", path.Base(exercice.Path), fname, err))
|
||||
continue
|
||||
} else if f.(fic.EFile).Size == 0 {
|
||||
errs = append(errs, fmt.Sprintf("%q: WARNING imported file %q is empty!", path.Base(exercice.Path), fname))
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
Reference in a new issue