2017-04-03 19:00:38 +05:00
|
|
|
package srnd
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/majestrate/configparser"
|
|
|
|
"golang.org/x/text/language"
|
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
2018-10-20 20:24:30 +05:00
|
|
|
"errors"
|
2017-04-03 19:00:38 +05:00
|
|
|
)
|
|
|
|
|
2017-10-10 21:17:38 +05:00
|
|
|
type I18N struct {
|
2017-04-03 19:00:38 +05:00
|
|
|
locale language.Tag
|
|
|
|
// loaded translations
|
2017-10-10 21:17:38 +05:00
|
|
|
Translations map[string]string
|
2017-04-03 19:00:38 +05:00
|
|
|
// loaded formats
|
2017-10-10 21:17:38 +05:00
|
|
|
Formats map[string]string
|
2017-04-03 19:00:38 +05:00
|
|
|
// root directory for translations
|
|
|
|
translation_dir string
|
2017-10-10 21:17:38 +05:00
|
|
|
// name of locale
|
2017-10-10 21:34:39 +05:00
|
|
|
Name string
|
2017-04-03 19:00:38 +05:00
|
|
|
}
|
|
|
|
|
2017-10-10 21:17:38 +05:00
|
|
|
var I18nProvider *I18N = nil
|
2018-10-20 20:24:30 +05:00
|
|
|
var ErrNoLang = errors.New("no such language")
|
2017-04-03 19:00:38 +05:00
|
|
|
|
|
|
|
//Read all .ini files in dir, where the filenames are BCP 47 tags
|
|
|
|
//Use the language matcher to get the best match for the locale preference
|
|
|
|
func InitI18n(locale, dir string) {
|
2017-10-10 21:17:38 +05:00
|
|
|
var err error
|
|
|
|
I18nProvider, err = NewI18n(locale, dir)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewI18n(locale, dir string) (*I18N, error) {
|
|
|
|
log.Println("get locale", locale)
|
2017-04-03 19:00:38 +05:00
|
|
|
pref := language.Make(locale) // falls back to en-US on parse error
|
|
|
|
files, err := ioutil.ReadDir(dir)
|
|
|
|
if err != nil {
|
2017-10-10 21:17:38 +05:00
|
|
|
return nil, err
|
2017-04-03 19:00:38 +05:00
|
|
|
}
|
|
|
|
|
2018-10-20 20:24:30 +05:00
|
|
|
found:= false
|
2017-04-03 19:00:38 +05:00
|
|
|
serverLangs := make([]language.Tag, 1)
|
2018-10-20 20:24:30 +05:00
|
|
|
// serverLangs[0] = language.AmericanEnglish // en-US fallback
|
2017-04-03 19:00:38 +05:00
|
|
|
for _, file := range files {
|
|
|
|
if filepath.Ext(file.Name()) == ".ini" {
|
|
|
|
name := strings.TrimSuffix(file.Name(), ".ini")
|
|
|
|
tag, err := language.Parse(name)
|
|
|
|
if err == nil {
|
|
|
|
serverLangs = append(serverLangs, tag)
|
2018-10-20 20:24:30 +05:00
|
|
|
found = true;
|
2017-04-03 19:00:38 +05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-10-20 20:24:30 +05:00
|
|
|
if !found {
|
|
|
|
return nil, ErrNoLang
|
|
|
|
}
|
|
|
|
|
2017-04-03 19:00:38 +05:00
|
|
|
matcher := language.NewMatcher(serverLangs)
|
|
|
|
tag, _, _ := matcher.Match(pref)
|
|
|
|
|
|
|
|
fname := filepath.Join(dir, tag.String()+".ini")
|
|
|
|
conf, err := configparser.Read(fname)
|
|
|
|
if err != nil {
|
2017-10-10 21:17:38 +05:00
|
|
|
return nil, err
|
2017-04-03 19:00:38 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
formats, err := conf.Section("formats")
|
|
|
|
if err != nil {
|
2017-10-10 21:17:38 +05:00
|
|
|
return nil, err
|
2017-04-03 19:00:38 +05:00
|
|
|
}
|
|
|
|
translations, err := conf.Section("strings")
|
|
|
|
if err != nil {
|
2017-10-10 21:17:38 +05:00
|
|
|
return nil, err
|
2017-04-03 19:00:38 +05:00
|
|
|
}
|
|
|
|
|
2017-10-10 21:17:38 +05:00
|
|
|
return &I18N{
|
2017-10-10 21:34:39 +05:00
|
|
|
Name: locale,
|
2017-04-03 19:00:38 +05:00
|
|
|
translation_dir: dir,
|
2017-10-10 21:17:38 +05:00
|
|
|
Formats: formats.Options(),
|
|
|
|
Translations: translations.Options(),
|
2017-04-03 19:00:38 +05:00
|
|
|
locale: tag,
|
2017-10-10 21:17:38 +05:00
|
|
|
}, nil
|
2017-04-03 19:00:38 +05:00
|
|
|
}
|
|
|
|
|
2017-10-10 21:17:38 +05:00
|
|
|
func (self *I18N) Translate(key string) string {
|
|
|
|
return self.Translations[key]
|
2017-04-03 19:00:38 +05:00
|
|
|
}
|
|
|
|
|
2017-10-10 21:17:38 +05:00
|
|
|
func (self *I18N) Format(key string) string {
|
|
|
|
return self.Formats[key]
|
2017-04-03 19:00:38 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
//this signature seems to be expected by mustache
|
2017-10-10 21:17:38 +05:00
|
|
|
//func (self *I18N) Translations() (map[string]string, error) {
|
|
|
|
// return self._translations, nil
|
|
|
|
//}
|
2017-04-03 19:00:38 +05:00
|
|
|
|
2017-10-10 21:17:38 +05:00
|
|
|
//func (self *I18N) Formats() (map[string]string, error) {
|
|
|
|
// return self.formats, nil
|
|
|
|
//}
|