camper/pkg/locale/locale.go

111 lines
2.3 KiB
Go

/*
* SPDX-FileCopyrightText: 2023 jordi fita mas <jfita@peritasoft.com>
* SPDX-License-Identifier: AGPL-3.0-only
*/
package locale
import (
"context"
"github.com/leonelquinteros/gotext"
"golang.org/x/text/language"
"dev.tandem.ws/tandem/camper/pkg/database"
)
type Locale struct {
*gotext.Locale
CurrencyPattern string
Language language.Tag
}
type Locales map[language.Tag]*Locale
func (m Locales) Tags() []language.Tag {
keys := make([]language.Tag, len(m))
i := 0
for k := range m {
keys[i] = k
i++
}
return keys
}
func MustGetAll(ctx context.Context, db *database.DB) Locales {
availableLanguages := mustGetAvailableLanguages(ctx, db)
locales := map[language.Tag]*Locale{}
for _, lang := range availableLanguages {
locale := newLocale(lang)
locale.AddDomain("camper")
locales[lang.tag] = locale
}
return locales
}
func newLocale(lang availableLanguage) *Locale {
return &Locale{
gotext.NewLocale("locale", lang.tag.String()),
lang.currencyPattern,
lang.tag,
}
}
func (l *Locale) Gettext(str string) string {
return l.GetD(l.GetDomain(), str)
}
func (l *Locale) Pgettext(str string, ctx string) string {
return l.GetDC(l.GetDomain(), str, ctx)
}
func (l *Locale) GettextNoop(str string) string {
return str
}
func Match(acceptLanguage string, locales Locales, matcher language.Matcher) *Locale {
t, _, err := language.ParseAcceptLanguage(acceptLanguage)
if err != nil {
return nil
}
var locale *Locale
tag, _, confidence := matcher.Match(t...)
if confidence > language.No {
var ok bool
locale, ok = locales[tag]
for !ok && !tag.IsRoot() {
tag = tag.Parent()
locale, ok = locales[tag]
}
}
return locale
}
type availableLanguage struct {
tag language.Tag
currencyPattern string
}
func mustGetAvailableLanguages(ctx context.Context, db *database.DB) []availableLanguage {
rows, err := db.Query(ctx, "select lang_tag, currency_pattern from language where selectable")
if err != nil {
panic(err)
}
defer rows.Close()
var languages []availableLanguage
for rows.Next() {
var langTag string
var currencyPattern string
err = rows.Scan(&langTag, &currencyPattern)
if err != nil {
panic(err)
}
languages = append(languages, availableLanguage{language.MustParse(langTag), currencyPattern})
}
if rows.Err() != nil {
panic(rows.Err())
}
return languages
}