github.com/erda-project/erda-infra@v1.0.10-0.20240327085753-f3a249292aeb/providers/i18n/register.go (about) 1 // Copyright (c) 2021 Terminus, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package i18n 16 17 import ( 18 "bytes" 19 "embed" 20 "fmt" 21 "io/fs" 22 "path/filepath" 23 "strings" 24 25 cfg "github.com/erda-project/erda-infra/pkg/config" 26 "github.com/erda-project/erda-infra/pkg/strutil" 27 ) 28 29 type file struct { 30 isDir bool 31 name string 32 fullPath string 33 data []byte 34 } 35 36 func newDir(fullPath string) *file { 37 return &file{isDir: true, name: filepath.Base(fullPath), fullPath: fullPath, data: nil} 38 } 39 func newFile(fullPath string, data []byte) *file { 40 return &file{isDir: false, name: filepath.Base(fullPath), fullPath: fullPath, data: data} 41 } 42 43 func (p *provider) RegisterFilesFromFS(fsPrefix string, rootFS embed.FS) error { 44 var err error 45 var filesItems []*file 46 var commonItems []*file 47 walkEmbedFS(rootFS, fmt.Sprintf("%s/common", fsPrefix), &commonItems) 48 walkEmbedFS(rootFS, fmt.Sprintf("%s/files", fsPrefix), &filesItems) 49 for _, file := range filesItems { 50 if file.isDir { 51 continue 52 } 53 if !strutil.HasSuffixes(file.name, ".yml", ".yaml") { 54 continue 55 } 56 err = p.loadI18nFileByte(file.fullPath, file.data) 57 if err != nil { 58 return err 59 } 60 } 61 for _, file := range commonItems { 62 if file.isDir { 63 continue 64 } 65 if !strutil.HasSuffixes(file.name, ".yml", ".yaml") { 66 continue 67 } 68 err = p.loadByteToDic(file.fullPath, file.data, p.common) 69 if err != nil { 70 return err 71 } 72 } 73 return nil 74 } 75 76 func walkEmbedFS(rootFS embed.FS, fullPath string, files *[]*file) { 77 entries, err := fs.ReadDir(rootFS, fullPath) 78 if err != nil { 79 panic(fmt.Errorf("fullPath: %s, err: %v", fullPath, err)) 80 } 81 for _, entry := range entries { 82 entryPath := filepath.Join(fullPath, entry.Name()) 83 if !entry.IsDir() { 84 data, err := rootFS.ReadFile(entryPath) 85 if err != nil { 86 panic(fmt.Errorf("failed to read file, filePath: %s, err: %v", entryPath, err)) 87 } 88 *files = append(*files, newFile(entryPath, data)) 89 continue 90 } 91 *files = append(*files, newDir(entryPath)) 92 walkEmbedFS(rootFS, entryPath, files) 93 } 94 } 95 96 func (p *provider) loadByteToDic(path string, byte []byte, dic map[string]map[string]string) error { 97 m := make(map[string]interface{}) 98 typ := filepath.Ext(path) 99 if len(typ) <= 0 { 100 return fmt.Errorf("%s unknown file extension", path) 101 } 102 err := cfg.UnmarshalToMap(bytes.NewReader(byte), typ[1:], m) 103 if err != nil { 104 return fmt.Errorf("fail to load i18n file: %s", err) 105 } 106 for lang, v := range m { 107 text := dic[lang] 108 if text == nil { 109 text = make(map[string]string) 110 dic[lang] = text 111 } 112 switch m := v.(type) { 113 case map[string]string: 114 for k, v := range m { 115 text[strings.ToLower(k)] = fmt.Sprint(v) 116 } 117 case map[string]interface{}: 118 for k, v := range m { 119 text[strings.ToLower(k)] = fmt.Sprint(v) 120 } 121 case map[interface{}]interface{}: 122 for k, v := range m { 123 text[strings.ToLower(fmt.Sprint(k))] = fmt.Sprint(v) 124 } 125 default: 126 return fmt.Errorf("invalid i18n file format: %s", path) 127 } 128 } 129 return nil 130 } 131 132 func (p *provider) loadI18nFileByte(file string, byte []byte) error { 133 base := filepath.Base(file) 134 name := base[0 : len(base)-len(filepath.Ext(base))] 135 dic := p.dic[name] 136 if dic == nil { 137 dic = make(map[string]map[string]string) 138 p.dic[name] = dic 139 } 140 err := p.loadByteToDic(file, byte, dic) 141 if err != nil { 142 return err 143 } 144 return nil 145 }