Commit 2b62f61cc84cc1e486f68f7e8d8f26a1fab71e2b

Authored by Marko Tikvić
1 parent 89f45d7aa8
Exists in master

minor changes

Showing 1 changed file with 16 additions and 9 deletions   Show diff stats
1 package webutility 1 package webutility
2 2
3 import ( 3 import (
4 "encoding/json" 4 "encoding/json"
5 "fmt"
5 "io/ioutil" 6 "io/ioutil"
6 "net/http" 7 "net/http"
7 "path" 8 "path"
8 "strconv" 9 "strconv"
9 "strings" 10 "strings"
10 "sync" 11 "sync"
11 ) 12 )
12 13
13 type Dictionary struct { 14 type Dictionary struct {
14 my sync.Mutex 15 my sync.Mutex
15 locales map[string]map[string]string 16 locales map[string]map[string]string
16 supported []string 17 supported []string
17 defaultLocale string 18 defaultLocale string
18 } 19 }
19 20
20 func NewDictionary(def string) *Dictionary { 21 func NewDictionary() *Dictionary {
21 d := Dictionary{ 22 return &Dictionary{
22 locales: map[string]map[string]string{}, 23 locales: map[string]map[string]string{},
23 } 24 }
24 d.defaultLocale = def
25 return &d
26 } 25 }
27 26
28 func (d *Dictionary) AddTranslations(directory string) error { 27 func (d *Dictionary) AddTranslations(directory string) error {
29 files, err := ioutil.ReadDir(directory) 28 files, err := ioutil.ReadDir(directory)
30 if err != nil { 29 if err != nil {
31 return err 30 return err
32 } 31 }
33 32
34 for _, fileInfo := range files { 33 for _, fileInfo := range files {
35 fName := fileInfo.Name() 34 fName := fileInfo.Name()
36 path := directory + "/" + fName 35 path := directory + "/" + fName
37 file, err := ioutil.ReadFile(path) 36 file, err := ioutil.ReadFile(path)
38 if err != nil { 37 if err != nil {
39 return err 38 return err
40 } 39 }
41 40
42 loc := stripFileExtension(fName) 41 loc := stripFileExtension(fName)
43 42
44 var data interface{} 43 var data interface{}
45 err = json.Unmarshal(file, &data) 44 err = json.Unmarshal(file, &data)
46 if err != nil { 45 if err != nil {
47 return err 46 return err
48 } 47 }
49 48
50 l := map[string]string{} 49 l := map[string]string{}
51 for k, v := range data.(map[string]interface{}) { 50 for k, v := range data.(map[string]interface{}) {
52 l[k] = v.(string) 51 l[k] = v.(string)
53 } 52 }
54 53
55 mu.Lock() 54 mu.Lock()
56 defer mu.Unlock() 55 defer mu.Unlock()
57 d.locales[loc] = l 56 d.locales[loc] = l
58 d.supported = append(d.supported, loc) 57 d.supported = append(d.supported, loc)
59 } 58 }
60 59
61 if d.defaultLocale == "" { 60 if d.defaultLocale == "" && len(d.supported) > 0 {
62 if len(d.supported) > 0 { 61 d.defaultLocale = d.supported[0]
63 d.defaultLocale = d.supported[0]
64 }
65 } 62 }
66 63
67 return nil 64 return nil
68 } 65 }
69 66
70 func (d *Dictionary) GetBestMatchLocale(req *http.Request) (best string) { 67 func (d *Dictionary) GetBestMatchLocale(req *http.Request) (best string) {
71 accepted := d.parseAcceptedLanguages(req.Header.Get("Accept-Language")) 68 accepted := d.parseAcceptedLanguages(req.Header.Get("Accept-Language"))
72 69
73 for i, _ := range accepted { 70 for i, _ := range accepted {
74 if accepted[i].Code == "*" { 71 if accepted[i].Code == "*" {
75 return d.defaultLocale 72 return d.defaultLocale
76 } 73 }
77 for j, _ := range d.supported { 74 for j, _ := range d.supported {
78 if accepted[i].Code == d.supported[j] { 75 if accepted[i].Code == d.supported[j] {
79 return d.supported[j] 76 return d.supported[j]
80 } 77 }
81 } 78 }
82 } 79 }
83 80
84 return d.defaultLocale 81 return d.defaultLocale
85 } 82 }
86 83
87 func (d *Dictionary) Translate(loc, key string) string { 84 func (d *Dictionary) Translate(loc, key string) string {
88 return d.locales[loc][key] 85 return d.locales[loc][key]
89 } 86 }
90 87
91 func (d *Dictionary) hasLocale(loc string) bool { 88 func (d *Dictionary) SetDefaultLocale(loc string) error {
89 if !d.contains(loc) {
90 return fmt.Errorf("locale file not loaded: %s", loc)
91 }
92
93 d.defaultLocale = loc
94
95 return nil
96 }
97
98 func (d *Dictionary) contains(loc string) bool {
92 for _, v := range d.supported { 99 for _, v := range d.supported {
93 if v == loc { 100 if v == loc {
94 return true 101 return true
95 } 102 }
96 } 103 }
97 return false 104 return false
98 } 105 }
99 106
100 type LangWeight struct { 107 type LangWeight struct {
101 Code string 108 Code string
102 Weight float64 109 Weight float64
103 } 110 }
104 111
105 func (d *Dictionary) parseAcceptedLanguages(accepted string) (langs []LangWeight) { 112 func (d *Dictionary) parseAcceptedLanguages(accepted string) (langs []LangWeight) {
106 if accepted == "" { 113 if accepted == "" {
107 langs = append(langs, LangWeight{Code: d.defaultLocale, Weight: 1.0}) 114 langs = append(langs, LangWeight{Code: d.defaultLocale, Weight: 1.0})
108 return langs 115 return langs
109 } 116 }
110 117
111 parts := strings.Split(accepted, ",") 118 parts := strings.Split(accepted, ",")
112 for i, _ := range parts { 119 for i, _ := range parts {
113 parts[i] = strings.Trim(parts[i], " ") 120 parts[i] = strings.Trim(parts[i], " ")
114 121
115 var code string = "" 122 var code string = ""
116 var weight float64 = 0.0 123 var weight float64 = 0.0
117 124
118 cw := strings.Split(parts[i], ";") 125 cw := strings.Split(parts[i], ";")
119 paramCount := len(cw) 126 paramCount := len(cw)
120 127
121 if paramCount == 1 { 128 if paramCount == 1 {
122 // default weight of 1 129 // default weight of 1
123 code = cw[0] 130 code = cw[0]
124 weight = 1.0 131 weight = 1.0
125 } else if paramCount == 2 { 132 } else if paramCount == 2 {
126 // parse weight 133 // parse weight
127 code = cw[0] 134 code = cw[0]
128 weight, _ = strconv.ParseFloat(cw[1][2:], 64) 135 weight, _ = strconv.ParseFloat(cw[1][2:], 64)
129 136
130 } 137 }
131 138
132 langs = append(langs, LangWeight{Code: code, Weight: weight}) 139 langs = append(langs, LangWeight{Code: code, Weight: weight})
133 } 140 }
134 141
135 // TODO(marko): sort langs by weights? 142 // TODO(marko): sort langs by weights?
136 143
137 return langs 144 return langs
138 } 145 }
139 146
140 func stripFileExtension(full string) (stripped string) { 147 func stripFileExtension(full string) (stripped string) {
141 extension := path.Ext(full) 148 extension := path.Ext(full)