fx build fix
This commit is contained in:
151
api/notification/internal/localizer/loc_imp.go
Normal file
151
api/notification/internal/localizer/loc_imp.go
Normal file
@@ -0,0 +1,151 @@
|
||||
package lclrimp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"path"
|
||||
|
||||
"github.com/tech/sendico/pkg/merrors"
|
||||
"github.com/tech/sendico/pkg/mlogger"
|
||||
"github.com/tech/sendico/pkg/mutil/fr"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
type Lang struct {
|
||||
bundle *i18n.Bundle
|
||||
localizer *i18n.Localizer
|
||||
}
|
||||
|
||||
type Localizers = map[string]Lang
|
||||
|
||||
type Localizer struct {
|
||||
logger mlogger.Logger
|
||||
l9rs Localizers
|
||||
support string
|
||||
serviceName string
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Path string `yaml:"path"`
|
||||
Langs []string `yaml:"languages"`
|
||||
Support string `yaml:"support"`
|
||||
ServiceName string `yaml:"service_name"`
|
||||
}
|
||||
|
||||
func loadBundleLocalization(logger mlogger.Logger, bundle *i18n.Bundle, localizationPath string) error {
|
||||
b, err := fr.ReadFile(logger, localizationPath)
|
||||
if err != nil {
|
||||
logger.Error("Failed to read localization", zap.Error(err), zap.String("localization_path", localizationPath))
|
||||
return err
|
||||
}
|
||||
_, err = bundle.ParseMessageFileBytes(b, localizationPath)
|
||||
if err != nil {
|
||||
logger.Error("Failed to parse localization", zap.Error(err), zap.String("localization_path", localizationPath))
|
||||
return err
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func loadLocalizations(logger mlogger.Logger, source string) (*i18n.Bundle, error) {
|
||||
bundle := i18n.NewBundle(language.English)
|
||||
|
||||
// Register a json unmarshal function for i18n bundle.
|
||||
bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
|
||||
|
||||
// Load translations from json files for non-default languages.
|
||||
err := loadBundleLocalization(logger, bundle, source)
|
||||
if err != nil {
|
||||
// will not log error once again, just return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bundle, nil
|
||||
}
|
||||
|
||||
func newLang(logger mlogger.Logger, language string, source string) (*Lang, error) {
|
||||
var lang Lang
|
||||
var err error
|
||||
lang.bundle, err = loadLocalizations(logger, source)
|
||||
if err != nil {
|
||||
logger.Error("Failed to install language bundle", zap.Error(err),
|
||||
zap.String("language", language), zap.String("source", source))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lang.localizer = i18n.NewLocalizer(lang.bundle, language)
|
||||
if lang.localizer != nil {
|
||||
logger.Info("Installed language bundle",
|
||||
zap.String("language", language), zap.String("source", source))
|
||||
} else {
|
||||
logger.Error("Failed to install language bundle", zap.String("language", language), zap.String("source", source))
|
||||
return nil, merrors.Internal("failed_to_load_localization")
|
||||
}
|
||||
|
||||
return &lang, nil
|
||||
}
|
||||
|
||||
func prepareLocalizers(logger mlogger.Logger, conf *Config) (Localizers, error) {
|
||||
localizers := make(Localizers)
|
||||
for _, lang := range conf.Langs {
|
||||
path := path.Join(conf.Path, lang+".json")
|
||||
l, err := newLang(logger, lang, path)
|
||||
if err != nil {
|
||||
logger.Error("Failed to load localization", zap.Error(err), zap.String("language", lang), zap.String("source", path))
|
||||
return localizers, err
|
||||
}
|
||||
localizers[lang] = *l
|
||||
}
|
||||
return localizers, nil
|
||||
}
|
||||
|
||||
func (loc *Localizer) LocalizeTemplate(id string, templateData, ctr any, lang string) (string, error) {
|
||||
lclzr, found := loc.l9rs[lang]
|
||||
if !found {
|
||||
loc.logger.Info("Language not found, falling back to en", zap.String("message_id", id), zap.String("language", lang))
|
||||
lclzr = loc.l9rs["en"]
|
||||
}
|
||||
|
||||
config := i18n.LocalizeConfig{
|
||||
MessageID: id,
|
||||
TemplateData: templateData,
|
||||
PluralCount: ctr,
|
||||
}
|
||||
localized, err := lclzr.localizer.Localize(&config)
|
||||
if err != nil {
|
||||
loc.logger.Warn("Failed to localize string", zap.Error(err), zap.String("message_id", id), zap.String("language", lang))
|
||||
}
|
||||
|
||||
return localized, err
|
||||
}
|
||||
|
||||
func (loc *Localizer) LocalizeString(id string, lang string) (string, error) {
|
||||
return loc.LocalizeTemplate(id, nil, nil, lang)
|
||||
}
|
||||
|
||||
func (loc *Localizer) ServiceName() string {
|
||||
return loc.serviceName
|
||||
}
|
||||
|
||||
func (loc *Localizer) SupportMail() string {
|
||||
return loc.support
|
||||
}
|
||||
|
||||
// NewConnection creates a new database connection
|
||||
func CreateLocalizer(logger mlogger.Logger, config *Config) (*Localizer, error) {
|
||||
p := new(Localizer)
|
||||
p.logger = logger.Named("localizer")
|
||||
var err error
|
||||
p.l9rs, err = prepareLocalizers(p.logger, config)
|
||||
if err != nil {
|
||||
logger.Warn("Failed to create localizer", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
p.serviceName = config.ServiceName
|
||||
p.support = config.Support
|
||||
|
||||
logger.Info("Localizer is up", zap.String("service_name", p.serviceName), zap.String("support", p.support))
|
||||
|
||||
return p, nil
|
||||
}
|
||||
Reference in New Issue
Block a user