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) } }