challenge-sync-airbus: Do job
This commit is contained in:
parent
18b8f0f722
commit
3344e05e0d
@ -6,6 +6,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
@ -32,6 +33,7 @@ func (a *AirbusAPI) request(method, endpoint string, data []byte, out interface{
|
|||||||
return fmt.Errorf("unable to prepare request to %q: %w", endpoint, err)
|
return fmt.Errorf("unable to prepare request to %q: %w", endpoint, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req.Header.Add("Authorization", "Bearer "+a.Token)
|
||||||
req.Header.Add("Content-Type", "application/json")
|
req.Header.Add("Content-Type", "application/json")
|
||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
@ -40,7 +42,7 @@ func (a *AirbusAPI) request(method, endpoint string, data []byte, out interface{
|
|||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode == http.StatusOK {
|
||||||
if out != nil {
|
if out != nil {
|
||||||
jdec := json.NewDecoder(resp.Body)
|
jdec := json.NewDecoder(resp.Body)
|
||||||
|
|
||||||
@ -149,30 +151,44 @@ func (a *AirbusAPI) GetChallengeFromName(name string) (*AirbusChallenge, error)
|
|||||||
return nil, fmt.Errorf("unable to find challenge %q", name)
|
return nil, fmt.Errorf("unable to find challenge %q", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AirbusAPI) ValidateChallengeFromUser(userId AirbusUserId, challengeId AirbusChallengeId) (err error) {
|
func (a *AirbusAPI) ValidateChallengeFromUser(team *AirbusTeam, challengeId AirbusChallengeId) (err error) {
|
||||||
err = a.request("GET", fmt.Sprintf("/v1/sessions/%d/%s/%s/validate", a.SessionID, challengeId.String(), userId.String()), nil, nil)
|
if dryRun {
|
||||||
|
log.Printf("ValidateChallenge: %d, %s, %d", a.SessionID, challengeId.String(), team.Members[0].ID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = a.request("GET", fmt.Sprintf("/v1/sessions/%d/%s/%d/validate", a.SessionID, challengeId.String(), team.Members[0].ID), nil, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
type AirbusUserAwards struct {
|
type AirbusUserAwards struct {
|
||||||
UserId AirbusUserId `json:"gaming_user_id"`
|
UserId int64 `json:"gaming_user_id"`
|
||||||
Message string `json:"name"`
|
Message string `json:"name"`
|
||||||
Value int64 `json:"value"`
|
Value int64 `json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AirbusAPI) AwardUser(userId AirbusUserId, value int64, message string) (err error) {
|
func (a *AirbusAPI) AwardUser(team *AirbusTeam, value int64, message string) (err error) {
|
||||||
awards := AirbusUserAwards{
|
awards := AirbusUserAwards{
|
||||||
UserId: userId,
|
UserId: team.Members[0].ID,
|
||||||
Message: message,
|
Message: message,
|
||||||
Value: value,
|
Value: value,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if dryRun {
|
||||||
|
log.Printf("AwardUser: %v", awards)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
j, err := json.Marshal(awards)
|
j, err := json.Marshal(awards)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to marshall JSON from awards struct: %w", err)
|
return fmt.Errorf("unable to marshall JSON from awards struct: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = a.request("POST", fmt.Sprintf("/v1/sessions/%d/awards", a.SessionID), j, nil)
|
err = a.request("POST", fmt.Sprintf("/v1/sessions/%d/awards", a.SessionID), j, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,11 +18,13 @@ import (
|
|||||||
var (
|
var (
|
||||||
TeamsDir string
|
TeamsDir string
|
||||||
skipInitialSync bool
|
skipInitialSync bool
|
||||||
|
dryRun bool
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.StringVar(&TeamsDir, "teams", "./TEAMS", "Base directory where save teams JSON files")
|
flag.StringVar(&TeamsDir, "teams", "./TEAMS", "Base directory where save teams JSON files")
|
||||||
var debugINotify = flag.Bool("debuginotify", false, "Show skipped inotofy events")
|
var debugINotify = flag.Bool("debuginotify", false, "Show skipped inotofy events")
|
||||||
|
flag.BoolVar(&dryRun, "dry-run", dryRun, "Don't perform any write action, just display")
|
||||||
flag.BoolVar(&skipInitialSync, "skipinitialsync", skipInitialSync, "Skip the initial synchronization")
|
flag.BoolVar(&skipInitialSync, "skipinitialsync", skipInitialSync, "Skip the initial synchronization")
|
||||||
flag.BoolVar(&noValidateChallenge, "no-validate-challenge", noValidateChallenge, "Consider challenge validation as a standard award (if each exercice hasn't been imported on their side)")
|
flag.BoolVar(&noValidateChallenge, "no-validate-challenge", noValidateChallenge, "Consider challenge validation as a standard award (if each exercice hasn't been imported on their side)")
|
||||||
daemon := flag.Bool("watch", false, "Enable daemon mode by watching the directory")
|
daemon := flag.Bool("watch", false, "Enable daemon mode by watching the directory")
|
||||||
@ -41,13 +43,27 @@ func main() {
|
|||||||
if v, exists := os.LookupEnv("AIRBUS_TOKEN"); exists {
|
if v, exists := os.LookupEnv("AIRBUS_TOKEN"); exists {
|
||||||
api.Token = v
|
api.Token = v
|
||||||
}
|
}
|
||||||
|
|
||||||
if v, exists := os.LookupEnv("AIRBUS_SESSIONID"); exists {
|
if v, exists := os.LookupEnv("AIRBUS_SESSIONID"); exists {
|
||||||
var err error
|
var err error
|
||||||
api.SessionID, err = strconv.ParseInt(v, 10, 64)
|
api.SessionID, err = strconv.ParseInt(v, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("AIRBUS_SESSIONID is invalid: ", err.Error())
|
log.Fatal("AIRBUS_SESSIONID is invalid: ", err.Error())
|
||||||
}
|
}
|
||||||
|
} else if v, exists := os.LookupEnv("AIRBUS_SESSION_NAME"); exists {
|
||||||
|
sessions, err := api.GetSessions()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Unable to retrieve session: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, session := range sessions {
|
||||||
|
if session.Name == v {
|
||||||
|
api.SessionID = session.ID
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if v, exists := os.LookupEnv("AIRBUS_SESSIONUUID"); exists {
|
if v, exists := os.LookupEnv("AIRBUS_SESSIONUUID"); exists {
|
||||||
api.SessionUUID = v
|
api.SessionUUID = v
|
||||||
}
|
}
|
||||||
@ -62,12 +78,6 @@ func main() {
|
|||||||
log.Fatal("Unable to open timestamp file: ", err.Error())
|
log.Fatal("Unable to open timestamp file: ", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load exercices bindings
|
|
||||||
exbindings, err := ReadExercicesBindings(*exercicespath)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Unable to open exercices bindings file: ", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load teams.json
|
// Load teams.json
|
||||||
teamsbindings, err := getTeams(filepath.Join(TeamsDir, "teams.json"))
|
teamsbindings, err := getTeams(filepath.Join(TeamsDir, "teams.json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -76,17 +86,27 @@ func main() {
|
|||||||
|
|
||||||
w := Walker{
|
w := Walker{
|
||||||
LastSync: ts,
|
LastSync: ts,
|
||||||
Exercices: exbindings,
|
|
||||||
Teams: teamsbindings,
|
Teams: teamsbindings,
|
||||||
API: api,
|
API: api,
|
||||||
Coeff: *coeff,
|
Coeff: *coeff,
|
||||||
}
|
}
|
||||||
|
if err = w.fetchTeams(); err != nil {
|
||||||
|
log.Fatal("Unable to fetch Airbus teams: ", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if !noValidateChallenge {
|
||||||
|
// Load exercices bindings
|
||||||
|
w.Exercices, err = ReadExercicesBindings(*exercicespath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Unable to open exercices bindings file: ", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !skipInitialSync {
|
if !skipInitialSync {
|
||||||
// Iterate over teams scores
|
// Iterate over teams scores
|
||||||
err = filepath.WalkDir(TeamsDir, w.WalkScoreSync)
|
err = filepath.WalkDir(TeamsDir, w.WalkScoreSync)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Something goes wrong during walking")
|
log.Println("Something goes wrong during walking: ", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// save current timestamp for teams
|
// save current timestamp for teams
|
||||||
@ -131,6 +151,9 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Teams = teamsbindings
|
w.Teams = teamsbindings
|
||||||
|
if err = w.fetchTeams(); err != nil {
|
||||||
|
log.Fatal("Unable to fetch teams: ", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
// save current timestamp for teams
|
// save current timestamp for teams
|
||||||
err = saveTS(*tspath, w.LastSync)
|
err = saveTS(*tspath, w.LastSync)
|
||||||
@ -160,6 +183,9 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Teams = teamsbindings
|
w.Teams = teamsbindings
|
||||||
|
if err = w.fetchTeams(); err != nil {
|
||||||
|
log.Fatal("Unable to fetch teams: ", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
|
|
||||||
@ -183,6 +209,9 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Teams = teamsbindings
|
w.Teams = teamsbindings
|
||||||
|
if err = w.fetchTeams(); err != nil {
|
||||||
|
log.Fatal("Unable to fetch teams: ", err.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if ev.Op&fsnotify.Write == fsnotify.Write {
|
} else if ev.Op&fsnotify.Write == fsnotify.Write {
|
||||||
log.Println("FSNOTIFY WRITE SEEN. Prefer looking at them, as it appears files are not atomically moved.")
|
log.Println("FSNOTIFY WRITE SEEN. Prefer looking at them, as it appears files are not atomically moved.")
|
||||||
|
15
remote/challenge-sync-airbus/session.go
Normal file
15
remote/challenge-sync-airbus/session.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import ()
|
||||||
|
|
||||||
|
type Session struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Mode string `json:"mode"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AirbusAPI) GetSessions() (ret []Session, err error) {
|
||||||
|
err = a.request("GET", "/api/v1/sessions", nil, &ret)
|
||||||
|
return
|
||||||
|
}
|
32
remote/challenge-sync-airbus/team.go
Normal file
32
remote/challenge-sync-airbus/team.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AirbusTeam struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Members []TeamMember `json:"members"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TeamMember struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Nickname string `json:"nickname"`
|
||||||
|
EMail string `json:"email"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type airbusDataTeam struct {
|
||||||
|
Data []AirbusTeam `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AirbusAPI) GetTeams() ([]AirbusTeam, error) {
|
||||||
|
var data airbusDataTeam
|
||||||
|
err := a.request("GET", fmt.Sprintf("/api/v1/sessions/%d/teams", a.SessionID), nil, &data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return data.Data, nil
|
||||||
|
}
|
||||||
|
}
|
@ -6,10 +6,15 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadTS(tspath string) (timestamp map[AirbusUserId]time.Time, err error) {
|
type TSValue struct {
|
||||||
|
Time time.Time `json:"t"`
|
||||||
|
Score int64 `json:"s"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadTS(tspath string) (timestamp map[string]*TSValue, err error) {
|
||||||
var fd *os.File
|
var fd *os.File
|
||||||
if _, err = os.Stat(tspath); os.IsNotExist(err) {
|
if _, err = os.Stat(tspath); os.IsNotExist(err) {
|
||||||
timestamp = map[AirbusUserId]time.Time{}
|
timestamp = map[string]*TSValue{}
|
||||||
err = saveTS(tspath, timestamp)
|
err = saveTS(tspath, timestamp)
|
||||||
return
|
return
|
||||||
} else if fd, err = os.Open(tspath); err != nil {
|
} else if fd, err = os.Open(tspath); err != nil {
|
||||||
@ -26,7 +31,7 @@ func loadTS(tspath string) (timestamp map[AirbusUserId]time.Time, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveTS(tspath string, ts map[AirbusUserId]time.Time) error {
|
func saveTS(tspath string, ts map[string]*TSValue) error {
|
||||||
if fd, err := os.Create(tspath); err != nil {
|
if fd, err := os.Create(tspath); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
|
||||||
|
|
||||||
"srs.epita.fr/fic-server/libfic"
|
"srs.epita.fr/fic-server/libfic"
|
||||||
)
|
)
|
||||||
@ -15,55 +15,144 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Walker struct {
|
type Walker struct {
|
||||||
LastSync map[AirbusUserId]time.Time
|
LastSync map[string]*TSValue
|
||||||
Exercices AirbusExercicesBindings
|
Exercices AirbusExercicesBindings
|
||||||
Teams map[string]fic.ExportedTeam
|
Teams map[string]fic.ExportedTeam
|
||||||
|
RevTeams map[string]string
|
||||||
|
TeamBindings map[string]*AirbusTeam
|
||||||
API AirbusAPI
|
API AirbusAPI
|
||||||
Coeff float64
|
Coeff float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Walker) fetchTeams() error {
|
||||||
|
teams, err := w.API.GetTeams()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
w.RevTeams = map[string]string{}
|
||||||
|
w.TeamBindings = map[string]*AirbusTeam{}
|
||||||
|
|
||||||
|
for tid, team := range w.Teams {
|
||||||
|
for _, t := range teams {
|
||||||
|
if team.Name == t.Name || team.ExternalId == t.Name {
|
||||||
|
w.TeamBindings[tid] = &t
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := w.TeamBindings[tid]; !ok {
|
||||||
|
log.Printf("Team binding not found: %s - %s", tid, team.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.RevTeams[team.Name] = tid
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Walker) treat(path string) {
|
func (w *Walker) treat(path string) {
|
||||||
mypath := filepath.Join(filepath.Dir(path), "my.json")
|
teamid := filepath.Base(filepath.Dir(path))
|
||||||
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 _, ok := w.TeamBindings[teamid]; ok {
|
||||||
if err != nil {
|
w.TreatScoreGrid(path, w.TeamBindings[teamid])
|
||||||
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) LoadScoreState(path string) (int64, error) {
|
||||||
|
mypath := filepath.Join(filepath.Dir(path), "airbus.json")
|
||||||
|
if _, err := os.Stat(mypath); os.IsNotExist(err) {
|
||||||
|
fd, err := os.Create(mypath)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
defer fd.Close()
|
||||||
|
|
||||||
|
fd.Write([]byte("0"))
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
fd, err := os.Open(mypath)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
defer fd.Close()
|
||||||
|
|
||||||
|
var ret int64
|
||||||
|
|
||||||
|
jdec := json.NewDecoder(fd)
|
||||||
|
if err := jdec.Decode(&ret); err != nil {
|
||||||
|
return 0, fmt.Errorf("an error occurs when trying to decode airbus.json: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Walker) LoadScoreGrid(path string) ([]fic.ScoreGridRow, error) {
|
||||||
|
fd, err := os.Open(filepath.Join(filepath.Dir(path), "scores.json"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer fd.Close()
|
||||||
|
|
||||||
|
var ret []fic.ScoreGridRow
|
||||||
|
|
||||||
|
jdec := json.NewDecoder(fd)
|
||||||
|
if err := jdec.Decode(&ret); err != nil {
|
||||||
|
return nil, fmt.Errorf("an error occurs when trying to decode airbus.json: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Walker) WalkScoreSync(path string, d os.DirEntry, err error) error {
|
func (w *Walker) WalkScoreSync(path string, d os.DirEntry, err error) error {
|
||||||
if filepath.Base(path) == "scores.json" {
|
if filepath.Base(path) == "scores.json" {
|
||||||
w.treat(path)
|
w.treat(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for team, ts := range w.LastSync {
|
||||||
|
team_id, ok := w.RevTeams[team]
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
myteam, err := w.loadMyFile(filepath.Join(TeamsDir, team_id, "my.json"))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Unable to open %s/my.json: %w", team_id, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
airbusTeam := w.TeamBindings[fmt.Sprintf("%d", myteam.Id)]
|
||||||
|
|
||||||
|
if ts.Score != myteam.Points*int64(w.Coeff) {
|
||||||
|
err := w.API.AwardUser(airbusTeam, myteam.Points-ts.Score, "Équilibrage")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Unable to open %s/my.json: %w", team, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.LastSync[airbusTeam.Name].Score = myteam.Points * int64(w.Coeff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Walker) loadMyFile(path string) (*fic.MyTeam, error) {
|
||||||
|
fd, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer fd.Close()
|
||||||
|
|
||||||
|
var ret fic.MyTeam
|
||||||
|
|
||||||
|
jdec := json.NewDecoder(fd)
|
||||||
|
if err := jdec.Decode(&ret); err != nil {
|
||||||
|
return nil, fmt.Errorf("an error occurs when trying to decode airbus.json: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Walker) WalkScore(path string, d os.DirEntry, err error) error {
|
func (w *Walker) WalkScore(path string, d os.DirEntry, err error) error {
|
||||||
if filepath.Base(path) == "scores.json" {
|
if filepath.Base(path) == "scores.json" {
|
||||||
go w.treat(path)
|
go w.treat(path)
|
||||||
@ -71,7 +160,7 @@ func (w *Walker) WalkScore(path string, d os.DirEntry, err error) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Walker) TreatScoreGrid(path string, airbusTeamId AirbusUserId) error {
|
func (w *Walker) TreatScoreGrid(path string, airbusTeam *AirbusTeam) error {
|
||||||
// Read score grid
|
// Read score grid
|
||||||
fdscores, err := os.Open(path)
|
fdscores, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -85,30 +174,35 @@ func (w *Walker) TreatScoreGrid(path string, airbusTeamId AirbusUserId) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Found all new entries
|
// Found all new entries
|
||||||
maxts := w.LastSync[airbusTeamId]
|
maxts := &TSValue{}
|
||||||
for _, row := range teamscores {
|
if ts, ok := w.LastSync[airbusTeam.Name]; ok {
|
||||||
if row.Time.After(maxts) {
|
maxts = ts
|
||||||
maxts = row.Time
|
|
||||||
}
|
}
|
||||||
if row.Time.After(w.LastSync[airbusTeamId]) {
|
for _, row := range teamscores {
|
||||||
|
if row.Time.After(maxts.Time) {
|
||||||
|
maxts.Time = row.Time
|
||||||
|
}
|
||||||
|
if row.Time.After(w.LastSync[airbusTeam.Name].Time) {
|
||||||
if !noValidateChallenge && row.Reason == "Validation" {
|
if !noValidateChallenge && row.Reason == "Validation" {
|
||||||
err = w.API.ValidateChallengeFromUser(airbusTeamId, w.Exercices[row.IdExercice])
|
err = w.API.ValidateChallengeFromUser(airbusTeam, w.Exercices[row.IdExercice])
|
||||||
} else {
|
} else {
|
||||||
err = w.API.AwardUser(airbusTeamId, int64(row.Points*row.Coeff*w.Coeff), row.Reason)
|
err = w.API.AwardUser(airbusTeam, int64(row.Points*row.Coeff*w.Coeff), row.Reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maxts.Score += int64(row.Points * row.Coeff * w.Coeff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
w.LastSync[airbusTeamId] = maxts
|
w.LastSync[airbusTeam.Name] = maxts
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Walker) BalanceScore(score int64, airbusTeamId AirbusUserId) error {
|
func (w *Walker) BalanceScore(score int64, airbusTeam *AirbusTeam) error {
|
||||||
// Read current score on other platform
|
// Read current score on other platform
|
||||||
stats, err := w.API.GetCurrentStats()
|
stats, err := w.API.GetCurrentStats()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -120,9 +214,9 @@ func (w *Walker) BalanceScore(score int64, airbusTeamId AirbusUserId) error {
|
|||||||
return fmt.Errorf("session not found")
|
return fmt.Errorf("session not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
other_team := my_session.GetTeam(AirbusUUID(airbusTeamId))
|
other_team := my_session.GetTeam(AirbusUUID(airbusTeam.Name))
|
||||||
if other_team == nil {
|
if other_team == nil {
|
||||||
return fmt.Errorf("team %q not found", airbusTeamId)
|
return fmt.Errorf("team %q not found", airbusTeam.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
other_score := other_team.Score
|
other_score := other_team.Score
|
||||||
@ -130,7 +224,7 @@ func (w *Walker) BalanceScore(score int64, airbusTeamId AirbusUserId) error {
|
|||||||
// Send diff to the platform
|
// Send diff to the platform
|
||||||
if other_score != score {
|
if other_score != score {
|
||||||
diff := score - other_score
|
diff := score - other_score
|
||||||
return w.API.AwardUser(airbusTeamId, diff, "Équilibrage")
|
return w.API.AwardUser(airbusTeam, diff, "Équilibrage")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
x
Reference in New Issue
Block a user