From 6ee2c88fe25d0bdab9305c3d14a388831473cb29 Mon Sep 17 00:00:00 2001 From: lash Date: Thu, 2 Jan 2025 09:39:49 +0000 Subject: [PATCH 01/11] Implement gettext spec in local vm cmd --- cmd/main.go | 23 +++++++++++++++++++- config/config.go | 8 +++++++ internal/args/lang.go | 34 ++++++++++++++++++++++++++++++ internal/storage/storageservice.go | 22 +++++++++++++++++++ 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 internal/args/lang.go diff --git a/cmd/main.go b/cmd/main.go index 4fd084f..e6f96ab 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -10,10 +10,12 @@ import ( "git.defalsify.org/vise.git/engine" "git.defalsify.org/vise.git/logging" "git.defalsify.org/vise.git/resource" + "git.defalsify.org/vise.git/lang" "git.grassecon.net/urdt/ussd/config" "git.grassecon.net/urdt/ussd/initializers" "git.grassecon.net/urdt/ussd/internal/handlers" "git.grassecon.net/urdt/ussd/internal/storage" + "git.grassecon.net/urdt/ussd/internal/args" "git.grassecon.net/urdt/ussd/remote" ) @@ -31,22 +33,38 @@ func main() { config.LoadConfig() var dbDir string + var gettextDir string var size uint var sessionId string var database string var engineDebug bool + var langs args.LangVar flag.StringVar(&sessionId, "session-id", "075xx2123", "session id") flag.StringVar(&database, "db", "gdbm", "database to be used") flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from") flag.BoolVar(&engineDebug, "d", false, "use engine debug output") flag.UintVar(&size, "s", 160, "max size of output") + flag.StringVar(&gettextDir, "gettext", "", "use gettext translations from given directory") + flag.Var(&langs, "language", "add symbol resolution for language") flag.Parse() logg.Infof("start command", "dbdir", dbDir, "outputsize", size) + if len(langs.Langs()) == 0 { + langs.Set(config.DefaultLanguage) + } + ctx := context.Background() ctx = context.WithValue(ctx, "SessionId", sessionId) ctx = context.WithValue(ctx, "Database", database) + + ln, err := lang.LanguageFromCode(config.DefaultLanguage) + if err != nil { + fmt.Fprintf(os.Stderr, "default language set error: %v", err) + os.Exit(1) + } + ctx = context.WithValue(ctx, "Language", ln) + pfp := path.Join(scriptDir, "pp.csv") cfg := engine.Config{ @@ -59,8 +77,11 @@ func main() { resourceDir := scriptDir menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir) + if gettextDir != "" { + menuStorageService = menuStorageService.WithGettext(gettextDir, langs.Langs()) + } - err := menuStorageService.EnsureDbDir() + err = menuStorageService.EnsureDbDir() if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) diff --git a/config/config.go b/config/config.go index 3a8e8ed..6575310 100644 --- a/config/config.go +++ b/config/config.go @@ -18,6 +18,10 @@ const ( AliasPrefix = "api/v1/alias" ) +var ( + defaultLanguage = "eng" +) + var ( custodialURLBase string dataURLBase string @@ -34,6 +38,7 @@ var ( VoucherTransfersURL string VoucherDataURL string CheckAliasURL string + DefaultLanguage string ) func setBase() error { @@ -51,6 +56,8 @@ func setBase() error { if err != nil { return err } + + defaultLanguage = initializers.GetEnv("DEFAULT_LANGUAGE", defaultLanguage) return nil } @@ -69,6 +76,7 @@ func LoadConfig() error { VoucherTransfersURL, _ = url.JoinPath(dataURLBase, voucherTransfersPathPrefix) VoucherDataURL, _ = url.JoinPath(dataURLBase, voucherDataPathPrefix) CheckAliasURL, _ = url.JoinPath(dataURLBase, AliasPrefix) + DefaultLanguage = defaultLanguage return nil } diff --git a/internal/args/lang.go b/internal/args/lang.go new file mode 100644 index 0000000..f9afdc9 --- /dev/null +++ b/internal/args/lang.go @@ -0,0 +1,34 @@ +package args + +import ( + "strings" + + "git.defalsify.org/vise.git/lang" +) + +type LangVar struct { + v []lang.Language +} + +func(lv *LangVar) Set(s string) error { + v, err := lang.LanguageFromCode(s) + if err != nil { + return err + } + lv.v = append(lv.v, v) + return err +} + +func(lv *LangVar) String() string { + var s []string + for _, v := range(lv.v) { + s = append(s, v.Code) + } + return strings.Join(s, ",") +} + +func(lv *LangVar) Langs() []lang.Language { + return lv.v +} + + diff --git a/internal/storage/storageservice.go b/internal/storage/storageservice.go index ca28bbb..e420dee 100644 --- a/internal/storage/storageservice.go +++ b/internal/storage/storageservice.go @@ -9,6 +9,7 @@ import ( "git.defalsify.org/vise.git/db" fsdb "git.defalsify.org/vise.git/db/fs" "git.defalsify.org/vise.git/db/postgres" + "git.defalsify.org/vise.git/lang" "git.defalsify.org/vise.git/logging" "git.defalsify.org/vise.git/persist" "git.defalsify.org/vise.git/resource" @@ -29,6 +30,7 @@ type StorageService interface { type MenuStorageService struct { dbDir string resourceDir string + poResource resource.Resource resourceStore db.Db stateStore db.Db userDataStore db.Db @@ -57,6 +59,22 @@ func NewMenuStorageService(dbDir string, resourceDir string) *MenuStorageService } } +func (ms *MenuStorageService) WithGettext(path string, lns []lang.Language) *MenuStorageService { + ln := lang.Language{ + Code: "xxx", + Name: "Translation key", + } + rs := resource.NewPoResource(ln, path) + + for _, ln = range(lns) { + rs = rs.WithLanguage(ln) + } + + ms.poResource = rs + + return ms +} + func (ms *MenuStorageService) getOrCreateDb(ctx context.Context, existingDb db.Db, fileName string) (db.Db, error) { database, ok := ctx.Value("Database").(string) if !ok { @@ -119,6 +137,10 @@ func (ms *MenuStorageService) GetResource(ctx context.Context) (resource.Resourc return nil, err } rfs := resource.NewDbResource(ms.resourceStore) + if ms.poResource != nil { + rfs.WithMenuGetter(ms.poResource.GetMenu) + rfs.WithTemplateGetter(ms.poResource.GetTemplate) + } return rfs, nil } From 06230dc557b71e304a824f0eaf42b66bf5233310 Mon Sep 17 00:00:00 2001 From: lash Date: Thu, 2 Jan 2025 14:31:13 +0000 Subject: [PATCH 02/11] Add todo comment --- cmd/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/main.go b/cmd/main.go index e6f96ab..2737c84 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -29,6 +29,7 @@ func init() { initializers.LoadEnvVariables() } +// TODO: external script automatically generate language handler list from select language vise code OR consider dynamic menu generation script possibility func main() { config.LoadConfig() From 43b2c3b78d4d49f792f143ac91faf265095454d0 Mon Sep 17 00:00:00 2001 From: lash Date: Thu, 2 Jan 2025 18:13:37 +0000 Subject: [PATCH 03/11] Rehabilitate gettext resource --- go.mod | 2 +- go.sum | 4 ++-- internal/storage/storageservice.go | 17 ++++++++++++----- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 16ccdc3..09d2cd5 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.grassecon.net/urdt/ussd go 1.23.0 require ( - git.defalsify.org/vise.git v0.2.3-0.20241231085136-8582c7e157d9 + git.defalsify.org/vise.git v0.2.3-0.20250102175429-e5b5bc34a2be github.com/alecthomas/assert/v2 v2.2.2 github.com/gofrs/uuid v4.4.0+incompatible github.com/grassrootseconomics/eth-custodial v1.3.0-beta diff --git a/go.sum b/go.sum index 9086cd8..29b3893 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -git.defalsify.org/vise.git v0.2.3-0.20241231085136-8582c7e157d9 h1:O3m+NgWDWtJm8OculT99c4bDMAO4xLe2c8hpCKpsd9g= -git.defalsify.org/vise.git v0.2.3-0.20241231085136-8582c7e157d9/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck= +git.defalsify.org/vise.git v0.2.3-0.20250102175429-e5b5bc34a2be h1:bh+VQanntFrMjQA/ZPRv5Wlist4e743EbiBvK1l9Qac= +git.defalsify.org/vise.git v0.2.3-0.20250102175429-e5b5bc34a2be/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck= github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= github.com/alecthomas/participle/v2 v2.0.0 h1:Fgrq+MbuSsJwIkw3fEj9h75vDP0Er5JzepJ0/HNHv0g= diff --git a/internal/storage/storageservice.go b/internal/storage/storageservice.go index e420dee..451358e 100644 --- a/internal/storage/storageservice.go +++ b/internal/storage/storageservice.go @@ -59,14 +59,20 @@ func NewMenuStorageService(dbDir string, resourceDir string) *MenuStorageService } } +// WithGettext triggers use of gettext for translation of templates and menus. +// +// The first language in `lns` will be used as default language, to resolve node keys to +// language strings. +// +// If `lns` is an empty array, gettext will not be used. func (ms *MenuStorageService) WithGettext(path string, lns []lang.Language) *MenuStorageService { - ln := lang.Language{ - Code: "xxx", - Name: "Translation key", + if len(lns) == 0 { + logg.Warnf("Gettext requested but no languages supplied") + return ms } - rs := resource.NewPoResource(ln, path) + rs := resource.NewPoResource(lns[0], path) - for _, ln = range(lns) { + for _, ln := range(lns) { rs = rs.WithLanguage(ln) } @@ -138,6 +144,7 @@ func (ms *MenuStorageService) GetResource(ctx context.Context) (resource.Resourc } rfs := resource.NewDbResource(ms.resourceStore) if ms.poResource != nil { + logg.InfoCtxf(ctx, "using poresource for menu and template") rfs.WithMenuGetter(ms.poResource.GetMenu) rfs.WithTemplateGetter(ms.poResource.GetTemplate) } From b888af446d44c0dace1387f7ec56f94e2a391c7c Mon Sep 17 00:00:00 2001 From: lash Date: Thu, 2 Jan 2025 18:49:16 +0000 Subject: [PATCH 04/11] update govise --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 09d2cd5..780f0e6 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.grassecon.net/urdt/ussd go 1.23.0 require ( - git.defalsify.org/vise.git v0.2.3-0.20250102175429-e5b5bc34a2be + git.defalsify.org/vise.git v0.2.3-0.20250102184614-1c71081a3b57 github.com/alecthomas/assert/v2 v2.2.2 github.com/gofrs/uuid v4.4.0+incompatible github.com/grassrootseconomics/eth-custodial v1.3.0-beta diff --git a/go.sum b/go.sum index 29b3893..812dc15 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -git.defalsify.org/vise.git v0.2.3-0.20250102175429-e5b5bc34a2be h1:bh+VQanntFrMjQA/ZPRv5Wlist4e743EbiBvK1l9Qac= -git.defalsify.org/vise.git v0.2.3-0.20250102175429-e5b5bc34a2be/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck= +git.defalsify.org/vise.git v0.2.3-0.20250102184614-1c71081a3b57 h1:fBGbWr7AMPj5gEyZmMwLaaaIFNvxAhY7fteDFolGMlw= +git.defalsify.org/vise.git v0.2.3-0.20250102184614-1c71081a3b57/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck= github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= github.com/alecthomas/participle/v2 v2.0.0 h1:Fgrq+MbuSsJwIkw3fEj9h75vDP0Er5JzepJ0/HNHv0g= From 6723884103f93827457c3294fa5984c157aec745 Mon Sep 17 00:00:00 2001 From: lash Date: Thu, 2 Jan 2025 21:02:01 +0000 Subject: [PATCH 05/11] Update go-vise --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 780f0e6..9862ff0 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.grassecon.net/urdt/ussd go 1.23.0 require ( - git.defalsify.org/vise.git v0.2.3-0.20250102184614-1c71081a3b57 + git.defalsify.org/vise.git v0.2.3-0.20250102205756-049511818ec7 github.com/alecthomas/assert/v2 v2.2.2 github.com/gofrs/uuid v4.4.0+incompatible github.com/grassrootseconomics/eth-custodial v1.3.0-beta diff --git a/go.sum b/go.sum index 812dc15..59b2258 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -git.defalsify.org/vise.git v0.2.3-0.20250102184614-1c71081a3b57 h1:fBGbWr7AMPj5gEyZmMwLaaaIFNvxAhY7fteDFolGMlw= -git.defalsify.org/vise.git v0.2.3-0.20250102184614-1c71081a3b57/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck= +git.defalsify.org/vise.git v0.2.3-0.20250102205756-049511818ec7 h1:/PLEm5DCJXwlgDsQ36s20qfdlKIwdBfTGmFYqsIy29E= +git.defalsify.org/vise.git v0.2.3-0.20250102205756-049511818ec7/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck= github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= github.com/alecthomas/participle/v2 v2.0.0 h1:Fgrq+MbuSsJwIkw3fEj9h75vDP0Er5JzepJ0/HNHv0g= From c1e0617bb317e398487db8d33744c1542611e100 Mon Sep 17 00:00:00 2001 From: lash Date: Thu, 2 Jan 2025 21:13:06 +0000 Subject: [PATCH 06/11] Update go-vise --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9862ff0..6ddb811 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.grassecon.net/urdt/ussd go 1.23.0 require ( - git.defalsify.org/vise.git v0.2.3-0.20250102205756-049511818ec7 + git.defalsify.org/vise.git v0.2.3-0.20250102211200-fd3db37d2626 github.com/alecthomas/assert/v2 v2.2.2 github.com/gofrs/uuid v4.4.0+incompatible github.com/grassrootseconomics/eth-custodial v1.3.0-beta diff --git a/go.sum b/go.sum index 59b2258..58b405f 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -git.defalsify.org/vise.git v0.2.3-0.20250102205756-049511818ec7 h1:/PLEm5DCJXwlgDsQ36s20qfdlKIwdBfTGmFYqsIy29E= -git.defalsify.org/vise.git v0.2.3-0.20250102205756-049511818ec7/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck= +git.defalsify.org/vise.git v0.2.3-0.20250102211200-fd3db37d2626 h1:ANfeAGxCtjDtkzHNesttnI7CtF0zjhhxsTZj0+ipq9s= +git.defalsify.org/vise.git v0.2.3-0.20250102211200-fd3db37d2626/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck= github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= github.com/alecthomas/participle/v2 v2.0.0 h1:Fgrq+MbuSsJwIkw3fEj9h75vDP0Er5JzepJ0/HNHv0g= From 1b12f0ba5f0f62ff006a8a0b6e05edcf6592901f Mon Sep 17 00:00:00 2001 From: lash Date: Fri, 3 Jan 2025 10:00:52 +0000 Subject: [PATCH 07/11] Add po language alternative to all runners --- cmd/africastalking/main.go | 13 +++++++++++++ cmd/async/main.go | 14 ++++++++++++++ cmd/http/main.go | 14 ++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/cmd/africastalking/main.go b/cmd/africastalking/main.go index ca88978..9f42199 100644 --- a/cmd/africastalking/main.go +++ b/cmd/africastalking/main.go @@ -18,6 +18,7 @@ import ( "git.defalsify.org/vise.git/engine" "git.defalsify.org/vise.git/logging" "git.defalsify.org/vise.git/resource" + "git.defalsify.org/vise.git/lang" "git.grassecon.net/urdt/ussd/common" "git.grassecon.net/urdt/ussd/config" @@ -26,6 +27,7 @@ import ( httpserver "git.grassecon.net/urdt/ussd/internal/http" "git.grassecon.net/urdt/ussd/internal/storage" "git.grassecon.net/urdt/ussd/remote" + "git.grassecon.net/urdt/ussd/internal/args" ) var ( @@ -114,6 +116,8 @@ func main() { var engineDebug bool var host string var port uint + var gettextDir string + var langs args.LangVar flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from") flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir") flag.StringVar(&database, "db", "gdbm", "database to be used") @@ -121,12 +125,21 @@ func main() { flag.UintVar(&size, "s", 160, "max size of output") flag.StringVar(&host, "h", initializers.GetEnv("HOST", "127.0.0.1"), "http host") flag.UintVar(&port, "p", initializers.GetEnvUint("PORT", 7123), "http port") + flag.StringVar(&gettextDir, "gettext", "", "use gettext translations from given directory") + flag.Var(&langs, "language", "add symbol resolution for language") flag.Parse() logg.Infof("start command", "build", build, "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size) ctx := context.Background() ctx = context.WithValue(ctx, "Database", database) + ln, err := lang.LanguageFromCode(config.DefaultLanguage) + if err != nil { + fmt.Fprintf(os.Stderr, "default language set error: %v", err) + os.Exit(1) + } + ctx = context.WithValue(ctx, "Language", ln) + pfp := path.Join(scriptDir, "pp.csv") cfg := engine.Config{ diff --git a/cmd/async/main.go b/cmd/async/main.go index 9cd04b3..de2a85b 100644 --- a/cmd/async/main.go +++ b/cmd/async/main.go @@ -12,12 +12,14 @@ import ( "git.defalsify.org/vise.git/engine" "git.defalsify.org/vise.git/logging" "git.defalsify.org/vise.git/resource" + "git.defalsify.org/vise.git/lang" "git.grassecon.net/urdt/ussd/config" "git.grassecon.net/urdt/ussd/initializers" "git.grassecon.net/urdt/ussd/internal/handlers" "git.grassecon.net/urdt/ussd/internal/storage" "git.grassecon.net/urdt/ussd/remote" + "git.grassecon.net/urdt/ussd/internal/args" ) var ( @@ -54,6 +56,8 @@ func main() { var engineDebug bool var host string var port uint + var gettextDir string + var langs args.LangVar flag.StringVar(&sessionId, "session-id", "075xx2123", "session id") flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from") flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir") @@ -62,12 +66,22 @@ func main() { flag.UintVar(&size, "s", 160, "max size of output") flag.StringVar(&host, "h", initializers.GetEnv("HOST", "127.0.0.1"), "http host") flag.UintVar(&port, "p", initializers.GetEnvUint("PORT", 7123), "http port") + flag.StringVar(&gettextDir, "gettext", "", "use gettext translations from given directory") + flag.Var(&langs, "language", "add symbol resolution for language") flag.Parse() logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size, "sessionId", sessionId) ctx := context.Background() ctx = context.WithValue(ctx, "Database", database) + + ln, err := lang.LanguageFromCode(config.DefaultLanguage) + if err != nil { + fmt.Fprintf(os.Stderr, "default language set error: %v", err) + os.Exit(1) + } + ctx = context.WithValue(ctx, "Language", ln) + pfp := path.Join(scriptDir, "pp.csv") cfg := engine.Config{ diff --git a/cmd/http/main.go b/cmd/http/main.go index 6ddfded..c47447a 100644 --- a/cmd/http/main.go +++ b/cmd/http/main.go @@ -14,6 +14,7 @@ import ( "git.defalsify.org/vise.git/engine" "git.defalsify.org/vise.git/logging" "git.defalsify.org/vise.git/resource" + "git.defalsify.org/vise.git/lang" "git.grassecon.net/urdt/ussd/config" "git.grassecon.net/urdt/ussd/initializers" @@ -21,6 +22,7 @@ import ( httpserver "git.grassecon.net/urdt/ussd/internal/http" "git.grassecon.net/urdt/ussd/internal/storage" "git.grassecon.net/urdt/ussd/remote" + "git.grassecon.net/urdt/ussd/internal/args" ) var ( @@ -43,6 +45,8 @@ func main() { var engineDebug bool var host string var port uint + var gettextDir string + var langs args.LangVar flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from") flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir") flag.StringVar(&database, "db", "gdbm", "database to be used") @@ -50,12 +54,22 @@ func main() { flag.UintVar(&size, "s", 160, "max size of output") flag.StringVar(&host, "h", initializers.GetEnv("HOST", "127.0.0.1"), "http host") flag.UintVar(&port, "p", initializers.GetEnvUint("PORT", 7123), "http port") + flag.StringVar(&gettextDir, "gettext", "", "use gettext translations from given directory") + flag.Var(&langs, "language", "add symbol resolution for language") flag.Parse() logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size) ctx := context.Background() ctx = context.WithValue(ctx, "Database", database) + + ln, err := lang.LanguageFromCode(config.DefaultLanguage) + if err != nil { + fmt.Fprintf(os.Stderr, "default language set error: %v", err) + os.Exit(1) + } + ctx = context.WithValue(ctx, "Language", ln) + pfp := path.Join(scriptDir, "pp.csv") cfg := engine.Config{ From e16b7445e8841f5fe4f4cc00f7095b2c320cb296 Mon Sep 17 00:00:00 2001 From: lash Date: Fri, 3 Jan 2025 10:28:27 +0000 Subject: [PATCH 08/11] Move arg var to same spot as other runners --- cmd/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/main.go b/cmd/main.go index 2737c84..a61176d 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -34,11 +34,11 @@ func main() { config.LoadConfig() var dbDir string - var gettextDir string var size uint var sessionId string var database string var engineDebug bool + var gettextDir string var langs args.LangVar flag.StringVar(&sessionId, "session-id", "075xx2123", "session id") flag.StringVar(&database, "db", "gdbm", "database to be used") From 056d0566138fac247bcf25d53003ad41d4fa2bdb Mon Sep 17 00:00:00 2001 From: lash Date: Fri, 3 Jan 2025 14:43:08 +0000 Subject: [PATCH 09/11] Add language source and template file generator --- config/config.go | 28 +++++++++- devtools/lang/main.go | 126 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 devtools/lang/main.go diff --git a/config/config.go b/config/config.go index 6575310..02fdaab 100644 --- a/config/config.go +++ b/config/config.go @@ -2,6 +2,7 @@ package config import ( "net/url" + "strings" "git.grassecon.net/urdt/ussd/initializers" ) @@ -20,6 +21,7 @@ const ( var ( defaultLanguage = "eng" + languages []string ) var ( @@ -39,8 +41,27 @@ var ( VoucherDataURL string CheckAliasURL string DefaultLanguage string + Languages []string ) +func setLanguage() error { + defaultLanguage = initializers.GetEnv("DEFAULT_LANGUAGE", defaultLanguage) + languages = strings.Split(initializers.GetEnv("LANGUAGES", defaultLanguage), ",") + haveDefaultLanguage := false + for i, v := range(languages) { + languages[i] = strings.ReplaceAll(v, " ", "") + if languages[i] == defaultLanguage { + haveDefaultLanguage = true + } + } + + if !haveDefaultLanguage { + languages = append([]string{defaultLanguage}, languages...) + } + + return nil +} + func setBase() error { var err error @@ -56,8 +77,6 @@ func setBase() error { if err != nil { return err } - - defaultLanguage = initializers.GetEnv("DEFAULT_LANGUAGE", defaultLanguage) return nil } @@ -67,6 +86,10 @@ func LoadConfig() error { if err != nil { return err } + err = setLanguage() + if err != nil { + return err + } CreateAccountURL, _ = url.JoinPath(custodialURLBase, createAccountPath) TrackStatusURL, _ = url.JoinPath(custodialURLBase, trackStatusPath) BalanceURL, _ = url.JoinPath(custodialURLBase, balancePathPrefix) @@ -77,6 +100,7 @@ func LoadConfig() error { VoucherDataURL, _ = url.JoinPath(dataURLBase, voucherDataPathPrefix) CheckAliasURL, _ = url.JoinPath(dataURLBase, AliasPrefix) DefaultLanguage = defaultLanguage + Languages = languages return nil } diff --git a/devtools/lang/main.go b/devtools/lang/main.go new file mode 100644 index 0000000..81655f0 --- /dev/null +++ b/devtools/lang/main.go @@ -0,0 +1,126 @@ +package main + +import ( + "flag" + "fmt" + "os" + "path" + "strings" + + "git.defalsify.org/vise.git/logging" + "git.defalsify.org/vise.git/lang" + "git.grassecon.net/urdt/ussd/config" + "git.grassecon.net/urdt/ussd/initializers" +) + +const ( + + changeHeadSrc = `LOAD reset_account_authorized 0 +LOAD reset_incorrect 0 +CATCH incorrect_pin flag_incorrect_pin 1 +CATCH pin_entry flag_account_authorized 0 +` + + selectSrc = `LOAD set_language 6 +RELOAD set_language +CATCH terms flag_account_created 0 +MOVE language_changed +` +) + +var ( + logg = logging.NewVanilla() + mouts string + incmps string +) + +func init() { + initializers.LoadEnvVariables() +} + +func toLanguageLabel(ln lang.Language) string { + s := ln.Name + v := strings.Split(s, " (") + if len(v) > 1 { + s = v[0] + } + return s +} + +func toLanguageKey(ln lang.Language) string { + s := toLanguageLabel(ln) + return strings.ToLower(s) +} + +func main() { + var srcDir string + + flag.StringVar(&srcDir, "o", ".", "resource dir write to") + flag.Parse() + + logg.Infof("start command", "dir", srcDir) + + err := config.LoadConfig() + if err != nil { + fmt.Fprintf(os.Stderr, "config load error: %v", err) + os.Exit(1) + } + logg.Tracef("using languages", "lang", config.Languages) + + for i, v := range(config.Languages) { + ln, err := lang.LanguageFromCode(v) + if err != nil { + fmt.Fprintf(os.Stderr, "error parsing language: %s", v) + os.Exit(1) + } + n := i + 1 + s := toLanguageKey(ln) + mouts += fmt.Sprintf("MOUT %s %v\n", s, n) + //incmp += fmt.Sprintf("INCMP set_%s %u\n", + v = "set_" + ln.Code + incmps += fmt.Sprintf("INCMP %s %v\n", v, n) + + p := path.Join(srcDir, v) + w, err := os.OpenFile(p, os.O_WRONLY | os.O_CREATE | os.O_TRUNC, 0600) + if err != nil { + fmt.Fprintf(os.Stderr, "failed open language set template output: %v", err) + os.Exit(1) + } + s = toLanguageLabel(ln) + defer w.Close() + _, err = w.Write([]byte(s)) + if err != nil { + fmt.Fprintf(os.Stderr, "failed write select language vis output: %v", err) + os.Exit(1) + } + } + src := mouts + "HALT\n" + incmps + src += "INCMP . *\n" + + p := path.Join(srcDir, "select_language.vis") + w, err := os.OpenFile(p, os.O_WRONLY | os.O_CREATE | os.O_TRUNC, 0600) + if err != nil { + fmt.Fprintf(os.Stderr, "failed open select language vis output: %v", err) + os.Exit(1) + } + defer w.Close() + _, err = w.Write([]byte(src)) + if err != nil { + fmt.Fprintf(os.Stderr, "failed write select language vis output: %v", err) + os.Exit(1) + } + + src = changeHeadSrc + src + p = path.Join(srcDir, "change_language.vis") + w, err = os.OpenFile(p, os.O_WRONLY | os.O_CREATE | os.O_TRUNC, 0600) + if err != nil { + fmt.Fprintf(os.Stderr, "failed open select language vis output: %v", err) + os.Exit(1) + } + defer w.Close() + _, err = w.Write([]byte(src)) + if err != nil { + fmt.Fprintf(os.Stderr, "failed write select language vis output: %v", err) + os.Exit(1) + } +} From 9013cc3618e2968029c2b3923b646fbe68766dd1 Mon Sep 17 00:00:00 2001 From: lash Date: Fri, 3 Jan 2025 15:10:20 +0000 Subject: [PATCH 10/11] Improve error messages --- devtools/lang/main.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/devtools/lang/main.go b/devtools/lang/main.go index 81655f0..83c68b3 100644 --- a/devtools/lang/main.go +++ b/devtools/lang/main.go @@ -1,3 +1,4 @@ +// create language files from environment package main import ( @@ -70,27 +71,26 @@ func main() { for i, v := range(config.Languages) { ln, err := lang.LanguageFromCode(v) if err != nil { - fmt.Fprintf(os.Stderr, "error parsing language: %s", v) + fmt.Fprintf(os.Stderr, "error parsing language: %s\n", v) os.Exit(1) } n := i + 1 s := toLanguageKey(ln) mouts += fmt.Sprintf("MOUT %s %v\n", s, n) - //incmp += fmt.Sprintf("INCMP set_%s %u\n", v = "set_" + ln.Code incmps += fmt.Sprintf("INCMP %s %v\n", v, n) p := path.Join(srcDir, v) - w, err := os.OpenFile(p, os.O_WRONLY | os.O_CREATE | os.O_TRUNC, 0600) + w, err := os.OpenFile(p, os.O_WRONLY | os.O_CREATE | os.O_EXCL, 0600) if err != nil { - fmt.Fprintf(os.Stderr, "failed open language set template output: %v", err) + fmt.Fprintf(os.Stderr, "failed open language set template output: %v\n", err) os.Exit(1) } s = toLanguageLabel(ln) defer w.Close() _, err = w.Write([]byte(s)) if err != nil { - fmt.Fprintf(os.Stderr, "failed write select language vis output: %v", err) + fmt.Fprintf(os.Stderr, "failed write select language vis output: %v\n", err) os.Exit(1) } } @@ -98,29 +98,29 @@ func main() { src += "INCMP . *\n" p := path.Join(srcDir, "select_language.vis") - w, err := os.OpenFile(p, os.O_WRONLY | os.O_CREATE | os.O_TRUNC, 0600) + w, err := os.OpenFile(p, os.O_WRONLY | os.O_CREATE | os.O_EXCL, 0600) if err != nil { - fmt.Fprintf(os.Stderr, "failed open select language vis output: %v", err) + fmt.Fprintf(os.Stderr, "failed open select language vis output: %v\n", err) os.Exit(1) } defer w.Close() _, err = w.Write([]byte(src)) if err != nil { - fmt.Fprintf(os.Stderr, "failed write select language vis output: %v", err) + fmt.Fprintf(os.Stderr, "failed write select language vis output: %v\n", err) os.Exit(1) } src = changeHeadSrc + src p = path.Join(srcDir, "change_language.vis") - w, err = os.OpenFile(p, os.O_WRONLY | os.O_CREATE | os.O_TRUNC, 0600) + w, err = os.OpenFile(p, os.O_WRONLY | os.O_CREATE | os.O_EXCL, 0600) if err != nil { - fmt.Fprintf(os.Stderr, "failed open select language vis output: %v", err) + fmt.Fprintf(os.Stderr, "failed open select language vis output: %v\n", err) os.Exit(1) } defer w.Close() _, err = w.Write([]byte(src)) if err != nil { - fmt.Fprintf(os.Stderr, "failed write select language vis output: %v", err) + fmt.Fprintf(os.Stderr, "failed write select language vis output: %v\n", err) os.Exit(1) } } From bb4037e73f6c1c3f4b8a65e21298b5c6d399c2ad Mon Sep 17 00:00:00 2001 From: lash Date: Sun, 5 Jan 2025 21:25:09 +0000 Subject: [PATCH 11/11] Add languages env example --- .env.example | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.env.example b/.env.example index c636fa8..f60c1aa 100644 --- a/.env.example +++ b/.env.example @@ -18,3 +18,7 @@ DB_TIMEZONE=Africa/Nairobi CUSTODIAL_URL_BASE=http://localhost:5003 BEARER_TOKEN=eyJeSIsInRcCI6IkpXVCJ.yJwdWJsaWNLZXkiOiIwrrrrrr DATA_URL_BASE=http://localhost:5006 + +#Language +DEFAULT_LANGUAGE=eng +LANGUAGES=eng, swa