2023-06-19 14:42:47 -07:00
|
|
|
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
2018-09-22 15:04:55 -07:00
|
|
|
|
2023-08-10 19:46:45 -07:00
|
|
|
package locale // import "miniflux.app/v2/internal/locale"
|
2018-09-22 15:04:55 -07:00
|
|
|
|
|
|
|
import (
|
2021-02-16 22:58:44 -08:00
|
|
|
"embed"
|
2018-09-22 15:04:55 -07:00
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
2025-08-01 04:10:14 +02:00
|
|
|
type translationDict struct {
|
|
|
|
singulars map[string]string
|
|
|
|
plurals map[string][]string
|
|
|
|
}
|
2018-09-22 15:04:55 -07:00
|
|
|
type catalog map[string]translationDict
|
|
|
|
|
2024-12-10 01:05:14 +00:00
|
|
|
var defaultCatalog = make(catalog, len(AvailableLanguages))
|
2018-09-22 15:04:55 -07:00
|
|
|
|
2021-02-16 22:58:44 -08:00
|
|
|
//go:embed translations/*.json
|
|
|
|
var translationFiles embed.FS
|
|
|
|
|
2025-07-06 00:28:00 +02:00
|
|
|
func getTranslationDict(language string) (translationDict, error) {
|
2024-12-10 01:05:14 +00:00
|
|
|
if _, ok := defaultCatalog[language]; !ok {
|
|
|
|
var err error
|
|
|
|
if defaultCatalog[language], err = loadTranslationFile(language); err != nil {
|
2025-08-01 04:10:14 +02:00
|
|
|
return translationDict{}, err
|
2024-12-10 01:05:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return defaultCatalog[language], nil
|
|
|
|
}
|
|
|
|
|
2021-02-16 22:58:44 -08:00
|
|
|
func loadTranslationFile(language string) (translationDict, error) {
|
2025-07-06 00:29:04 +02:00
|
|
|
translationFileData, err := translationFiles.ReadFile("translations/" + language + ".json")
|
2021-02-16 22:58:44 -08:00
|
|
|
if err != nil {
|
2025-08-01 04:10:14 +02:00
|
|
|
return translationDict{}, err
|
2018-09-22 15:04:55 -07:00
|
|
|
}
|
2021-02-16 22:58:44 -08:00
|
|
|
|
|
|
|
translationMessages, err := parseTranslationMessages(translationFileData)
|
|
|
|
if err != nil {
|
2025-08-01 04:10:14 +02:00
|
|
|
return translationDict{}, err
|
2021-02-16 22:58:44 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return translationMessages, nil
|
2018-09-22 15:04:55 -07:00
|
|
|
}
|
|
|
|
|
2025-08-01 04:10:14 +02:00
|
|
|
func (t *translationDict) UnmarshalJSON(data []byte) error {
|
|
|
|
var tmpMap map[string]any
|
|
|
|
err := json.Unmarshal(data, &tmpMap)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
m := translationDict{
|
|
|
|
singulars: make(map[string]string),
|
|
|
|
plurals: make(map[string][]string),
|
|
|
|
}
|
|
|
|
|
|
|
|
for key, value := range tmpMap {
|
|
|
|
switch vtype := value.(type) {
|
|
|
|
case string:
|
|
|
|
m.singulars[key] = vtype
|
|
|
|
case []any:
|
|
|
|
for _, translation := range vtype {
|
|
|
|
if translationStr, ok := translation.(string); ok {
|
|
|
|
m.plurals[key] = append(m.plurals[key], translationStr)
|
|
|
|
} else {
|
|
|
|
return fmt.Errorf("invalid type for translation in an array: %v", translation)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return fmt.Errorf("invalid type (%T) for translation: %v", vtype, value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*t = m
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-02-16 22:58:44 -08:00
|
|
|
func parseTranslationMessages(data []byte) (translationDict, error) {
|
|
|
|
var translationMessages translationDict
|
|
|
|
if err := json.Unmarshal(data, &translationMessages); err != nil {
|
2025-08-01 04:10:14 +02:00
|
|
|
return translationDict{}, fmt.Errorf(`invalid translation file: %w`, err)
|
2018-09-22 15:04:55 -07:00
|
|
|
}
|
2021-02-16 22:58:44 -08:00
|
|
|
return translationMessages, nil
|
2018-09-22 15:04:55 -07:00
|
|
|
}
|