Backend: start by generating files for all teams
[fic/server.git] / backend / main.go
1 package main
2
3 import (
4 "flag"
5 "fmt"
6 "io/ioutil"
7 "log"
8 "math/rand"
9 "os"
10 "path"
11 "strings"
12 "time"
13
14 "golang.org/x/exp/inotify"
15 "srs.epita.fr/fic-server/libfic"
16 )
17
18 var TeamsDir string
19 var SubmissionDir string
20
21 func watchsubdir(watcher *inotify.Watcher, pathname string) error {
22 log.Println("Watch new directory:", pathname)
23 if err := watcher.AddWatch(pathname, inotify.IN_CLOSE_WRITE|inotify.IN_CREATE); err != nil {
24 return err
25 }
26
27 if ds, err := ioutil.ReadDir(pathname); err != nil {
28 return err
29 } else {
30 for _, d := range ds {
31 p := path.Join(pathname, d.Name())
32 if d.IsDir() {
33 if err := watchsubdir(watcher, p); err != nil {
34 return err
35 }
36 } else if d.Mode().IsRegular() {
37 go treat(p)
38 }
39 }
40 return nil
41 }
42 }
43
44 func main() {
45 var dsn = flag.String("dsn", "fic:fic@/fic", "DSN to connect to the MySQL server")
46 flag.StringVar(&SubmissionDir, "submission", "./submissions", "Base directory where save submissions")
47 flag.StringVar(&TeamsDir, "teams", "../TEAMS", "Base directory where save teams JSON files")
48 var skipFullGeneration = flag.Bool("skipFullGeneration", false, "Skip initial full generation (safe to skip after start)")
49 flag.Parse()
50
51 SubmissionDir = path.Clean(SubmissionDir)
52
53 rand.Seed(time.Now().UnixNano())
54
55 log.Println("Creating submission directory...")
56 if _, err := os.Stat(SubmissionDir); os.IsNotExist(err) {
57 if err := os.MkdirAll(SubmissionDir, 0777); err != nil {
58 log.Fatal("Unable to create submission directory: ", err)
59 }
60 }
61
62 log.Println("Opening DB...")
63 if err := fic.DBInit(fmt.Sprintf("%s?parseTime=true", *dsn)); err != nil {
64 log.Fatal("Cannot open the database: ", err)
65 os.Exit(1)
66
67 }
68 defer fic.DBClose()
69
70 log.Println("Registering directory events...")
71 watcher, err := inotify.NewWatcher()
72 if err != nil {
73 log.Fatal(err)
74 }
75
76 if err := watchsubdir(watcher, SubmissionDir); err != nil {
77 log.Fatal(err)
78 }
79
80 if !*skipFullGeneration {
81 log.Println("Generating files...")
82 go genAll()
83 }
84
85 for {
86 select {
87 case ev := <-watcher.Event:
88 if ev.Mask&inotify.IN_CREATE == inotify.IN_CREATE {
89 // Register new subdirectory
90 if d, err := os.Stat(ev.Name); err == nil && d.IsDir() {
91 if err := watchsubdir(watcher, ev.Name); err != nil {
92 log.Println(err)
93 }
94 }
95 } else if ev.Mask&inotify.IN_CLOSE_WRITE == inotify.IN_CLOSE_WRITE {
96 go treat(ev.Name)
97 }
98 case err := <-watcher.Error:
99 log.Println("error:", err)
100 }
101 }
102 }
103
104 func treat(raw_path string) {
105 // Extract
106 spath := strings.Split(strings.TrimPrefix(raw_path, SubmissionDir), "/")
107
108 if len(spath) > 2 {
109 treatSubmission(raw_path, spath[1], spath[2])
110 } else {
111 log.Println("Invalid new file:", raw_path)
112 }
113 }