goserver_sync/core/i18n/config.go

161 lines
3.6 KiB
Go

package i18n
import (
"crypto/md5"
"encoding/hex"
"encoding/json"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/howeyc/fsnotify"
"mongo.games.com/goserver/core"
"mongo.games.com/goserver/core/basic"
"mongo.games.com/goserver/core/logger"
)
var Config = Configuration{}
type Configuration struct {
RootPath string
hashCodes map[string]string
watcher *fsnotify.Watcher
}
func (this *Configuration) Name() string {
return "i18n"
}
func (this *Configuration) Init() error {
var err error
workDir, err := os.Getwd()
if err != nil {
return err
}
this.RootPath = filepath.Join(workDir, this.RootPath)
this.watcher, err = fsnotify.NewWatcher()
if err != nil {
logger.Logger.Warn(" fsnotify.NewWatcher err:", err)
return err
}
// Process events
go func() {
defer func() {
if err := recover(); err != nil {
logger.Logger.Warn("watch data director modify goroutine err:", err)
}
}()
for {
select {
case ev := <-this.watcher.Event:
if ev != nil && ev.IsModify() && filepath.Ext(ev.Name) == ".json" {
core.CoreObject().SendCommand(&fileModifiedCommand{fileName: ev.Name}, false)
logger.Logger.Trace("fsnotify event:", ev)
}
case err := <-this.watcher.Error:
logger.Logger.Warn("fsnotify error:", err)
}
}
logger.Logger.Warn(this.RootPath, " watcher quit!")
}()
this.watcher.Watch(this.RootPath)
this.hashCodes = make(map[string]string)
//获得配置目录中所有的数据文件
var files = []string{}
filepath.Walk(this.RootPath, func(path string, info os.FileInfo, err error) error {
if info.IsDir() == false && filepath.Ext(info.Name()) == ".json" {
files = append(files, info.Name())
}
return nil
})
//加载这些数据文件
h := md5.New()
for _, f := range files {
logger.Logger.Trace("load file name ======", f)
buf, err := ioutil.ReadFile(filepath.Join(this.RootPath, f))
if err != nil {
logger.Logger.Warn("i18n Config.Init ioutil.ReadFile error", err)
return err
}
kv := make(map[string]string)
err = json.Unmarshal(buf, &kv)
if err != nil {
logger.Logger.Warn("i18n Config.Init json.Unmarshal error", err)
return err
}
nameAndExt := strings.SplitN(f, ".", 2)
if len(nameAndExt) == 2 {
lang := nameAndExt[0]
loc := &locale{lang: lang, message: kv}
if loc != nil {
locales.Add(loc)
}
h.Reset()
h.Write(buf)
this.hashCodes[f] = hex.EncodeToString(h.Sum(nil))
}
}
return nil
}
func (this *Configuration) Close() error {
this.watcher.Close()
return nil
}
type fileModifiedCommand struct {
fileName string
}
func (fmc *fileModifiedCommand) Done(o *basic.Object) error {
fn := filepath.Base(fmc.fileName)
hashCode := Config.hashCodes[fn]
buf, err := ioutil.ReadFile(filepath.Join(Config.RootPath, fn))
if err != nil {
logger.Logger.Warn("i18n fileModifiedCommand ioutil.ReadFile error", err)
return err
}
if len(buf) == 0 {
return nil
}
h := md5.New()
h.Reset()
h.Write(buf)
newCode := hex.EncodeToString(h.Sum(nil))
if newCode != hashCode {
logger.Logger.Trace("modified file name ======", fn)
kv := make(map[string]string)
err = json.Unmarshal(buf, &kv)
if err != nil {
logger.Logger.Warn("i18n Config.Init json.Unmarshal error", err)
return err
}
nameAndExt := strings.SplitN(fn, ".", 2)
if len(nameAndExt) == 2 {
lang := nameAndExt[0]
loc, exist := locales.getLocale(lang)
if exist {
loc.message = kv
} else {
loc = &locale{lang: lang, message: kv}
if loc != nil {
locales.Add(loc)
}
}
Config.hashCodes[fn] = newCode
}
}
return nil
}
func init() {
core.RegistePackage(&Config)
}