log.Fatal already do Exit(1)
[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 }
66 defer fic.DBClose()
67
68 log.Println("Registering directory events...")
69 watcher, err := inotify.NewWatcher()
70 if err != nil {
71 log.Fatal(err)
72 }
73
74 if err := watchsubdir(watcher, SubmissionDir); err != nil {
75 log.Fatal(err)
76 }
77
78 if !*skipFullGeneration {
79 log.Println("Generating files...")
80 go genAll()
81 }
82
83 for {
84 select {
85 case ev := <-watcher.Event:
86 if ev.Mask&inotify.IN_CREATE == inotify.IN_CREATE {
87 // Register new subdirectory
88 if d, err := os.Stat(ev.Name); err == nil && d.IsDir() {
89 if err := watchsubdir(watcher, ev.Name); err != nil {
90 log.Println(err)
91 }
92 }
93 } else if ev.Mask&inotify.IN_CLOSE_WRITE == inotify.IN_CLOSE_WRITE {
94 go treat(ev.Name)
95 }
96 case err := <-watcher.Error:
97 log.Println("error:", err)
98 }
99 }
100 }
101
102 func treat(raw_path string) {
103 // Extract
104 spath := strings.Split(strings.TrimPrefix(raw_path, SubmissionDir), "/")
105
106 if len(spath) == 3 {
107 if spath[1] == "_registration" {
108 treatRegistration(raw_path)
109 } else if team, err := fic.GetTeamByInitialName(spath[1]); err != nil {
110 log.Println("[ERR]", err)
111 } else if spath[2] == "name" {
112 treatRename(raw_path, team)
113 } else {
114 treatSubmission(raw_path, team, spath[2])
115 }
116 } else {
117 log.Println("Invalid new file:", raw_path)
118 }
119 }