diff --git a/.env.example b/.env.example index e905324f..e44445f2 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,8 @@ DATABASE_PATH="/absolute/path/" -DATABASE_NAME="aftermath.db" +DATABASE_URL="postgresql://aftermath:password@0.0.0.0:5432/aftermath-local?sslmode=disable" +DATABASE_NAME="aftermath-local" +DATABASE_USER="aftermath" +DATABASE_PASSWORD="password" # Init INIT_GLOBAL_ADMIN_USER="" # Discord user ID for a user who will be assigned permissions.GlobalAdmin on startup, can be left blank diff --git a/Dockerfile b/Dockerfile index 0edc4f83..5d6bdbf6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,16 @@ -# Download localizations -FROM node:23 AS builder-node +# # Download localizations +# FROM node:23 AS builder-node -ARG LOCALIZE_API_KEY -ENV LOCALIZE_API_KEY $LOCALIZE_API_KEY +# ARG LOCALIZE_API_KEY +# ENV LOCALIZE_API_KEY $LOCALIZE_API_KEY -WORKDIR /workspace +# WORKDIR /workspace -RUN npm install @tolgee/cli +# RUN npm install @tolgee/cli -COPY ./.tolgeerc ./ +# COPY ./.tolgeerc ./ -RUN npx tolgee pull --api-key "${LOCALIZE_API_KEY}" --states REVIEWED +# RUN npx tolgee pull --api-key "${LOCALIZE_API_KEY}" --states REVIEWED # Build app FROM golang:1.24.3 AS builder-go @@ -26,14 +26,14 @@ RUN --mount=type=cache,target=$GOPATH/pkg/mod go mod download COPY ./ ./ # load localizations -COPY --from=builder-node /workspace/static/localization/ ./static/localization/ +# COPY --from=builder-node /workspace/static/localization/ ./static/localization/ # generate static assets RUN --mount=type=cache,target=$GOPATH/pkg/mod go generate ./internal/assets RUN --mount=type=cache,target=$GOPATH/pkg/mod go generate ./cmd/frontend/assets/generate # generate frontend -RUN go tool templ generate +RUN --mount=type=cache,target=$GOPATH/pkg/mod go tool templ generate # build a fully standalone binary with zero dependencies RUN --mount=type=cache,target=$GOPATH/pkg/mod CGO_ENABLED=0 GOOS=linux go build -ldflags='-s -w' -trimpath -o /bin/aftermath . diff --git a/Taskfile.yaml b/Taskfile.yaml index f906886d..ffd078e5 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -9,10 +9,10 @@ tasks: - ".env.test" desc: runs tests cmds: - # - task: db-migrate-apply-test + - task: db-migrate-tests - | if [ -z "{{ .CLI_ARGS }}" ]; then - go test -timeout 30s --count=1 -v ./... + go test -timeout 30s --count=1 -v ./... | grep -v "\[no test files\]" else go test -timeout 30s --count=1 -v -run {{ .CLI_ARGS }} fi diff --git a/atlas.hcl b/atlas.hcl index 7ff4811c..0cf77fae 100644 --- a/atlas.hcl +++ b/atlas.hcl @@ -1,18 +1,6 @@ -variable "database_name" { +variable "database_url" { type = string - default = getenv("DATABASE_NAME") -} -variable "database_user" { - type = string - default = getenv("DATABASE_USER") -} -variable "database_password" { - type = string - default = getenv("DATABASE_PASSWORD") -} -variable "database_host" { - type = string - default = getenv("DATABASE_HOST") + default = getenv("DATABASE_URL") } variable "sources" { type = list(string) @@ -35,7 +23,7 @@ env "local" { dir = "file://internal/database/migrations" } - url = "postgresql://${var.database_user}:${var.database_password}@${var.database_host}/${var.database_name}?sslmode=disable" + url = var.database_url dev = "docker://postgres/17/dev?search_path=public" } @@ -55,5 +43,5 @@ env "migrate" { } tx-mode = "all" - url = "postgresql://${var.database_user}:${var.database_password}@${var.database_host}/${var.database_name}?sslmode=disable" + url = var.database_url } \ No newline at end of file diff --git a/cmd/core/scheduler/workers.go b/cmd/core/scheduler/workers.go index 3c05b08e..5ab39b6c 100644 --- a/cmd/core/scheduler/workers.go +++ b/cmd/core/scheduler/workers.go @@ -89,18 +89,12 @@ func UpdateAveragesWorker(client core.Client) func() { return } - aErr, err := client.Database().UpsertVehicleAverages(ctx, averages) + err = client.Database().UpsertVehicleAverages(ctx, averages) if err != nil { log.Err(err).Msg("failed to update averages cache") return } - for id, err := range aErr { - if err != nil { - log.Err(err).Str("", id).Msg("failed to update some average cache") - } - } - log.Info().Msg("averages cache updated") } } @@ -148,7 +142,7 @@ func UpdateGlossaryWorker(client core.Client) func() { vctx, cancel := context.WithTimeout(context.Background(), time.Second*15) defer cancel() - _, err = client.Database().UpsertVehicles(vctx, vehicles) + err = client.Database().UpsertVehicles(vctx, vehicles) if err != nil { log.Err(err).Msg("failed to save vehicle glossary") return @@ -208,7 +202,7 @@ func UpdateGlossaryWorker(client core.Client) func() { gmctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() - _, err = client.Database().UpsertGameModes(gmctx, withTags) + err = client.Database().UpsertGameModes(gmctx, withTags) if err != nil { log.Err(err).Msg("failed save game modes glossary") return diff --git a/cmd/core/server/handlers/private/accounts.go b/cmd/core/server/handlers/private/accounts.go index a8805b28..16008f6b 100644 --- a/cmd/core/server/handlers/private/accounts.go +++ b/cmd/core/server/handlers/private/accounts.go @@ -62,9 +62,6 @@ func LoadAccountsHandler(client core.Client) http.HandlerFunc { batchSize := 50 var wg sync.WaitGroup sem := semaphore.NewWeighted(5) - errors := make(map[string]error) - var errorsMx sync.Mutex - for realm, accounts := range accountsByRealm { for i := 0; i < len(accounts); i += batchSize { end := i + batchSize @@ -113,29 +110,15 @@ func LoadAccountsHandler(client core.Client) http.HandlerFunc { inserts = append(inserts, &update) } - accErr, err := client.Database().UpsertAccounts(ctx, inserts...) + err = client.Database().UpsertAccounts(ctx, inserts...) if err != nil { log.Err(err).Msg("failed to upsert accounts") } - if len(accErr) > 0 { - errorsMx.Lock() - for id, err := range accErr { - errors[id] = err - } - errorsMx.Unlock() - } - }(accounts[i:end], realm) } } wg.Wait() - for id, err := range errors { - if err != nil { - log.Err(err).Str("id", id).Msg("some account imports failed") - } - } - log.Debug().Int("count", len(accounts)-len(existing)).Msg("finished importing accounts") }(accounts, existing) } diff --git a/cmd/frontend/handler/context.go b/cmd/frontend/handler/context.go index 42fe6360..02d3b27e 100644 --- a/cmd/frontend/handler/context.go +++ b/cmd/frontend/handler/context.go @@ -304,7 +304,7 @@ func (ws WebSocket) Serve(ctx *Context) error { conn, err := u.Upgrade(ctx.w, ctx.r, nil) if err != nil { - return ctx.String(err.Error()) + return ctx.String("%v", err) } return handler(conn) } diff --git a/docker-compose.base.yaml b/docker-compose.base.yaml index f88453ef..9dc2d98a 100644 --- a/docker-compose.base.yaml +++ b/docker-compose.base.yaml @@ -31,7 +31,7 @@ services: build: context: . dockerfile: Dockerfile.migrate - command: migrate apply --dir "file:///migrations" --tx-mode all --url "postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}/${DATABASE_NAME}?sslmode=disable" + command: migrate apply --dir "file:///migrations" --tx-mode all --url "${DATABASE_URL}" volumes: - /var/run/docker.sock:/var/run/docker.sock deploy: diff --git a/docker-compose.dokploy.yaml b/docker-compose.dokploy.yaml index 4f9ea53d..3575e4b7 100644 --- a/docker-compose.dokploy.yaml +++ b/docker-compose.dokploy.yaml @@ -6,7 +6,7 @@ services: restart: no environment: - COLLECTOR_BACKEND_URL=backend-${ENVIRONMENT}:${PRIVATE_SERVER_PORT} - - DATABASE_HOST=database-${ENVIRONMENT}:5432 + - DATABASE_URL=${DATABASE_URL} networks: dokploy-network: aliases: @@ -28,7 +28,7 @@ services: file: docker-compose.base.yaml service: aftermath-migrate-base environment: - - DATABASE_HOST=database-${ENVIRONMENT}:5432 + - DATABASE_URL=${DATABASE_URL} depends_on: database: condition: service_healthy @@ -41,11 +41,16 @@ services: extends: file: docker-compose.base.yaml service: aftermath-backup-base - restart: no + restart: always + entrypoint: ["/bin/sh", "-c", "sleep infinity"] + labels: + ofelia.enabled: "true" + ofelia.job-exec.backup-run.schedule: "@daily" + ofelia.job-exec.backup-run.command: "/backup.sh" environment: # relations will not be scanned when making a backup - TARGET_TABLES=account,clan,app_configuration,application_command,user,user_connection,user_subscription,user_content,user_restriction,moderation_request,widget_settings - - DATABASE_URL=postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}/${DATABASE_NAME}?sslmode=disable + - DATABASE_URL=${DATABASE_URL} - S3_BUCKET=${DATABASE_BACKUP_S3_BUCKET} - ENDPOINT_URL=${DATABASE_BACKUP_ENDPOINT_URL} - AWS_ACCESS_KEY_ID=${DATABASE_BACKUP_AWS_ACCESS_KEY_ID} @@ -68,7 +73,7 @@ services: environment: # the rest is imported from .env, which is going to be created by Dokploy automatically - PORT=3000 # the port does not matter, but it needs to match Traefik labels. we set it here explicitly in order to avoid any issues - - DATABASE_HOST=database-${ENVIRONMENT}:5432 + - DATABASE_URL=${DATABASE_URL} depends_on: migrate: condition: service_completed_successfully diff --git a/go.mod b/go.mod index 78ba673f..3daa440b 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,6 @@ go 1.24.3 require github.com/go-jet/jet/v2 v2.13.0 -// replace github.com/cufee/facepaint => ../facepaint - require ( github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9 github.com/PuerkitoBio/goquery v1.10.3 diff --git a/internal/assets/generate.go b/internal/assets/generate.go index ed93b3a8..b177447d 100644 --- a/internal/assets/generate.go +++ b/internal/assets/generate.go @@ -123,7 +123,7 @@ func generateDiscordHelpImage(printer func(string) string) { dctx.Fill() fontSize := 20.0 - commands := []string{"help", "links", "stats", "session"} + commands := []string{"help", "links", "career", "session"} for i, name := range commands { drawY := float64((padding + int(fontSize)) + i*(int(fontSize*2)+padding)) dctx.SetColor(color.White) diff --git a/internal/constants/database.go b/internal/constants/database.go index d7e999de..4a8da651 100644 --- a/internal/constants/database.go +++ b/internal/constants/database.go @@ -1,7 +1,5 @@ package constants -import "fmt" - var ( - DatabaseConnString = fmt.Sprintf("postgresql://%s:%s@%s/%s?sslmode=disable", MustGetEnv("DATABASE_USER"), MustGetEnv("DATABASE_PASSWORD"), MustGetEnv("DATABASE_HOST"), MustGetEnv("DATABASE_NAME")) + DatabaseConnString = MustGetEnv("DATABASE_URL") ) diff --git a/internal/database/accounts.go b/internal/database/accounts.go index d3e9aa2f..2e7dd1dd 100644 --- a/internal/database/accounts.go +++ b/internal/database/accounts.go @@ -73,13 +73,12 @@ func (c *client) GetAccounts(ctx context.Context, ids []string) ([]models.Accoun return accounts, nil } -func (c *client) UpsertAccounts(ctx context.Context, accounts ...*models.Account) (map[string]error, error) { +func (c *client) UpsertAccounts(ctx context.Context, accounts ...*models.Account) error { if len(accounts) < 1 { - return nil, nil + return nil } - errors := make(map[string]error) - return errors, c.withTx(ctx, func(tx *transaction) error { + return c.withTx(ctx, func(tx *transaction) error { for _, a := range accounts { stmt := t.Account. INSERT(t.Account.AllColumns). @@ -96,7 +95,7 @@ func (c *client) UpsertAccounts(ctx context.Context, accounts ...*models.Account ) _, err := tx.exec(ctx, stmt) if err != nil { - errors[a.ID] = err + return err } } return nil diff --git a/internal/database/accounts_test.go b/internal/database/accounts_test.go index c33e4729..29a01ecf 100644 --- a/internal/database/accounts_test.go +++ b/internal/database/accounts_test.go @@ -16,7 +16,7 @@ func TestAccounts(t *testing.T) { t.Run("upsert and check a new account", func(t *testing.T) { is := is.New(t) - errors, err := client.UpsertAccounts(context.Background(), &models.Account{ + err := client.UpsertAccounts(context.Background(), &models.Account{ ID: "id-1", Realm: "realm", Nickname: "nickname-1", @@ -26,15 +26,12 @@ func TestAccounts(t *testing.T) { LastBattleTime: time.Now(), }) is.NoErr(err) - for _, err := range errors { - is.NoErr(err) - } account, err := client.GetAccountByID(context.Background(), "id-1") is.NoErr(err) is.True(account.Nickname == "nickname-1") - errors, err = client.UpsertAccounts(context.Background(), &models.Account{ + err = client.UpsertAccounts(context.Background(), &models.Account{ ID: "id-1", Realm: "realm", Nickname: "nickname-2", @@ -44,9 +41,6 @@ func TestAccounts(t *testing.T) { LastBattleTime: time.Now(), }) is.NoErr(err) - for _, err := range errors { - is.NoErr(err) - } account, err = client.GetAccountByID(context.Background(), "id-1") is.NoErr(err) @@ -56,7 +50,7 @@ func TestAccounts(t *testing.T) { t.Run("get multiple accounts", func(t *testing.T) { is := is.New(t) - errors, err := client.UpsertAccounts(context.Background(), + err := client.UpsertAccounts(context.Background(), &models.Account{ ID: "id-21", Realm: "realm", @@ -76,9 +70,6 @@ func TestAccounts(t *testing.T) { LastBattleTime: time.Now(), }) is.NoErr(err) - for _, err := range errors { - is.NoErr(err) - } accounts, err := client.GetAccounts(context.Background(), []string{"id-21", "id-22"}) is.NoErr(err) @@ -91,7 +82,7 @@ func TestAccounts(t *testing.T) { t.Run("set account to private", func(t *testing.T) { is := is.New(t) - errors, err := client.UpsertAccounts(context.Background(), &models.Account{ + err := client.UpsertAccounts(context.Background(), &models.Account{ ID: "id-10", Realm: "realm", Nickname: "nickname-10", @@ -101,9 +92,6 @@ func TestAccounts(t *testing.T) { LastBattleTime: time.Now(), }) is.NoErr(err) - for _, err := range errors { - is.NoErr(err) - } account, err := client.GetAccountByID(context.Background(), "id-10") is.NoErr(err) @@ -111,9 +99,6 @@ func TestAccounts(t *testing.T) { err = client.AccountSetPrivate(context.Background(), "id-10", true) is.NoErr(err) - for _, err := range errors { - is.NoErr(err) - } account, err = client.GetAccountByID(context.Background(), "id-10") is.NoErr(err) diff --git a/internal/database/averages.go b/internal/database/averages.go index b894af73..3440d947 100644 --- a/internal/database/averages.go +++ b/internal/database/averages.go @@ -13,18 +13,16 @@ import ( s "github.com/go-jet/jet/v2/postgres" ) -func (c *client) UpsertVehicleAverages(ctx context.Context, averages map[string]frame.StatsFrame) (map[string]error, error) { +func (c *client) UpsertVehicleAverages(ctx context.Context, averages map[string]frame.StatsFrame) error { if len(averages) < 1 { - return nil, nil + return nil } - errors := make(map[string]error) - return errors, c.withTx(ctx, func(tx *transaction) error { + return c.withTx(ctx, func(tx *transaction) error { for id, data := range averages { encoded, err := json.Marshal(data) if err != nil { - errors[id] = err - continue + return err } model := m.VehicleAverage{ @@ -44,7 +42,7 @@ func (c *client) UpsertVehicleAverages(ctx context.Context, averages map[string] )) _, err = tx.exec(ctx, stmt) if err != nil { - errors[id] = err + return err } } return nil diff --git a/internal/database/averages_test.go b/internal/database/averages_test.go index 6ac81e28..6822d238 100644 --- a/internal/database/averages_test.go +++ b/internal/database/averages_test.go @@ -24,11 +24,8 @@ func TestAverages(t *testing.T) { "id-2": {Battles: 228}, } - errors, err := client.UpsertVehicleAverages(context.Background(), averages) + err := client.UpsertVehicleAverages(context.Background(), averages) is.NoErr(err) - for _, err := range errors { - is.NoErr(err) - } found, err := client.GetVehicleAverages(context.Background(), []string{"id-1", "id-2"}) is.NoErr(err) diff --git a/internal/database/cleanup_test.go b/internal/database/cleanup_test.go index 485ef4a2..d5f9aa3d 100644 --- a/internal/database/cleanup_test.go +++ b/internal/database/cleanup_test.go @@ -24,7 +24,7 @@ func TestSnapshotCleanup(t *testing.T) { defer client.db.Exec(fmt.Sprintf("DELETE FROM %s;", table.AccountSnapshot.TableName())) accountID := "a-TestSnapshotCleanup" - _, err := client.UpsertAccounts(context.Background(), &models.Account{ID: accountID, Realm: "test", Nickname: "test_account"}) + err := client.UpsertAccounts(context.Background(), &models.Account{ID: accountID, Realm: "test", Nickname: "test_account"}) assert.NoError(t, err, "failed to upsert an account") defer client.db.Exec(fmt.Sprintf("DELETE FROM %s WHERE id = '%s';", table.Account.TableName(), accountID)) diff --git a/internal/database/client.go b/internal/database/client.go index 026da508..ac07e1b6 100644 --- a/internal/database/client.go +++ b/internal/database/client.go @@ -37,7 +37,7 @@ type AccountsClient interface { GetAccountByID(ctx context.Context, id string) (models.Account, error) GetRealmAccountIDs(ctx context.Context, realm string) ([]string, error) AccountSetPrivate(ctx context.Context, id string, value bool) error - UpsertAccounts(ctx context.Context, accounts ...*models.Account) (map[string]error, error) + UpsertAccounts(ctx context.Context, accounts ...*models.Account) error } type GlossaryClient interface { @@ -45,14 +45,14 @@ type GlossaryClient interface { GetVehicles(ctx context.Context, ids []string) (map[string]models.Vehicle, error) GetVehicleAverages(ctx context.Context, ids []string) (map[string]frame.StatsFrame, error) - UpsertVehicles(ctx context.Context, vehicles map[string]models.Vehicle) (map[string]error, error) - UpsertVehicleAverages(ctx context.Context, averages map[string]frame.StatsFrame) (map[string]error, error) + UpsertVehicles(ctx context.Context, vehicles map[string]models.Vehicle) error + UpsertVehicleAverages(ctx context.Context, averages map[string]frame.StatsFrame) error GetMap(ctx context.Context, id string) (types.Map, error) UpsertMaps(ctx context.Context, maps map[string]types.Map) error GetGameModeNames(ctx context.Context, id string) (map[language.Tag]string, error) - UpsertGameModes(ctx context.Context, modes map[string]map[language.Tag]string) (map[string]error, error) + UpsertGameModes(ctx context.Context, modes map[string]map[language.Tag]string) error } type UsersClient interface { diff --git a/internal/database/game_modes.go b/internal/database/game_modes.go index 799dfee9..6b8245aa 100644 --- a/internal/database/game_modes.go +++ b/internal/database/game_modes.go @@ -12,18 +12,16 @@ import ( "golang.org/x/text/language" ) -func (c *client) UpsertGameModes(ctx context.Context, modes map[string]map[language.Tag]string) (map[string]error, error) { +func (c *client) UpsertGameModes(ctx context.Context, modes map[string]map[language.Tag]string) error { if len(modes) < 1 { - return nil, nil + return nil } - errors := make(map[string]error) - return errors, c.withTx(ctx, func(tx *transaction) error { + return c.withTx(ctx, func(tx *transaction) error { for id, locales := range modes { encoded, err := json.Marshal(locales) if err != nil { - errors[id] = err - continue + return err } model := m.GameMode{ @@ -43,7 +41,7 @@ func (c *client) UpsertGameModes(ctx context.Context, modes map[string]map[langu )) _, err = tx.exec(ctx, stmt) if err != nil { - errors[id] = err + return err } } return nil diff --git a/internal/database/snapshots_test.go b/internal/database/snapshots_test.go index 01c81305..a1c1d9a3 100644 --- a/internal/database/snapshots_test.go +++ b/internal/database/snapshots_test.go @@ -21,7 +21,7 @@ func TestVehicleSnapshots(t *testing.T) { defer client.db.Exec(fmt.Sprintf("DELETE FROM %s;", table.VehicleSnapshot.TableName())) accountID := "a-TestVehicleSnapshots" - _, err := client.UpsertAccounts(ctx, &models.Account{ID: accountID, Realm: "test", Nickname: "test_account"}) + err := client.UpsertAccounts(ctx, &models.Account{ID: accountID, Realm: "test", Nickname: "test_account"}) assert.NoError(t, err, "failed to upsert an account") defer client.db.Exec(fmt.Sprintf("DELETE FROM %s WHERE id = '%s';", table.Account.TableName(), accountID)) @@ -137,7 +137,7 @@ func TestAccountSnapshots(t *testing.T) { accountID := "a-TestAccountSnapshots" accountID2 := "a-TestAccountSnapshots-2" - _, err := client.UpsertAccounts(ctx, &models.Account{ID: accountID, Realm: "test", Nickname: "test_account"}, &models.Account{ID: accountID2, Realm: "test", Nickname: "test_account"}) + err := client.UpsertAccounts(ctx, &models.Account{ID: accountID, Realm: "test", Nickname: "test_account"}, &models.Account{ID: accountID2, Realm: "test", Nickname: "test_account"}) is.NoErr(err) defer client.db.Exec(fmt.Sprintf("DELETE FROM %s WHERE id IN ('%s', '%s');", table.Account.TableName(), accountID, accountID2)) diff --git a/internal/database/vehicles.go b/internal/database/vehicles.go index 1f47729b..95839f3a 100644 --- a/internal/database/vehicles.go +++ b/internal/database/vehicles.go @@ -12,13 +12,12 @@ import ( s "github.com/go-jet/jet/v2/postgres" ) -func (c *client) UpsertVehicles(ctx context.Context, vehicles map[string]models.Vehicle) (map[string]error, error) { +func (c *client) UpsertVehicles(ctx context.Context, vehicles map[string]models.Vehicle) error { if len(vehicles) < 1 { - return nil, nil + return nil } - errors := make(map[string]error) - return errors, c.withTx(ctx, func(tx *transaction) error { + return c.withTx(ctx, func(tx *transaction) error { for id, data := range vehicles { model := m.Vehicle{ ID: id, @@ -28,8 +27,7 @@ func (c *client) UpsertVehicles(ctx context.Context, vehicles map[string]models. } names, err := json.Marshal(data.LocalizedNames) if err != nil { - errors[id] = err - continue + return err } model.LocalizedNames = names @@ -45,7 +43,7 @@ func (c *client) UpsertVehicles(ctx context.Context, vehicles map[string]models. _, err = tx.exec(ctx, stmt) if err != nil { - errors[id] = err + return err } } return nil diff --git a/internal/logic/snapshots.go b/internal/logic/snapshots.go index 1a02ebab..2832005b 100644 --- a/internal/logic/snapshots.go +++ b/internal/logic/snapshots.go @@ -254,17 +254,12 @@ func RecordAccountSnapshots(ctx context.Context, wgClient wargaming.Client, dbCl } } -outer: for _, accountSnapshot := range accountSnapshots { // update account cache - aErr, err := dbClient.UpsertAccounts(ctx, accountUpdates[accountSnapshot.AccountID]) + err := dbClient.UpsertAccounts(ctx, accountUpdates[accountSnapshot.AccountID]) if err != nil { log.Err(err).Str("accountId", accountSnapshot.AccountID).Msg("failed to upsert account") - } - for _, err := range aErr { - log.Err(err).Str("accountId", accountSnapshot.AccountID).Msg("failed to upsert account") - accountErrors[accountSnapshot.AccountID] = err - continue outer + continue } // save account snapshot diff --git a/internal/stats/fetch/v1/multisource.go b/internal/stats/fetch/v1/multisource.go index f396563f..067c1f87 100644 --- a/internal/stats/fetch/v1/multisource.go +++ b/internal/stats/fetch/v1/multisource.go @@ -161,13 +161,10 @@ func (c *multiSourceClient) Account(ctx context.Context, id string) (models.Acco ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() - aErr, err := c.database.UpsertAccounts(ctx, &account) + err := c.database.UpsertAccounts(ctx, &account) if err != nil { log.Err(err).Msg("failed to update account cache") } - if err := aErr[account.ID]; err != nil { - log.Err(err).Msg("failed to update account cache") - } }(account) return account, nil @@ -227,7 +224,7 @@ func (c *multiSourceClient) CurrentStats(ctx context.Context, id string, opts .. } // manually filter vehicles for cases where the slice of ids was 100+ - if options.VehicleIDs != nil && len(options.VehicleIDs) >= 100 { + if len(options.VehicleIDs) >= 100 { var filtered []types.VehicleStatsFrame for _, v := range vehicles.Data { if !slices.Contains(options.VehicleIDs, fmt.Sprint(v.TankID)) { @@ -269,13 +266,10 @@ func (c *multiSourceClient) CurrentStats(ctx context.Context, id string, opts .. ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() - aErr, err := c.database.UpsertAccounts(ctx, &account) + err := c.database.UpsertAccounts(ctx, &account) if err != nil { log.Err(err).Msg("failed to update account cache") } - if err := aErr[account.ID]; err != nil { - log.Err(err).Msg("failed to update account cache") - } }(stats.Account) return stats, nil diff --git a/static/.gitignore b/static/.gitignore index 07bf85a9..bbdff85d 100644 --- a/static/.gitignore +++ b/static/.gitignore @@ -1 +1 @@ -localization +# localization diff --git a/static/localization/en/cta.yaml b/static/localization/en/cta.yaml new file mode 100644 index 00000000..8a6fd64b --- /dev/null +++ b/static/localization/en/cta.yaml @@ -0,0 +1,50 @@ +cta_abandoned_negative_growth_body: |- + It looks like you haven't used Aftermath in a while, but I can be really helpful for players looking to improve their stats. + + Here is your recent session, try using `/session` if you want to dive deeper into your stats! +cta_abandoned_negative_growth_head: "We miss you :cry:" +cta_abandoned_neutral_growth_body: |- + It looks like you haven't used Aftermath in a while. + + Check out your recent stats, you can also dive deeper using the `/session` command! +cta_abandoned_neutral_growth_head: "We miss you :cry:" +cta_abandoned_positive_growth_body: |- + It looks like you haven't used Aftermath in a while, but your growth is impressive! + + Here is your recent session, try using `/session` if you want to dive deeper into your stats. +cta_abandoned_positive_growth_head: "We miss you :cry:" +cta_command_help_body: |- + Looking for more information on all the awesome features? + + Check `/help` for an overview of every supported command! +cta_command_help_button: "Have a question?" +cta_command_help_head: "Learn about Aftermath!" +cta_command_links_add_body: |- + You can link your Blitz account to Aftermath to make checking stats even easier! + + Give it a try with `/links add` +cta_command_links_add_head: "Link your Blitz account!" +cta_command_links_verify_body: |- + You can verify your Blitz account using `/link verify`. + + This will make your custom background images visible to other users and unlock the `/my` command! +cta_command_links_verify_head: "Verify your Blitz account!" +cta_command_replay_body: |- + You can upload a replay using `/replay` to get an overview of your battle with stats for every player! + + Replays are always kept private, never stored, and never uploaded to any third party service - your strats are safe with us! +cta_command_replay_head: "Aftermath can also process your replays!" +cta_guild_install_body: |- + Just share this link with a server owner! + https://amth.one/install +cta_guild_install_button: "Share Aftermath" +cta_guild_install_head: "Want to add Aftermath to your favorite server?" +cta_personal_install_body: |- + Install Aftermath as a personal App and use it across all servers and Direct Message groups! + + Just select **Add to My Apps** when installing Aftermath +cta_personal_install_button: "Install Aftermath" +cta_personal_install_head: "You can use Aftermath across all of your servers!" +cta_report_issues_body: "You can report any errors and submit feature requests on the Aftermath Official Discord server!" +cta_report_issues_button: "Join Aftermath Official" +cta_report_issues_head: "Spotted an error or want to share some feedback?" diff --git a/static/localization/en/discord.yaml b/static/localization/en/discord.yaml new file mode 100644 index 00000000..e67754bd --- /dev/null +++ b/static/localization/en/discord.yaml @@ -0,0 +1,241 @@ +background_error_invalid_attachment_image: "The image you have provided is invalid. Please make sure it is a PNG or JPEG image." +background_error_invalid_attachment_vague: "The file attached is not a valid image." +background_error_missing_attachment: "You need to attach an image or provide a link in order to upload a custom background." +background_error_payment_required: |- + This feature of Aftermath is only available for users with an active subscription. + + You can subscribe by using the `/subscribe` command or pick a background using `/fancy` instead. +blitz_stars_error_service_down: "Some of your career stats rely on BlitzStars, which is currently unavailable. However, most other commands, including sessions, are still working." +buttons_add_aftermath_to_your_server: "Install Aftermath" +buttons_have_a_question_question: "Have a Question?" +buttons_join_primary_guild: "Join Aftermath Official" +buttons_need_help_question: "Need Help?" +buttons_submit: "Submit" +command_auction_description: "View the current Blitz Auction" +command_auction_name: "auction" +command_auction_result_fmt: "### Updated " +command_career_desc: "Get an overview of your career stats" +command_career_help_message: |- + ## View Career Stats for Your Account! + To get started, include a nickname and server, mention another user, or link an account using `/links add`! +command_career_name: "career" +command_fancy_description: "Manage your custom background images" +command_fancy_help_message: |- + ## Upload a Custom Background! + To get started, attach an image or provide a link to an image when sending the command! +command_fancy_name: "fancy" +command_help_description: "Get some helpful information about the bot" +command_help_name: "help" +command_links_buttons_manage: "Manage Accounts" +command_links_description: "Manage your linked Blitz accounts" +command_links_linked_successfully_fmt: |- + Your account has been linked! Aftermath will now default to **%s** on **%s** when checking stats. + You can also verify your account with `/links verify` +command_links_name: "links" +command_links_set_default_successfully_fmt: "Your default account has been updated! Aftermath will now default to **%s** on **%s** when checking stats." +command_links_unlinked_successfully: "Your linked account was removed." +command_links_verify_cta: "You can also verify your account with `/links verify`" +command_links_verify_response_fmt: |- + ## Here is your verification link! + ### You will need to log in using the Discord account you are currently using in order to link your Blitz account. + _This link is specific to %s. It does not contain any personal information._ + :link: %s +command_links_view_content_fmt: |- + ## Here is a list of your linked Blitz accounts! + %s +   + You can manage and verify them on our website! +command_my_career_description: "View career stats for your linked accounts" +command_my_career_name: "career" +command_my_description: "View stats for your linked accounts" +command_my_name: "my" +command_my_session_description: "View session stats for your linked account" +command_my_session_name: "session" +command_option_fancy_file_description: "A JPEG or PNG image file" +command_option_fancy_file_name: "file" +command_option_fancy_link_description: "A link to a JPEG or PNG image" +command_option_fancy_link_name: "link" +command_option_fancy_remove_desc: "Remove a custom background you have previously uploaded" +command_option_fancy_remove_name: "remove" +command_option_fancy_upload_desc: "Upload a new custom background for your stats" +command_option_fancy_upload_name: "upload" +command_option_links_add_desc: "Link a new Blitz account" +command_option_links_add_name: "add" +command_option_links_fav_desc: "Mark your linked account as default for Aftermath to check" +command_option_links_fav_name: "favorite" +command_option_links_remove_desc: "Remove your linked Blitz account" +command_option_links_remove_name: "remove" +command_option_links_verify_desc: "Link and verify your Blitz account to unlock more features!" +command_option_links_verify_name: "verify" +command_option_links_view_desc: "View your linked Blitz accounts" +command_option_links_view_name: "view" +command_option_my_account_description: "Select one of your linked account" +command_option_my_account_name: "account" +command_option_replay_file_description: "A Blitz replay file" +command_option_replay_file_name: "file" +command_option_replay_link_description: "A link to a Blitz replay file" +command_option_replay_link_name: "link" +command_option_widget_account_description: "Select one of your linked account" +command_option_widget_account_name: "account" +command_replay_help_message: |- + ## Analyze Your Replay and View Stats for All Players! + To get started, attach a replay file or provide a link to a replay file when sending the command! +command_session_description: "Get detailed stats for your recent session" +command_session_help_message: |- + ## View Session Stats for Your Account! + To get started, include a nickname and server, mention another user, or link an account using `/links add`! +command_session_name: "session" +commands_help_message_fmt: |- + ## :chart_with_upwards_trend: Track your progress + ### ○ /session + Get an image with your current session stats. You can also mention another user to view their session. + ### Aftermath sessions will be reset at the following times: + %s + ### ○ /career + Get an image with your career stats. You can also mention another user to view their stats. + ## :film_frames: Dive deeper into every battle + ### ○ /replay + Upload your replay and get an overview of the battle you have played. + ## :link: Tell Aftermath your Blitz nickname + ### ○ /links + You can set a default account by using the _/links favorite_ command to use _/session_ and _/career_ without providing a nickname and server. + ### ○ /links verify + Verify your Wargaming account to unlock additional features. + ## :frame_photo: Add a splash of style + ### ○ /fancy + Upload a custom background image for your session stats. Your unique style will be visible to everyone who views your stats. + ## :desktop: Show off on your stream + ### ○ /widget + Get a link to a streaming widget for your stream overlay. + This widget will automatically update with your latest session stats. + + _Found a translation error? Let us know on Aftermath Official_ + ## :heart: Share the love! +commands_help_refresh_times_fmt: |- + North America: () + Europe: () + Asia: () +commands_replay_description: "Analyze your replay and view stats for every single player" +commands_replay_name: "replay" +commands_subscribe_action_button: "Subscribe" +commands_widget_description: "Get a live streaming widget for your account" +commands_widget_message_fmt: |- + ## [Here is your widget link!](%s) + _Add it as a Browser Source in OBS_ [_(learn more)_](https://obsproject.com/kb/browser-source). +commands_widget_name: "widget" +common_error_command_expired_fmt: "This is a seasonal command that was disabled on and will be removed soon." +common_error_command_missing_permissions: "You don't have permission to use this command." +common_error_discord_outage: "It looks like Discord is having some temporary issues. Please try again in a few seconds." +common_error_missing_permissions_dm: "Aftermath is not able to send you a direct message." +common_error_missing_permissions_dm_mention_fmt: "Hey %s, Aftermath is not able to send you a direct message." +common_error_payment_required: |- + This feature of Aftermath is only available for users with an active subscription. + You can subscribe by using the `/subscribe` command. +common_error_service_outage: "Aftermath is currently undergoing maintenance and is temporarily unavailable. Please try again in a few moments." +common_error_unhandled_not_reported: |- + Something unexpected happened and your command failed. + *You can reach out to our team on Aftermath Official if you would like to report this error* +common_error_unhandled_reported: |- + Something unexpected happened and your command failed. + *This error was reported automatically, you can also reach out to our team on Aftermath Official* +common_error_user_restricted_vague_fmt: "### You are banned from using some or all features of Aftermath until " +common_error_user_spam_detected: "Hey there! It seems like you're using commands too quickly. To ensure a smooth experience for everyone, please refrain from spamming." +common_label_realm_as: "Asia" +common_label_realm_eu: "Europe" +common_label_realm_na: "North America" +common_label_realm_ru: "CIS" +common_label_tier_1: "Tier I" +common_label_tier_10: "Tier X" +common_label_tier_2: "Tier II" +common_label_tier_3: "Tier III" +common_label_tier_4: "Tier IV" +common_label_tier_5: "Tier V" +common_label_tier_6: "Tier VI" +common_label_tier_7: "Tier VII" +common_label_tier_8: "Tier VIII" +common_label_tier_9: "Tier IX" +common_option_stats_days_description: "How far back should the session go?" +common_option_stats_days_name: "days" +common_option_stats_nickname_description: "Blitz player name" +common_option_stats_nickname_name: "nickname" +common_option_stats_realm_description: "What server is this account on?" +common_option_stats_realm_name: "server" +common_option_stats_tank_description: "Filter vehicles by name" +common_option_stats_tank_tier_description: "Filter vehicles by tier" +common_option_stats_user_description: "Select another user to view their stats" +common_option_stats_user_name: "user" +discord_error_invalid_interaction_fmt: | + -# <@%s> used a command + **It looks like Discord is having some issues at the moment.** + Aftermath replies might be delayed, but we will try our best to make things work! +error_command_auction_still_refreshing: "Aftermath is still working on refreshing the current auction offers, please try again in a couple minutes." +errors_help_missing_dm_permissions_fmt: "Hey %s, Aftermath is not able to send you a direct message. Try using `/help` instead." +fancy_error_too_many_options_non_blocking: "When using this command, you only need to provide either a link or a file. The image file will override the link if both are provided." +fancy_errors_invalid_format: "The image you have provided is not in a JPEG or PNG format. This command does not support other file formats." +fancy_errors_invalid_image: |- + The image you have provided may be broken or is too large. + _The maximum recommended image size is 1000px x 1000px._ +fancy_errors_invalid_link: "The image you have provided is invalid, Aftermath was not able to view it." +fancy_errors_missing_attachment: "You need to provide a link or attach an image file." +fancy_errors_pending_request_exists: "You have a pending moderation request. Please wait until your previously submitted image is approved or rejected." +fancy_errors_preview_expired: "This preview has expired. Please create a new one to submit it for moderation." +fancy_errors_upload_timeout_fmt: |- + It looks like you have uploaded a custom background image recently. + You will be able to use this command again . +fancy_hint_image_transformation: "Images uploaded to Aftermath via this command will be scaled down and blurred. They will also require manual moderation." +fancy_moderation_request_approved: |- + ## :tada: **Your Custom Background is set!** :tada: + The image you have submitted was approved by a moderator and is now set as your stats background. Other users will only see this background if your default linked account is verified. +fancy_moderation_request_declined: |- + **Your recent image moderation request was declined** + It looks like the image you have uploaded did not pass out safety standards. You background will not be updated. +fancy_moderation_request_declined_and_banned_fmt: |- + **Your recent image moderation request was declined** + It looks like you have tried to upload an image that is against Aftermath Terms Of Service. As a result, your account will be restricted from uploading custom content until . This decision is final and cannot be appealed. +fancy_preview_msg: |- + ## Here is a preview of your image! + Use the buttons below to submit it for moderation. +fancy_remove_completed: "Your custom background image was removed." +fancy_remove_not_found: |- + ## You don't have a custom background image uploaded + To get started, use `/fancy upload`. +fancy_submitted_msg: |- + **Your request was submitted** + You will get a Direct Message when it is reviewed - no further action is required. + + _Please make sure your Direct Messages are open._ +links_error_connection_not_found: "Your linked account is no longer available. Try adding a new one with `/links add`." +links_error_connection_not_found_selected: "The account you have selected is no longer available" +links_error_no_account_selected: "It looks like you did not select an account from the options provided. Please pick one of the accounts shown as you type." +links_error_no_accounts_linked: "You don't have any linked accounts." +links_error_too_many_connections: |- + It looks like you have reached the limit for the number of Blitz accounts linked. + Try removing an existing account with `/links remove` before adding a new one. +my_error_no_account_linked: "It looks like you don't have a default Blitz account set. You can manage your accounts with `/links`." +nickname_autocomplete_invalid_input: "This does not look like a valid player name, make sure you are using your in-game name" +nickname_autocomplete_not_enough_length: "Continue typing to search for accounts..." +nickname_autocomplete_not_found: "Nothing found. Please select a nickname from the autocompletion list" +replay_error_too_many_options_non_blocking: "When using this command, you only need to provide either a link or a replay file. The replay file will override the link if both are provided." +replay_errors_all_attachments_invalid: "None of the files you have attached are valid WoT Blitz replays." +replay_errors_invalid_attachment: "The file you have attached is not a valid WoT Blitz replay." +replay_errors_missing_attachment: "You need to provide a link or attach a WoT Blitz replay file." +replay_errors_missing_permissions_vague: "Aftermath is missing some required permissions in this channel. Try using the `/replay` command instead." +replay_errors_some_attachments_invalid: "Some of the files you have attached are valid WoT Blitz replays and were skipped." +replay_errors_too_many_files: "Aftermath can process up to 5 replays at once. Please use the `/replay` command to upload any additional files." +session_error_account_was_not_tracked: "Aftermath just started tracking this account. Please play a few battles before using this command again." +session_error_no_session_for_period: "Aftermath does not yet have a session for this period. Try changing the number of days or using `/career` instead." +stats_account_not_found: "It looks like there are no Blitz accounts matching your search, please select an option from the list of accounts that is shown as you type in the nickname." +stats_autocomplete_not_enough_length: "Continue typing to search for available tanks..." +stats_autocomplete_not_found: "Nothing found. Please select a tank from the autocompletion list" +stats_bad_nickname_input_hint: "Wrong account? When searching for a Blitz account by nickname, try selecting a specific account from the results shown as you type" +stats_error_connection_not_found_personal: "Looks like you don't have a Blitz account linked yet. Give the `/links add` command a shot." +stats_error_connection_not_found_vague: "The user you mentioned does not have a Blitz account linked." +stats_error_connection_not_verified: "Looks like you haven't verified your Blitz account yet. Give the `/links verify` command a shot." +stats_error_mentioned_self_non_blocking: "You don't need to @mention yourself when checking stats, just type the command without any options to check your own account." +stats_error_nickname_invalid: "This does not look like a valid player name, make sure you are using your in-game name." +stats_error_too_many_arguments_non_blocking: "When using this command, you only need to mention a user or provide a nickname. The mentioned user will override the nickname if both are provided." +stats_multiple_accounts_found: "### It looks like there are multiple Blitz accounts matching your search, please select one using the buttons below." +stats_refresh_interaction_error_expired: "This refresh button has expired. Please use the command instead." +wargaming_error_outage: "It looks like Wargaming are having some temporary issues. Please try again in a few seconds." +wargaming_error_outage_short: "It looks like Wargaming are having some issues. Please try again" +wargaming_error_private_account: "This account is marked private by Wargaming and no stats are available for it at this time." diff --git a/static/localization/en/stats.yaml b/static/localization/en/stats.yaml new file mode 100644 index 00000000..e9dca1f6 --- /dev/null +++ b/static/localization/en/stats.yaml @@ -0,0 +1,48 @@ +game_mode_lunar: "Lunar" +game_mode_training: "Training Room" +game_mode_tutorial: "Tutorial" +game_mode_unknown: "Unknown" +label_accuracy: "Accuracy" +label_assisted: "Assisted" +label_assisted_combined: "Assisted+" +label_avg_damage: "Damage" +label_avg_tier: "Tier" +label_battle_type_regular: "Encounter" +label_battle_type_supremacy: "Supremacy" +label_battle_type_unknown: "Unknown" +label_battles: "Battles" +label_blocked: "Blocked" +label_damage_assisted: "Assisted" +label_damage_blocked: "Blocked" +label_damage_dealt: "Damage" +label_damage_ratio: "Dmg. Ratio" +label_damage_taken: "Damage Received" +label_defeat: "Defeat" +label_frags: "Kills" +label_game_mode_burning_games: "Burning Games" +label_game_mode_gravity: "Gravity" +label_game_mode_mad_games: "Mad Games" +label_game_mode_quick_tournament: "Quick Tournament" +label_game_mode_rating: "Rating Battle" +label_game_mode_realistic: "Realistic Battle" +label_game_mode_regular: "Regular Battle" +label_game_mode_skirmish: "Skirmish" +label_game_mode_tournament: "Tournament" +label_game_mode_training: "Training Room" +label_game_mode_unknown: "Unknown" +label_game_mode_uprising: "Uprising" +label_highlight_avg_damage: "Best Performance" +label_highlight_battles: "Favorite Tank" +label_highlight_recent_battle: "Last Battle" +label_highlight_wn8: "Biggest Impact" +label_map_name_unknown: "Unknown" +label_overview_rating: "Rating Battles" +label_overview_unrated: "Regular Battles" +label_ranked_rating: "Rating" +label_survival_percent: "Survived" +label_survival_ratio: "Survival" +label_victory: "Victory" +label_winrate: "Winrate" +label_wn8: "WN8" +tag_quick_tournament: "Quick Tournament" +tag_tournament: "Tournament" diff --git a/static/localization/pl/cta.yaml b/static/localization/pl/cta.yaml new file mode 100644 index 00000000..0a11f90f --- /dev/null +++ b/static/localization/pl/cta.yaml @@ -0,0 +1,50 @@ +cta_abandoned_negative_growth_body: |- + Wygląda na to, że nie używałeś Aftermath od jakiegoś czasu, ale mogę być naprawdę pomocny dla graczy, którzy chcą poprawić swoje statystyki. + + Oto twoja ostatnia sesja, spróbuj użyć `/session`, jeśli chcesz zagłębić się w swoje statystyki! +cta_abandoned_negative_growth_head: "Tęsknimy za Tobą :cry:" +cta_abandoned_neutral_growth_body: |- + Wygląda na to, że nie używałeś Aftermath od jakiegoś czasu. + + Sprawdź swoje ostatnie statystyki, możesz też zanurkować głębiej używając polecenia `/session`! +cta_abandoned_neutral_growth_head: "Tęsknimy za Tobą :cry:" +cta_abandoned_positive_growth_body: |- + Wygląda na to, że nie używałeś Aftermath od jakiegoś czasu, ale twój rozwój jest imponujący! + + Oto twoja ostatnia sesja, spróbuj użyć `/session`, jeśli chcesz zagłębić się w swoje statystyki. +cta_abandoned_positive_growth_head: "Tęsknimy za Tobą :cry:" +cta_command_help_body: |- + Szukasz więcej informacji o wszystkich niesamowitych funkcjach? + + Sprawdź `/help`, aby uzyskać przegląd wszystkich obsługiwanych poleceń! +cta_command_help_button: "Masz pytanie?" +cta_command_help_head: "Dowiedz się więcej o Aftermath!" +cta_command_links_add_body: |- + Możesz połączyć swoje konto Blitz z Aftermath, aby jeszcze bardziej ułatwić sprawdzanie statystyk! + + Wypróbuj z `/links add` +cta_command_links_add_head: "Połącz swoje konto Blitz!" +cta_command_links_verify_body: |- + Możesz zweryfikować swoje konto Blitz za pomocą `/link verify`. + + To sprawi, że Twoje niestandardowe obrazy tła będą widoczne dla innych użytkowników i odblokuje polecenie `/my`! +cta_command_links_verify_head: "Zweryfikuj swoje konto Blitz!" +cta_command_replay_body: |- + Możesz przesłać powtórkę za pomocą `/replay`, aby uzyskać przegląd swojej bitwy ze statystykami każdego gracza! + + Powtórki są zawsze prywatne, nigdy nie są przechowywane i nigdy nie są przesyłane do żadnej usługi zewnętrznej - Twoje strategie są u nas bezpieczne! +cta_command_replay_head: "Aftermath może również przetwarzać Twoje powtórki!" +cta_guild_install_body: |- + Po prostu udostępnij ten link właścicielowi serwera! + https://amth.one/install +cta_guild_install_button: "Udostępnij Aftermath" +cta_guild_install_head: "Chcesz dodać Aftermath do swojego ulubionego serwera?" +cta_personal_install_body: |- + Zainstaluj Aftermath jako osobistą aplikację i używaj jej na wszystkich serwerach i grupach Direct Message! + + Po prostu wybierz **Dodaj do moich aplikacji** podczas instalowania Aftermath +cta_personal_install_button: "Zainstaluj Aftermath" +cta_personal_install_head: "Możesz używać Aftermath na wszystkich swoich serwerach!" +cta_report_issues_body: "Możesz zgłaszać wszelkie błędy i przesyłać prośby o dodanie funkcji na oficjalnym serwerze Aftermath w serwisie Discord!" +cta_report_issues_button: "Dołącz do Aftermath Official" +cta_report_issues_head: "Znalazłeś błąd lub chcesz podzielić się swoją opinią?" diff --git a/static/localization/pl/discord.yaml b/static/localization/pl/discord.yaml new file mode 100644 index 00000000..86eab17e --- /dev/null +++ b/static/localization/pl/discord.yaml @@ -0,0 +1,241 @@ +background_error_invalid_attachment_image: "Podany obraz jest nieprawidłowy. Upewnij się, że jest to obraz PNG lub JPEG." +background_error_invalid_attachment_vague: "Załączony plik nie jest prawidłowym obrazem." +background_error_missing_attachment: "Aby przesłać niestandardowe tło, musisz dołączyć obraz lub podać link." +background_error_payment_required: |- + Ta funkcja Aftermath jest dostępna tylko dla użytkowników z aktywną subskrypcją. + + Możesz subskrybować, używając polecenia `/subscribe` lub wybrać tło, używając polecenia `/fancy`. +blitz_stars_error_service_down: "Niektóre statystyki twojej kariery opierają się na BlitzStars, który jest obecnie niedostępny. Jednak większość innych poleceń, w tym sesje, nadal działa." +buttons_add_aftermath_to_your_server: "Zainstaluj Aftermath" +buttons_have_a_question_question: "Masz pytanie?" +buttons_join_primary_guild: "Dołącz do Aftermath Official" +buttons_need_help_question: "Potrzebujesz pomocy?" +buttons_submit: "Wyślij" +command_auction_description: "Zobacz aktualną aukcję Blitz" +command_auction_name: "aukcja" +command_auction_result_fmt: "### Zaktualizowano " +command_career_desc: "Uzyskaj przegląd statystyk swojej kariery" +command_career_help_message: |- + ## Zobacz statystyki kariery dla swojego konta! + Aby rozpocząć, podaj pseudonim i serwer, wspomnij o innym użytkowniku lub połącz konto za pomocą `/links add`! +command_career_name: "kariera" +command_fancy_description: "Zarządzaj swoimi niestandardowymi obrazami tła" +command_fancy_help_message: |- + ## Prześlij niestandardowe tło! + Aby rozpocząć, dołącz obraz lub podaj link do obrazu podczas wysyłania polecenia! +command_fancy_name: "wymyślny" +command_help_description: "Uzyskaj przydatne informacje o bocie" +command_help_name: "pomoc" +command_links_buttons_manage: "Zarządzaj kontami" +command_links_description: "Zarządzaj swoimi połączonymi kontami Blitz" +command_links_linked_successfully_fmt: |- + Twoje konto zostało połączone! Aftermath będzie teraz domyślnie używać **%s** na **%s** podczas sprawdzania statystyk. + Możesz również zweryfikować swoje konto za pomocą `/links verify` +command_links_name: "linki" +command_links_set_default_successfully_fmt: "Twoje domyślne konto zostało zaktualizowane! Aftermath będzie teraz domyślnie **%s** na **%s** podczas sprawdzania statystyk." +command_links_unlinked_successfully: "Twoje powiązane konto zostało usunięte." +command_links_verify_cta: "Możesz również zweryfikować swoje konto za pomocą `/links verify`" +command_links_verify_response_fmt: |- + ## Oto Twój link weryfikacyjny! + ### Musisz zalogować się przy użyciu konta Discord, którego aktualnie używasz, aby połączyć swoje konto Blitz. + _Ten link jest specyficzny dla %s. Nie zawiera żadnych danych osobowych._ + :link: %s +command_links_view_content_fmt: |- + ## Oto lista Twoich powiązanych kont Blitz! + %s +   + Możesz nimi zarządzać i weryfikować je na naszej stronie internetowej! +command_my_career_description: "Wyświetl statystyki kariery dla powiązanych kont" +command_my_career_name: "kariera" +command_my_description: "Wyświetl statystyki dla połączonych kont" +command_my_name: "mój" +command_my_session_description: "Wyświetl statystyki sesji dla połączonego konta" +command_my_session_name: "sesja" +command_option_fancy_file_description: "Plik obrazu JPEG lub PNG" +command_option_fancy_file_name: "plik" +command_option_fancy_link_description: "Link do obrazu JPEG lub PNG" +command_option_fancy_link_name: "link" +command_option_fancy_remove_desc: "Usuń niestandardowe tło, które wcześniej przesłałeś" +command_option_fancy_remove_name: "usuń" +command_option_fancy_upload_desc: "Prześlij nowe, niestandardowe tło dla swoich statystyk" +command_option_fancy_upload_name: "wgraj" +command_option_links_add_desc: "Połącz nowe konto Blitz" +command_option_links_add_name: "dodaj" +command_option_links_fav_desc: "Oznacz swoje połączone konto jako domyślne, aby Aftermath je sprawdził" +command_option_links_fav_name: "ulubione" +command_option_links_remove_desc: "Usuń powiązane konto Blitz" +command_option_links_remove_name: "usuń" +command_option_links_verify_desc: "Połącz i zweryfikuj swoje konto Blitz, aby odblokować więcej funkcji!" +command_option_links_verify_name: "zweryfikuj" +command_option_links_view_desc: "Wyświetl powiązane konta Blitz" +command_option_links_view_name: "pogląd" +command_option_my_account_description: "Wybierz jedno ze swoich powiązanych kont" +command_option_my_account_name: "konto" +command_option_replay_file_description: "Plik powtórki Blitz" +command_option_replay_file_name: "plik" +command_option_replay_link_description: "Link do pliku powtórki Blitza" +command_option_replay_link_name: "link" +command_option_widget_account_description: "Wybierz jedno ze swoich powiązanych kont" +command_option_widget_account_name: "konto" +command_replay_help_message: |- + ## Przeanalizuj swoją powtórkę i zobacz statystyki wszystkich graczy! + Aby rozpocząć, dołącz plik powtórki lub podaj link do pliku powtórki podczas wysyłania polecenia! +command_session_description: "Uzyskaj szczegółowe statystyki dotyczące ostatniej sesji" +command_session_help_message: |- + ## Wyświetl statystyki sesji dla swojego konta! + Aby rozpocząć, podaj pseudonim i serwer, wspomnij o innym użytkowniku lub połącz konto za pomocą `/links add`! +command_session_name: "sesja" +commands_help_message_fmt: |- + ## :chart_with_upwards_trend: Śledź swoje postępy + ### ○ /session + Uzyskaj obraz ze statystykami swojej bieżącej sesji. Możesz również wspomnieć o innym użytkowniku, aby zobaczyć jego sesję. + ### Sesje Aftermath zostaną zresetowane w następujących momentach: + %s + ### ○ /career + Uzyskaj obraz ze statystykami swojej kariery. Możesz również wspomnieć o innym użytkowniku, aby zobaczyć jego statystyki. + ## :film_frames: Zanurz się głębiej w każdej bitwie + ### ○ /replay + Prześlij swoją powtórkę i zobacz przegląd rozegranej bitwy. + ## :link: Podaj Aftermath swój pseudonim Blitz + ### ○ /links + Możesz ustawić domyślne konto, używając polecenia _/links favorite_, aby używać _/session_ i _/career_ bez podawania pseudonimu i serwera. + ### ○ /links verify + Zweryfikuj swoje konto Wargaming, aby odblokować dodatkowe funkcje. + ## :frame_photo: Dodaj odrobinę stylu + ### ○ /fancy + Prześlij niestandardowy obraz tła dla statystyk sesji. Twój unikalny styl będzie widoczny dla wszystkich, którzy oglądają Twoje statystyki. + ## :desktop: Pokaż się na swoim streamie + ### ○ /widget + Uzyskaj link do widżetu streamingu dla nakładki streamu. + Ten widżet automatycznie zaktualizuje się o najnowsze statystyki sesji. + + _Znalazłeś błąd w tłumaczeniu? Daj nam znać na Aftermath Official_ + ## :heart: Podziel się miłością! +commands_help_refresh_times_fmt: |- + Ameryka Północna: () + Europa: () + Azja: () +commands_replay_description: "Przeanalizuj powtórkę i zobacz statystyki każdego gracza" +commands_replay_name: "powtórka" +commands_subscribe_action_button: "Subskrybuj" +commands_widget_description: "Uzyskaj widget transmisji strumieniowej na żywo dla swojego konta" +commands_widget_message_fmt: |- + ## [Oto link do Twojego widżetu!](%s) + _Dodaj go jako źródło przeglądarki w OBS_ [_(dowiedz się więcej)_](https://obsproject.com/kb/browser-source). +commands_widget_name: "widżet" +common_error_command_expired_fmt: "Jest to polecenie sezonowe, które zostało wyłączone w i wkrótce zostanie usunięte." +common_error_command_missing_permissions: "Nie masz uprawnień do użycia tego polecenia." +common_error_discord_outage: "Wygląda na to, że Discord ma chwilowe problemy. Spróbuj ponownie za kilka sekund." +common_error_missing_permissions_dm: "Aftermath nie jest w stanie wysłać Ci bezpośredniej wiadomości." +common_error_missing_permissions_dm_mention_fmt: "Hej %s, Aftermath nie jest w stanie wysłać Ci bezpośredniej wiadomości." +common_error_payment_required: |- + Ta funkcja Aftermath jest dostępna tylko dla użytkowników z aktywną subskrypcją. + Możesz subskrybować, używając polecenia `/subscribe`. +common_error_service_outage: "Aftermath jest obecnie w trakcie konserwacji i jest tymczasowo niedostępny. Spróbuj ponownie za chwilę." +common_error_unhandled_not_reported: |- + Wydarzyło się coś nieoczekiwanego i Twoje polecenie się nie powiodło. + *Możesz skontaktować się z naszym zespołem na Aftermath Official, jeśli chcesz zgłosić ten błąd* +common_error_unhandled_reported: |- + Wydarzyło się coś nieoczekiwanego i Twoje polecenie nie powiodło się. + *Ten błąd został zgłoszony automatycznie, możesz również skontaktować się z naszym zespołem na Aftermath Official* +common_error_user_restricted_vague_fmt: "### Do czasu nie możesz korzystać z niektórych lub wszystkich funkcji Aftermath" +common_error_user_spam_detected: "Hej! Wygląda na to, że używasz poleceń zbyt szybko. Aby zapewnić wszystkim płynne działanie, powstrzymaj się od spamowania." +common_label_realm_as: "Azja" +common_label_realm_eu: "Europa" +common_label_realm_na: "Ameryka Północna" +common_label_realm_ru: "WNP" +common_label_tier_1: "Poziom I" +common_label_tier_10: "Poziom X" +common_label_tier_2: "Poziom II" +common_label_tier_3: "Poziom III" +common_label_tier_4: "Poziom IV" +common_label_tier_5: "Poziom V" +common_label_tier_6: "Poziom VI" +common_label_tier_7: "Poziom VII" +common_label_tier_8: "Poziom VIII" +common_label_tier_9: "Poziom IX" +common_option_stats_days_description: "Jak daleko wstecz powinna sięgać sesja?" +common_option_stats_days_name: "dni" +common_option_stats_nickname_description: "Nazwa gracza Blitza" +common_option_stats_nickname_name: "przydomek" +common_option_stats_realm_description: "Na jakim serwerze znajduje się to konto?" +common_option_stats_realm_name: "serwer" +common_option_stats_tank_description: "Filtruj pojazdy według nazwy" +common_option_stats_tank_tier_description: "Filtruj pojazdy według poziomu" +common_option_stats_user_description: "Wybierz innego użytkownika, aby wyświetlić jego statystyki" +common_option_stats_user_name: "użytkownik" +discord_error_invalid_interaction_fmt: | + -# <@%s> użył polecenia + **Wygląda na to, że Discord ma obecnie pewne problemy.** + Odpowiedzi na Aftermatch mogą być opóźnione, ale zrobimy co w naszej mocy, żeby wszystko działało! +error_command_auction_still_refreshing: "Aftermath nadal pracuje nad odświeżeniem bieżących ofert aukcyjnych. Prosimy spróbować ponownie za kilka minut." +errors_help_missing_dm_permissions_fmt: "Hej %s, Aftermath nie jest w stanie wysłać Ci bezpośredniej wiadomości. Spróbuj zamiast tego użyć `/help`." +fancy_error_too_many_options_non_blocking: "Podczas korzystania z tego polecenia, musisz podać tylko link lub plik. Plik obrazu zastąpi link, jeśli podano oba." +fancy_errors_invalid_format: "Obraz, który podałeś, nie jest w formacie JPEG lub PNG. To polecenie nie obsługuje innych formatów plików." +fancy_errors_invalid_image: |- + Dostarczony obraz może być uszkodzony lub jest za duży. + _Maksymalny zalecany rozmiar obrazu to 1000px x 1000px._ +fancy_errors_invalid_link: "Dostarczony obraz jest nieprawidłowy. Aftermath nie mógł go wyświetlić." +fancy_errors_missing_attachment: "Musisz podać link lub załączyć plik graficzny." +fancy_errors_pending_request_exists: "Masz oczekującą prośbę o moderację. Poczekaj, aż Twój poprzednio przesłany obraz zostanie zatwierdzony lub odrzucony." +fancy_errors_preview_expired: "Ten podgląd wygasł. Utwórz nowy, aby przesłać go do moderacji." +fancy_errors_upload_timeout_fmt: |- + Wygląda na to, że niedawno przesłałeś niestandardowy obraz tła. + Będziesz mógł ponownie użyć tego polecenia . +fancy_hint_image_transformation: "Obrazy przesłane do Aftermath za pomocą tego polecenia zostaną zmniejszone i rozmyte. Będą również wymagały ręcznej moderacji." +fancy_moderation_request_approved: |- + ## :tada: **Twoje niestandardowe tło jest ustawione!** :tada: + Przesłany obraz został zatwierdzony przez moderatora i jest teraz ustawiony jako tło statystyk. Inni użytkownicy zobaczą to tło tylko wtedy, gdy Twoje domyślne połączone konto zostanie zweryfikowane. +fancy_moderation_request_declined: |- + **Twoja ostatnia prośba o moderację obrazu została odrzucona** + Wygląda na to, że przesłany przez Ciebie obraz nie spełnia standardów bezpieczeństwa. Twoje tło nie zostanie zaktualizowane. +fancy_moderation_request_declined_and_banned_fmt: |- + **Twoja ostatnia prośba o moderację obrazu została odrzucona** + Wygląda na to, że próbowałeś przesłać obraz, który jest niezgodny z Warunkami korzystania z usługi Aftermath. W rezultacie Twoje konto zostanie ograniczone do przesyłania niestandardowych treści do . Ta decyzja jest ostateczna i nie można się od niej odwołać. +fancy_preview_msg: |- + ## Oto podgląd Twojego obrazu! + Użyj poniższych przycisków, aby przesłać go do moderacji. +fancy_remove_completed: "Twój niestandardowy obraz tła został usunięty." +fancy_remove_not_found: |- + ## Nie przesłano niestandardowego obrazu tła + Aby rozpocząć, użyj `/fancy upload`. +fancy_submitted_msg: |- + **Twoje żądanie zostało wysłane** + Po jego rozpatrzeniu otrzymasz wiadomość bezpośrednią — nie jest wymagane żadne dalsze działanie. + + _Upewnij się, że Twoje wiadomości bezpośrednie są otwarte._ +links_error_connection_not_found: "Twoje połączone konto nie jest już dostępne. Spróbuj dodać nowe za pomocą `/links add`." +links_error_connection_not_found_selected: "Wybrane przez Ciebie konto nie jest już dostępne" +links_error_no_account_selected: "Wygląda na to, że nie wybrałeś konta z podanych opcji. Wybierz jedno z kont wyświetlanych podczas pisania." +links_error_no_accounts_linked: "Nie masz żadnych powiązanych kont." +links_error_too_many_connections: |- + Wygląda na to, że osiągnąłeś limit liczby połączonych kont Blitz. + Spróbuj usunąć istniejące konto za pomocą `/links remove` przed dodaniem nowego. +my_error_no_account_linked: "Wygląda na to, że nie masz ustawionego domyślnego konta Blitz. Możesz zarządzać swoimi kontami za pomocą `/links`." +nickname_autocomplete_invalid_input: "To nie wygląda na prawidłową nazwę gracza. Upewnij się, że używasz swojej nazwy w grze." +nickname_autocomplete_not_enough_length: "Kontynuuj wpisywanie, aby wyszukać konta..." +nickname_autocomplete_not_found: "Nic nie znaleziono. Wybierz pseudonim z listy autouzupełniania" +replay_error_too_many_options_non_blocking: "Podczas korzystania z tego polecenia, musisz podać tylko link lub plik powtórki. Plik powtórki zastąpi link, jeśli podano oba." +replay_errors_all_attachments_invalid: "Żaden z załączonych plików nie jest prawidłową powtórką WoT Blitz." +replay_errors_invalid_attachment: "Załączony plik nie jest prawidłową powtórką WoT Blitz." +replay_errors_missing_attachment: "Musisz podać link lub załączyć plik powtórki WoT Blitz." +replay_errors_missing_permissions_vague: "Aftermathowi brakuje niektórych wymaganych uprawnień w tym kanale. Spróbuj zamiast tego użyć polecenia `/replay`." +replay_errors_some_attachments_invalid: "Niektóre z załączonych plików to prawidłowe powtórki WoT Blitz, więc zostały pominięte." +replay_errors_too_many_files: "Aftermath może przetworzyć do 5 powtórek na raz. Proszę użyć polecenia `/replay`, aby przesłać dodatkowe pliki." +session_error_account_was_not_tracked: "Aftermath właśnie zaczął śledzić to konto. Proszę rozegrać kilka bitew przed ponownym użyciem tej komendy." +session_error_no_session_for_period: "Aftermath nie ma jeszcze sesji na ten okres. Spróbuj zmienić liczbę dni lub zamiast tego użyj `/career`." +stats_account_not_found: "Wygląda na to, że nie znaleziono żadnych kont Blitz odpowiadających Twojemu wyszukiwaniu. Wybierz opcję z listy kont, która zostanie wyświetlona po wpisaniu pseudonimu." +stats_autocomplete_not_enough_length: "Kontynuuj wpisywanie, aby wyszukać dostępne czołgi..." +stats_autocomplete_not_found: "Nic nie znaleziono. Wybierz zbiornik z listy autouzupełniania" +stats_bad_nickname_input_hint: "Złe konto? Podczas wyszukiwania konta Blitz według pseudonimu spróbuj wybrać konkretne konto z wyników wyświetlanych podczas pisania" +stats_error_connection_not_found_personal: "Wygląda na to, że nie masz jeszcze połączonego konta Blitz. Wypróbuj polecenie `/links add`." +stats_error_connection_not_found_vague: "Użytkownik, o którym wspomniałeś, nie ma połączonego konta Blitz." +stats_error_connection_not_verified: "Wygląda na to, że jeszcze nie zweryfikowałeś swojego konta Blitz. Wypróbuj polecenie `/links verify`." +stats_error_mentioned_self_non_blocking: "Nie musisz @wspominać o sobie przy sprawdzaniu statystyk, po prostu wpisz polecenie bez żadnych opcji, aby sprawdzić własne konto." +stats_error_nickname_invalid: "To nie wygląda na prawidłową nazwę gracza. Upewnij się, że używasz swojej nazwy z gry." +stats_error_too_many_arguments_non_blocking: "Podczas korzystania z tego polecenia wystarczy wspomnieć użytkownika lub podać pseudonim. Wspomniany użytkownik zastąpi pseudonim, jeśli podano oba." +stats_multiple_accounts_found: "### Wygląda na to, że istnieje wiele kont Blitz odpowiadających Twojemu wyszukiwaniu. Wybierz jedno, korzystając z przycisków poniżej." +stats_refresh_interaction_error_expired: "Ten przycisk odświeżania wygasł. Proszę użyć zamiast tego polecenia." +wargaming_error_outage: "Wygląda na to, że Wargaming ma chwilowe problemy. Spróbuj ponownie za kilka sekund." +wargaming_error_outage_short: "Wygląda na to, że Wargaming ma pewne problemy. Spróbuj ponownie" +wargaming_error_private_account: "To konto zostało oznaczone przez Wargaming jako prywatne i w chwili obecnej nie są dla niego dostępne żadne statystyki." diff --git a/static/localization/pl/stats.yaml b/static/localization/pl/stats.yaml new file mode 100644 index 00000000..c7ac58d7 --- /dev/null +++ b/static/localization/pl/stats.yaml @@ -0,0 +1,48 @@ +game_mode_lunar: "Lunar" +game_mode_training: "Pokój treningowy" +game_mode_tutorial: "Samouczek" +game_mode_unknown: "Nieznany" +label_accuracy: "Dokładność" +label_assisted: "Asysty" +label_assisted_combined: "Asysty+" +label_avg_damage: "Obrażenia" +label_avg_tier: "Poziom" +label_battle_type_regular: "Spotkanie" +label_battle_type_supremacy: "Dominacja" +label_battle_type_unknown: "Nieznany" +label_battles: "Bitwy" +label_blocked: "Zablok." +label_damage_assisted: "Asysty" +label_damage_blocked: "Zablok." +label_damage_dealt: "Obraż." +label_damage_ratio: "Stos. obrażeń" +label_damage_taken: "Otrzymane obraż." +label_defeat: "Porażka" +label_frags: "Kille" +label_game_mode_burning_games: "Burning Games" +label_game_mode_gravity: "Grawitacja" +label_game_mode_mad_games: "Mad Games" +label_game_mode_quick_tournament: "Szybki turniej" +label_game_mode_rating: "Bitwa Rankingowa" +label_game_mode_realistic: "Realistyczna bitwa" +label_game_mode_regular: "Regularna bitwa" +label_game_mode_skirmish: "Potyczka" +label_game_mode_tournament: "Turniej" +label_game_mode_training: "Pokój treningowy" +label_game_mode_unknown: "Nieznany" +label_game_mode_uprising: "Uprising" +label_highlight_avg_damage: "Najlepsza wydajność" +label_highlight_battles: "Ulubiony czołg" +label_highlight_recent_battle: "Ostatnia bitwa" +label_highlight_wn8: "Największy wpływ" +label_map_name_unknown: "Nieznany" +label_overview_rating: "Bitwy Rankingowe" +label_overview_unrated: "Regularne bitwy" +label_ranked_rating: "Ranking" +label_survival_percent: "Przetrwano" +label_survival_ratio: "Przetrwanie" +label_victory: "Zwycięstwo" +label_winrate: "% Wygr." +label_wn8: "WN8" +tag_quick_tournament: "Szybki turniej" +tag_tournament: "Turniej" diff --git a/static/localization/pt-BR/cta.yaml b/static/localization/pt-BR/cta.yaml new file mode 100644 index 00000000..19cc8c77 --- /dev/null +++ b/static/localization/pt-BR/cta.yaml @@ -0,0 +1,50 @@ +cta_abandoned_negative_growth_body: |- + Parece que você não usou o Aftermath já faz um tempo, mas eu posso ser muito útil para jogadores que querem melhorar suas estatísticas. + + Esta é a sua Sessão mais recente, tente usar `/session` se você deseja se aprofundar mais! +cta_abandoned_negative_growth_head: "Estamos com saudades :cry:" +cta_abandoned_neutral_growth_body: |- + Parece que você não usou o Aftermath já faz um tempo. + + Dê uma olhada nas suas estatísticas mais recentes, use `/session` se você desejar se aprofundar mais! +cta_abandoned_neutral_growth_head: "Estamos com saudades :cry:" +cta_abandoned_positive_growth_body: |- + Parece que você não usou o Aftermath já faz um tempo, mas você melhorou muito! + + Esta é a sua sessão mais recente, tente usar `/session` se você deseja se aprofundar mais! +cta_abandoned_positive_growth_head: "Estamos com saudades :cry:" +cta_command_help_body: |- + Quer informações sobre todos os recursos incríveis? + + Use `/help` para receber uma lista com os comandos disponíveis! +cta_command_help_button: "Dúvidas?" +cta_command_help_head: "Aprenda mais sobre o Aftermath!" +cta_command_links_add_body: |- + Você pode vincular sua conta do Blitz ao Aftermath para faciliar o uso de comandos! + + Tente usando o comandos `/links add`. +cta_command_links_add_head: "Vincule a sua conta Blitz!" +cta_command_links_verify_body: |- + Você pode verificar sua conta do Blitz usando `/link verify`. + + Isso fará com que outros usuários possam ver o seu fundo e desbloqueará o comando `/my`! +cta_command_links_verify_head: "Verifique sua conta Blitz!" +cta_command_replay_body: |- + Você pode enviar um replay usando `/replay` para obter uma visão geral da sua batalha com estatísticas para cada jogador! + + Os replays são sempre mantidos em sigilo, nunca armazenados e nunca enviamos para nenhum serviço de terceiros - suas estratégias estão seguras conosco! +cta_command_replay_head: "O Aftermath também pode verificar os seus replays!" +cta_guild_install_body: |- + Compartilhe este link com o dono do servidor! + https://amth.one/install +cta_guild_install_button: "Compartilhe o Aftermath" +cta_guild_install_head: "Quer adicionar o Aftermath ao seu servidor favorito?" +cta_personal_install_body: |- + Instale o Aftermath como um aplicativo pessoal e use-o em todos os servidores e grupos de conversa! + + Basta selecionar **Adicionar aos Meus Aplicativos** ao instalar o Aftermath. +cta_personal_install_button: "Instale o Aftermath" +cta_personal_install_head: "Você pode usar o Aftermath em todos os seus servidores!" +cta_report_issues_body: "Você pode reportar quaisquer erros e enviar solicitações de recursos no servidor oficial do Aftermath no Discord!" +cta_report_issues_button: "Junte-se ao Aftermath Oficial" +cta_report_issues_head: "Viu algum erro ou quer compartilhar algum feedback?" diff --git a/static/localization/pt-BR/discord.yaml b/static/localization/pt-BR/discord.yaml new file mode 100644 index 00000000..ecf580a8 --- /dev/null +++ b/static/localization/pt-BR/discord.yaml @@ -0,0 +1,241 @@ +background_error_invalid_attachment_image: "A imagem que você enviou não é valida. Tenha certeza de que o arquivo é uma imagem em formato PNG ou JPEG." +background_error_invalid_attachment_vague: "O arquivo anexado não é uma imagem valida." +background_error_missing_attachment: "Você deve anexar uma imagem ou um link para ter um fundo personalizado." +background_error_payment_required: |- + Esse recurso é exclusivo de assinantes. + + Você pode ter uma assinatura pelo comando `/subscribe` ou usar `/fancy` para escolher um fundo. +blitz_stars_error_service_down: "Algumas estatísticas da sua carreira dependem do BlitzStars, que no momento está indisponível. Entretanto, a maioria dos outros comandos, incluindo o de sessões, ainda funcionam." +buttons_add_aftermath_to_your_server: "Instale o Aftermath" +buttons_have_a_question_question: "Tem Dúvidas?" +buttons_join_primary_guild: "Entre no Aftermath Oficial" +buttons_need_help_question: "Precisa de Ajuda?" +buttons_submit: "Enviar" +command_auction_description: "Veja o Leilão atual no Blitz" +command_auction_name: "leilão" +command_auction_result_fmt: "### Atualizado " +command_career_desc: "Tenha um resumo das estatísticas da sua carreira" +command_career_help_message: |- + ## Veja as Estatísticas da sua Conta! + Para começar, coloque o seu nome e um servidor, mencione outro usuário ou vincule uma conta usando `/links add`! +command_career_name: "carreira" +command_fancy_description: "Veja suas imagens de fundo personalizado" +command_fancy_help_message: |- + ## Tenha um fundo personalizado! + Para começar, anexe uma imagem ou um link para uma imagem ao enviar o comando! +command_fancy_name: "chique" +command_help_description: "Veja informações úteis sobre o bot" +command_help_name: "ajuda" +command_links_buttons_manage: "Gerenciar Contas" +command_links_description: "Gerencie as suas contas Blitz vinculadas" +command_links_linked_successfully_fmt: |- + Sua conta foi vinculada! O Aftermath agora exibirá como padrão **%s** em **%s** ao verificar as estatísticas. + Você também pode verificar sua conta com "/links verify". +command_links_name: "links" +command_links_set_default_successfully_fmt: "Sua conta padrão foi atualizada! O Aftermath agora exibirá como padrão **%s** em **%s** ao verificar as estatísticas." +command_links_unlinked_successfully: "Sua conta vinculada foi removida." +command_links_verify_cta: "Você também pode verificar sua conta com \"/links verify\"" +command_links_verify_response_fmt: |- + ## Aqui está o seu link de verificação! + ### Você precisará fazer login com a conta do Discord que está usando atualmente para vincular sua conta do Blitz. + _Este link é específico para %s. Ele não contém nenhuma informação pessoal._ + :link: %s +command_links_view_content_fmt: |- + ## Aqui está uma lista das suas contas Blitz vinculadas! + %s +   + Você pode gerenciá-las e verificá-las em nosso site! +command_my_career_description: "Veja estatísticas de carreira das suas contas vinculadas" +command_my_career_name: "carreira" +command_my_description: "Ver estatísticas das suas contas vinculadas" +command_my_name: "minha" +command_my_session_description: "Ver estatísticas de sessão para sua conta vinculada" +command_my_session_name: "sessão" +command_option_fancy_file_description: "Um arquivo de imagem JPEG ou PNG" +command_option_fancy_file_name: "arquivo" +command_option_fancy_link_description: "Link para uma imagem JPEG ou PNG" +command_option_fancy_link_name: "link" +command_option_fancy_remove_desc: "Remova um plano de fundo personalizado que você enviou anteriormente" +command_option_fancy_remove_name: "remover" +command_option_fancy_upload_desc: "Envie um novo fundo personalizado para suas estatísticas" +command_option_fancy_upload_name: "enviar" +command_option_links_add_desc: "Vincular uma nova conta Blitz" +command_option_links_add_name: "adicionar" +command_option_links_fav_desc: "Marque sua conta vinculada como principal para o Aftermath verificar" +command_option_links_fav_name: "favorito" +command_option_links_remove_desc: "Remover sua conta Blitz vinculada" +command_option_links_remove_name: "remover" +command_option_links_verify_desc: "Vincule e verifique sua conta Blitz para desbloquear mais recursos!" +command_option_links_verify_name: "verificar" +command_option_links_view_desc: "Veja suas contas Blitz vinculadas" +command_option_links_view_name: "visualizar" +command_option_my_account_description: "Selecione uma das suas contas vinculadas" +command_option_my_account_name: "conta" +command_option_replay_file_description: "Um arquivo de replay do Blitz" +command_option_replay_file_name: "arquivo" +command_option_replay_link_description: "Um link para uma replay do Blitz" +command_option_replay_link_name: "link" +command_option_widget_account_description: "Selecione uma das suas contas vinculadas" +command_option_widget_account_name: "conta" +command_replay_help_message: |- + ## Analise seu replay e veja estatística de todos os jogadores! + Para começar, anexe um arquivo de replay ou forneça um link do replay ao enviar o comando! +command_session_description: "Obtenha estatísticas detalhadas da sua sessão recente" +command_session_help_message: |- + ## Veja as estatísticas da sessão da sua conta! + Para começar, inclua um nome e um servidor, mencione outro usuário ou vincule uma conta usando `/links add`! +command_session_name: "sessão" +commands_help_message_fmt: |- + ## :chart_with_upwards_trend: Acompanhe seu progresso + ### ○ /session + Obtenha uma imagem com as estatísticas da sua sessão atual. Você também pode mencionar outro usuário para visualizar a sessão dele. + ### As sessões do Aftermath serão reiniciadas nos seguintes horários: + %s + ### ○ /career + Obtenha uma imagem com as estatísticas da sua carreira. Você também pode mencionar outro usuário para visualizar as estatísticas dele. + ## :film_frames: Mergulhe mais fundo em cada batalha + ### ○ /replay + Envie seu replay e tenha uma visão geral da batalha que você jogou. + ## :link: Informe seu nome do Blitz para o Aftermath + ### ○ /links + Você pode definir uma conta padrão usando o comando _/links favorite_ para usar _/session_ e _/career_ sem fornecer um nome e servidor. + ### ○ /links verify + Verifique sua conta Wargaming para desbloquear recursos adicionais. + ## :frame_photo: Adicione um toque de estilo + ### ○ /fancy + Envie uma imagem de fundo personalizada para as estatísticas da sua sessão. Seu estilo único ficará visível para todos que visualizarem suas estatísticas. + ## :desktop: Se exiba na transmissão + ### ○ /widget + Obtenha um link para um widget de transmissão para o overlay da sua transmissão. + Este widget será atualizado automaticamente com as estatísticas mais recentes da sua sessão. + + _Encontrou um erro de tradução? Avise-nos no Aftermath Official_ + ## :heart: Compartilhe amor! +commands_help_refresh_times_fmt: |- + América do Norte: () + Europa: () + Ásia: () +commands_replay_description: "Analise o seu replay e veja as estatísticas de cada jogador" +commands_replay_name: "replay" +commands_subscribe_action_button: "Inscrever-se" +commands_widget_description: "Obtenha um widget de transmissão para sua conta" +commands_widget_message_fmt: |- + ## [Aqui está o link do seu widget!](%s) + _Adicione-o como uma fonte do navegador no OBS_ [_(saiba mais)_](https://obsproject.com/kb/browser-source). +commands_widget_name: "widget" +common_error_command_expired_fmt: "Este é um comando sazonal que foi desabilitado em e será removido em breve." +common_error_command_missing_permissions: "Você não tem permissão para usar este comando." +common_error_discord_outage: "Parece que o Discord está com problemas temporários. Tente novamente em alguns segundos." +common_error_missing_permissions_dm: "O Aftermath não pode te enviar uma mensagem direta." +common_error_missing_permissions_dm_mention_fmt: "Olá %s, o Aftermath não pode lhe enviar uma mensagem direta." +common_error_payment_required: |- + Este recurso é exclusivo de assinantes. + Você pode ter uma assinatura pelo comando `/subscribe`. +common_error_service_outage: "O Aftermath está em manutenção e temporariamente indisponível. Tente novamente em alguns instantes." +common_error_unhandled_not_reported: |- + Algo inesperado aconteceu e seu comando falhou. + *Você pode entrar em contato com nossa equipe no Aftermath Oficial se desejar reportar este erro* +common_error_unhandled_reported: |- + Algo inesperado aconteceu e seu comando falhou. + *Este erro foi reportado automaticamente. Você também pode entrar em contato com nossa equipe no Aftermath Oficial* +common_error_user_restricted_vague_fmt: "### Você está proibido de usar alguns ou todos os recursos do Aftermath até " +common_error_user_spam_detected: "Ei! Parece que você está usando os comandos muito rápido. Para garantir uma boa experiência para todos, evite spam." +common_label_realm_as: "Ásia" +common_label_realm_eu: "Europa" +common_label_realm_na: "América do Norte" +common_label_realm_ru: "CEI" +common_label_tier_1: "Nível I" +common_label_tier_10: "Nível X" +common_label_tier_2: "Nível II" +common_label_tier_3: "Nível III" +common_label_tier_4: "Nível IV" +common_label_tier_5: "Nível V" +common_label_tier_6: "Nível VI" +common_label_tier_7: "Nível VII" +common_label_tier_8: "Nível VIII" +common_label_tier_9: "Nível IX" +common_option_stats_days_description: "Até quando a sessão deve ir?" +common_option_stats_days_name: "dias" +common_option_stats_nickname_description: "Nome do jogador Blitz" +common_option_stats_nickname_name: "nome" +common_option_stats_realm_description: "Em qual servidor esta conta está?" +common_option_stats_realm_name: "servidor" +common_option_stats_tank_description: "Filtrar veículos por nome" +common_option_stats_tank_tier_description: "Filtrar veículos por nível" +common_option_stats_user_description: "Selecione outro usuário para visualizar suas estatísticas" +common_option_stats_user_name: "usuário" +discord_error_invalid_interaction_fmt: | + -# <@%s> usou um comando + **Parece que o Discord está com alguns problemas no momento.** + As respostas do Aftermath podem demorar, mas faremos o possível para que tudo funcione! +error_command_auction_still_refreshing: "O Aftermath ainda está tentando atualizar as ofertas atuais do leilão. Tente novamente em alguns minutos." +errors_help_missing_dm_permissions_fmt: "Olá %s, o Aftermath não conseguiu enviar uma mensagem direta para você. Tente usar `/help`." +fancy_error_too_many_options_non_blocking: "Ao usar este comando, você só precisa fornecer uma imagem ou um link. A imagem terá prioridade se ambos forem fornecidos." +fancy_errors_invalid_format: "A imagem que você forneceu não está no formato JPEG ou PNG. Este comando não suporta outros tipos de formatos." +fancy_errors_invalid_image: |- + A imagem que você forneceu pode estar corrompida ou ser muito grande. + _O tamanho máximo de imagem recomendado é 1000px por 1000px._ +fancy_errors_invalid_link: "A imagem que você forneceu é inválida, o Aftermath não conseguiu visualizá-la." +fancy_errors_missing_attachment: "Você precisa fornecer um link ou anexar um arquivo de imagem." +fancy_errors_pending_request_exists: "Você tem uma solicitação de moderação pendente. Aguarde até que a imagem enviada anteriormente seja aprovada ou rejeitada." +fancy_errors_preview_expired: "Esta prévia expirou. Crie uma nova para envia-la à moderação." +fancy_errors_upload_timeout_fmt: |- + Parece que você enviou uma imagem de fundo personalizada recentemente. + Você poderá usar este comando novamente . +fancy_hint_image_transformation: "As imagens enviadas para o Aftermath por meio deste comando serão reduzidas e desfocadas. Elas também precisarão de moderação manual." +fancy_moderation_request_approved: |- + ## :tada: **Seu plano de fundo personalizado foi definido!** :tada: + A imagem que você enviou foi aprovada por um moderador e agora está definida como seu plano de fundo de estatísticas. Outros usuários só verão este plano de fundo se sua conta vinculada padrão for verificada. +fancy_moderation_request_declined: |- + **Sua solicitação recente de moderação de imagem foi recusada** + Parece que a imagem que você enviou não atendeu aos padrões de segurança. Seu plano de fundo não será atualizado. +fancy_moderation_request_declined_and_banned_fmt: |- + **Sua solicitação recente de moderação de imagem foi recusada** + Parece que você tentou enviar uma imagem que viola os Termos de Serviço do Aftermath. Como resultado, sua conta ficará suspensa de enviar conteúdo personalizado até . Esta decisão é final e não pode ser apelada. +fancy_preview_msg: |- + ## Aqui está uma prévia da sua imagem! + Use os botões abaixo para envia-la à moderação. +fancy_remove_completed: "Sua imagem de fundo personalizada foi removida." +fancy_remove_not_found: |- + ## Você não possui uma imagem de fundo personalizada enviada + Para começar, use `/fancy upload`. +fancy_submitted_msg: |- + **Sua solicitação foi enviada** + Você receberá uma Mensagem Direta quando ela for analisada - nenhuma outra ação é necessária. + + _Certifique-se de que suas Mensagens Diretas estejam abertas._ +links_error_connection_not_found: "Não consegui encontrar uma conta vinculada com este nome. Tente adicionar uma com `/links add`." +links_error_connection_not_found_selected: "Não consegui acessar a conta que você selecionou." +links_error_no_account_selected: "Parece que você não selecionou uma conta entre as opções fornecidas. Escolha uma das contas exibidas conforme você digita." +links_error_no_accounts_linked: "Você não tem nenhuma conta vinculada." +links_error_too_many_connections: |- + Parece que você atingiu o limite de contas vinculadas do Blitz. + Tente remover uma conta existente com `/links remove` antes de adicionar uma nova. +my_error_no_account_linked: "Parece que você não tem uma conta padrão do Blitz definida. Você pode gerenciar suas contas com `/links`." +nickname_autocomplete_invalid_input: "Este não parece ser um nome de jogador válido, certifique-se de que está usando seu nome no jogo" +nickname_autocomplete_not_enough_length: "Continue digitando para procurar contas..." +nickname_autocomplete_not_found: "Nada encontrado. Selecione um nome na lista de preenchimento automático." +replay_error_too_many_options_non_blocking: "Ao usar este comando, você só precisa fornecer um replay ou um link. O replay terá prioridade se ambos forem fornecidos." +replay_errors_all_attachments_invalid: "Nenhum dos arquivos que você anexou são replays válidos do WoT Blitz." +replay_errors_invalid_attachment: "O arquivo que você anexou não é um replay válido do WoT Blitz." +replay_errors_missing_attachment: "Você precisa fornecer um link ou anexar um arquivo de replay do WoT Blitz." +replay_errors_missing_permissions_vague: "O Aftermath não possui algumas permissões necessárias neste canal. Tente usar o comando `/replay`." +replay_errors_some_attachments_invalid: "Alguns dos arquivos que você anexou são replays válidos do WoT Blitz e foram pulados." +replay_errors_too_many_files: "O Aftermath pode processar até 5 replays simultaneamente. Use o comando `/replay` para enviar arquivos adicionais." +session_error_account_was_not_tracked: "O Aftermath começou a rastrear esta conta. Jogue algumas batalhas antes de usar este comando novamente." +session_error_no_session_for_period: "O Aftermath ainda não possui uma sessão para este período. Tente alterar o número de dias ou use `/career`." +stats_account_not_found: "Parece que não há contas do Blitz que correspondam à sua pesquisa. Selecione uma opção na lista de contas que é exibida conforme você digita o nome." +stats_autocomplete_not_enough_length: "Continue digitando para procurar por tanques disponíveis..." +stats_autocomplete_not_found: "Nada encontrado. Selecione um tanque na lista de preenchimento automático." +stats_bad_nickname_input_hint: "Conta errada? Ao procurar uma conta do Blitz pelo nome, tente selecionar uma conta específica nos resultados exibidos conforme você digita." +stats_error_connection_not_found_personal: "Parece que você ainda não tem uma conta Blitz vinculada. Experimente o comando `/links add`." +stats_error_connection_not_found_vague: "O usuário que você mencionou não tem uma conta Blitz vinculada." +stats_error_connection_not_verified: "Parece que você ainda não verificou sua conta do Blitz. Experimente o comando `/links verify`." +stats_error_mentioned_self_non_blocking: "Você não precisa @mencionar a si mesmo ao verificar as estatísticas, basta digitar o comando sem nenhuma opção para verificar sua própria conta." +stats_error_nickname_invalid: "Este não parece ser um nome de jogador válido. Certifique-se de que você está usando seu nome no jogo." +stats_error_too_many_arguments_non_blocking: "Ao usar este comando, você só precisa mencionar um usuário ou fornecer um nome. O nome terá prioridade se ambos forem fornecidos." +stats_multiple_accounts_found: "### Parece que há várias contas do Blitz que correspondem à sua pesquisa. Selecione uma usando os botões abaixo." +stats_refresh_interaction_error_expired: "Este botão de atualização expirou. Em vez disso, use o comando." +wargaming_error_outage: "Parece que a Wargaming está com problemas temporários. Tente novamente em alguns segundos." +wargaming_error_outage_short: "Parece que a Wargaming está com problemas. Tente novamente." +wargaming_error_private_account: "Esta conta foi marcada como privada pela Wargaming e não há estatísticas disponíveis para ela no momento." diff --git a/static/localization/pt-BR/stats.yaml b/static/localization/pt-BR/stats.yaml new file mode 100644 index 00000000..5581cc28 --- /dev/null +++ b/static/localization/pt-BR/stats.yaml @@ -0,0 +1,48 @@ +game_mode_lunar: "Lunar" +game_mode_training: "Sala de Treinamento" +game_mode_tutorial: "Tutorial" +game_mode_unknown: "Desconhecido" +label_accuracy: "Precisão" +label_assisted: "Auxiliado" +label_assisted_combined: "Auxiliado+" +label_avg_damage: "Dano" +label_avg_tier: "Nível" +label_battle_type_regular: "Encontro" +label_battle_type_supremacy: "Supremacia" +label_battle_type_unknown: "Desconhecido" +label_battles: "Batalhas" +label_blocked: "Bloqueado" +label_damage_assisted: "Auxiliado" +label_damage_blocked: "Bloqueado" +label_damage_dealt: "Dano" +label_damage_ratio: "Dano Médio" +label_damage_taken: "Dano Recebido" +label_defeat: "Derrota" +label_frags: "Destruído" +label_game_mode_burning_games: "Burning Games" +label_game_mode_gravity: "Gravidade" +label_game_mode_mad_games: "Mad Games" +label_game_mode_quick_tournament: "Torneio Rápido" +label_game_mode_rating: "Classificatória" +label_game_mode_realistic: "Batalha Realista" +label_game_mode_regular: "Regular" +label_game_mode_skirmish: "Skirmish" +label_game_mode_tournament: "Torneio" +label_game_mode_training: "Sala de Treinamento" +label_game_mode_unknown: "Desconhecido" +label_game_mode_uprising: "Renascimento" +label_highlight_avg_damage: "Melhor Desempenho" +label_highlight_battles: "Tanque Favorito" +label_highlight_recent_battle: "Última Batalha" +label_highlight_wn8: "Mais Impactamte" +label_map_name_unknown: "Desconhecido" +label_overview_rating: "Classificatória" +label_overview_unrated: "Regular" +label_ranked_rating: "Classificação" +label_survival_percent: "Sobreviveu" +label_survival_ratio: "Sobrevivência" +label_victory: "Vitória" +label_winrate: "Taxa de Vitórias" +label_wn8: "WN8" +tag_quick_tournament: "Torneio Rápido" +tag_tournament: "Torneio" diff --git a/tests/static_database.go b/tests/static_database.go index 7c5e7f5a..4e553d5c 100644 --- a/tests/static_database.go +++ b/tests/static_database.go @@ -64,13 +64,13 @@ func (c *staticTestingDatabase) GetRealmAccountIDs(ctx context.Context, realm st func (c *staticTestingDatabase) AccountSetPrivate(ctx context.Context, id string, value bool) error { return errors.New("AccountSetPrivate not implemented") } -func (c *staticTestingDatabase) UpsertAccounts(ctx context.Context, accounts ...*models.Account) (map[string]error, error) { +func (c *staticTestingDatabase) UpsertAccounts(ctx context.Context, accounts ...*models.Account) error { for _, acc := range accounts { if _, ok := staticAccounts[acc.ID]; ok { staticAccounts[acc.ID] = *acc } } - return nil, nil + return nil } func (c *staticTestingDatabase) GetAllVehicles(ctx context.Context) (map[string]models.Vehicle, error) { @@ -95,11 +95,11 @@ func (c *staticTestingDatabase) GetVehicleAverages(ctx context.Context, ids []st } return averages, nil } -func (c *staticTestingDatabase) UpsertVehicles(ctx context.Context, vehicles map[string]models.Vehicle) (map[string]error, error) { - return nil, errors.New("UpsertVehicles not implemented") +func (c *staticTestingDatabase) UpsertVehicles(ctx context.Context, vehicles map[string]models.Vehicle) error { + return errors.New("UpsertVehicles not implemented") } -func (c *staticTestingDatabase) UpsertVehicleAverages(ctx context.Context, averages map[string]frame.StatsFrame) (map[string]error, error) { - return nil, errors.New("UpsertVehicleAverages not implemented") +func (c *staticTestingDatabase) UpsertVehicleAverages(ctx context.Context, averages map[string]frame.StatsFrame) error { + return errors.New("UpsertVehicleAverages not implemented") } func (c *staticTestingDatabase) GetUserByID(ctx context.Context, id string, opts ...database.UserQueryOption) (models.User, error) { @@ -270,8 +270,8 @@ func (c *staticTestingDatabase) CreateWidgetSettings(ctx context.Context, userID func (c *staticTestingDatabase) GetGameModeNames(ctx context.Context, id string) (map[language.Tag]string, error) { return map[language.Tag]string{}, nil } -func (c *staticTestingDatabase) UpsertGameModes(ctx context.Context, modes map[string]map[language.Tag]string) (map[string]error, error) { - return nil, nil +func (c *staticTestingDatabase) UpsertGameModes(ctx context.Context, modes map[string]map[language.Tag]string) error { + return nil } func (c *staticTestingDatabase) FindUserModerationRequests(ctx context.Context, userID string, referenceIDs []string, status []models.ModerationStatus, since time.Time) ([]models.ModerationRequest, error) {