server/remote/challenge-sync-airbus/treat.go

134 lines
2.9 KiB
Go

package main
import (
"fmt"
"log"
"os"
"path/filepath"
"time"
"srs.epita.fr/fic-server/libfic"
)
type Walker struct {
LastSync map[AirbusUserId]time.Time
Exercices AirbusExercicesBindings
Teams map[string]fic.ExportedTeam
API AirbusAPI
Coeff float64
}
func (w *Walker) treat(path string) {
mypath := filepath.Join(filepath.Dir(path), "my.json")
if _, err := os.Stat(mypath); !os.IsNotExist(err) {
// Read team ID
fdmy, err := os.Open(mypath)
if err != nil {
log.Println("Unable to open my.json:", err)
return
}
defer fdmy.Close()
teammy, err := fic.ReadMyJSON(fdmy)
if err != nil {
log.Println("Unable to parse my.json:", err)
return
}
airbusTeamId := NewAirbusUserId(w.Teams[fmt.Sprintf("%d", teammy.Id)].ExternalId)
// Treat score grid
/*err = w.TreatScoreGrid(path, airbusTeamId)
if err != nil {
log.Println("Unable to treat score grid:", err)
return
}*/
// Balance scores
err = w.BalanceScore(int64(float64(teammy.Points)*w.Coeff), airbusTeamId)
if err != nil {
log.Println("Unable to balance score:", err)
return
}
}
}
func (w *Walker) WalkScoreSync(path string, d os.DirEntry, err error) error {
if filepath.Base(path) == "scores.json" {
w.treat(path)
}
return nil
}
func (w *Walker) WalkScore(path string, d os.DirEntry, err error) error {
if filepath.Base(path) == "scores.json" {
go w.treat(path)
}
return nil
}
func (w *Walker) TreatScoreGrid(path string, airbusTeamId AirbusUserId) error {
// Read score grid
fdscores, err := os.Open(path)
if err != nil {
return err
}
defer fdscores.Close()
teamscores, err := fic.ReadScoreGrid(fdscores)
if err != nil {
return err
}
// Found all new entries
maxts := w.LastSync[airbusTeamId]
for _, row := range teamscores {
if row.Time.After(maxts) {
maxts = row.Time
}
if row.Time.After(w.LastSync[airbusTeamId]) {
if row.Reason == "Validation" {
err = w.API.ValidateChallengeFromUser(airbusTeamId, w.Exercices[row.IdExercice])
} else {
err = w.API.AwardUser(airbusTeamId, int64(row.Points*row.Coeff*w.Coeff), row.Reason)
}
if err != nil {
return err
}
}
}
w.LastSync[airbusTeamId] = maxts
return nil
}
func (w *Walker) BalanceScore(score int64, airbusTeamId AirbusUserId) error {
// Read current score on other platform
stats, err := w.API.GetCurrentStats()
if err != nil {
fmt.Errorf("unable to retrieve current stats: %w", err)
}
my_session := stats.Data.GetSession(AirbusUUID(w.API.SessionUUID))
if my_session == nil {
return fmt.Errorf("session not found")
}
other_team := my_session.GetTeam(AirbusUUID(airbusTeamId))
if other_team == nil {
return fmt.Errorf("team %q not found", airbusTeamId)
}
other_score := other_team.Score
// Send diff to the platform
if other_score != score {
diff := score - other_score
return w.API.AwardUser(airbusTeamId, diff, "Équilibrage")
}
return nil
}