use i18n resource item to replace ambiguous configuration item

This commit is contained in:
MaysWind
2025-12-12 12:23:07 +08:00
parent c170cb42e6
commit 89dd306bb4
30 changed files with 90 additions and 25 deletions
-3
View File
@@ -1,7 +1,4 @@
[global]
# Application instance name
app_name = ezBookkeeping
# Either "production", "development"
mode = production
+2 -2
View File
@@ -13,7 +13,7 @@ import (
"github.com/mayswind/ezbookkeeping/pkg/utils"
)
const mcpServerName = "ezBookkeeping-mcp"
const mcpServerName = core.ApplicationName + "-mcp"
// ModelContextProtocolAPI represents model context protocol api
type ModelContextProtocolAPI struct {
@@ -102,7 +102,7 @@ func (a *ModelContextProtocolAPI) InitializeHandler(c *core.WebContext, jsonRPCR
},
ServerInfo: &mcp.MCPImplementation{
Name: mcpServerName,
Title: a.CurrentConfig().AppName,
Title: core.ApplicationName,
Version: settings.Version,
},
}
+1 -1
View File
@@ -85,7 +85,7 @@ func (a *TwoFactorAuthorizationsApi) TwoFactorEnableRequestHandler(c *core.WebCo
return nil, errs.ErrNotPermittedToPerformThisAction
}
key, err := a.twoFactorAuthorizations.GenerateTwoFactorSecret(c, user)
key, err := a.twoFactorAuthorizations.GenerateTwoFactorSecret(c, user, c.GetClientLocale())
if err != nil {
log.Errorf(c, "[twofactor_authorizations.TwoFactorEnableRequestHandler] failed to generate two-factor secret, because %s", err.Error())
+4
View File
@@ -0,0 +1,4 @@
package core
// ApplicationName represents the application name
const ApplicationName = "ezBookkeeping"
@@ -27,7 +27,7 @@ func (p *OpenRouterChatCompletionsAPIProvider) BuildChatCompletionsHttpRequest(c
req.Header.Set("Authorization", "Bearer "+p.OpenRouterAPIKey)
req.Header.Set("HTTP-Referer", "https://ezbookkeeping.mayswind.net/")
req.Header.Set("X-Title", "ezBookkeeping")
req.Header.Set("X-Title", core.ApplicationName)
return req, nil
}
+6
View File
@@ -6,12 +6,18 @@ import (
// LocaleTextItems represents all text items need to be translated
type LocaleTextItems struct {
GlobalTextItems *GlobalTextItems
DefaultTypes *DefaultTypes
DataConverterTextItems *DataConverterTextItems
VerifyEmailTextItems *VerifyEmailTextItems
ForgetPasswordMailTextItems *ForgetPasswordMailTextItems
}
// GlobalTextItems represents global text items need to be translated
type GlobalTextItems struct {
AppName string
}
// DefaultTypes represents default types for the language
type DefaultTypes struct {
DecimalSeparator core.DecimalSeparator
+3
View File
@@ -5,6 +5,9 @@ import (
)
var de = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_DOT,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var en = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_DOT,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_COMMA,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var es = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_DOT,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var fr = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_SPACE,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var it = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_DOT,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var ja = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_DOT,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_COMMA,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var kn = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_DOT,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_COMMA,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var ko = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_DOT,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_COMMA,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var nl = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_DOT,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var ptBR = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_SPACE,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var ru = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_SPACE,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var th = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_DOT,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_COMMA,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var tr = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_DOT,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var uk = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_SPACE,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var vi = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_COMMA,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_DOT,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var zhHans = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_DOT,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_COMMA,
+3
View File
@@ -5,6 +5,9 @@ import (
)
var zhHant = &LocaleTextItems{
GlobalTextItems: &GlobalTextItems{
AppName: "ezBookkeeping",
},
DefaultTypes: &DefaultTypes{
DecimalSeparator: core.DECIMAL_SEPARATOR_DOT,
DigitGroupingSymbol: core.DIGIT_GROUPING_SYMBOL_COMMA,
+1 -1
View File
@@ -59,7 +59,7 @@ func (s *ForgetPasswordService) SendPasswordResetEmail(c core.Context, user *mod
}
templateParams := map[string]any{
"AppName": s.CurrentConfig().AppName,
"AppName": localeTextItems.GlobalTextItems.AppName,
"ForgetPasswordMail": map[string]any{
"Title": forgetPasswordTextItems.Title,
"Salutation": fmt.Sprintf(forgetPasswordTextItems.SalutationFormat, user.Nickname),
+3 -3
View File
@@ -21,13 +21,13 @@ import (
)
// TokenUserAgentCreatedViaCli is the user agent of token created via cli
const TokenUserAgentCreatedViaCli = "ezbookkeeping Cli"
const TokenUserAgentCreatedViaCli = core.ApplicationName + " Cli"
// TokenUserAgentForAPI is the user agent for API token
const TokenUserAgentForAPI = "ezbookkeeping API"
const TokenUserAgentForAPI = core.ApplicationName + " API"
// TokenUserAgentForMCP is the user agent for MCP token
const TokenUserAgentForMCP = "ezbookkeeping MCP"
const TokenUserAgentForMCP = core.ApplicationName + " MCP"
const tokenMaxExpiredAtUnixTime = int64(253402300799) // 9999-12-31 23:59:59 UTC
+11 -2
View File
@@ -10,6 +10,7 @@ import (
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/datastore"
"github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/locales"
"github.com/mayswind/ezbookkeeping/pkg/models"
"github.com/mayswind/ezbookkeeping/pkg/settings"
"github.com/mayswind/ezbookkeeping/pkg/utils"
@@ -70,13 +71,21 @@ func (s *TwoFactorAuthorizationService) GetUserTwoFactorSettingByUid(c core.Cont
}
// GenerateTwoFactorSecret generates a new 2fa secret
func (s *TwoFactorAuthorizationService) GenerateTwoFactorSecret(c core.Context, user *models.User) (*otp.Key, error) {
func (s *TwoFactorAuthorizationService) GenerateTwoFactorSecret(c core.Context, user *models.User, backupLocale string) (*otp.Key, error) {
if user == nil {
return nil, errs.ErrUserNotFound
}
locale := user.Language
if locale == "" {
locale = backupLocale
}
localeTextItems := locales.GetLocaleTextItems(locale)
key, err := totp.Generate(totp.GenerateOpts{
Issuer: s.CurrentConfig().AppName,
Issuer: localeTextItems.GlobalTextItems.AppName,
AccountName: user.Username,
Period: twoFactorPeriod,
SecretSize: twoFactorSecretSize,
+2 -2
View File
@@ -684,14 +684,14 @@ func (s *UserService) SendVerifyEmail(user *models.User, verifyEmailToken string
}
templateParams := map[string]any{
"AppName": s.CurrentConfig().AppName,
"AppName": localeTextItems.GlobalTextItems.AppName,
"VerifyEmail": map[string]any{
"Title": verifyEmailTextItems.Title,
"Salutation": fmt.Sprintf(verifyEmailTextItems.SalutationFormat, user.Nickname),
"DescriptionAboveBtn": verifyEmailTextItems.DescriptionAboveBtn,
"VerifyEmailUrl": verifyEmailUrl,
"VerifyEmail": verifyEmailTextItems.VerifyEmail,
"DescriptionBelowBtn": fmt.Sprintf(verifyEmailTextItems.DescriptionBelowBtnFormat, s.CurrentConfig().AppName, expireTimeInMinutes),
"DescriptionBelowBtn": fmt.Sprintf(verifyEmailTextItems.DescriptionBelowBtnFormat, localeTextItems.GlobalTextItems.AppName, expireTimeInMinutes),
},
}
-5
View File
@@ -145,8 +145,6 @@ const (
)
const (
defaultAppName string = "ezBookkeeping"
defaultHttpAddr string = "0.0.0.0"
defaultHttpPort uint16 = 8080
defaultDomain string = "localhost"
@@ -267,7 +265,6 @@ type MultiLanguageContentConfig struct {
// Config represents the global setting config
type Config struct {
// Global
AppName string
Mode SystemMode
WorkingPath string
@@ -595,8 +592,6 @@ func GetDefaultConfigFilePath() (string, error) {
}
func loadGlobalConfiguration(config *Config, configFile *ini.File, sectionName string) error {
config.AppName = getConfigItemStringValue(configFile, sectionName, "app_name", defaultAppName)
if getConfigItemStringValue(configFile, sectionName, "mode") == "production" {
config.Mode = MODE_PRODUCTION
} else if getConfigItemStringValue(configFile, sectionName, "mode") == "development" {
+7 -3
View File
@@ -1,6 +1,10 @@
package settings
import "fmt"
import (
"fmt"
"github.com/mayswind/ezbookkeeping/pkg/core"
)
// ConfigContainer contains the current setting config
type ConfigContainer struct {
@@ -27,8 +31,8 @@ func (c *ConfigContainer) GetCurrentConfig() *Config {
func GetUserAgent() string {
if Version == "" {
return "ezBookkeeping"
return core.ApplicationName
}
return fmt.Sprintf("ezBookkeeping/%s", Version)
return fmt.Sprintf("%s/%s", core.ApplicationName, Version)
}
-1
View File
@@ -10,7 +10,6 @@ import (
func TestClone(t *testing.T) {
expectedObject := &settings.Config{
AppName: "ezbookkeeping",
Mode: settings.MODE_PRODUCTION,
DatabaseConfig: &settings.DatabaseConfig{
DatabaseType: settings.MySqlDbType,