2022-08-21 05:19:17 +00:00
|
|
|
package service
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"gitea.dwysokinski.me/twhelp/core/internal/domain"
|
2022-12-20 07:27:13 +00:00
|
|
|
"gitea.dwysokinski.me/twhelp/core/internal/tw"
|
2022-08-21 05:19:17 +00:00
|
|
|
)
|
|
|
|
|
2022-09-06 07:50:00 +00:00
|
|
|
const (
|
2022-09-07 04:16:46 +00:00
|
|
|
ennoblementChunkSize = 1000
|
2022-10-19 04:25:26 +00:00
|
|
|
ennoblementMaxLimit = 200
|
2022-09-06 07:50:00 +00:00
|
|
|
ennoblementSortMaxLen = 2
|
|
|
|
)
|
|
|
|
|
2022-08-21 05:19:17 +00:00
|
|
|
var (
|
|
|
|
errEnnoblementNotFound = errors.New("ennoblement not found")
|
|
|
|
)
|
|
|
|
|
|
|
|
//counterfeiter:generate -o internal/mock/ennoblement_repository.gen.go . EnnoblementRepository
|
|
|
|
type EnnoblementRepository interface {
|
|
|
|
Create(ctx context.Context, params ...domain.CreateEnnoblementParams) error
|
2022-12-24 09:21:26 +00:00
|
|
|
List(ctx context.Context, params domain.ListEnnoblementsParams) ([]domain.Ennoblement, error)
|
|
|
|
ListCountWithRelations(
|
2022-10-21 05:19:04 +00:00
|
|
|
ctx context.Context,
|
|
|
|
params domain.ListEnnoblementsParams,
|
|
|
|
) ([]domain.EnnoblementWithRelations, int64, error)
|
2022-12-30 08:00:25 +00:00
|
|
|
Delete(ctx context.Context, serverKey string, createdAtLTE time.Time) error
|
2022-08-21 05:19:17 +00:00
|
|
|
}
|
|
|
|
|
2022-09-16 05:08:33 +00:00
|
|
|
//counterfeiter:generate -o internal/mock/ennoblement_getter.gen.go . EnnoblementGetter
|
|
|
|
type EnnoblementGetter interface {
|
2022-10-20 04:16:37 +00:00
|
|
|
GetEnnoblements(ctx context.Context, baseURL string, since time.Time) ([]tw.Ennoblement, error)
|
2022-08-21 05:19:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type Ennoblement struct {
|
|
|
|
repo EnnoblementRepository
|
2022-09-16 05:08:33 +00:00
|
|
|
client EnnoblementGetter
|
2022-08-21 05:19:17 +00:00
|
|
|
}
|
|
|
|
|
2022-09-16 05:08:33 +00:00
|
|
|
func NewEnnoblement(repo EnnoblementRepository, client EnnoblementGetter) *Ennoblement {
|
2022-08-21 05:19:17 +00:00
|
|
|
return &Ennoblement{repo: repo, client: client}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Ennoblement) Refresh(ctx context.Context, key, url string) error {
|
|
|
|
latestEnnoblement, err := e.getLatestEnnoblement(ctx, key)
|
|
|
|
if err != nil && !errors.Is(err, errEnnoblementNotFound) {
|
|
|
|
return fmt.Errorf("EnnoblementService.getLatestEnnoblements: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var since time.Time
|
|
|
|
if err == nil {
|
|
|
|
since = latestEnnoblement.CreatedAt
|
|
|
|
}
|
|
|
|
|
|
|
|
ennoblements, err := e.client.GetEnnoblements(ctx, url, since)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("TWClient.GetEnnoblements: %w", err)
|
|
|
|
}
|
|
|
|
|
2022-09-07 04:16:46 +00:00
|
|
|
for i := 0; i < len(ennoblements); i += ennoblementChunkSize {
|
|
|
|
end := i + ennoblementChunkSize
|
|
|
|
if end > len(ennoblements) {
|
|
|
|
end = len(ennoblements)
|
|
|
|
}
|
|
|
|
|
|
|
|
chunk := ennoblements[i:end]
|
|
|
|
|
|
|
|
params := make([]domain.CreateEnnoblementParams, 0, len(chunk))
|
|
|
|
for _, ennoblement := range chunk {
|
|
|
|
params = append(params, domain.CreateEnnoblementParams{
|
2022-10-20 04:16:37 +00:00
|
|
|
VillageID: ennoblement.VillageID,
|
|
|
|
NewOwnerID: ennoblement.NewOwnerID,
|
|
|
|
NewTribeID: ennoblement.NewTribeID,
|
|
|
|
OldOwnerID: ennoblement.OldOwnerID,
|
|
|
|
OldTribeID: ennoblement.OldTribeID,
|
|
|
|
Points: ennoblement.Points,
|
|
|
|
CreatedAt: ennoblement.CreatedAt,
|
|
|
|
ServerKey: key,
|
2022-09-07 04:16:46 +00:00
|
|
|
})
|
|
|
|
}
|
2022-10-20 04:16:37 +00:00
|
|
|
if err = e.repo.Create(ctx, params...); err != nil {
|
2022-09-07 04:16:46 +00:00
|
|
|
return fmt.Errorf("EnnoblementRepository.Create: %w", err)
|
|
|
|
}
|
2022-08-21 05:19:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-12-24 09:21:26 +00:00
|
|
|
func (e *Ennoblement) ListCountWithRelations(
|
2022-10-21 05:19:04 +00:00
|
|
|
ctx context.Context,
|
|
|
|
params domain.ListEnnoblementsParams,
|
|
|
|
) ([]domain.EnnoblementWithRelations, int64, error) {
|
2022-09-06 07:50:00 +00:00
|
|
|
if len(params.Sort) == 0 {
|
|
|
|
params.Sort = []domain.EnnoblementSort{
|
|
|
|
{
|
|
|
|
By: domain.EnnoblementSortByID,
|
|
|
|
Direction: domain.SortDirectionASC,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(params.Sort) > ennoblementSortMaxLen {
|
2022-12-20 07:27:13 +00:00
|
|
|
return nil, 0, domain.ValidationError{
|
2022-09-06 07:50:00 +00:00
|
|
|
Field: "sort",
|
|
|
|
Err: domain.MaxLengthError{
|
|
|
|
Max: ennoblementSortMaxLen,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if params.Pagination.Limit == 0 {
|
|
|
|
params.Pagination.Limit = ennoblementMaxLimit
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := validatePagination(params.Pagination, ennoblementMaxLimit); err != nil {
|
|
|
|
return nil, 0, fmt.Errorf("validatePagination: %w", err)
|
|
|
|
}
|
|
|
|
|
2022-12-24 09:21:26 +00:00
|
|
|
ennoblements, count, err := e.repo.ListCountWithRelations(ctx, params)
|
2022-09-06 07:50:00 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, 0, fmt.Errorf("EnnoblementRepository.List: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return ennoblements, count, nil
|
|
|
|
}
|
|
|
|
|
2022-12-24 09:21:26 +00:00
|
|
|
func (e *Ennoblement) getLatestEnnoblement(ctx context.Context, key string) (domain.Ennoblement, error) {
|
|
|
|
ennoblements, err := e.repo.List(ctx, domain.ListEnnoblementsParams{
|
2022-08-21 05:19:17 +00:00
|
|
|
ServerKeys: []string{key},
|
|
|
|
Pagination: domain.Pagination{
|
|
|
|
Limit: 1,
|
|
|
|
},
|
|
|
|
Sort: []domain.EnnoblementSort{
|
|
|
|
{By: domain.EnnoblementSortByCreatedAt, Direction: domain.SortDirectionDESC},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
2022-12-24 09:21:26 +00:00
|
|
|
return domain.Ennoblement{}, fmt.Errorf("EnnoblementRepository.List: %w", err)
|
2022-08-21 05:19:17 +00:00
|
|
|
}
|
|
|
|
if len(ennoblements) == 0 {
|
2022-12-24 09:21:26 +00:00
|
|
|
return domain.Ennoblement{}, errEnnoblementNotFound
|
2022-08-21 05:19:17 +00:00
|
|
|
}
|
2022-09-12 05:34:46 +00:00
|
|
|
|
2022-08-21 05:19:17 +00:00
|
|
|
return ennoblements[0], nil
|
|
|
|
}
|
2022-12-30 08:00:25 +00:00
|
|
|
|
|
|
|
func (e *Ennoblement) CleanUp(ctx context.Context, srv domain.Server) error {
|
|
|
|
if srv.Special || srv.Open || srv.EnnoblementDataUpdatedAt.After(time.Now().Add(-30*24*time.Hour) /* 30 days */) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// delete ennoblements older than 1 year
|
|
|
|
if err := e.repo.Delete(ctx, srv.Key, time.Now().Add(-365*24*time.Hour)); err != nil {
|
|
|
|
return fmt.Errorf("couldn't delete old ennoblements: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|