parent
6415b162de
commit
4012bd0a2f
|
@ -31,6 +31,7 @@ func (g *Group) Create(ctx context.Context, params domain.CreateGroupParams) (do
|
|||
ServerKey: params.ServerKey(),
|
||||
Barbarians: params.Barbarians(),
|
||||
Internals: params.Internals(),
|
||||
LanguageTag: params.LanguageTag(),
|
||||
}
|
||||
|
||||
if _, err := g.db.NewInsert().
|
||||
|
@ -232,6 +233,14 @@ func (u updateGroupsParamsApplier) apply(q *bun.UpdateQuery) *bun.UpdateQuery {
|
|||
}
|
||||
}
|
||||
|
||||
if u.params.LanguageTag.Valid {
|
||||
if u.params.LanguageTag.String != "" {
|
||||
q = q.Set("language_tag = ?", u.params.LanguageTag.String)
|
||||
} else {
|
||||
q = q.Set("language_tag = NULL")
|
||||
}
|
||||
}
|
||||
|
||||
if u.params.Barbarians.Valid {
|
||||
q = q.Set("barbarians = ?", u.params.Barbarians.Bool)
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func TestGroup_Create(t *testing.T) {
|
||||
|
@ -28,6 +29,7 @@ func TestGroup_Create(t *testing.T) {
|
|||
"592292203234328587",
|
||||
"en",
|
||||
"en113",
|
||||
language.Polish.String(),
|
||||
"1234",
|
||||
"1235",
|
||||
true,
|
||||
|
@ -45,6 +47,7 @@ func TestGroup_Create(t *testing.T) {
|
|||
assert.Equal(t, params.ChannelLosses(), group.ChannelLosses)
|
||||
assert.Equal(t, params.Barbarians(), group.Barbarians)
|
||||
assert.Equal(t, params.Internals(), group.Internals)
|
||||
assert.Equal(t, params.LanguageTag(), group.LanguageTag)
|
||||
assert.WithinDuration(t, time.Now(), group.CreatedAt, 1*time.Second)
|
||||
})
|
||||
}
|
||||
|
@ -73,6 +76,10 @@ func TestGroup_Update(t *testing.T) {
|
|||
String: group.ChannelLosses + "update",
|
||||
Valid: true,
|
||||
},
|
||||
LanguageTag: domain.NullString{
|
||||
String: language.AmericanEnglish.String(),
|
||||
Valid: true,
|
||||
},
|
||||
Barbarians: domain.NullBool{
|
||||
Bool: !group.Barbarians,
|
||||
Valid: true,
|
||||
|
@ -87,6 +94,7 @@ func TestGroup_Update(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Equal(t, params.ChannelGains.String, updatedGroup.ChannelGains)
|
||||
assert.Equal(t, params.ChannelLosses.String, updatedGroup.ChannelLosses)
|
||||
assert.Equal(t, params.LanguageTag.String, updatedGroup.LanguageTag)
|
||||
assert.Equal(t, params.Barbarians.Bool, updatedGroup.Barbarians)
|
||||
assert.Equal(t, params.Internals.Bool, updatedGroup.Internals)
|
||||
})
|
||||
|
|
|
@ -19,6 +19,7 @@ type Group struct {
|
|||
Barbarians bool `bun:"barbarians"`
|
||||
ServerKey string `bun:"server_key,nullzero"`
|
||||
VersionCode string `bun:"version_code,nullzero"`
|
||||
LanguageTag string `bun:"language_tag,nullzero"`
|
||||
CreatedAt time.Time `bun:"created_at,nullzero"`
|
||||
Monitors []Monitor `bun:"monitors,rel:has-many,join:id=group_id"`
|
||||
}
|
||||
|
@ -38,6 +39,7 @@ func (g Group) ToDomain() domain.GroupWithMonitors {
|
|||
Barbarians: g.Barbarians,
|
||||
ServerKey: g.ServerKey,
|
||||
VersionCode: g.VersionCode,
|
||||
LanguageTag: g.LanguageTag,
|
||||
CreatedAt: g.CreatedAt,
|
||||
},
|
||||
Monitors: monitors,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
server_key: pl181
|
||||
version_code: pl
|
||||
channel_losses: 125
|
||||
language_tag: pl
|
||||
created_at: 2022-03-15T15:00:10.000Z
|
||||
- _id: group-2-server-1
|
||||
id: 429b790e-7186-4106-b531-4cc4931ce2ba
|
||||
|
@ -13,12 +14,14 @@
|
|||
server_key: pl181
|
||||
version_code: pl
|
||||
channel_gains: 125
|
||||
language_tag: pl
|
||||
created_at: 2022-03-15T15:03:10.000Z
|
||||
- _id: group-1-server-2
|
||||
id: abeb6c8e-70b6-445c-989f-890cd2a1f87a
|
||||
server_id: server-2
|
||||
server_key: pl181
|
||||
version_code: pl
|
||||
language_tag: pl
|
||||
created_at: 2022-03-18T15:03:10.000Z
|
||||
- _id: group-2-server-2
|
||||
id: 0be82203-4ca3-4b4c-a0c8-3a70099d88f7
|
||||
|
@ -27,6 +30,7 @@
|
|||
version_code: pl
|
||||
channel_gains: 1555
|
||||
channel_losses: 1235
|
||||
language_tag: pl
|
||||
created_at: 2022-03-19T15:03:10.000Z
|
||||
- _id: group-3-server-1
|
||||
id: 982a9765-471c-43e8-9abb-1e4ee4f03738
|
||||
|
@ -35,6 +39,7 @@
|
|||
version_code: pl
|
||||
channel_gains: 1555
|
||||
channel_losses: 1235
|
||||
language_tag: pl
|
||||
created_at: 2022-03-23T18:03:10.000Z
|
||||
- _id: group-3-server-2
|
||||
id: f3a0a5d9-07fe-4770-8b43-79cbe10bb310
|
||||
|
@ -43,6 +48,7 @@
|
|||
version_code: en
|
||||
channel_gains: 1555
|
||||
channel_losses: 1235
|
||||
language_tag: en
|
||||
created_at: 2022-04-23T18:03:10.000Z
|
||||
- model: Monitor
|
||||
rows:
|
||||
|
|
|
@ -17,6 +17,7 @@ type GroupService interface {
|
|||
Create(ctx context.Context, params domain.CreateGroupParams) (domain.GroupWithMonitors, error)
|
||||
AddTribe(ctx context.Context, id, serverID, tribeTag string) (domain.GroupWithMonitors, error)
|
||||
RemoveTribe(ctx context.Context, id, serverID, tribeTag string) (domain.GroupWithMonitors, error)
|
||||
SetLanguageTag(ctx context.Context, id, serverID, languageTag string) (domain.GroupWithMonitors, error)
|
||||
SetChannelGains(ctx context.Context, id, serverID, channel string) (domain.GroupWithMonitors, error)
|
||||
SetChannelLosses(ctx context.Context, id, serverID, channel string) (domain.GroupWithMonitors, error)
|
||||
SetInternals(ctx context.Context, id, serverID string, internals bool) (domain.GroupWithMonitors, error)
|
||||
|
@ -54,7 +55,7 @@ func NewBot(
|
|||
|
||||
s, err := discordgo.New("Bot " + token)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("discordgo.New: %w", err)
|
||||
return nil, err
|
||||
}
|
||||
s.Identify.Intents = discordgo.IntentsNone
|
||||
|
||||
|
@ -80,16 +81,16 @@ func NewBot(
|
|||
|
||||
func (b *Bot) Run() error {
|
||||
if err := b.registerCronJobs(); err != nil {
|
||||
return fmt.Errorf("initCron: %w", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := b.session.Open(); err != nil {
|
||||
return fmt.Errorf("s.Open: %w", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := b.registerCommands(); err != nil {
|
||||
_ = b.session.Close()
|
||||
return fmt.Errorf("couldn't register commands: %w", err)
|
||||
return err
|
||||
}
|
||||
|
||||
b.cron.Run()
|
||||
|
@ -123,7 +124,7 @@ func (b *Bot) registerCronJobs() error {
|
|||
}{
|
||||
{
|
||||
spec: "@every 1m",
|
||||
job: &executeMonitorsJob{svc: b.groupSvc, s: b.session, logger: b.logger},
|
||||
job: &executeMonitorsJob{svc: b.groupSvc, s: b.session, localizer: b.localizer, logger: b.logger},
|
||||
},
|
||||
{
|
||||
spec: "0 */8 * * *",
|
||||
|
|
|
@ -80,7 +80,7 @@ func (c *groupCommand) create(s *discordgo.Session) error {
|
|||
}
|
||||
|
||||
func (c *groupCommand) buildSubcommandCreate() (*discordgo.ApplicationCommandOption, error) {
|
||||
versionChoices, err := c.getVersionChoices()
|
||||
options, err := c.buildSubcommandCreateOptions()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -90,6 +90,26 @@ func (c *groupCommand) buildSubcommandCreate() (*discordgo.ApplicationCommandOpt
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return &discordgo.ApplicationCommandOption{
|
||||
Name: "create",
|
||||
Description: cmdDescriptionDefault,
|
||||
DescriptionLocalizations: cmdDescriptionLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionSubCommand,
|
||||
Options: options,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *groupCommand) buildSubcommandCreateOptions() ([]*discordgo.ApplicationCommandOption, error) {
|
||||
versionChoices, err := c.getVersionChoices()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
languageChoices, err := c.getLanguageChoices()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
optionVersionDefault, optionVersionLocalizations, err := c.localizer.LocalizeDiscord("cmd.group.create.option.version.description")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -115,6 +135,11 @@ func (c *groupCommand) buildSubcommandCreate() (*discordgo.ApplicationCommandOpt
|
|||
return nil, err
|
||||
}
|
||||
|
||||
optionLanguageDefault, optionLanguageLocalizations, err := c.localizer.LocalizeDiscord("cmd.group.create.option.language.description")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
optionChannelLossesDefault, optionChannelLossesLocalizations, err := c.localizer.LocalizeDiscord(
|
||||
"cmd.group.create.option.channel-losses.description",
|
||||
)
|
||||
|
@ -122,65 +147,101 @@ func (c *groupCommand) buildSubcommandCreate() (*discordgo.ApplicationCommandOpt
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return &discordgo.ApplicationCommandOption{
|
||||
Name: "create",
|
||||
Description: cmdDescriptionDefault,
|
||||
DescriptionLocalizations: cmdDescriptionLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionSubCommand,
|
||||
Options: []*discordgo.ApplicationCommandOption{
|
||||
{
|
||||
Name: "version",
|
||||
Description: optionVersionDefault,
|
||||
DescriptionLocalizations: optionVersionLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionString,
|
||||
Choices: versionChoices,
|
||||
Required: true,
|
||||
return []*discordgo.ApplicationCommandOption{
|
||||
{
|
||||
Name: "version",
|
||||
Description: optionVersionDefault,
|
||||
DescriptionLocalizations: optionVersionLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionString,
|
||||
Choices: versionChoices,
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Name: "server",
|
||||
Description: optionServerDefault,
|
||||
DescriptionLocalizations: optionServerLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionString,
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Name: "language",
|
||||
Description: optionLanguageDefault,
|
||||
DescriptionLocalizations: optionLanguageLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionString,
|
||||
Choices: languageChoices,
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Name: "internals",
|
||||
Description: optionInternalsDefault,
|
||||
DescriptionLocalizations: optionInternalsLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionBoolean,
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Name: "barbarians",
|
||||
Description: optionBarbariansDefault,
|
||||
DescriptionLocalizations: optionBarbariansLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionBoolean,
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Name: "channel-gains",
|
||||
Description: optionChannelGainsDefault,
|
||||
DescriptionLocalizations: optionChannelGainsLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionChannel,
|
||||
ChannelTypes: []discordgo.ChannelType{
|
||||
discordgo.ChannelTypeGuildText,
|
||||
},
|
||||
{
|
||||
Name: "server",
|
||||
Description: optionServerDefault,
|
||||
DescriptionLocalizations: optionServerLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionString,
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Name: "internals",
|
||||
Description: optionInternalsDefault,
|
||||
DescriptionLocalizations: optionInternalsLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionBoolean,
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Name: "barbarians",
|
||||
Description: optionBarbariansDefault,
|
||||
DescriptionLocalizations: optionBarbariansLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionBoolean,
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Name: "channel-gains",
|
||||
Description: optionChannelGainsDefault,
|
||||
DescriptionLocalizations: optionChannelGainsLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionChannel,
|
||||
ChannelTypes: []discordgo.ChannelType{
|
||||
discordgo.ChannelTypeGuildText,
|
||||
},
|
||||
Required: false,
|
||||
},
|
||||
{
|
||||
Name: "channel-losses",
|
||||
Description: optionChannelLossesDefault,
|
||||
DescriptionLocalizations: optionChannelLossesLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionChannel,
|
||||
ChannelTypes: []discordgo.ChannelType{
|
||||
discordgo.ChannelTypeGuildText,
|
||||
},
|
||||
Required: false,
|
||||
Required: false,
|
||||
},
|
||||
{
|
||||
Name: "channel-losses",
|
||||
Description: optionChannelLossesDefault,
|
||||
DescriptionLocalizations: optionChannelLossesLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionChannel,
|
||||
ChannelTypes: []discordgo.ChannelType{
|
||||
discordgo.ChannelTypeGuildText,
|
||||
},
|
||||
Required: false,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *groupCommand) getVersionChoices() ([]*discordgo.ApplicationCommandOptionChoice, error) {
|
||||
choices, err := c.choiceSvc.Versions(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ChoiceService.Versions: %w", err)
|
||||
}
|
||||
|
||||
dcChoices := make([]*discordgo.ApplicationCommandOptionChoice, 0, len(choices))
|
||||
for _, v := range choices {
|
||||
dcChoices = append(dcChoices, &discordgo.ApplicationCommandOptionChoice{
|
||||
Name: v.Name,
|
||||
Value: v.Value,
|
||||
})
|
||||
}
|
||||
|
||||
return dcChoices, nil
|
||||
}
|
||||
|
||||
func (c *groupCommand) getLanguageChoices() ([]*discordgo.ApplicationCommandOptionChoice, error) {
|
||||
tags := c.localizer.LanguageTags()
|
||||
choices := make([]*discordgo.ApplicationCommandOptionChoice, 0, len(tags))
|
||||
for _, tag := range tags {
|
||||
lang, langLocalizations, err := c.localizer.LocalizeDiscord(buildLangMessageID(tag.String()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
choices = append(choices, &discordgo.ApplicationCommandOptionChoice{
|
||||
Name: lang,
|
||||
NameLocalizations: langLocalizations,
|
||||
Value: tag.String(),
|
||||
})
|
||||
}
|
||||
return choices, nil
|
||||
}
|
||||
|
||||
func (c *groupCommand) buildSubcommandList() (*discordgo.ApplicationCommandOption, error) {
|
||||
cmdDescriptionDefault, cmdDescriptionLocalizations, err := c.localizer.LocalizeDiscord("cmd.group.list.description")
|
||||
if err != nil {
|
||||
|
@ -329,6 +390,7 @@ func (c *groupCommand) buildSubcommandMonitorRemove() (*discordgo.ApplicationCom
|
|||
|
||||
func (c *groupCommand) buildSubcommandSet() (*discordgo.ApplicationCommandOption, error) {
|
||||
subcommandBuilders := []func() (*discordgo.ApplicationCommandOption, error){
|
||||
c.buildSubcommandSetLanguage,
|
||||
c.buildSubcommandSetChannelGains,
|
||||
c.buildSubcommandSetChannelLosses,
|
||||
c.buildSubcommandSetInternals,
|
||||
|
@ -357,6 +419,52 @@ func (c *groupCommand) buildSubcommandSet() (*discordgo.ApplicationCommandOption
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *groupCommand) buildSubcommandSetLanguage() (*discordgo.ApplicationCommandOption, error) {
|
||||
languageChoices, err := c.getLanguageChoices()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmdDescriptionDefault, cmdDescriptionLocalizations, err := c.localizer.LocalizeDiscord("cmd.group.set.language.description")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
optionGroupDefault, optionGroupLocalizations, err := c.localizer.LocalizeDiscord("cmd.group.set.language.option.group.description")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
optionLanguageDefault, optionLanguageLocalizations, err := c.localizer.LocalizeDiscord("cmd.group.set.language.option.language.description")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &discordgo.ApplicationCommandOption{
|
||||
Name: "language",
|
||||
Description: cmdDescriptionDefault,
|
||||
DescriptionLocalizations: cmdDescriptionLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionSubCommand,
|
||||
Options: []*discordgo.ApplicationCommandOption{
|
||||
{
|
||||
Name: "group",
|
||||
Description: optionGroupDefault,
|
||||
DescriptionLocalizations: optionGroupLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionString,
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Name: "language",
|
||||
Description: optionLanguageDefault,
|
||||
DescriptionLocalizations: optionLanguageLocalizations,
|
||||
Type: discordgo.ApplicationCommandOptionString,
|
||||
Choices: languageChoices,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *groupCommand) buildSubcommandSetChannelGains() (*discordgo.ApplicationCommandOption, error) {
|
||||
cmdDescriptionDefault, cmdDescriptionLocalizations, err := c.localizer.LocalizeDiscord("cmd.group.set.channel-gains.description")
|
||||
if err != nil {
|
||||
|
@ -549,23 +657,6 @@ func (c *groupCommand) buildSubcommandDelete() (*discordgo.ApplicationCommandOpt
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *groupCommand) getVersionChoices() ([]*discordgo.ApplicationCommandOptionChoice, error) {
|
||||
choices, err := c.choiceSvc.Versions(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ChoiceService.Versions: %w", err)
|
||||
}
|
||||
|
||||
dcChoices := make([]*discordgo.ApplicationCommandOptionChoice, 0, len(choices))
|
||||
for _, v := range choices {
|
||||
dcChoices = append(dcChoices, &discordgo.ApplicationCommandOptionChoice{
|
||||
Name: v.Name,
|
||||
Value: v.Value,
|
||||
})
|
||||
}
|
||||
|
||||
return dcChoices, nil
|
||||
}
|
||||
|
||||
func (c *groupCommand) handle(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
cmdData := i.ApplicationCommandData()
|
||||
|
||||
|
@ -575,7 +666,8 @@ func (c *groupCommand) handle(s *discordgo.Session, i *discordgo.InteractionCrea
|
|||
|
||||
ctx := context.Background()
|
||||
|
||||
switch cmdData.Options[0].Name {
|
||||
name := cmdData.Options[0].Name
|
||||
switch name {
|
||||
case "create":
|
||||
c.handleCreate(ctx, s, i)
|
||||
case "list":
|
||||
|
@ -588,6 +680,8 @@ func (c *groupCommand) handle(s *discordgo.Session, i *discordgo.InteractionCrea
|
|||
c.handleTribe(ctx, s, i)
|
||||
case "delete":
|
||||
c.handleDelete(ctx, s, i)
|
||||
default:
|
||||
c.logger.Error("unknown subcommand", zap.String("command", "group"), zap.String("subcommand", name))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -647,12 +741,15 @@ func (c *groupCommand) optionsToCreateGroupParams(
|
|||
channelLosses := ""
|
||||
internals := false
|
||||
barbarians := false
|
||||
languageTag := ""
|
||||
for _, opt := range options {
|
||||
switch opt.Name {
|
||||
case "version":
|
||||
version = opt.StringValue()
|
||||
case "server":
|
||||
server = opt.StringValue()
|
||||
case "language":
|
||||
languageTag = opt.StringValue()
|
||||
case "channel-gains":
|
||||
channelGains = opt.ChannelValue(s).ID
|
||||
case "channel-losses":
|
||||
|
@ -663,8 +760,16 @@ func (c *groupCommand) optionsToCreateGroupParams(
|
|||
barbarians = opt.BoolValue()
|
||||
}
|
||||
}
|
||||
|
||||
return domain.NewCreateGroupParams(guildID, version, server, channelGains, channelLosses, barbarians, internals)
|
||||
return domain.NewCreateGroupParams(
|
||||
guildID,
|
||||
version,
|
||||
server,
|
||||
languageTag,
|
||||
channelGains,
|
||||
channelLosses,
|
||||
barbarians,
|
||||
internals,
|
||||
)
|
||||
}
|
||||
|
||||
func (c *groupCommand) handleList(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
|
@ -688,10 +793,21 @@ func (c *groupCommand) handleList(ctx context.Context, s *discordgo.Session, i *
|
|||
if g.ChannelGains != "" {
|
||||
channelGains = buildChannelMention(g.ChannelGains)
|
||||
}
|
||||
|
||||
channelLosses := "-"
|
||||
if g.ChannelLosses != "" {
|
||||
channelLosses = buildChannelMention(g.ChannelLosses)
|
||||
}
|
||||
|
||||
langMessageID := buildLangMessageID(g.LanguageTag)
|
||||
lang, localizeErr := c.localizer.Localize(locale, &i18n.LocalizeConfig{
|
||||
MessageID: langMessageID,
|
||||
})
|
||||
if localizeErr != nil {
|
||||
c.logger.Error("no message with the specified identifier", zap.String("id", langMessageID), zap.Error(localizeErr))
|
||||
return
|
||||
}
|
||||
|
||||
fieldValue, localizeErr := c.localizer.Localize(locale, &i18n.LocalizeConfig{
|
||||
MessageID: fieldValueMessageID,
|
||||
TemplateData: map[string]any{
|
||||
|
@ -701,12 +817,14 @@ func (c *groupCommand) handleList(ctx context.Context, s *discordgo.Session, i *
|
|||
"Internals": boolToEmoji(g.Internals),
|
||||
"Barbarians": boolToEmoji(g.Barbarians),
|
||||
"NumTribes": len(g.Monitors),
|
||||
"Language": lang,
|
||||
},
|
||||
})
|
||||
if localizeErr != nil {
|
||||
c.logger.Error("no message with the specified identifier", zap.String("id", fieldValueMessageID), zap.Error(localizeErr))
|
||||
return
|
||||
}
|
||||
|
||||
fields = append(fields, &discordgo.MessageEmbedField{
|
||||
Name: g.ID,
|
||||
Value: fieldValue,
|
||||
|
@ -770,6 +888,15 @@ func (c *groupCommand) handleDetails(ctx context.Context, s *discordgo.Session,
|
|||
channelLosses = buildChannelMention(g.ChannelLosses)
|
||||
}
|
||||
|
||||
langMessageID := buildLangMessageID(g.LanguageTag)
|
||||
lang, localizeErr := c.localizer.Localize(locale, &i18n.LocalizeConfig{
|
||||
MessageID: langMessageID,
|
||||
})
|
||||
if localizeErr != nil {
|
||||
c.logger.Error("no message with the specified identifier", zap.String("id", langMessageID), zap.Error(localizeErr))
|
||||
return
|
||||
}
|
||||
|
||||
descriptionMessageID := "cmd.group.details.embed.description"
|
||||
description, err := c.localizer.Localize(locale, &i18n.LocalizeConfig{
|
||||
MessageID: descriptionMessageID,
|
||||
|
@ -780,6 +907,7 @@ func (c *groupCommand) handleDetails(ctx context.Context, s *discordgo.Session,
|
|||
"Internals": boolToEmoji(g.Internals),
|
||||
"Barbarians": boolToEmoji(g.Barbarians),
|
||||
"Tribes": builderTribes.String(),
|
||||
"Language": lang,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -802,7 +930,10 @@ func (c *groupCommand) handleDetails(ctx context.Context, s *discordgo.Session,
|
|||
}
|
||||
|
||||
func (c *groupCommand) handleSet(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
switch i.ApplicationCommandData().Options[0].Options[0].Name {
|
||||
name := i.ApplicationCommandData().Options[0].Options[0].Name
|
||||
switch name {
|
||||
case "language":
|
||||
c.handleSetLanguage(ctx, s, i)
|
||||
case "channel-gains":
|
||||
c.handleSetChannelGains(ctx, s, i)
|
||||
case "channel-losses":
|
||||
|
@ -811,9 +942,54 @@ func (c *groupCommand) handleSet(ctx context.Context, s *discordgo.Session, i *d
|
|||
c.handleSetInternals(ctx, s, i)
|
||||
case "barbarians":
|
||||
c.handleSetBarbarians(ctx, s, i)
|
||||
default:
|
||||
c.logger.Error("unknown subcommand", zap.String("command", "group set"), zap.String("subcommand", name))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *groupCommand) handleSetLanguage(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
locale := string(i.Locale)
|
||||
|
||||
group := ""
|
||||
languageTag := ""
|
||||
for _, opt := range i.ApplicationCommandData().Options[0].Options[0].Options {
|
||||
if opt == nil {
|
||||
continue
|
||||
}
|
||||
switch opt.Name {
|
||||
case "group":
|
||||
group = opt.StringValue()
|
||||
case "language":
|
||||
languageTag = opt.StringValue()
|
||||
}
|
||||
}
|
||||
|
||||
_, err := c.groupSvc.SetLanguageTag(ctx, group, i.GuildID, languageTag)
|
||||
if err != nil {
|
||||
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: c.localizer.LocalizeError(locale, err),
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
successMessageID := "cmd.group.set.language.success"
|
||||
successMsg, err := c.localizer.Localize(locale, &i18n.LocalizeConfig{MessageID: successMessageID})
|
||||
if err != nil {
|
||||
c.logger.Error("no message with the specified identifier", zap.String("id", successMessageID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||
Data: &discordgo.InteractionResponseData{
|
||||
Content: successMsg,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (c *groupCommand) handleSetChannelGains(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
locale := string(i.Locale)
|
||||
|
||||
|
@ -987,11 +1163,14 @@ func (c *groupCommand) handleSetBarbarians(ctx context.Context, s *discordgo.Ses
|
|||
}
|
||||
|
||||
func (c *groupCommand) handleTribe(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
switch i.ApplicationCommandData().Options[0].Options[0].Name {
|
||||
name := i.ApplicationCommandData().Options[0].Options[0].Name
|
||||
switch name {
|
||||
case "add":
|
||||
c.handleTribeAdd(ctx, s, i)
|
||||
case "remove":
|
||||
c.handleTribeRemove(ctx, s, i)
|
||||
default:
|
||||
c.logger.Error("unknown subcommand", zap.String("command", "group tribe"), zap.String("subcommand", name))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,3 +30,7 @@ func boolToEmoji(val bool) string {
|
|||
}
|
||||
return ":x:"
|
||||
}
|
||||
|
||||
func buildLangMessageID(languageTag string) string {
|
||||
return "lang." + languageTag
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
{
|
||||
"lang.pl": "Polish",
|
||||
"lang.en": "English",
|
||||
|
||||
"err.default": "Something went wrong. Try again later.",
|
||||
"err.required": "{{ .Field }} can't be blank.",
|
||||
"err.group-limit-reached": "The group limit has been reached ({{ .Current }}/{{ .Limit }}).",
|
||||
|
@ -12,11 +15,14 @@
|
|||
"err.tribe-not-found": "Tribe (tag={{ .Tag }}) not found.",
|
||||
"err.tribe-does-not-exist": "The tribe (tag={{ .Tag }}) doesn't exist.",
|
||||
|
||||
"job.execute-monitors.embed.description": "{{ buildPlayerMarkdown .Ennoblement.NewOwner }} has taken {{ buildLink .Ennoblement.Village.FullName .Ennoblement.Village.ProfileURL }} (Old owner: {{ buildPlayerMarkdown .Ennoblement.Village.Player }}).",
|
||||
|
||||
"cmd.group.description": "Manages groups on this server",
|
||||
|
||||
"cmd.group.create.description": "Creates a new monitor group",
|
||||
"cmd.group.create.option.version.description": "e.g. www.tribalwars.net, www.plemiona.pl",
|
||||
"cmd.group.create.option.server.description": "Tribal Wars server (e.g. en115, pl170)",
|
||||
"cmd.group.create.option.language.description": "Language in which you wish to receive notifications",
|
||||
"cmd.group.create.option.internals.description": "Show conquers in the same group",
|
||||
"cmd.group.create.option.barbarians.description": "Show barbarian conquers",
|
||||
"cmd.group.create.option.channel-gains.description": "Channel where notifications of gained villages will appear",
|
||||
|
@ -25,10 +31,10 @@
|
|||
|
||||
"cmd.group.list.description": "Lists all created groups on this server",
|
||||
"cmd.group.list.embed.title": "Group list",
|
||||
"cmd.group.list.embed.field.value": "**Server**: {{ .ServerKey }}\n**Channel gains**: {{ .ChannelGains }}\n**Channel losses**: {{ .ChannelLosses }}\n**Internals**: {{ .Internals }}\n **Barbarians**: {{ .Barbarians }}\n **Number of monitored tribes**: {{ .NumTribes }}",
|
||||
"cmd.group.list.embed.field.value": "**Server**: {{ .ServerKey }}\n**Language**: {{ .Language }}\n**Channel gains**: {{ .ChannelGains }}\n**Channel losses**: {{ .ChannelLosses }}\n**Internals**: {{ .Internals }}\n **Barbarians**: {{ .Barbarians }}\n **Number of monitored tribes**: {{ .NumTribes }}",
|
||||
|
||||
"cmd.group.details.description": "Displays group details (including added tribes)",
|
||||
"cmd.group.details.embed.description": "**Server**: {{ .ServerKey }}\n**Channel gains**: {{ .ChannelGains }}\n**Channel losses**: {{ .ChannelLosses }}\n**Internals**: {{ .Internals }}\n **Barbarians**: {{ .Barbarians }}\n **Tribes**: {{ .Tribes }}",
|
||||
"cmd.group.details.embed.description": "**Server**: {{ .ServerKey }}\n**Language**: {{ .Language }}\n**Channel gains**: {{ .ChannelGains }}\n**Channel losses**: {{ .ChannelLosses }}\n**Internals**: {{ .Internals }}\n **Barbarians**: {{ .Barbarians }}\n **Tribes**: {{ .Tribes }}",
|
||||
|
||||
"cmd.group.tribe.description": "Manages tribes in a group",
|
||||
|
||||
|
@ -44,6 +50,11 @@
|
|||
|
||||
"cmd.group.set.description": "Sets various properties in group configuration",
|
||||
|
||||
"cmd.group.set.language.description": "Sets the language in which you will receive notifications",
|
||||
"cmd.group.set.language.option.group.description": "Group ID",
|
||||
"cmd.group.set.language.option.language.description": "Language in which you wish to receive notifications",
|
||||
"cmd.group.set.language.success": "The group has been successfully updated.",
|
||||
|
||||
"cmd.group.set.channel-gains.description": "Enables/disables notifications of gained villages",
|
||||
"cmd.group.set.channel-gains.option.group.description": "Group ID",
|
||||
"cmd.group.set.channel-gains.option.channel.description": "Channel where notifications of gained villages will appear",
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
{
|
||||
"lang.pl": "Polski",
|
||||
"lang.en": "Angielski",
|
||||
|
||||
"err.default": "Coś poszło nie tak. Spróbuj ponownie później.",
|
||||
"err.required": "{{ .Field }} nie może być pusty.",
|
||||
"err.group-limit-reached": "Limit grup został osiągnięty ({{ .Current }}/{{ .Limit }}).",
|
||||
|
@ -12,11 +15,14 @@
|
|||
"err.tribe-not-found": "Plemię (skrót={{ .Tag }}) nie zostało znalezione.",
|
||||
"err.tribe-does-not-exist": "Plemię (skrót={{ .Tag }}) nie istnieje.",
|
||||
|
||||
"job.execute-monitors.embed.description": "{{ buildPlayerMarkdown .Ennoblement.NewOwner }} przejął {{ buildLink .Ennoblement.Village.FullName .Ennoblement.Village.ProfileURL }} (Poprzedni właściciel: {{ buildPlayerMarkdown .Ennoblement.Village.Player }}).",
|
||||
|
||||
"cmd.group.description": "Umożliwia zarządzanie grupami na tym serwerze",
|
||||
|
||||
"cmd.group.create.description": "Tworzy nową grupę",
|
||||
"cmd.group.create.option.version.description": "np. www.tribalwars.net, www.plemiona.pl",
|
||||
"cmd.group.create.option.server.description": "Serwer (np. en115, pl170)",
|
||||
"cmd.group.create.option.language.description": "Język, w którym mają być wysyłane powiadomienia",
|
||||
"cmd.group.create.option.internals.description": "Informuj o przejęciach wewnętrznych",
|
||||
"cmd.group.create.option.barbarians.description": "Informuj o przejęciach wiosek barbarzyńskich",
|
||||
"cmd.group.create.option.channel-gains.description": "Kanał na którym będą pojawiać się powiadomienia o zdobytych wioskach",
|
||||
|
@ -25,10 +31,10 @@
|
|||
|
||||
"cmd.group.list.description": "Wyświetla wszystkie utworzone grupy na tym serwerze",
|
||||
"cmd.group.list.embed.title": "Grupy",
|
||||
"cmd.group.list.embed.field.value": "**Serwer**: {{ .ServerKey }}\n**Kanał zdobyte wioski**: {{ .ChannelGains }}\n**Kanał stracone wioski**: {{ .ChannelLosses }}\n**Przejęcia wewnętrzne**: {{ .Internals }}\n **Przejęcia barbarek**: {{ .Barbarians }}\n **Liczba monitorowanych plemion**: {{ .NumTribes }}",
|
||||
"cmd.group.list.embed.field.value": "**Serwer**: {{ .ServerKey }}\n**Język**: {{ .Language }}\n**Kanał zdobyte wioski**: {{ .ChannelGains }}\n**Kanał stracone wioski**: {{ .ChannelLosses }}\n**Przejęcia wewnętrzne**: {{ .Internals }}\n **Przejęcia barbarek**: {{ .Barbarians }}\n **Liczba monitorowanych plemion**: {{ .NumTribes }}",
|
||||
|
||||
"cmd.group.details.description": "Wyświetla szczegóły grupy (w tym dodane plemiona)",
|
||||
"cmd.group.details.embed.description": "**Serwer**: {{ .ServerKey }}\n**Kanał zdobyte wioski**: {{ .ChannelGains }}\n**Kanał stracone wioski**: {{ .ChannelLosses }}\n**Przejęcia wewnętrzne**: {{ .Internals }}\n **Przejęcia barbarek**: {{ .Barbarians }}\n **Plemiona**: {{ .Tribes }}",
|
||||
"cmd.group.details.embed.description": "**Serwer**: {{ .ServerKey }}\n**Język**: {{ .Language }}\n**Kanał zdobyte wioski**: {{ .ChannelGains }}\n**Kanał stracone wioski**: {{ .ChannelLosses }}\n**Przejęcia wewnętrzne**: {{ .Internals }}\n **Przejęcia barbarek**: {{ .Barbarians }}\n **Plemiona**: {{ .Tribes }}",
|
||||
|
||||
"cmd.group.tribe.description": "Zarządza plemionami w grupie",
|
||||
|
||||
|
@ -44,6 +50,11 @@
|
|||
|
||||
"cmd.group.set.description": "Ustawia różne właściwości w konfiguracji grupy",
|
||||
|
||||
"cmd.group.set.language.description": "Ustawia język w którym będziesz otrzymywać powiadomienia",
|
||||
"cmd.group.set.language.option.group.description": "ID grupy",
|
||||
"cmd.group.set.language.option.language.description": "Język, w którym mają być wysyłane powiadomienia",
|
||||
"cmd.group.set.language.success": "Grupa została pomyślnie zaaktualizowana.",
|
||||
|
||||
"cmd.group.set.channel-gains.description": "Włącza/wyłącza powiadomienia o podbitych wioskach",
|
||||
"cmd.group.set.channel-gains.option.group.description": "ID grupy",
|
||||
"cmd.group.set.channel-gains.option.channel.description": "Kanał na którym będą pojawiać się powiadomienia o zdobytych wioskach",
|
||||
|
|
|
@ -112,3 +112,7 @@ func (l *Localizer) LocalizeError(lang string, errToLocalize error) string {
|
|||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
func (l *Localizer) LanguageTags() []language.Tag {
|
||||
return l.bundle.LanguageTags()
|
||||
}
|
||||
|
|
|
@ -2,12 +2,14 @@ package discord
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/dcbot/internal/discord/internal/discordi18n"
|
||||
"gitea.dwysokinski.me/twhelp/dcbot/internal/domain"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
@ -18,9 +20,10 @@ const (
|
|||
)
|
||||
|
||||
type executeMonitorsJob struct {
|
||||
s *discordgo.Session
|
||||
svc GroupService
|
||||
logger *zap.Logger
|
||||
s *discordgo.Session
|
||||
svc GroupService
|
||||
localizer *discordi18n.Localizer
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func (e *executeMonitorsJob) Run() {
|
||||
|
@ -30,19 +33,32 @@ func (e *executeMonitorsJob) Run() {
|
|||
start := time.Now()
|
||||
notifications, err := e.svc.Execute(ctx)
|
||||
if err != nil {
|
||||
e.logger.Error("something went wrong while executing monitors", zap.Error(err))
|
||||
e.logger.Error(
|
||||
"something went wrong while executing monitors",
|
||||
zap.Error(err),
|
||||
zap.Duration("duration", time.Since(start)),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
convertedNotifications, err := (ennoblementNotificationToMessageEmbedConverter{notifications, e.localizer}).convert()
|
||||
if err != nil {
|
||||
e.logger.Error("couldn't convert []domain.EnnoblementNotification to []*discordgo.MessageEmbed", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for ch, embeds := range (ennoblementNotificationToMessageEmbedConverter{notifications}).convert() {
|
||||
for ch, embeds := range convertedNotifications {
|
||||
wg.Add(1)
|
||||
|
||||
go func(ch string, embeds []*discordgo.MessageEmbed) {
|
||||
defer wg.Done()
|
||||
for _, embed := range embeds {
|
||||
_, _ = e.s.ChannelMessageSendEmbed(ch, embed)
|
||||
_, sendErr := e.s.ChannelMessageSendEmbed(ch, embed)
|
||||
if sendErr != nil {
|
||||
e.logger.Warn("couldn't send notification", zap.String("channel", ch), zap.Error(sendErr))
|
||||
}
|
||||
}
|
||||
}(ch, embeds)
|
||||
}
|
||||
|
@ -57,10 +73,11 @@ func (e *executeMonitorsJob) Run() {
|
|||
}
|
||||
|
||||
type ennoblementNotificationToMessageEmbedConverter struct {
|
||||
ns []domain.EnnoblementNotification
|
||||
ns []domain.EnnoblementNotification
|
||||
localizer *discordi18n.Localizer
|
||||
}
|
||||
|
||||
func (c ennoblementNotificationToMessageEmbedConverter) convert() map[string][]*discordgo.MessageEmbed {
|
||||
func (c ennoblementNotificationToMessageEmbedConverter) convert() (map[string][]*discordgo.MessageEmbed, error) {
|
||||
m := make(map[string]map[domain.EnnoblementNotificationType][]*discordgo.MessageEmbed)
|
||||
timestamp := formatTimestamp(time.Now())
|
||||
for _, n := range c.ns {
|
||||
|
@ -70,8 +87,11 @@ func (c ennoblementNotificationToMessageEmbedConverter) convert() map[string][]*
|
|||
|
||||
embeds := m[n.ChannelID][n.Type]
|
||||
|
||||
str := c.buildDescription(n)
|
||||
if l := len(embeds); l == 0 || len(embeds[l-1].Description)+len(str) > embedDescriptionCharLimit {
|
||||
description, err := c.buildDescription(n)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if l := len(embeds); l == 0 || len(embeds[l-1].Description)+len(description) > embedDescriptionCharLimit {
|
||||
embeds = append(embeds, &discordgo.MessageEmbed{
|
||||
Color: c.mapNotificationTypeToColor(n.Type),
|
||||
Type: discordgo.EmbedTypeRich,
|
||||
|
@ -79,9 +99,9 @@ func (c ennoblementNotificationToMessageEmbedConverter) convert() map[string][]*
|
|||
})
|
||||
}
|
||||
if len(embeds[len(embeds)-1].Description) > 0 {
|
||||
str = "\n" + str
|
||||
description = "\n" + description
|
||||
}
|
||||
embeds[len(embeds)-1].Description += str
|
||||
embeds[len(embeds)-1].Description += description
|
||||
|
||||
m[n.ChannelID][n.Type] = embeds
|
||||
}
|
||||
|
@ -99,16 +119,20 @@ func (c ennoblementNotificationToMessageEmbedConverter) convert() map[string][]*
|
|||
}
|
||||
}
|
||||
|
||||
return res
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c ennoblementNotificationToMessageEmbedConverter) buildDescription(n domain.EnnoblementNotification) string {
|
||||
return fmt.Sprintf(
|
||||
"%s has taken %s (Old owner: %s)",
|
||||
c.buildPlayerMarkdown(n.Ennoblement.NewOwner),
|
||||
buildLink(n.Ennoblement.Village.FullName, n.Ennoblement.Village.ProfileURL),
|
||||
c.buildPlayerMarkdown(n.Ennoblement.Village.Player),
|
||||
)
|
||||
func (c ennoblementNotificationToMessageEmbedConverter) buildDescription(n domain.EnnoblementNotification) (string, error) {
|
||||
return c.localizer.Localize(n.LanguageTag, &i18n.LocalizeConfig{
|
||||
MessageID: "job.execute-monitors.embed.description",
|
||||
TemplateData: map[string]any{
|
||||
"Ennoblement": n.Ennoblement,
|
||||
},
|
||||
Funcs: template.FuncMap{
|
||||
"buildPlayerMarkdown": c.buildPlayerMarkdown,
|
||||
"buildLink": buildLink,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (c ennoblementNotificationToMessageEmbedConverter) buildPlayerMarkdown(p domain.NullPlayerMeta) string {
|
||||
|
|
|
@ -11,5 +11,6 @@ type EnnoblementNotification struct {
|
|||
Type EnnoblementNotificationType
|
||||
ServerID string
|
||||
ChannelID string
|
||||
LanguageTag string
|
||||
Ennoblement Ennoblement
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ type Group struct {
|
|||
Barbarians bool // Show barbarian conquers
|
||||
ServerKey string // TW server key (e.g. en130)
|
||||
VersionCode string
|
||||
LanguageTag string // BCP 47 language tag
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
|
@ -37,10 +38,11 @@ type CreateGroupParams struct {
|
|||
channelLosses string
|
||||
barbarians bool
|
||||
internals bool
|
||||
languageTag string
|
||||
}
|
||||
|
||||
func NewCreateGroupParams(
|
||||
serverID, versionCode, serverKey, channelGains, channelLosses string,
|
||||
serverID, versionCode, serverKey, languageTag, channelGains, channelLosses string,
|
||||
barbarians, internals bool,
|
||||
) (CreateGroupParams, error) {
|
||||
if serverID == "" {
|
||||
|
@ -55,6 +57,10 @@ func NewCreateGroupParams(
|
|||
return CreateGroupParams{}, RequiredError{Field: "ServerKey"}
|
||||
}
|
||||
|
||||
if languageTag == "" {
|
||||
return CreateGroupParams{}, RequiredError{Field: "LanguageTag"}
|
||||
}
|
||||
|
||||
return CreateGroupParams{
|
||||
serverID: serverID,
|
||||
serverKey: serverKey,
|
||||
|
@ -63,6 +69,7 @@ func NewCreateGroupParams(
|
|||
channelLosses: channelLosses,
|
||||
barbarians: barbarians,
|
||||
internals: internals,
|
||||
languageTag: languageTag,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -74,6 +81,10 @@ func (c CreateGroupParams) VersionCode() string {
|
|||
return c.versionCode
|
||||
}
|
||||
|
||||
func (c CreateGroupParams) LanguageTag() string {
|
||||
return c.languageTag
|
||||
}
|
||||
|
||||
func (c CreateGroupParams) ServerKey() string {
|
||||
return c.serverKey
|
||||
}
|
||||
|
@ -97,6 +108,7 @@ func (c CreateGroupParams) Internals() bool {
|
|||
type UpdateGroupParams struct {
|
||||
ChannelGains NullString
|
||||
ChannelLosses NullString
|
||||
LanguageTag NullString
|
||||
Internals NullBool
|
||||
Barbarians NullBool
|
||||
}
|
||||
|
@ -105,7 +117,8 @@ func (u UpdateGroupParams) IsZero() bool {
|
|||
return !u.ChannelGains.Valid &&
|
||||
!u.ChannelLosses.Valid &&
|
||||
!u.Internals.Valid &&
|
||||
!u.Barbarians.Valid
|
||||
!u.Barbarians.Valid &&
|
||||
!u.LanguageTag.Valid
|
||||
}
|
||||
|
||||
type ListGroupsParams struct {
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"gitea.dwysokinski.me/twhelp/dcbot/internal/domain"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func TestNewCreateGroupParams(t *testing.T) {
|
||||
|
@ -15,6 +16,7 @@ func TestNewCreateGroupParams(t *testing.T) {
|
|||
serverID string
|
||||
versionCode string
|
||||
serverKey string
|
||||
languageTag string
|
||||
channelGains string
|
||||
channelLosses string
|
||||
barbarians bool
|
||||
|
@ -26,6 +28,7 @@ func TestNewCreateGroupParams(t *testing.T) {
|
|||
serverID: "123441",
|
||||
versionCode: "en",
|
||||
serverKey: "en113",
|
||||
languageTag: language.English.String(),
|
||||
channelGains: "1234",
|
||||
channelLosses: "1234",
|
||||
barbarians: true,
|
||||
|
@ -51,6 +54,14 @@ func TestNewCreateGroupParams(t *testing.T) {
|
|||
serverKey: "",
|
||||
err: domain.RequiredError{Field: "ServerKey"},
|
||||
},
|
||||
{
|
||||
name: "ERR: LanguageTag cannot be blank",
|
||||
serverID: "1234",
|
||||
versionCode: "en",
|
||||
serverKey: "en113",
|
||||
languageTag: "",
|
||||
err: domain.RequiredError{Field: "LanguageTag"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
@ -63,6 +74,7 @@ func TestNewCreateGroupParams(t *testing.T) {
|
|||
tt.serverID,
|
||||
tt.versionCode,
|
||||
tt.serverKey,
|
||||
tt.languageTag,
|
||||
tt.channelGains,
|
||||
tt.channelLosses,
|
||||
tt.barbarians,
|
||||
|
@ -93,28 +105,6 @@ func TestUpdateGroupParams_IsZero(t *testing.T) {
|
|||
params domain.UpdateGroupParams
|
||||
output bool
|
||||
}{
|
||||
{
|
||||
name: "OK: all",
|
||||
params: domain.UpdateGroupParams{
|
||||
ChannelGains: domain.NullString{
|
||||
String: "123",
|
||||
Valid: true,
|
||||
},
|
||||
ChannelLosses: domain.NullString{
|
||||
String: "123",
|
||||
Valid: true,
|
||||
},
|
||||
Barbarians: domain.NullBool{
|
||||
Bool: false,
|
||||
Valid: true,
|
||||
},
|
||||
Internals: domain.NullBool{
|
||||
Bool: false,
|
||||
Valid: true,
|
||||
},
|
||||
},
|
||||
output: false,
|
||||
},
|
||||
{
|
||||
name: "OK: ChannelGains",
|
||||
params: domain.UpdateGroupParams{
|
||||
|
@ -155,6 +145,16 @@ func TestUpdateGroupParams_IsZero(t *testing.T) {
|
|||
},
|
||||
output: false,
|
||||
},
|
||||
{
|
||||
name: "OK: LanguageTag",
|
||||
params: domain.UpdateGroupParams{
|
||||
LanguageTag: domain.NullString{
|
||||
String: language.English.String(),
|
||||
Valid: true,
|
||||
},
|
||||
},
|
||||
output: false,
|
||||
},
|
||||
{
|
||||
name: "OK: empty struct",
|
||||
params: domain.UpdateGroupParams{},
|
||||
|
|
|
@ -27,6 +27,7 @@ func (b ennoblementNotificationBuilder) buildGroup(g domain.GroupWithMonitors) [
|
|||
Type: domain.EnnoblementNotificationTypeGain,
|
||||
ServerID: g.ServerID,
|
||||
ChannelID: g.ChannelGains,
|
||||
LanguageTag: g.LanguageTag,
|
||||
Ennoblement: b.ennoblementToDomainModel(e),
|
||||
})
|
||||
}
|
||||
|
@ -36,6 +37,7 @@ func (b ennoblementNotificationBuilder) buildGroup(g domain.GroupWithMonitors) [
|
|||
Type: domain.EnnoblementNotificationTypeLoss,
|
||||
ServerID: g.ServerID,
|
||||
ChannelID: g.ChannelLosses,
|
||||
LanguageTag: g.LanguageTag,
|
||||
Ennoblement: b.ennoblementToDomainModel(e),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -209,6 +209,15 @@ func (g *Group) SetBarbarians(ctx context.Context, id, serverID string, barbaria
|
|||
})
|
||||
}
|
||||
|
||||
func (g *Group) SetLanguageTag(ctx context.Context, id, serverID, languageTag string) (domain.GroupWithMonitors, error) {
|
||||
return g.update(ctx, id, serverID, domain.UpdateGroupParams{
|
||||
LanguageTag: domain.NullString{
|
||||
String: languageTag,
|
||||
Valid: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (g *Group) update(ctx context.Context, id, serverID string, params domain.UpdateGroupParams) (domain.GroupWithMonitors, error) {
|
||||
// check if group exists
|
||||
if _, err := g.Get(ctx, id, serverID); err != nil {
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func TestGroup_Create(t *testing.T) {
|
||||
|
@ -26,6 +27,7 @@ func TestGroup_Create(t *testing.T) {
|
|||
"592292203234328587",
|
||||
"en",
|
||||
"en113",
|
||||
language.English.String(),
|
||||
"1234",
|
||||
"1235",
|
||||
true,
|
||||
|
@ -457,6 +459,90 @@ func TestGroup_RemoveTribe(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestGroup_SetLanguageTag(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
repo := &mock.FakeGroupRepository{}
|
||||
group := domain.GroupWithMonitors{
|
||||
Group: domain.Group{
|
||||
ID: uuid.NewString(),
|
||||
ServerID: uuid.NewString(),
|
||||
},
|
||||
}
|
||||
repo.GetReturns(group, nil)
|
||||
repo.UpdateCalls(func(ctx context.Context, id string, params domain.UpdateGroupParams) (domain.GroupWithMonitors, error) {
|
||||
return domain.GroupWithMonitors{
|
||||
Group: domain.Group{
|
||||
ID: id,
|
||||
LanguageTag: params.LanguageTag.String,
|
||||
},
|
||||
}, nil
|
||||
})
|
||||
|
||||
languageTag := uuid.NewString()
|
||||
|
||||
g, err := service.
|
||||
NewGroup(repo, nil, zap.NewNop(), 1, 1).
|
||||
SetLanguageTag(context.Background(), group.ID, group.ServerID, languageTag)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, group.ID, g.ID)
|
||||
assert.Equal(t, languageTag, g.LanguageTag)
|
||||
})
|
||||
|
||||
t.Run("ERR: group not found", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
group := domain.GroupWithMonitors{
|
||||
Group: domain.Group{
|
||||
ID: uuid.NewString(),
|
||||
ServerID: uuid.NewString(),
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
group domain.GroupWithMonitors
|
||||
serverID string
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "repository returned error",
|
||||
serverID: group.ServerID,
|
||||
err: domain.GroupNotFoundError{
|
||||
ID: group.ID,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "incorrect server id",
|
||||
group: group,
|
||||
serverID: uuid.NewString(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
repo := &mock.FakeGroupRepository{}
|
||||
repo.GetReturns(tt.group, tt.err)
|
||||
|
||||
g, err := service.
|
||||
NewGroup(repo, nil, zap.NewNop(), 1, 1).
|
||||
SetLanguageTag(context.Background(), group.ID, tt.serverID, uuid.NewString())
|
||||
assert.ErrorIs(t, err, domain.GroupNotFoundError{
|
||||
ID: group.ID,
|
||||
})
|
||||
assert.Zero(t, g)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestGroup_SetChannelGains(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE groups ADD COLUMN language_tag varchar(10) NOT NULL DEFAULT 'en'; -- BCP 47 language tag
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE groups DROP COLUMN IF EXISTS language_tag;
|
||||
-- +goose StatementEnd
|
Loading…
Reference in New Issue