chore: translate config package

This commit is contained in:
krau
2025-06-08 13:37:51 +08:00
parent c798c7ae99
commit 481427683e
5 changed files with 96 additions and 8 deletions

View File

@@ -4,18 +4,30 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"time" "time"
"github.com/krau/SaveAny-Bot/i18n"
"github.com/krau/SaveAny-Bot/i18n/i18nk"
) )
func RmFileAfter(path string, td time.Duration) { func RmFileAfter(path string, td time.Duration) {
_, err := os.Stat(path) _, err := os.Stat(path)
if err != nil { if err != nil {
Log.Errorf("Failed to create timer for %s: %s", path, err) Log.Errorf(i18n.T(i18nk.CreateRmTimerFailed, map[string]any{
"Path": path,
"Error": err,
}))
return return
} }
Log.Debugf("Remove file after %s: %s", td, path) Log.Debugf(i18n.T(i18nk.RemoveFileAfter, map[string]any{
"Duration": td.String(),
"Path": path,
}))
time.AfterFunc(td, func() { time.AfterFunc(td, func() {
if err := os.Remove(path); err != nil { if err := os.Remove(path); err != nil {
Log.Errorf("Failed to remove file %s: %s", path, err) Log.Errorf(i18n.T(i18nk.RemoveFileFailed, map[string]any{
"Path": path,
"Error": err,
}))
} }
}) })
} }

View File

