All checks were successful
continuous-integration/drone/push Build is passing
176 lines
4.6 KiB
Go
176 lines
4.6 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"flag"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"path"
|
|
"strings"
|
|
|
|
"srs.epita.fr/fic-server/admin/sync"
|
|
"srs.epita.fr/fic-server/libfic"
|
|
)
|
|
|
|
var OutputFormats = map[string]func(...string) (func(string) (io.WriteCloser, error), error){}
|
|
|
|
func exportThemeFiles(tdir string) (errs error) {
|
|
theme, exceptions, err := sync.BuildTheme(sync.GlobalImporter, tdir)
|
|
errs = errors.Join(errs, err)
|
|
|
|
err = sync.SyncThemeFiles(sync.GlobalImporter, theme)
|
|
if err != nil {
|
|
errs = errors.Join(errs, err)
|
|
}
|
|
|
|
exercices, err := sync.GetExercices(sync.GlobalImporter, theme)
|
|
if err != nil {
|
|
log.Fatalf("Unable to list exercices for theme %q: %s", theme.Name, err)
|
|
}
|
|
|
|
dmap := map[int64]*fic.Exercice{}
|
|
|
|
for i, edir := range exercices {
|
|
log.Printf("In theme %s, doing exercice %d/%d: %s", tdir, i+1, len(exercices), edir)
|
|
err = exportExerciceFiles(theme, edir, &dmap, exceptions)
|
|
errs = errors.Join(errs, err)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func exportExerciceFiles(theme *fic.Theme, edir string, dmap *map[int64]*fic.Exercice, exceptions *sync.CheckExceptions) (errs error) {
|
|
exercice, _, eid, exceptions, _, berrs := sync.BuildExercice(sync.GlobalImporter, theme, path.Join(theme.Path, edir), dmap, nil)
|
|
errs = errors.Join(errs, berrs)
|
|
|
|
if exercice != nil {
|
|
paramsFiles, err := sync.GetExerciceFilesParams(sync.GlobalImporter, exercice)
|
|
if err != nil {
|
|
errs = errors.Join(errs, sync.NewChallengeTxtError(exercice, 0, err))
|
|
return
|
|
}
|
|
|
|
_, err = sync.SyncExerciceFiles(sync.GlobalImporter, exercice, paramsFiles, func(fname string, digests map[string][]byte, filePath, origin string) (interface{}, error) {
|
|
return nil, nil
|
|
})
|
|
errs = errors.Join(errs, err)
|
|
|
|
if dmap != nil {
|
|
(*dmap)[int64(eid)] = exercice
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
type nopCloser struct {
|
|
w io.Writer
|
|
}
|
|
|
|
func (nc *nopCloser) Close() error {
|
|
return nil
|
|
}
|
|
|
|
func (nc *nopCloser) Write(p []byte) (int, error) {
|
|
return nc.w.Write(p)
|
|
}
|
|
|
|
func NopCloser(w io.Writer) *nopCloser {
|
|
return &nopCloser{w}
|
|
}
|
|
|
|
func writeFileToTar(dest string) (io.WriteCloser, error) {
|
|
log.Println("import2Tar", dest)
|
|
return NopCloser(bytes.NewBuffer([]byte{})), nil
|
|
}
|
|
|
|
func main() {
|
|
cloudDAVBase := ""
|
|
cloudUsername := "fic"
|
|
cloudPassword := ""
|
|
localImporterDirectory := ""
|
|
|
|
// Read paremeters from environment
|
|
if v, exists := os.LookupEnv("FICCLOUD_URL"); exists {
|
|
cloudDAVBase = v
|
|
}
|
|
if v, exists := os.LookupEnv("FICCLOUD_USER"); exists {
|
|
cloudUsername = v
|
|
}
|
|
if v, exists := os.LookupEnv("FICCLOUD_PASS"); exists {
|
|
cloudPassword = v
|
|
}
|
|
|
|
// Read parameters from command line
|
|
flag.StringVar(&localImporterDirectory, "localimport", localImporterDirectory,
|
|
"Base directory where to find challenges files to import, local part")
|
|
flag.StringVar(&cloudDAVBase, "clouddav", cloudDAVBase,
|
|
"Base directory where to find challenges files to import, cloud part")
|
|
flag.StringVar(&cloudUsername, "clouduser", cloudUsername, "Username used to sync")
|
|
flag.StringVar(&cloudPassword, "cloudpass", cloudPassword, "Password used to sync")
|
|
flag.BoolVar(&fic.OptionalDigest, "optionaldigest", fic.OptionalDigest, "Is the digest required when importing files?")
|
|
flag.BoolVar(&fic.StrongDigest, "strongdigest", fic.StrongDigest, "Are BLAKE2b digests required or is SHA-1 good enough?")
|
|
flag.Parse()
|
|
|
|
// Do not display timestamp
|
|
log.SetFlags(0)
|
|
|
|
// Instantiate importer
|
|
if localImporterDirectory != "" {
|
|
sync.GlobalImporter = sync.LocalImporter{Base: localImporterDirectory, Symlink: false}
|
|
} else if cloudDAVBase != "" {
|
|
sync.GlobalImporter, _ = sync.NewCloudImporter(cloudDAVBase, cloudUsername, cloudPassword)
|
|
}
|
|
|
|
if sync.GlobalImporter == nil {
|
|
log.Fatal("No importer configured!")
|
|
}
|
|
|
|
log.Println("Using", sync.GlobalImporter.Kind())
|
|
|
|
// Configure destination
|
|
if flag.NArg() < 1 {
|
|
var formats []string
|
|
|
|
for k := range OutputFormats {
|
|
formats = append(formats, k)
|
|
}
|
|
|
|
log.Fatal("Please define wanted output format between [" + strings.Join(formats, " ") + "]")
|
|
} else if outputFormat, ok := OutputFormats[flag.Arg(0)]; !ok {
|
|
var formats []string
|
|
|
|
for k := range OutputFormats {
|
|
formats = append(formats, k)
|
|
}
|
|
|
|
log.Fatal("Please define wanted output format between [" + strings.Join(formats, " ") + "]")
|
|
} else {
|
|
fw, err := outputFormat(flag.Args()[1:]...)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
} else if fw != nil {
|
|
sync.SetWriteFileFunc(fw)
|
|
}
|
|
}
|
|
|
|
themes, err := sync.GetThemesExtended(sync.GlobalImporter)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
hasError := false
|
|
for i, tdir := range themes {
|
|
log.Printf("Doing theme %d/%d: %s", i+1, len(themes), tdir)
|
|
err = exportThemeFiles(tdir)
|
|
if err != nil {
|
|
hasError = true
|
|
log.Println(err)
|
|
}
|
|
}
|
|
|
|
if hasError {
|
|
os.Exit(1)
|
|
}
|
|
}
|