mirror of
https://github.com/krau/SaveAny-Bot.git
synced 2026-07-13 00:11:56 +08:00
chore: translate config package
This commit is contained in:
18
common/os.go
18
common/os.go
@@ -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,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
52
i18n/i18n.go
52
i18n/i18n.go
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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}}"
|
||||||
|
|||||||
Reference in New Issue
Block a user