podman

Форк
0
274 строки · 5.6 Кб
1
package ut
2

3
import (
4
	"encoding/json"
5
	"fmt"
6
	"os"
7
	"path/filepath"
8

9
	"io"
10

11
	"github.com/go-playground/locales"
12
)
13

14
type translation struct {
15
	Locale           string      `json:"locale"`
16
	Key              interface{} `json:"key"` // either string or integer
17
	Translation      string      `json:"trans"`
18
	PluralType       string      `json:"type,omitempty"`
19
	PluralRule       string      `json:"rule,omitempty"`
20
	OverrideExisting bool        `json:"override,omitempty"`
21
}
22

23
const (
24
	cardinalType = "Cardinal"
25
	ordinalType  = "Ordinal"
26
	rangeType    = "Range"
27
)
28

29
// ImportExportFormat is the format of the file import or export
30
type ImportExportFormat uint8
31

32
// supported Export Formats
33
const (
34
	FormatJSON ImportExportFormat = iota
35
)
36

37
// Export writes the translations out to a file on disk.
38
//
39
// NOTE: this currently only works with string or int translations keys.
40
func (t *UniversalTranslator) Export(format ImportExportFormat, dirname string) error {
41

42
	_, err := os.Stat(dirname)
43
	if err != nil {
44

45
		if !os.IsNotExist(err) {
46
			return err
47
		}
48

49
		if err = os.MkdirAll(dirname, 0744); err != nil {
50
			return err
51
		}
52
	}
53

54
	// build up translations
55
	var trans []translation
56
	var b []byte
57
	var ext string
58

59
	for _, locale := range t.translators {
60

61
		for k, v := range locale.(*translator).translations {
62
			trans = append(trans, translation{
63
				Locale:      locale.Locale(),
64
				Key:         k,
65
				Translation: v.text,
66
			})
67
		}
68

69
		for k, pluralTrans := range locale.(*translator).cardinalTanslations {
70

71
			for i, plural := range pluralTrans {
72

73
				// leave enough for all plural rules
74
				// but not all are set for all languages.
75
				if plural == nil {
76
					continue
77
				}
78

79
				trans = append(trans, translation{
80
					Locale:      locale.Locale(),
81
					Key:         k.(string),
82
					Translation: plural.text,
83
					PluralType:  cardinalType,
84
					PluralRule:  locales.PluralRule(i).String(),
85
				})
86
			}
87
		}
88

89
		for k, pluralTrans := range locale.(*translator).ordinalTanslations {
90

91
			for i, plural := range pluralTrans {
92

93
				// leave enough for all plural rules
94
				// but not all are set for all languages.
95
				if plural == nil {
96
					continue
97
				}
98

99
				trans = append(trans, translation{
100
					Locale:      locale.Locale(),
101
					Key:         k.(string),
102
					Translation: plural.text,
103
					PluralType:  ordinalType,
104
					PluralRule:  locales.PluralRule(i).String(),
105
				})
106
			}
107
		}
108

109
		for k, pluralTrans := range locale.(*translator).rangeTanslations {
110

111
			for i, plural := range pluralTrans {
112

113
				// leave enough for all plural rules
114
				// but not all are set for all languages.
115
				if plural == nil {
116
					continue
117
				}
118

119
				trans = append(trans, translation{
120
					Locale:      locale.Locale(),
121
					Key:         k.(string),
122
					Translation: plural.text,
123
					PluralType:  rangeType,
124
					PluralRule:  locales.PluralRule(i).String(),
125
				})
126
			}
127
		}
128

129
		switch format {
130
		case FormatJSON:
131
			b, err = json.MarshalIndent(trans, "", "    ")
132
			ext = ".json"
133
		}
134

135
		if err != nil {
136
			return err
137
		}
138

139
		err = os.WriteFile(filepath.Join(dirname, fmt.Sprintf("%s%s", locale.Locale(), ext)), b, 0644)
140
		if err != nil {
141
			return err
142
		}
143

144
		trans = trans[0:0]
145
	}
146

147
	return nil
148
}
149

150
// Import reads the translations out of a file or directory on disk.
151
//
152
// NOTE: this currently only works with string or int translations keys.
153
func (t *UniversalTranslator) Import(format ImportExportFormat, dirnameOrFilename string) error {
154

155
	fi, err := os.Stat(dirnameOrFilename)
156
	if err != nil {
157
		return err
158
	}
159

160
	processFn := func(filename string) error {
161

162
		f, err := os.Open(filename)
163
		if err != nil {
164
			return err
165
		}
166
		defer f.Close()
167

168
		return t.ImportByReader(format, f)
169
	}
170

171
	if !fi.IsDir() {
172
		return processFn(dirnameOrFilename)
173
	}
174

175
	// recursively go through directory
176
	walker := func(path string, info os.FileInfo, err error) error {
177

178
		if info.IsDir() {
179
			return nil
180
		}
181

182
		switch format {
183
		case FormatJSON:
184
			// skip non JSON files
185
			if filepath.Ext(info.Name()) != ".json" {
186
				return nil
187
			}
188
		}
189

190
		return processFn(path)
191
	}
192

193
	return filepath.Walk(dirnameOrFilename, walker)
194
}
195

196
// ImportByReader imports the the translations found within the contents read from the supplied reader.
197
//
198
// NOTE: generally used when assets have been embedded into the binary and are already in memory.
199
func (t *UniversalTranslator) ImportByReader(format ImportExportFormat, reader io.Reader) error {
200

201
	b, err := io.ReadAll(reader)
202
	if err != nil {
203
		return err
204
	}
205

206
	var trans []translation
207

208
	switch format {
209
	case FormatJSON:
210
		err = json.Unmarshal(b, &trans)
211
	}
212

213
	if err != nil {
214
		return err
215
	}
216

217
	for _, tl := range trans {
218

219
		locale, found := t.FindTranslator(tl.Locale)
220
		if !found {
221
			return &ErrMissingLocale{locale: tl.Locale}
222
		}
223

224
		pr := stringToPR(tl.PluralRule)
225

226
		if pr == locales.PluralRuleUnknown {
227

228
			err = locale.Add(tl.Key, tl.Translation, tl.OverrideExisting)
229
			if err != nil {
230
				return err
231
			}
232

233
			continue
234
		}
235

236
		switch tl.PluralType {
237
		case cardinalType:
238
			err = locale.AddCardinal(tl.Key, tl.Translation, pr, tl.OverrideExisting)
239
		case ordinalType:
240
			err = locale.AddOrdinal(tl.Key, tl.Translation, pr, tl.OverrideExisting)
241
		case rangeType:
242
			err = locale.AddRange(tl.Key, tl.Translation, pr, tl.OverrideExisting)
243
		default:
244
			return &ErrBadPluralDefinition{tl: tl}
245
		}
246

247
		if err != nil {
248
			return err
249
		}
250
	}
251

252
	return nil
253
}
254

255
func stringToPR(s string) locales.PluralRule {
256

257
	switch s {
258
	case "Zero":
259
		return locales.PluralRuleZero
260
	case "One":
261
		return locales.PluralRuleOne
262
	case "Two":
263
		return locales.PluralRuleTwo
264
	case "Few":
265
		return locales.PluralRuleFew
266
	case "Many":
267
		return locales.PluralRuleMany
268
	case "Other":
269
		return locales.PluralRuleOther
270
	default:
271
		return locales.PluralRuleUnknown
272
	}
273

274
}
275

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.