From a41318d822aeb8d433b253df3400d154b48f5500 Mon Sep 17 00:00:00 2001 From: Philipp Wolfer Date: Sat, 9 Dec 2023 11:46:32 +0100 Subject: [PATCH] Basic i18n setup --- go.mod | 3 +- go.sum | 12 ++ internal/cli/transfer.go | 19 +- internal/i18n/i18n.go | 39 ++++ internal/i18n/localizer.go | 37 ++++ internal/translations/catalog.go | 75 ++++++++ .../locales/de/messages.gotext.json | 164 ++++++++++++++++ .../translations/locales/de/out.gotext.json | 164 ++++++++++++++++ .../translations/locales/en/out.gotext.json | 178 ++++++++++++++++++ internal/translations/translations.go | 18 ++ 10 files changed, 700 insertions(+), 9 deletions(-) create mode 100644 internal/i18n/i18n.go create mode 100644 internal/i18n/localizer.go create mode 100644 internal/translations/catalog.go create mode 100644 internal/translations/locales/de/messages.gotext.json create mode 100644 internal/translations/locales/de/out.gotext.json create mode 100644 internal/translations/locales/en/out.gotext.json create mode 100644 internal/translations/translations.go diff --git a/go.mod b/go.mod index a827f0f..4c5487f 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module go.uploadedlobster.com/scotty go 1.21.1 require ( + github.com/Xuanwo/go-locale v1.1.0 github.com/cli/browser v1.3.0 github.com/delucks/go-subsonic v0.0.0-20220915164742-2744002c4be5 github.com/fatih/color v1.16.0 @@ -19,6 +20,7 @@ require ( github.com/vbauerster/mpb/v8 v8.6.2 golang.org/x/exp v0.0.0-20230905200255-921286631fa9 golang.org/x/oauth2 v0.14.0 + golang.org/x/text v0.14.0 gorm.io/datatypes v1.2.0 gorm.io/gorm v1.25.5 ) @@ -56,7 +58,6 @@ require ( go.uber.org/multierr v1.9.0 // indirect golang.org/x/net v0.18.0 // indirect golang.org/x/sys v0.14.0 // indirect - golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 91c80bb..fd1332d 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= +github.com/Xuanwo/go-locale v1.1.0 h1:51gUxhxl66oXAjI9uPGb2O0qwPECpriKQb2hl35mQkg= +github.com/Xuanwo/go-locale v1.1.0/go.mod h1:UKrHoZB3FPIk9wIG2/tVSobnHgNnceGSH3Y8DY5cASs= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -155,6 +157,8 @@ github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -178,6 +182,8 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -229,6 +235,10 @@ github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6g github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/shkh/lastfm-go v0.0.0-20191215035245-89a801c244e0 h1:cgqwZtnR+IQfUYDLJ3Kiy4aE+O/wExTzEIg8xwC4Qfs= github.com/shkh/lastfm-go v0.0.0-20191215035245-89a801c244e0/go.mod h1:n3nudMl178cEvD44PaopxH9jhJaQzthSxUzLO5iKMy4= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.7 h1:I6tZjLXD2Q1kjvNbIzB1wvQBsXmKXiVrhpRE8ZjP5jY= +github.com/smartystreets/goconvey v1.6.7/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= @@ -416,6 +426,7 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211023085530-d6a326fbbf70/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -455,6 +466,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= diff --git a/internal/cli/transfer.go b/internal/cli/transfer.go index 0ad67f1..e073864 100644 --- a/internal/cli/transfer.go +++ b/internal/cli/transfer.go @@ -24,6 +24,7 @@ import ( "github.com/spf13/viper" "go.uploadedlobster.com/scotty/internal/backends" "go.uploadedlobster.com/scotty/internal/config" + "go.uploadedlobster.com/scotty/internal/i18n" "go.uploadedlobster.com/scotty/internal/models" "go.uploadedlobster.com/scotty/internal/storage" ) @@ -84,7 +85,7 @@ func (c *TransferCmd[E, I, R]) resolveBackends(source string, target string) err } func (c *TransferCmd[E, I, R]) Transfer(exp backends.ExportProcessor[R], imp backends.ImportProcessor[R]) error { - fmt.Printf("Transferring %s from %s to %s...\n", c.entity, c.sourceName, c.targetName) + fmt.Println(i18n.Tr("Transferring %s from %s to %s...", c.entity, c.sourceName, c.targetName)) // Authenticate backends, if needed config := viper.GetViper() @@ -103,7 +104,7 @@ func (c *TransferCmd[E, I, R]) Transfer(exp backends.ExportProcessor[R], imp bac if err != nil { return err } - fmt.Printf("From timestamp: %v (%v)\n", timestamp, timestamp.Unix()) + fmt.Println(i18n.Tr("From timestamp: %v (%v)", timestamp, timestamp.Unix())) // Prepare progress bars exportProgress := make(chan models.Progress) @@ -123,11 +124,12 @@ func (c *TransferCmd[E, I, R]) Transfer(exp backends.ExportProcessor[R], imp bac wg.Wait() progress.Wait() if result.Error != nil { - fmt.Printf("Import failed, last reported timestamp was %v (%v)\n", result.LastTimestamp, result.LastTimestamp.Unix()) + fmt.Println(i18n.Tr("Import failed, last reported timestamp was %v (%v)", + result.LastTimestamp, result.LastTimestamp.Unix())) return result.Error } - fmt.Printf("Imported %v of %v %s into %v.\n", - result.ImportCount, result.TotalCount, c.entity, c.targetName) + fmt.Println(i18n.Tr("Imported %v of %v %s into %v.", + result.ImportCount, result.TotalCount, c.entity, c.targetName)) // Update timestamp err = c.updateTimestamp(result, timestamp) @@ -137,9 +139,10 @@ func (c *TransferCmd[E, I, R]) Transfer(exp backends.ExportProcessor[R], imp bac // Print errors if len(result.ImportErrors) > 0 { - fmt.Printf("\nDuring the import the following errors occurred:\n") + fmt.Println() + fmt.Println(i18n.Tr("During the import the following errors occurred:")) for _, err := range result.ImportErrors { - fmt.Printf("Error: %v\n", err) + fmt.Println(i18n.Tr("Error: %v\n", err)) } } @@ -159,7 +162,7 @@ func (c *TransferCmd[E, I, R]) updateTimestamp(result models.ImportResult, oldTi if result.LastTimestamp.Unix() < oldTimestamp.Unix() { result.LastTimestamp = oldTimestamp } - fmt.Printf("Latest timestamp: %v (%v)\n", result.LastTimestamp, result.LastTimestamp.Unix()) + fmt.Println(i18n.Tr("Latest timestamp: %v (%v)\n", result.LastTimestamp, result.LastTimestamp.Unix())) err := c.db.SetImportTimestamp(c.sourceName, c.targetName, c.entity, result.LastTimestamp) return err } diff --git a/internal/i18n/i18n.go b/internal/i18n/i18n.go new file mode 100644 index 0000000..cbfd516 --- /dev/null +++ b/internal/i18n/i18n.go @@ -0,0 +1,39 @@ +/* +Copyright © 2023 Philipp Wolfer + +Scotty is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later version. + +Scotty is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +Scotty. If not, see . +*/ + +package i18n + +import ( + "log" + + "github.com/Xuanwo/go-locale" + _ "go.uploadedlobster.com/scotty/internal/translations" + + "golang.org/x/text/message" +) + +var localizer Localizer + +func init() { + tag, err := locale.Detect() + if err != nil { + log.Fatal(err) + } + localizer = New(tag) +} + +func Tr(key message.Reference, args ...interface{}) string { + return localizer.Translate(key, args...) +} diff --git a/internal/i18n/localizer.go b/internal/i18n/localizer.go new file mode 100644 index 0000000..7e839a2 --- /dev/null +++ b/internal/i18n/localizer.go @@ -0,0 +1,37 @@ +/* +Copyright © 2023 Philipp Wolfer + +Scotty is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later version. + +Scotty is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +Scotty. If not, see . +*/ + +package i18n + +import ( + "golang.org/x/text/language" + "golang.org/x/text/message" +) + +type Localizer struct { + printer *message.Printer +} + +// Create a new Localizer for a language tag +func New(lang language.Tag) Localizer { + return Localizer{ + printer: message.NewPrinter(lang), + } +} + +// Return the translated string, with variables replaced. +func (l Localizer) Translate(key message.Reference, args ...interface{}) string { + return l.printer.Sprintf(key, args...) +} diff --git a/internal/translations/catalog.go b/internal/translations/catalog.go new file mode 100644 index 0000000..276eb87 --- /dev/null +++ b/internal/translations/catalog.go @@ -0,0 +1,75 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package translations + +import ( + "golang.org/x/text/language" + "golang.org/x/text/message" + "golang.org/x/text/message/catalog" +) + +type dictionary struct { + index []uint32 + data string +} + +func (d *dictionary) Lookup(key string) (data string, ok bool) { + p, ok := messageKeyToIndex[key] + if !ok { + return "", false + } + start, end := d.index[p], d.index[p+1] + if start == end { + return "", false + } + return d.data[start:end], true +} + +func init() { + dict := map[string]catalog.Dictionary{ + "de": &dictionary{index: deIndex, data: deData}, + "en": &dictionary{index: enIndex, data: enData}, + } + fallback := language.MustParse("en") + cat, err := catalog.NewFromMap(dict, catalog.Fallback(fallback)) + if err != nil { + panic(err) + } + message.DefaultCatalog = cat +} + +var messageKeyToIndex = map[string]int{ + "During the import the following errors occurred:": 4, + "Error: %v\n": 5, + "From timestamp: %v (%v)": 1, + "Import failed, last reported timestamp was %v (%v)": 2, + "Imported %v of %v %s into %v.": 3, + "Latest timestamp: %v (%v)\n": 6, + "Transferring %s from %s to %s...": 0, +} + +var deIndex = []uint32{ // 8 elements + 0x00000000, 0x00000029, 0x00000047, 0x00000087, + 0x000000b2, 0x000000e9, 0x000000fc, 0x00000125, +} // Size: 56 bytes + +const deData string = "" + // Size: 293 bytes + "\x02Übertrage %[1]s von %[2]s nach %[3]s...\x02Ab Zeitstempel: %[1]v (%[" + + "2]v)\x02Import fehlgeschlagen, der letzte Zeitstempel war %[1]v (%[2]v)" + + "\x02%[1]v von %[2]v %[3]s in %[4]v importiert.\x02Während des Imports si" + + "nd folgende Fehler aufgetreten:\x04\x00\x01\x0a\x0e\x02Fehler: %[1]v\x04" + + "\x00\x01\x0a$\x02Neuester Zeitstempel: %[1]v (%[2]v)" + +var enIndex = []uint32{ // 8 elements + 0x00000000, 0x0000002a, 0x00000048, 0x00000081, + 0x000000ab, 0x000000dc, 0x000000ee, 0x00000113, +} // Size: 56 bytes + +const enData string = "" + // Size: 275 bytes + "\x02Transferring %[1]s from %[2]s to %[3]s...\x02From timestamp: %[1]v (" + + "%[2]v)\x02Import failed, last reported timestamp was %[1]v (%[2]v)\x02Im" + + "ported %[1]v of %[2]v %[3]s into %[4]v.\x02During the import the followi" + + "ng errors occurred:\x04\x00\x01\x0a\x0d\x02Error: %[1]v\x04\x00\x01\x0a " + + "\x02Latest timestamp: %[1]v (%[2]v)" + + // Total table size 680 bytes (0KiB); checksum: D0CBF9F5 diff --git a/internal/translations/locales/de/messages.gotext.json b/internal/translations/locales/de/messages.gotext.json new file mode 100644 index 0000000..7e8940e --- /dev/null +++ b/internal/translations/locales/de/messages.gotext.json @@ -0,0 +1,164 @@ +{ + "language": "de", + "messages": [ + { + "id": "Transferring {Entity} from {SourceName} to {TargetName}...", + "message": "Transferring {Entity} from {SourceName} to {TargetName}...", + "translation": "Übertrage {Entity} von {SourceName} nach {TargetName}...", + "placeholders": [ + { + "id": "Entity", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "c.entity" + }, + { + "id": "SourceName", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "c.sourceName" + }, + { + "id": "TargetName", + "string": "%[3]s", + "type": "string", + "underlyingType": "string", + "argNum": 3, + "expr": "c.targetName" + } + ] + }, + { + "id": "From timestamp: {Timestamp} ({Unix})", + "message": "From timestamp: {Timestamp} ({Unix})", + "translation": "Ab Zeitstempel: {Timestamp} ({Unix})", + "placeholders": [ + { + "id": "Timestamp", + "string": "%[1]v", + "type": "time.Time", + "underlyingType": "struct{wall uint64; ext int64; loc *time.Location}", + "argNum": 1, + "expr": "timestamp" + }, + { + "id": "Unix", + "string": "%[2]v", + "type": "int64", + "underlyingType": "int64", + "argNum": 2, + "expr": "timestamp.Unix()" + } + ] + }, + { + "id": "Import failed, last reported timestamp was {LastTimestamp} ({Unix})", + "message": "Import failed, last reported timestamp was {LastTimestamp} ({Unix})", + "translation": "Import fehlgeschlagen, der letzte Zeitstempel war {LastTimestamp} ({Unix})", + "placeholders": [ + { + "id": "LastTimestamp", + "string": "%[1]v", + "type": "time.Time", + "underlyingType": "struct{wall uint64; ext int64; loc *time.Location}", + "argNum": 1, + "expr": "result.LastTimestamp" + }, + { + "id": "Unix", + "string": "%[2]v", + "type": "int64", + "underlyingType": "int64", + "argNum": 2, + "expr": "result.LastTimestamp.Unix()" + } + ] + }, + { + "id": "Imported {ImportCount} of {TotalCount} {Entity} into {TargetName}.", + "message": "Imported {ImportCount} of {TotalCount} {Entity} into {TargetName}.", + "translation": "{ImportCount} von {TotalCount} {Entity} in {TargetName} importiert.", + "placeholders": [ + { + "id": "ImportCount", + "string": "%[1]v", + "type": "int", + "underlyingType": "int", + "argNum": 1, + "expr": "result.ImportCount" + }, + { + "id": "TotalCount", + "string": "%[2]v", + "type": "int", + "underlyingType": "int", + "argNum": 2, + "expr": "result.TotalCount" + }, + { + "id": "Entity", + "string": "%[3]s", + "type": "string", + "underlyingType": "string", + "argNum": 3, + "expr": "c.entity" + }, + { + "id": "TargetName", + "string": "%[4]v", + "type": "string", + "underlyingType": "string", + "argNum": 4, + "expr": "c.targetName" + } + ] + }, + { + "id": "During the import the following errors occurred:", + "message": "During the import the following errors occurred:", + "translation": "Während des Imports sind folgende Fehler aufgetreten:" + }, + { + "id": "Error: {Err}", + "message": "Error: {Err}", + "translation": "Fehler: {Err}", + "placeholders": [ + { + "id": "Err", + "string": "%[1]v", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "err" + } + ] + }, + { + "id": "Latest timestamp: {LastTimestamp} ({Unix})", + "message": "Latest timestamp: {LastTimestamp} ({Unix})", + "translation": "Neuester Zeitstempel: {LastTimestamp} ({Unix})", + "placeholders": [ + { + "id": "LastTimestamp", + "string": "%[1]v", + "type": "time.Time", + "underlyingType": "struct{wall uint64; ext int64; loc *time.Location}", + "argNum": 1, + "expr": "result.LastTimestamp" + }, + { + "id": "Unix", + "string": "%[2]v", + "type": "int64", + "underlyingType": "int64", + "argNum": 2, + "expr": "result.LastTimestamp.Unix()" + } + ] + } + ] +} diff --git a/internal/translations/locales/de/out.gotext.json b/internal/translations/locales/de/out.gotext.json new file mode 100644 index 0000000..6788b8a --- /dev/null +++ b/internal/translations/locales/de/out.gotext.json @@ -0,0 +1,164 @@ +{ + "language": "de", + "messages": [ + { + "id": "Transferring {Entity} from {SourceName} to {TargetName}...", + "message": "Transferring {Entity} from {SourceName} to {TargetName}...", + "translation": "Übertrage {Entity} von {SourceName} nach {TargetName}...", + "placeholders": [ + { + "id": "Entity", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "c.entity" + }, + { + "id": "SourceName", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "c.sourceName" + }, + { + "id": "TargetName", + "string": "%[3]s", + "type": "string", + "underlyingType": "string", + "argNum": 3, + "expr": "c.targetName" + } + ] + }, + { + "id": "From timestamp: {Timestamp} ({Unix})", + "message": "From timestamp: {Timestamp} ({Unix})", + "translation": "Ab Zeitstempel: {Timestamp} ({Unix})", + "placeholders": [ + { + "id": "Timestamp", + "string": "%[1]v", + "type": "time.Time", + "underlyingType": "struct{wall uint64; ext int64; loc *time.Location}", + "argNum": 1, + "expr": "timestamp" + }, + { + "id": "Unix", + "string": "%[2]v", + "type": "int64", + "underlyingType": "int64", + "argNum": 2, + "expr": "timestamp.Unix()" + } + ] + }, + { + "id": "Import failed, last reported timestamp was {LastTimestamp} ({Unix})", + "message": "Import failed, last reported timestamp was {LastTimestamp} ({Unix})", + "translation": "Import fehlgeschlagen, der letzte Zeitstempel war {LastTimestamp} ({Unix})", + "placeholders": [ + { + "id": "LastTimestamp", + "string": "%[1]v", + "type": "time.Time", + "underlyingType": "struct{wall uint64; ext int64; loc *time.Location}", + "argNum": 1, + "expr": "result.LastTimestamp" + }, + { + "id": "Unix", + "string": "%[2]v", + "type": "int64", + "underlyingType": "int64", + "argNum": 2, + "expr": "result.LastTimestamp.Unix()" + } + ] + }, + { + "id": "Imported {ImportCount} of {TotalCount} {Entity} into {TargetName}.", + "message": "Imported {ImportCount} of {TotalCount} {Entity} into {TargetName}.", + "translation": "{ImportCount} von {TotalCount} {Entity} in {TargetName} importiert.", + "placeholders": [ + { + "id": "ImportCount", + "string": "%[1]v", + "type": "int", + "underlyingType": "int", + "argNum": 1, + "expr": "result.ImportCount" + }, + { + "id": "TotalCount", + "string": "%[2]v", + "type": "int", + "underlyingType": "int", + "argNum": 2, + "expr": "result.TotalCount" + }, + { + "id": "Entity", + "string": "%[3]s", + "type": "string", + "underlyingType": "string", + "argNum": 3, + "expr": "c.entity" + }, + { + "id": "TargetName", + "string": "%[4]v", + "type": "string", + "underlyingType": "string", + "argNum": 4, + "expr": "c.targetName" + } + ] + }, + { + "id": "During the import the following errors occurred:", + "message": "During the import the following errors occurred:", + "translation": "Während des Imports sind folgende Fehler aufgetreten:" + }, + { + "id": "Error: {Err}", + "message": "Error: {Err}", + "translation": "Fehler: {Err}", + "placeholders": [ + { + "id": "Err", + "string": "%[1]v", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "err" + } + ] + }, + { + "id": "Latest timestamp: {LastTimestamp} ({Unix})", + "message": "Latest timestamp: {LastTimestamp} ({Unix})", + "translation": "Neuester Zeitstempel: {LastTimestamp} ({Unix})", + "placeholders": [ + { + "id": "LastTimestamp", + "string": "%[1]v", + "type": "time.Time", + "underlyingType": "struct{wall uint64; ext int64; loc *time.Location}", + "argNum": 1, + "expr": "result.LastTimestamp" + }, + { + "id": "Unix", + "string": "%[2]v", + "type": "int64", + "underlyingType": "int64", + "argNum": 2, + "expr": "result.LastTimestamp.Unix()" + } + ] + } + ] +} \ No newline at end of file diff --git a/internal/translations/locales/en/out.gotext.json b/internal/translations/locales/en/out.gotext.json new file mode 100644 index 0000000..44e776d --- /dev/null +++ b/internal/translations/locales/en/out.gotext.json @@ -0,0 +1,178 @@ +{ + "language": "en", + "messages": [ + { + "id": "Transferring {Entity} from {SourceName} to {TargetName}...", + "message": "Transferring {Entity} from {SourceName} to {TargetName}...", + "translation": "Transferring {Entity} from {SourceName} to {TargetName}...", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "Entity", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "c.entity" + }, + { + "id": "SourceName", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "c.sourceName" + }, + { + "id": "TargetName", + "string": "%[3]s", + "type": "string", + "underlyingType": "string", + "argNum": 3, + "expr": "c.targetName" + } + ], + "fuzzy": true + }, + { + "id": "From timestamp: {Timestamp} ({Unix})", + "message": "From timestamp: {Timestamp} ({Unix})", + "translation": "From timestamp: {Timestamp} ({Unix})", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "Timestamp", + "string": "%[1]v", + "type": "time.Time", + "underlyingType": "struct{wall uint64; ext int64; loc *time.Location}", + "argNum": 1, + "expr": "timestamp" + }, + { + "id": "Unix", + "string": "%[2]v", + "type": "int64", + "underlyingType": "int64", + "argNum": 2, + "expr": "timestamp.Unix()" + } + ], + "fuzzy": true + }, + { + "id": "Import failed, last reported timestamp was {LastTimestamp} ({Unix})", + "message": "Import failed, last reported timestamp was {LastTimestamp} ({Unix})", + "translation": "Import failed, last reported timestamp was {LastTimestamp} ({Unix})", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "LastTimestamp", + "string": "%[1]v", + "type": "time.Time", + "underlyingType": "struct{wall uint64; ext int64; loc *time.Location}", + "argNum": 1, + "expr": "result.LastTimestamp" + }, + { + "id": "Unix", + "string": "%[2]v", + "type": "int64", + "underlyingType": "int64", + "argNum": 2, + "expr": "result.LastTimestamp.Unix()" + } + ], + "fuzzy": true + }, + { + "id": "Imported {ImportCount} of {TotalCount} {Entity} into {TargetName}.", + "message": "Imported {ImportCount} of {TotalCount} {Entity} into {TargetName}.", + "translation": "Imported {ImportCount} of {TotalCount} {Entity} into {TargetName}.", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "ImportCount", + "string": "%[1]v", + "type": "int", + "underlyingType": "int", + "argNum": 1, + "expr": "result.ImportCount" + }, + { + "id": "TotalCount", + "string": "%[2]v", + "type": "int", + "underlyingType": "int", + "argNum": 2, + "expr": "result.TotalCount" + }, + { + "id": "Entity", + "string": "%[3]s", + "type": "string", + "underlyingType": "string", + "argNum": 3, + "expr": "c.entity" + }, + { + "id": "TargetName", + "string": "%[4]v", + "type": "string", + "underlyingType": "string", + "argNum": 4, + "expr": "c.targetName" + } + ], + "fuzzy": true + }, + { + "id": "During the import the following errors occurred:", + "message": "During the import the following errors occurred:", + "translation": "During the import the following errors occurred:", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Error: {Err}", + "message": "Error: {Err}", + "translation": "Error: {Err}", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "Err", + "string": "%[1]v", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "err" + } + ], + "fuzzy": true + }, + { + "id": "Latest timestamp: {LastTimestamp} ({Unix})", + "message": "Latest timestamp: {LastTimestamp} ({Unix})", + "translation": "Latest timestamp: {LastTimestamp} ({Unix})", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "LastTimestamp", + "string": "%[1]v", + "type": "time.Time", + "underlyingType": "struct{wall uint64; ext int64; loc *time.Location}", + "argNum": 1, + "expr": "result.LastTimestamp" + }, + { + "id": "Unix", + "string": "%[2]v", + "type": "int64", + "underlyingType": "int64", + "argNum": 2, + "expr": "result.LastTimestamp.Unix()" + } + ], + "fuzzy": true + } + ] +} \ No newline at end of file diff --git a/internal/translations/translations.go b/internal/translations/translations.go new file mode 100644 index 0000000..76173f6 --- /dev/null +++ b/internal/translations/translations.go @@ -0,0 +1,18 @@ +/* +Copyright © 2023 Philipp Wolfer + +Scotty is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later version. + +Scotty is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +Scotty. If not, see . +*/ + +package translations + +//go:generate gotext -srclang=en update -out=catalog.go -lang=en,de go.uploadedlobster.com/scotty