Commit 715bb6ad842d3e2c326c7eb3cf469373b4699d48

Authored by Marko Tikvić
1 parent e97375e4d5
Exists in master

parsing of accepted languages header

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