commit 3a212f6626650acab306e2f5568e75f4d2326be9
parent 6b7046bc9f01f950c196b014624ae22889cd25d6
Author: lash <dev@holbrook.no>
Date: Thu, 2 Jan 2025 08:22:12 +0000
Add gettext resource
Diffstat:
7 files changed, 176 insertions(+), 9 deletions(-)
diff --git a/dev/walk/main.go b/dev/walk/main.go
@@ -19,6 +19,7 @@ import (
var (
logg = logging.NewVanilla()
+ poFilebase = "default"
)
type translator struct {
@@ -30,13 +31,13 @@ type translator struct {
w map[string]io.WriteCloser
}
-func newTranslator(ctx context.Context, rs resource.Resource, outPath string) *translator {
+func newTranslator(ctx context.Context, rs resource.Resource, outPath string, filebase string) *translator {
return &translator{
ctx: ctx,
rs: rs,
d: outPath,
w: make(map[string]io.WriteCloser),
- fileBase: "visedata",
+ fileBase: filebase,
}
}
@@ -44,9 +45,14 @@ func(tr *translator) applyLanguage(node *debug.Node) {
}
-func(tr *translator) fileNameFor(ln lang.Language) string {
- fileName := tr.fileBase + "." + ln.Code + ".po"
- return path.Join(tr.d, fileName)
+func(tr *translator) ensureFileNameFor(ln lang.Language) (string, error) {
+ fileName := tr.fileBase + ".po"
+ p := path.Join(tr.d, ln.Code)
+ err := os.MkdirAll(p, 0700)
+ if err != nil {
+ return "", err
+ }
+ return path.Join(p, fileName), nil
}
func(tr *translator) Close() error {
@@ -131,7 +137,10 @@ msgstr ""
}
func(tr *translator) AddLang(ln lang.Language) error {
- filePath := tr.fileNameFor(ln)
+ filePath, err := tr.ensureFileNameFor(ln)
+ if err != nil {
+ return err
+ }
w, err := os.OpenFile(filePath, os.O_WRONLY | os.O_CREATE, 0644)
s := fmt.Sprintf(`msgid ""
msgstr ""
@@ -176,16 +185,22 @@ func main() {
var langs langVar
flag.StringVar(&dir, "d", ".", "resource dir to read from")
- flag.StringVar(&outDir, "o", ".", "output directory")
+ flag.StringVar(&outDir, "o", "locale", "output directory")
flag.StringVar(&root, "root", "root", "entry point symbol")
flag.Var(&langs, "l", "process for language")
flag.Parse()
fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, dir)
+ err := os.MkdirAll(outDir, 0700)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "output dir create error: %v", err)
+ os.Exit(1)
+ }
+
ctx := context.Background()
rsStore := fsdb.NewFsDb()
- err := rsStore.Connect(ctx, dir)
+ err = rsStore.Connect(ctx, dir)
if err != nil {
fmt.Fprintf(os.Stderr, "resource db connect error: %v", err)
os.Exit(1)
@@ -193,7 +208,7 @@ func main() {
rs := resource.NewDbResource(rsStore)
- tr := newTranslator(ctx, rs, outDir)
+ tr := newTranslator(ctx, rs, outDir, poFilebase)
defer tr.Close()
for _, ln := range(langs.Langs()) {
logg.DebugCtxf(ctx, "lang", "lang", ln)
diff --git a/lang/lang.go b/lang/lang.go
@@ -1,6 +1,7 @@
package lang
import (
+ "context"
"fmt"
"github.com/barbashov/iso639-3"
@@ -37,3 +38,18 @@ func LanguageFromCode(code string) (Language, error) {
func(l Language) String() string {
return fmt.Sprintf("%s (%s)", l.Code, l.Name)
}
+
+// LanguageFromContext scans the given context for a valid language
+// specification, and if found returns a corresponding language
+// object.
+func LanguageFromContext(ctx context.Context) (Language, bool) {
+ //var code string
+ var lang Language
+ var ok bool
+ if ctx.Value("Language") != nil {
+ lang = ctx.Value("Language").(Language)
+ ok = true
+ //code = lang.Code
+ }
+ return lang, ok
+}
diff --git a/resource/gettext.go b/resource/gettext.go
@@ -0,0 +1,55 @@
+package resource
+
+import (
+ "context"
+
+ gotext "gopkg.in/leonelquinteros/gotext.v1"
+
+ "git.defalsify.org/vise.git/lang"
+)
+
+type PoResource struct {
+ path string
+ domain string
+ defaultLanguage lang.Language
+ tr map[string]*gotext.Locale
+}
+
+func NewPoResource(defaultLanguage lang.Language, path string, domain string) *PoResource {
+ o := &PoResource {
+ path: path,
+ domain: domain,
+ defaultLanguage: defaultLanguage,
+ tr: make(map[string]*gotext.Locale),
+ }
+ return o.WithLanguage(defaultLanguage)
+}
+
+func(p *PoResource) WithLanguage(ln lang.Language) *PoResource {
+ o := gotext.NewLocale(p.path, ln.Code)
+ o.AddDomain(p.domain)
+ p.tr[ln.Code] = o
+ return p
+}
+
+func(p *PoResource) get(ctx context.Context, sym string) (string, error) {
+ s := sym
+ ln, ok := lang.LanguageFromContext(ctx)
+ if !ok {
+ ln = p.defaultLanguage
+ }
+ o, ok := p.tr[ln.Code]
+ if ok {
+ logg.TraceCtxf(ctx, "poresource get", "sym", sym, "ln", ln, "path", p.path, "o", o)
+ s = o.Get(sym)
+ }
+ return s, nil
+}
+
+func(p *PoResource) GetMenu(ctx context.Context, sym string) (string, error) {
+ return p.get(ctx, sym)
+}
+
+func(p *PoResource) GetTemplate(ctx context.Context, sym string) (string, error) {
+ return p.get(ctx, sym)
+}
diff --git a/resource/gettext_test.go b/resource/gettext_test.go
@@ -0,0 +1,52 @@
+package resource
+
+import (
+ "context"
+ "testing"
+
+ "git.defalsify.org/vise.git/testdata/testlocale"
+ "git.defalsify.org/vise.git/lang"
+)
+
+func TestPoGet(t *testing.T) {
+ ln, err := lang.LanguageFromCode("nor")
+ if err != nil {
+ t.Fatal(err)
+ }
+ rs := NewPoResource(ln, testlocale.LocaleDir, "default")
+ ctx := context.WithValue(context.Background(), "Language", ln)
+
+ ln, err = lang.LanguageFromCode("eng")
+ if err != nil {
+ t.Fatal(err)
+ }
+ rs = rs.WithLanguage(ln)
+
+ s, err := rs.GetMenu(ctx, "foo")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if s != "fu" {
+ t.Fatalf("expected 'fu', got '%s'", s)
+ }
+
+ // eng now
+ ctx = context.WithValue(context.Background(), "Language", ln)
+
+ s, err = rs.GetMenu(ctx, "foo")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if s != "foo" {
+ t.Fatalf("expected 'foo', got '%s'", s)
+ }
+
+ s, err = rs.GetMenu(ctx, "bar")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if s != "baz" {
+ t.Fatalf("expected 'baz', got '%s'", s)
+ }
+}
diff --git a/testdata/testlocale/eng/default.po b/testdata/testlocale/eng/default.po
@@ -0,0 +1,9 @@
+msgid ""
+msgstr ""
+ "Content-Type: text/plain; charset=UTF-8\n"
+ "Language: eng\n"
+
+msgid ""
+ "bar"
+msgstr ""
+ "baz"
diff --git a/testdata/testlocale/nor/default.po b/testdata/testlocale/nor/default.po
@@ -0,0 +1,9 @@
+msgid ""
+msgstr ""
+ "Content-Type: text/plain; charset=UTF-8\n"
+ "Language: nor\n"
+
+msgid ""
+ "foo"
+msgstr ""
+ "fu"
diff --git a/testdata/testlocale/path.go b/testdata/testlocale/path.go
@@ -0,0 +1,11 @@
+package testlocale
+
+import (
+ "path"
+
+ testdataloader "github.com/peteole/testdata-loader"
+)
+
+var (
+ LocaleDir = path.Join(testdataloader.GetBasePath(), "testdata", "testlocale")
+)