Blame view

localization.go 2.79 KB
9933169c8   Marko Tikvić   localization support
1
2
3
4
  package webutility
  
  import (
  	"encoding/json"
2b62f61cc   Marko Tikvić   minor changes
5
  	"fmt"
9933169c8   Marko Tikvić   localization support
6
  	"io/ioutil"
89f45d7aa   Marko Tikvić   GetBestMatchLocal...
7
  	"net/http"
e97375e4d   Marko Tikvić   strip file extension
8
  	"path"
715bb6ad8   Marko Tikvić   parsing of accept...
9
  	"strconv"
3712c373f   Marko Tikvić   better localizati...
10
  	"strings"
3fffcb954   Marko Tikvić   removed old http API
11
  	"sync"
9933169c8   Marko Tikvić   localization support
12
  )
f84e7607d   Marko Tikvić   added dictionary;...
13
  type Dictionary struct {
3fffcb954   Marko Tikvić   removed old http API
14
  	my            sync.Mutex
a205e8f40   Marko Tikvić   changes
15
16
17
  	locales       map[string]map[string]string
  	supported     []string
  	defaultLocale string
f84e7607d   Marko Tikvić   added dictionary;...
18
  }
2b62f61cc   Marko Tikvić   minor changes
19
20
  func NewDictionary() *Dictionary {
  	return &Dictionary{
f84e7607d   Marko Tikvić   added dictionary;...
21
22
23
  		locales: map[string]map[string]string{},
  	}
  }
9933169c8   Marko Tikvić   localization support
24

0207726c4   Marko Tikvić   improved localiza...
25
26
  func (d *Dictionary) AddTranslations(directory string) error {
  	files, err := ioutil.ReadDir(directory)
9933169c8   Marko Tikvić   localization support
27
28
29
  	if err != nil {
  		return err
  	}
0207726c4   Marko Tikvić   improved localiza...
30
31
  	for _, fileInfo := range files {
  		fName := fileInfo.Name()
5bba6f75f   Marko Tikvić   bug fix
32
  		path := directory + "/" + fName
0207726c4   Marko Tikvić   improved localiza...
33
34
35
36
  		file, err := ioutil.ReadFile(path)
  		if err != nil {
  			return err
  		}
9933169c8   Marko Tikvić   localization support
37

e97375e4d   Marko Tikvić   strip file extension
38
  		loc := stripFileExtension(fName)
0207726c4   Marko Tikvić   improved localiza...
39

0207726c4   Marko Tikvić   improved localiza...
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  		var data interface{}
  		err = json.Unmarshal(file, &data)
  		if err != nil {
  			return err
  		}
  
  		l := map[string]string{}
  		for k, v := range data.(map[string]interface{}) {
  			l[k] = v.(string)
  		}
  
  		mu.Lock()
  		defer mu.Unlock()
  		d.locales[loc] = l
  		d.supported = append(d.supported, loc)
  	}
9933169c8   Marko Tikvić   localization support
56

2b62f61cc   Marko Tikvić   minor changes
57
58
  	if d.defaultLocale == "" && len(d.supported) > 0 {
  		d.defaultLocale = d.supported[0]
715bb6ad8   Marko Tikvić   parsing of accept...
59
  	}
9933169c8   Marko Tikvić   localization support
60
61
  	return nil
  }
89f45d7aa   Marko Tikvić   GetBestMatchLocal...
62
63
  func (d *Dictionary) GetBestMatchLocale(req *http.Request) (best string) {
  	accepted := d.parseAcceptedLanguages(req.Header.Get("Accept-Language"))
715bb6ad8   Marko Tikvić   parsing of accept...
64
65
  
  	for i, _ := range accepted {
89f45d7aa   Marko Tikvić   GetBestMatchLocal...
66
67
68
  		if accepted[i].Code == "*" {
  			return d.defaultLocale
  		}
715bb6ad8   Marko Tikvić   parsing of accept...
69
70
71
72
73
74
75
76
  		for j, _ := range d.supported {
  			if accepted[i].Code == d.supported[j] {
  				return d.supported[j]
  			}
  		}
  	}
  
  	return d.defaultLocale
0207726c4   Marko Tikvić   improved localiza...
77
  }
f84e7607d   Marko Tikvić   added dictionary;...
78
79
80
  func (d *Dictionary) Translate(loc, key string) string {
  	return d.locales[loc][key]
  }
2b62f61cc   Marko Tikvić   minor changes
81
82
83
84
85
86
87
88
89
90
91
  func (d *Dictionary) SetDefaultLocale(loc string) error {
  	if !d.contains(loc) {
  		return fmt.Errorf("locale file not loaded: %s", loc)
  	}
  
  	d.defaultLocale = loc
  
  	return nil
  }
  
  func (d *Dictionary) contains(loc string) bool {
a205e8f40   Marko Tikvić   changes
92
93
  	for _, v := range d.supported {
  		if v == loc {
f84e7607d   Marko Tikvić   added dictionary;...
94
95
96
97
  			return true
  		}
  	}
  	return false
9933169c8   Marko Tikvić   localization support
98
  }
a205e8f40   Marko Tikvić   changes
99

715bb6ad8   Marko Tikvić   parsing of accept...
100
101
102
  type LangWeight struct {
  	Code   string
  	Weight float64
a205e8f40   Marko Tikvić   changes
103
  }
715bb6ad8   Marko Tikvić   parsing of accept...
104
105
106
107
  func (d *Dictionary) parseAcceptedLanguages(accepted string) (langs []LangWeight) {
  	if accepted == "" {
  		langs = append(langs, LangWeight{Code: d.defaultLocale, Weight: 1.0})
  		return langs
3712c373f   Marko Tikvić   better localizati...
108
  	}
715bb6ad8   Marko Tikvić   parsing of accept...
109
110
  	parts := strings.Split(accepted, ",")
  	for i, _ := range parts {
89f45d7aa   Marko Tikvić   GetBestMatchLocal...
111
  		parts[i] = strings.Trim(parts[i], " ")
715bb6ad8   Marko Tikvić   parsing of accept...
112
113
114
115
116
117
118
119
120
121
122
123
124
125
  
  		var code string = ""
  		var weight float64 = 0.0
  
  		cw := strings.Split(parts[i], ";")
  		paramCount := len(cw)
  
  		if paramCount == 1 {
  			// default weight of 1
  			code = cw[0]
  			weight = 1.0
  		} else if paramCount == 2 {
  			// parse weight
  			code = cw[0]
89f45d7aa   Marko Tikvić   GetBestMatchLocal...
126
  			weight, _ = strconv.ParseFloat(cw[1][2:], 64)
715bb6ad8   Marko Tikvić   parsing of accept...
127
128
  
  		}
715bb6ad8   Marko Tikvić   parsing of accept...
129
  		langs = append(langs, LangWeight{Code: code, Weight: weight})
3712c373f   Marko Tikvić   better localizati...
130
  	}
89f45d7aa   Marko Tikvić   GetBestMatchLocal...
131
  	// TODO(marko): sort langs by weights?
715bb6ad8   Marko Tikvić   parsing of accept...
132
133
  
  	return langs
3712c373f   Marko Tikvić   better localizati...
134
  }
0207726c4   Marko Tikvić   improved localiza...
135
136
  
  func stripFileExtension(full string) (stripped string) {
e97375e4d   Marko Tikvić   strip file extension
137
138
139
  	extension := path.Ext(full)
  	stripped = strings.TrimSuffix(full, extension)
  	return stripped
0207726c4   Marko Tikvić   improved localiza...
140
  }