evcc-io/util/locale/locale.go

94 lines
2 KiB
Go

package locale
import (
"encoding/json"
"fmt"
"io/fs"
"path/filepath"
"strings"
"github.com/cloudfoundry/jibber_jabber"
"github.com/evcc-io/evcc/server/assets"
"github.com/evcc-io/evcc/util/locale/internal"
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
)
type Config = i18n.LocalizeConfig
var (
Locale internal.ContextKey
Bundle *i18n.Bundle
Language string
Localizer *i18n.Localizer
)
// Init initializes the localization bundle and loads all JSON message files.
func Init() error {
Bundle = i18n.NewBundle(language.English)
Bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
dir, err := fs.ReadDir(assets.I18n, ".")
if err != nil {
panic(err)
}
// Iterate over each file and process only .json files
for _, d := range dir {
if filepath.Ext(d.Name()) != ".json" {
continue
}
b, err := fs.ReadFile(assets.I18n, d.Name())
if err != nil {
return fmt.Errorf("reading locale file %s failed: %w", d.Name(), err)
}
var s struct {
Sessions struct {
CSV map[string]string `json:"csv"`
} `json:"sessions"`
Config struct {
Hems struct {
CSV map[string]string `json:"csv"`
} `json:"hems"`
} `json:"config"`
}
if err := json.Unmarshal(b, &s); err != nil {
return err
}
var m []*i18n.Message
for prefix, msgs := range map[string]map[string]string{
"sessions.csv": s.Sessions.CSV,
"config.hems.csv": s.Config.Hems.CSV,
} {
for k, v := range msgs {
m = append(m, &i18n.Message{
ID: prefix + "." + k,
Other: v,
})
}
}
if len(m) > 0 {
languageTag := language.Make(strings.TrimSuffix(d.Name(), filepath.Ext(d.Name())))
if err := Bundle.AddMessages(languageTag, m...); err != nil {
return fmt.Errorf("loading locales failed: %w", err)
}
}
}
// Detect system language; default to German on failure
Language, err = jibber_jabber.DetectLanguage()
if err != nil {
Language = language.German.String()
}
// Create a localizer for the detected language
Localizer = i18n.NewLocalizer(Bundle, Language)
return nil
}