catalog.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package locale // import "miniflux.app/v2/internal/locale"
  4. import (
  5. "embed"
  6. "encoding/json"
  7. "fmt"
  8. )
  9. type translationDict struct {
  10. singulars map[string]string
  11. plurals map[string][]string
  12. }
  13. type catalog map[string]translationDict
  14. var defaultCatalog = make(catalog, len(AvailableLanguages))
  15. //go:embed translations/*.json
  16. var translationFiles embed.FS
  17. func getTranslationDict(language string) (translationDict, error) {
  18. if _, ok := defaultCatalog[language]; !ok {
  19. var err error
  20. if defaultCatalog[language], err = loadTranslationFile(language); err != nil {
  21. return translationDict{}, err
  22. }
  23. }
  24. return defaultCatalog[language], nil
  25. }
  26. func loadTranslationFile(language string) (translationDict, error) {
  27. translationFileData, err := translationFiles.ReadFile("translations/" + language + ".json")
  28. if err != nil {
  29. return translationDict{}, err
  30. }
  31. translationMessages, err := parseTranslationMessages(translationFileData)
  32. if err != nil {
  33. return translationDict{}, err
  34. }
  35. return translationMessages, nil
  36. }
  37. func (t *translationDict) UnmarshalJSON(data []byte) error {
  38. var tmpMap map[string]any
  39. err := json.Unmarshal(data, &tmpMap)
  40. if err != nil {
  41. return err
  42. }
  43. m := translationDict{
  44. singulars: make(map[string]string),
  45. plurals: make(map[string][]string),
  46. }
  47. for key, value := range tmpMap {
  48. switch vtype := value.(type) {
  49. case string:
  50. m.singulars[key] = vtype
  51. case []any:
  52. for _, translation := range vtype {
  53. if translationStr, ok := translation.(string); ok {
  54. m.plurals[key] = append(m.plurals[key], translationStr)
  55. } else {
  56. return fmt.Errorf("invalid type for translation in an array: %v", translation)
  57. }
  58. }
  59. default:
  60. return fmt.Errorf("invalid type (%T) for translation: %v", vtype, value)
  61. }
  62. }
  63. *t = m
  64. return nil
  65. }
  66. func parseTranslationMessages(data []byte) (translationDict, error) {
  67. var translationMessages translationDict
  68. if err := json.Unmarshal(data, &translationMessages); err != nil {
  69. return translationDict{}, fmt.Errorf(`invalid translation file: %w`, err)
  70. }
  71. return translationMessages, nil
  72. }