package main import ( "flag" "fmt" "io/ioutil" "log" "math/rand" "os" "path" "strings" "time" "golang.org/x/exp/inotify" "srs.epita.fr/fic-server/libfic" ) var TeamsDir string var SubmissionDir string func watchsubdir(watcher *inotify.Watcher, pathname string) error { log.Println("Watch new directory:", pathname) if err := watcher.AddWatch(pathname, inotify.IN_CLOSE_WRITE|inotify.IN_CREATE); err != nil { return err } if ds, err := ioutil.ReadDir(pathname); err != nil { return err } else { for _, d := range ds { p := path.Join(pathname, d.Name()) if d.IsDir() { if err := watchsubdir(watcher, p); err != nil { return err } } else if d.Mode().IsRegular() { go treat(p) } } return nil } } func main() { var dsn = flag.String("dsn", "fic:fic@/fic", "DSN to connect to the MySQL server") flag.StringVar(&SubmissionDir, "submission", "./submissions", "Base directory where save submissions") flag.StringVar(&TeamsDir, "teams", "../TEAMS", "Base directory where save teams JSON files") flag.Parse() SubmissionDir = path.Clean(SubmissionDir) rand.Seed(time.Now().UnixNano()) log.Println("Creating submission directory...") if _, err := os.Stat(SubmissionDir); os.IsNotExist(err) { if err := os.MkdirAll(SubmissionDir, 0777); err != nil { log.Fatal("Unable to create submission directory: ", err) } } log.Println("Opening DB...") if err := fic.DBInit(fmt.Sprintf("%s?parseTime=true", *dsn)); err != nil { log.Fatal("Cannot open the database: ", err) os.Exit(1) } defer fic.DBClose() log.Println("Registering directory events...") watcher, err := inotify.NewWatcher() if err != nil { log.Fatal(err) } if err := watchsubdir(watcher, SubmissionDir); err != nil { log.Fatal(err) } for { select { case ev := <-watcher.Event: if ev.Mask&inotify.IN_CREATE == inotify.IN_CREATE { // Register new subdirectory if d, err := os.Stat(ev.Name); err == nil && d.IsDir() { if err := watchsubdir(watcher, ev.Name); err != nil { log.Println(err) } } } else if ev.Mask&inotify.IN_CLOSE_WRITE == inotify.IN_CLOSE_WRITE { go treat(ev.Name) } case err := <-watcher.Error: log.Println("error:", err) } } } func treat(raw_path string) { // Extract spath := strings.Split(strings.TrimPrefix(raw_path, SubmissionDir), "/") if len(spath) > 2 { treatSubmission(raw_path, spath[1], spath[2]) } else { log.Println("Invalid new file:", raw_path) } }