@@ -1,12 +1,15 @@
package config package config
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
"strings" "strings"
"github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/v2/slice"
"github.com/krau/SaveAny-Bot/config/storage" "github.com/krau/SaveAny-Bot/config/storage"
"github.com/krau/SaveAny-Bot/i18n"
"github.com/krau/SaveAny-Bot/i18n/i18nk"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@@ -131,18 +134,25 @@ func Init() error {
storageNames := make(map[string]struct{}) storageNames := make(map[string]struct{})
for _, storage := range Cfg.Storages { for _, storage := range Cfg.Storages {
if _, ok := storageNames[storage.GetName()]; ok { if _, ok := storageNames[storage.GetName()]; ok {
return fmt.Errorf("重复的存储名: %s", storage.GetName()) return errors.New(i18n.TWithoutInit(Cfg.Lang, i18nk.ConfigInvalidDuplicateStorageName, map[string]any{
"Name": storage.GetName(),
}))
} }
storageNames[storage.GetName()] = struct{}{} storageNames[storage.GetName()] = struct{}{}
} }
fmt.Printf("已加载 %d 个存储:\n", len(Cfg.Storages)) fmt.Println(i18n.TWithoutInit(Cfg.Lang, i18nk.LoadedStorages, map[string]any{
"Count": len(Cfg.Storages),
}))
for _, storage := range Cfg.Storages { for _, storage := range Cfg.Storages {
fmt.Printf(" - %s (%s)\n", storage.GetName(), storage.GetType()) fmt.Printf(" - %s (%s)\n", storage.GetName(), storage.GetType())
} }
if Cfg.Workers < 1 || Cfg.Retry < 1 { if Cfg.Workers < 1 || Cfg.Retry < 1 {
return fmt.Errorf("workers 和 retry 必须大于 0, 当前值: workers=%d, retry=%d", Cfg.Workers, Cfg.Retry) return errors.New(i18n.TWithoutInit(Cfg.Lang, i18nk.ConfigInvalidWorkersOrRetry, map[string]any{
"Workers": Cfg.Workers,
"Retry": Cfg.Retry,
}))
} }
for _, storage := range Cfg.Storages { for _, storage := range Cfg.Storages {

View File

@@ -5,7 +5,6 @@ import (
"maps" "maps"
"github.com/krau/SaveAny-Bot/common"
"github.com/nicksnyder/go-i18n/v2/i18n" "github.com/nicksnyder/go-i18n/v2/i18n"
"github.com/pelletier/go-toml/v2" "github.com/pelletier/go-toml/v2"
"golang.org/x/text/language" "golang.org/x/text/language"
@@ -53,7 +52,56 @@ func T(key string, templateData ...map[string]any) string {
TemplateData: templateDataMap, TemplateData: templateDataMap,
}) })
if err != nil { if err != nil {
common.Log.Errorf("failed to localize message for key '%s': %v", key, err) return key
}
return msg
}
func TWithLang(lang, key string, templateData ...map[string]any) string {
if bundle == nil {
panic("bundle is not initialized, call Init() first")
}
templateDataMap := make(map[string]any)
for _, data := range templateData {
maps.Copy(templateDataMap, data)
}
localizerWithLang := i18n.NewLocalizer(bundle, lang)
msg, err := localizerWithLang.Localize(&i18n.LocalizeConfig{
MessageID: key,
TemplateData: templateDataMap,
})
if err != nil {
return key
}
return msg
}
// Only use in tests or packages that load before i18n
func TWithoutInit(lang, key string, templateData ...map[string]any) string {
bundle := i18n.NewBundle(language.SimplifiedChinese)
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
files, err := localesFS.ReadDir("locale")
if err != nil {
return key
}
for _, file := range files {
if _, err := bundle.LoadMessageFileFS(localesFS, "locale/"+file.Name()); err != nil {
return key
}
}
localizer := i18n.NewLocalizer(bundle, lang)
if localizer == nil {
return key
}
templateDataMap := make(map[string]any)
for _, data := range templateData {
maps.Copy(templateDataMap, data)
}
msg, err := localizer.Localize(&i18n.LocalizeConfig{
MessageID: key,
TemplateData: templateDataMap,
})
if err != nil {
return key return key
} }
return msg return msg

View File

@@ -4,9 +4,15 @@ package i18nk
const ( const (
CleanCacheFailed = "CleanCacheFailed" CleanCacheFailed = "CleanCacheFailed"
CleaningCache = "CleaningCache" CleaningCache = "CleaningCache"
ConfigInvalidDuplicateStorageName = "ConfigInvalid.DuplicateStorageName"
ConfigInvalidWorkersOrRetry = "ConfigInvalid.WorkersOrRetry"
CreateRmTimerFailed = "CreateRmTimerFailed"
GetCacheAbsPathFailed = "GetCacheAbsPathFailed" GetCacheAbsPathFailed = "GetCacheAbsPathFailed"
GetWorkdirFailed = "GetWorkdirFailed" GetWorkdirFailed = "GetWorkdirFailed"
InvalidCacheDir = "InvalidCacheDir" InvalidCacheDir = "InvalidCacheDir"
LoadedStorages = "LoadedStorages"
RemoveFileAfter = "RemoveFileAfter"
RemoveFileFailed = "RemoveFileFailed"
Bye = "bye" Bye = "bye"
Exiting = "exiting" Exiting = "exiting"
Initing = "initing" Initing = "initing"

View File

@@ -14,3 +14,15 @@ other = "获取缓存绝对路径失败: {{.Error}}"
other = "正在清理缓存文件夹: {{.Path}}" other = "正在清理缓存文件夹: {{.Path}}"
[CleanCacheFailed] [CleanCacheFailed]
other = "清理缓存失败: {{.Error}}" other = "清理缓存失败: {{.Error}}"
[CreateRmTimerFailed]
other = "创建清理定时器失败, 路径: {{.Path}}, 错误: {{.Error}}"
[RemoveFileAfter]
other = "将在 {{.Duration}} 后删除文件: {{.Path}}"
[RemoveFileFailed]
other = "删除文件失败: {{.Path}}, 错误: {{.Error}}"
[LoadedStorages]
other = "已加载 {{.Count}} 个存储"
[ConfigInvalid.WorkersOrRetry]
other = "配置无效: workers 或 retry 必须大于 0, 但当前值为: workers={{.Workers}}, retry={{.Retry}}"
[ConfigInvalid.DuplicateStorageName]
other = "存储名称重复: {{.Name}}"