您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

languages.go 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright (c) 2018 Daniel Oaks <daniel@danieloaks.net>
  2. // released under the MIT license
  3. package irc
  4. import (
  5. "fmt"
  6. "sort"
  7. "strings"
  8. "sync"
  9. )
  10. // LanguageManager manages our languages and provides translation abilities.
  11. type LanguageManager struct {
  12. sync.RWMutex
  13. Info map[string]LangData
  14. translations map[string]map[string]string
  15. defaultLang string
  16. }
  17. // NewLanguageManager returns a new LanguageManager.
  18. func NewLanguageManager(defaultLang string, languageData map[string]LangData) *LanguageManager {
  19. lm := LanguageManager{
  20. Info: make(map[string]LangData),
  21. translations: make(map[string]map[string]string),
  22. defaultLang: defaultLang,
  23. }
  24. // make fake "en" info
  25. lm.Info["en"] = LangData{
  26. Code: "en",
  27. Name: "English",
  28. Contributors: "Oragono contributors and the IRC community",
  29. }
  30. // load language data
  31. for name, data := range languageData {
  32. lm.Info[name] = data
  33. // make sure we don't include empty translations
  34. lm.translations[name] = make(map[string]string)
  35. for key, value := range data.Translations {
  36. if strings.TrimSpace(value) == "" {
  37. continue
  38. }
  39. lm.translations[name][key] = value
  40. }
  41. }
  42. return &lm
  43. }
  44. // Default returns the default languages.
  45. func (lm *LanguageManager) Default() []string {
  46. lm.RLock()
  47. defer lm.RUnlock()
  48. if lm.defaultLang == "" {
  49. return []string{}
  50. }
  51. return []string{lm.defaultLang}
  52. }
  53. // Count returns how many languages we have.
  54. func (lm *LanguageManager) Count() int {
  55. lm.RLock()
  56. defer lm.RUnlock()
  57. return len(lm.Info)
  58. }
  59. // Translators returns the languages we have and the translators.
  60. func (lm *LanguageManager) Translators() []string {
  61. lm.RLock()
  62. defer lm.RUnlock()
  63. var tlist sort.StringSlice
  64. for _, info := range lm.Info {
  65. if info.Code == "en" {
  66. continue
  67. }
  68. tlist = append(tlist, fmt.Sprintf("%s (%s): %s", info.Name, info.Code, info.Contributors))
  69. }
  70. sort.Sort(tlist)
  71. return tlist
  72. }
  73. // Codes returns the proper language codes for the given casefolded language codes.
  74. func (lm *LanguageManager) Codes(codes []string) []string {
  75. lm.RLock()
  76. defer lm.RUnlock()
  77. var newCodes []string
  78. for _, code := range codes {
  79. info, exists := lm.Info[code]
  80. if exists {
  81. newCodes = append(newCodes, info.Code)
  82. }
  83. }
  84. if len(newCodes) == 0 {
  85. newCodes = []string{"en"}
  86. }
  87. return newCodes
  88. }
  89. // Translate returns the given string, translated into the given language.
  90. func (lm *LanguageManager) Translate(languages []string, originalString string) string {
  91. // not using any special languages
  92. if len(languages) == 0 || languages[0] == "en" || len(lm.translations) == 0 {
  93. return originalString
  94. }
  95. lm.RLock()
  96. defer lm.RUnlock()
  97. for _, lang := range languages {
  98. lang = strings.ToLower(lang)
  99. if lang == "en" {
  100. return originalString
  101. }
  102. translations, exists := lm.translations[lang]
  103. if !exists {
  104. continue
  105. }
  106. newString, exists := translations[originalString]
  107. if !exists {
  108. continue
  109. }
  110. // found a valid translation!
  111. return newString
  112. }
  113. // didn't find any translation
  114. return originalString
  115. }