mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
chore: generate leaderboard when enabled in user settings
This commit is contained in:
parent
13a3d9f03a
commit
4a22a19cb0
@ -66,7 +66,7 @@ var env string
|
|||||||
|
|
||||||
type appConfig struct {
|
type appConfig struct {
|
||||||
AggregationTime string `yaml:"aggregation_time" default:"02:15" env:"WAKAPI_AGGREGATION_TIME"`
|
AggregationTime string `yaml:"aggregation_time" default:"02:15" env:"WAKAPI_AGGREGATION_TIME"`
|
||||||
LeaderboardGenerationTime string `yaml:"leaderboard_generation_time" default:"06:00,18:00" env:"WAKAPI_LEADERBOARD_GENERATION_TIME"`
|
LeaderboardGenerationTime string `yaml:"leaderboard_generation_time" default:"06:00;18:00" env:"WAKAPI_LEADERBOARD_GENERATION_TIME"`
|
||||||
ReportTimeWeekly string `yaml:"report_time_weekly" default:"fri,18:00" env:"WAKAPI_REPORT_TIME_WEEKLY"`
|
ReportTimeWeekly string `yaml:"report_time_weekly" default:"fri,18:00" env:"WAKAPI_REPORT_TIME_WEEKLY"`
|
||||||
ImportBackoffMin int `yaml:"import_backoff_min" default:"5" env:"WAKAPI_IMPORT_BACKOFF_MIN"`
|
ImportBackoffMin int `yaml:"import_backoff_min" default:"5" env:"WAKAPI_IMPORT_BACKOFF_MIN"`
|
||||||
ImportBatchSize int `yaml:"import_batch_size" default:"50" env:"WAKAPI_IMPORT_BATCH_SIZE"`
|
ImportBatchSize int `yaml:"import_batch_size" default:"50" env:"WAKAPI_IMPORT_BATCH_SIZE"`
|
||||||
|
@ -69,6 +69,7 @@ type UserDataUpdate struct {
|
|||||||
Email string `schema:"email"`
|
Email string `schema:"email"`
|
||||||
Location string `schema:"location"`
|
Location string `schema:"location"`
|
||||||
ReportsWeekly bool `schema:"reports_weekly"`
|
ReportsWeekly bool `schema:"reports_weekly"`
|
||||||
|
PublicLeaderboard bool `schema:"public_leaderboard"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TimeByUser struct {
|
type TimeByUser struct {
|
||||||
|
@ -24,6 +24,15 @@ func (r *LeaderboardRepository) InsertBatch(items []*models.LeaderboardItem) err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *LeaderboardRepository) CountAllByUser(userId string) (int64, error) {
|
||||||
|
var count int64
|
||||||
|
err := r.db.
|
||||||
|
Table("leaderboard_items").
|
||||||
|
Where("user_id = ?", userId).
|
||||||
|
Count(&count).Error
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
|
|
||||||
func (r *LeaderboardRepository) GetAllAggregatedByInterval(key *models.IntervalKey, by *uint8) ([]*models.LeaderboardItem, error) {
|
func (r *LeaderboardRepository) GetAllAggregatedByInterval(key *models.IntervalKey, by *uint8) ([]*models.LeaderboardItem, error) {
|
||||||
// TODO: distinct by (user, key) to filter out potential duplicates ?
|
// TODO: distinct by (user, key) to filter out potential duplicates ?
|
||||||
var items []*models.LeaderboardItem
|
var items []*models.LeaderboardItem
|
||||||
|
@ -88,6 +88,7 @@ type IUserRepository interface {
|
|||||||
|
|
||||||
type ILeaderboardRepository interface {
|
type ILeaderboardRepository interface {
|
||||||
InsertBatch([]*models.LeaderboardItem) error
|
InsertBatch([]*models.LeaderboardItem) error
|
||||||
|
CountAllByUser(string) (int64, error)
|
||||||
DeleteByUserAndInterval(string, *models.IntervalKey) error
|
DeleteByUserAndInterval(string, *models.IntervalKey) error
|
||||||
GetAllAggregatedByInterval(*models.IntervalKey, *uint8) ([]*models.LeaderboardItem, error)
|
GetAllAggregatedByInterval(*models.IntervalKey, *uint8) ([]*models.LeaderboardItem, error)
|
||||||
GetAggregatedByUserAndInterval(string, *models.IntervalKey, *uint8) ([]*models.LeaderboardItem, error)
|
GetAggregatedByUserAndInterval(string, *models.IntervalKey, *uint8) ([]*models.LeaderboardItem, error)
|
||||||
|
@ -182,6 +182,7 @@ func (h *SettingsHandler) actionUpdateUser(w http.ResponseWriter, r *http.Reques
|
|||||||
user.Email = payload.Email
|
user.Email = payload.Email
|
||||||
user.Location = payload.Location
|
user.Location = payload.Location
|
||||||
user.ReportsWeekly = payload.ReportsWeekly
|
user.ReportsWeekly = payload.ReportsWeekly
|
||||||
|
user.PublicLeaderboard = payload.PublicLeaderboard
|
||||||
|
|
||||||
if _, err := h.userSrvc.Update(user); err != nil {
|
if _, err := h.userSrvc.Update(user); err != nil {
|
||||||
return http.StatusInternalServerError, "", conf.ErrInternalServerError
|
return http.StatusInternalServerError, "", conf.ErrInternalServerError
|
||||||
|
@ -2,6 +2,7 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/emvi/logbuch"
|
"github.com/emvi/logbuch"
|
||||||
|
"github.com/go-co-op/gocron"
|
||||||
"github.com/leandro-lugaresi/hub"
|
"github.com/leandro-lugaresi/hub"
|
||||||
"github.com/muety/wakapi/config"
|
"github.com/muety/wakapi/config"
|
||||||
"github.com/muety/wakapi/models"
|
"github.com/muety/wakapi/models"
|
||||||
@ -21,7 +22,7 @@ type LeaderboardService struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewLeaderboardService(leaderboardRepo repositories.ILeaderboardRepository, summaryService ISummaryService, userService IUserService) *LeaderboardService {
|
func NewLeaderboardService(leaderboardRepo repositories.ILeaderboardRepository, summaryService ISummaryService, userService IUserService) *LeaderboardService {
|
||||||
return &LeaderboardService{
|
srv := &LeaderboardService{
|
||||||
config: config.Get(),
|
config: config.Get(),
|
||||||
cache: cache.New(24*time.Hour, 24*time.Hour),
|
cache: cache.New(24*time.Hour, 24*time.Hour),
|
||||||
eventBus: config.EventBus(),
|
eventBus: config.EventBus(),
|
||||||
@ -29,6 +30,28 @@ func NewLeaderboardService(leaderboardRepo repositories.ILeaderboardRepository,
|
|||||||
summaryService: summaryService,
|
summaryService: summaryService,
|
||||||
userService: userService,
|
userService: userService,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onUserUpdate := srv.eventBus.Subscribe(0, config.EventUserUpdate)
|
||||||
|
go func(sub *hub.Subscription) {
|
||||||
|
for m := range sub.Receiver {
|
||||||
|
|
||||||
|
// generate leaderboard for updated user, if leaderboard enabled and none present, yet
|
||||||
|
user := m.Fields[config.FieldPayload].(*models.User)
|
||||||
|
if user.PublicLeaderboard {
|
||||||
|
exists, err := srv.ExistsAnyByUser(user.ID)
|
||||||
|
if err != nil {
|
||||||
|
config.Log().Error("failed to check existing leaderboards upon user update - %v", err)
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
logbuch.Info("generating leaderboard for '%s' after settings update", user.ID)
|
||||||
|
srv.Run([]*models.User{user}, models.IntervalPast7Days, []uint8{models.SummaryLanguage})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}(&onUserUpdate)
|
||||||
|
|
||||||
|
return srv
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *LeaderboardService) ScheduleDefault() {
|
func (srv *LeaderboardService) ScheduleDefault() {
|
||||||
@ -42,11 +65,9 @@ func (srv *LeaderboardService) ScheduleDefault() {
|
|||||||
srv.Run(users, interval, by)
|
srv.Run(users, interval, by)
|
||||||
}
|
}
|
||||||
|
|
||||||
runAllUsers(models.IntervalPast7Days, []uint8{models.SummaryLanguage})
|
s := gocron.NewScheduler(time.Local)
|
||||||
|
s.Every(1).Day().At(srv.config.App.LeaderboardGenerationTime).Do(runAllUsers, models.IntervalPast7Days, []uint8{models.SummaryLanguage})
|
||||||
//s := gocron.NewScheduler(time.Local)
|
s.StartBlocking()
|
||||||
//s.Every(1).Day().At(srv.config.App.LeaderboardGenerationTime).Do(runAllUsers, models.IntervalPast7Days, []uint8{models.SummaryLanguage})
|
|
||||||
//s.StartBlocking()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *LeaderboardService) Run(users []*models.User, interval *models.IntervalKey, by []uint8) error {
|
func (srv *LeaderboardService) Run(users []*models.User, interval *models.IntervalKey, by []uint8) error {
|
||||||
@ -92,6 +113,11 @@ func (srv *LeaderboardService) Run(users []*models.User, interval *models.Interv
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (srv *LeaderboardService) ExistsAnyByUser(userId string) (bool, error) {
|
||||||
|
count, err := srv.repository.CountAllByUser(userId)
|
||||||
|
return count > 0, err
|
||||||
|
}
|
||||||
|
|
||||||
func (srv *LeaderboardService) GetByInterval(interval *models.IntervalKey) ([]*models.LeaderboardItem, error) {
|
func (srv *LeaderboardService) GetByInterval(interval *models.IntervalKey) ([]*models.LeaderboardItem, error) {
|
||||||
return srv.GetAggregatedByInterval(interval, nil)
|
return srv.GetAggregatedByInterval(interval, nil)
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,7 @@ type IReportService interface {
|
|||||||
type ILeaderboardService interface {
|
type ILeaderboardService interface {
|
||||||
ScheduleDefault()
|
ScheduleDefault()
|
||||||
Run([]*models.User, *models.IntervalKey, []uint8) error
|
Run([]*models.User, *models.IntervalKey, []uint8) error
|
||||||
|
ExistsAnyByUser(string) (bool, error)
|
||||||
GetByInterval(*models.IntervalKey) ([]*models.LeaderboardItem, error)
|
GetByInterval(*models.IntervalKey) ([]*models.LeaderboardItem, error)
|
||||||
GetAggregatedByInterval(*models.IntervalKey, *uint8) ([]*models.LeaderboardItem, error)
|
GetAggregatedByInterval(*models.IntervalKey, *uint8) ([]*models.LeaderboardItem, error)
|
||||||
GenerateByUser(*models.User, *models.IntervalKey) (*models.LeaderboardItem, error)
|
GenerateByUser(*models.User, *models.IntervalKey) (*models.LeaderboardItem, error)
|
||||||
|
Loading…
Reference in New Issue
Block a user