From 41a0e6dffc1d935e24393264feda5ce499bf003e Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Thu, 14 Oct 2021 19:01:12 -0600 Subject: [PATCH] Prepend timestamp to award filenames Fixes #168 --- CHANGELOG.md | 4 +++- cmd/mothd/state.go | 9 +++++++-- cmd/mothd/state_test.go | 24 ++++++++++++++++++++++++ pkg/award/award.go | 14 +++++++++++++- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72bba3a..db46649 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [unreleased] ### Fixed -- +- Points awarded while scoring is paused are now correctly sorted (#168) +- Writing a new mothball with the same name is now detected and the new mothball loaded (#172) +- Regression test for issue where URL path leading directories were ignored (#144) ## [v4.2.2] - 2021-09-30 ### Added diff --git a/cmd/mothd/state.go b/cmd/mothd/state.go index e354b22..b8cb231 100644 --- a/cmd/mothd/state.go +++ b/cmd/mothd/state.go @@ -202,8 +202,12 @@ func (s *State) Messages() string { // It's just a courtesy to the user. // The update task makes sure we never have duplicate points in the log. func (s *State) AwardPoints(teamID, category string, points int) error { + return s.awardPointsAtTime(time.Now().Unix(), teamID, category, points) +} + +func (s *State) awardPointsAtTime(when int64, teamID string, category string, points int) error { a := award.T{ - When: time.Now().Unix(), + When: when, TeamID: teamID, Category: category, Points: points, @@ -215,7 +219,8 @@ func (s *State) AwardPoints(teamID, category string, points int) error { } } - fn := fmt.Sprintf("%s-%s-%d", teamID, category, points) + //fn := fmt.Sprintf("%s-%s-%d", a.TeamID, a.Category, a.Points) + fn := a.Filename() tmpfn := filepath.Join("points.tmp", fn) newfn := filepath.Join("points.new", fn) diff --git a/cmd/mothd/state_test.go b/cmd/mothd/state_test.go index 851e222..5cb1097 100644 --- a/cmd/mothd/state_test.go +++ b/cmd/mothd/state_test.go @@ -122,6 +122,30 @@ func TestState(t *testing.T) { } +// Out of order points insertion, issue #168 +func TestStateOutOfOrderAward(t *testing.T) { + s := NewTestState() + + category := "meow" + points := 100 + + now := time.Now().Unix() + if err := s.awardPointsAtTime(now+20, "AA", category, points); err != nil { + t.Error("Awarding points to team ZZ:", err) + } + if err := s.awardPointsAtTime(now+10, "ZZ", category, points); err != nil { + t.Error("Awarding points to team AA:", err) + } + s.refresh() + pl := s.PointsLog() + if len(pl) != 2 { + t.Error("Wrong length for points log") + } + if pl[0].TeamID != "ZZ" { + t.Error("Out of order points insertion not properly sorted in points log") + } +} + func TestStateEvents(t *testing.T) { s := NewTestState() s.LogEvent("moo", "", "", "", 0) diff --git a/pkg/award/award.go b/pkg/award/award.go index a589866..fda4c05 100644 --- a/pkg/award/award.go +++ b/pkg/award/award.go @@ -5,6 +5,7 @@ import ( "bytes" "encoding/json" "fmt" + "net/url" "reflect" "strconv" "strings" @@ -49,7 +50,7 @@ func Parse(s string) (T, error) { if err != nil { return ret, err } else if n != 4 { - return ret, fmt.Errorf("Malformed award string: only parsed %d fields", n) + return ret, fmt.Errorf("malformed award string: only parsed %d fields", n) } return ret, nil @@ -60,6 +61,17 @@ func (a T) String() string { return fmt.Sprintf("%d %s %s %d", a.When, a.TeamID, a.Category, a.Points) } +// Filename returns a string version of an award suitable for a filesystem +func (a T) Filename() string { + return fmt.Sprintf( + "%d-%s-%s-%d.award", + a.When, + url.PathEscape(a.TeamID), + url.PathEscape(a.Category), + a.Points, + ) +} + // MarshalJSON returns the award event, encoded as a list. func (a T) MarshalJSON() ([]byte, error) { ao := []interface{}{