diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 29 | ||||
-rw-r--r-- | README.md | 26 | ||||
-rw-r--r-- | catalog.go | 115 | ||||
-rw-r--r-- | locales/en-US/messages.gotext.json | 181 | ||||
-rw-r--r-- | locales/es-ES/messages.gotext.json | 169 | ||||
-rw-r--r-- | main.go | 14 | ||||
-rw-r--r-- | notificator.go | 6 | ||||
-rw-r--r-- | systray.go | 34 |
9 files changed, 552 insertions, 23 deletions
@@ -1,2 +1,3 @@ bitmask-systray +locales/*/out.gotext.json .*.swp diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9699c47 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +.PHONY: all build icon locales generate_locales clean + +all: icon locales build + +build: icon catalog.go + go build + +clean: + make -C icon clean + rm bitmask-systray + +icon: + make -C icon + + +LANGS ?= $(foreach path,$(wildcard locales/*/messages.gotext.json),$(patsubst locales/%/messages.gotext.json,%,$(path))) +empty := +space := $(empty) $(empty) +lang_list := $(subst $(space),,$(foreach lang,$(LANGS),$(lang),)) + +locales: catalog.go + +generate_locales: $(foreach lang,$(LANGS),locales/$(lang)/out.gotext.json) + +locales/%/out.gotext.json: systray.go notificator.go + gotext update -lang=$* + +catalog.go: $(foreach lang,$(LANGS),locales/$(lang)/messages.gotext.json) + gotext update -lang=$(lang_list) -out catalog.go @@ -14,10 +14,9 @@ Build the systray: $ go build ``` -Run bitmask and the systray: +To be able to build the assets you'll need: ``` - $ bitmaskd - $ ./bitmask-systray + $ go get -u golang.org/x/text/cmd/gotext github.com/cratonica/2goarray ``` OSX @@ -35,3 +34,24 @@ Using homebrew: Run it ------------- bitmask-systray assumes that you already have bitmaskd running. + +Run bitmask and the systray: +``` + $ bitmaskd + $ ./bitmask-systray +``` + +i18n +---- + +Generate `locales/*` files: +``` + $ make generate_locales LANGS="sjn tlh" +``` + +Edit the `locales/*/out.gotext.json` translations into `locales/*/messages.gotext.json`. + +To rebuild the locales: +``` + $ make locales +``` diff --git a/catalog.go b/catalog.go new file mode 100644 index 0000000..80f55b3 --- /dev/null +++ b/catalog.go @@ -0,0 +1,115 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package main + +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 := messageKeyToIndex[key] + 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{ + "en_US": &dictionary{index: en_USIndex, data: en_USData}, + "es_ES": &dictionary{index: es_ESIndex, data: es_ESData}, + } + fallback := language.MustParse("en-US") + cat, err := catalog.NewFromMap(dict, catalog.Fallback(fallback)) + if err != nil { + panic(err) + } + message.DefaultCatalog = cat +} + +var messageKeyToIndex = map[string]int{ + "... I have donated": 15, + "About ...": 16, + "Can't contact bitmask": 2, + "Cancel": 11, + "Cancel connection to RiseupVPN": 12, + "Checking status...": 6, + "Could not find a polkit authentication agent. Please run one and try again.": 5, + "Donate ...": 14, + "Donate to RiseupVPN": 0, + "Help ...": 13, + "Is bitmaskd running? Start bitmask and try again.": 3, + "Missing authentication agent": 4, + "Quit": 17, + "Quit BitmaskVPN": 18, + "Retry": 21, + "RiseupVPN is %v": 23, + "Route traffic through": 19, + "The RiseupVPN service is expensive to run. Because we don't want to store personal information about you, there is no accounts or billing for this service. But if you want the service to continue, donate at least $5 each month at https://riseup.net/donate-vpn": 1, + "Turn RiseupVPN off": 10, + "Turn RiseupVPN on": 8, + "Turn off": 9, + "Turn on": 7, + "Use RiseupVPN %v gateway": 20, + "VPN is %v": 24, + "blocking internet": 22, +} + +var en_USIndex = []uint32{ // 26 elements + 0x00000000, 0x00000014, 0x00000118, 0x0000012e, + 0x00000160, 0x0000017d, 0x000001c9, 0x000001dc, + 0x000001e4, 0x000001f6, 0x000001ff, 0x00000212, + 0x00000219, 0x00000238, 0x00000241, 0x00000250, + 0x00000263, 0x0000026d, 0x00000272, 0x00000282, + 0x00000298, 0x000002b4, 0x000002ba, 0x000002cc, + 0x000002df, 0x000002ec, +} // Size: 128 bytes + +const en_USData string = "" + // Size: 748 bytes + "\x02Donate to RiseupVPN\x02The RiseupVPN service is expensive to run. Be" + + "cause we don't want to store personal information about you, there is no" + + " accounts or billing for this service. But if you want the service to co" + + "ntinue, donate at least $5 each month at https://riseup.net/donate-vpn" + + "\x02Can't contact bitmask\x02Is bitmaskd running? Start bitmask and try " + + "again.\x02Missing authentication agent\x02Could not find a polkit authen" + + "tication agent. Please run one and try again.\x02Checking status...\x02T" + + "urn on\x02Turn RiseupVPN on\x02Turn off\x02Turn RiseupVPN off\x02Cancel" + + "\x02Cancel connection to RiseupVPN\x02Help ...\x02Donate ...!!!!\x02... " + + "I have donated\x02About ...\x02Quit\x02Quit BitmaskVPN\x02Route traffic " + + "through\x02Use RiseupVPN %[1]v gateway\x02Retry\x02blocking internet\x02" + + "RiseupVPN is %[1]v\x02VPN is %[1]v" + +var es_ESIndex = []uint32{ // 26 elements + 0x00000000, 0x00000011, 0x00000107, 0x00000124, + 0x00000164, 0x00000186, 0x000001e9, 0x00000202, + 0x0000020b, 0x0000021e, 0x00000225, 0x00000235, + 0x0000023e, 0x0000025f, 0x00000269, 0x00000272, + 0x00000283, 0x00000291, 0x00000298, 0x000002aa, + 0x000002bc, 0x000002e0, 0x000002eb, 0x000002fe, + 0x00000313, 0x00000322, +} // Size: 128 bytes + +const es_ESData string = "" + // Size: 802 bytes + "\x02Dona a RiseupVPN\x02El servicio RiseupVPN es caro de mantener. Como " + + "no queremos guardar ninguna información personal tuya, no hay cuentas ni" + + " servicio de facturación. Si quieres que este servicio continue, dona al" + + " menos $5 cada mes en https://riseup.net/donate-vpn\x02No puedo contacta" + + "r a bitmask\x02¿Esta bitmask en ejecucion? Arranca bitmask y prueba de n" + + "uevo.\x02Falta el agente de autenticación\x02No pude encontrar ningún ag" + + "ente de autenticacion polkit. Por favor ejecuta uno y prueba de nuevo." + + "\x02Comprobando el estado...\x02Encender\x02Enciende RiseupVPN\x02Apagar" + + "\x02Apaga RiseupVPN\x02Cancelar\x02Cancela la conexión a RiseupVPN\x02Ay" + + "uda ...\x02Dona ...\x02... ya he donado\x02Acerca de ...\x02Cerrar\x02Ci" + + "erra BitmaskVPN\x02Salir a traves de\x02Usa la salida de RiseupVPN en %[" + + "1]v\x02Reintentar\x02internet bloqueado\x02RiseupVPN esta %[1]v\x02VPN e" + + "sta %[1]v" + + // Total table size 1806 bytes (1KiB); checksum: 85661B86 diff --git a/locales/en-US/messages.gotext.json b/locales/en-US/messages.gotext.json new file mode 100644 index 0000000..1559f61 --- /dev/null +++ b/locales/en-US/messages.gotext.json @@ -0,0 +1,181 @@ +{ + "language": "en-US", + "messages": [ + { + "id": "Donate to RiseupVPN", + "message": "Donate to RiseupVPN", + "translation": "Donate to RiseupVPN", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": [ + "donationText", + "The RiseupVPN service is expensive to run. Because we don't want to store personal information about you, there is no accounts or billing for this service. But if you want the service to continue, donate at least $5 each month at https://riseup.net/donate-vpn" + ], + "message": "The RiseupVPN service is expensive to run. Because we don't want to store personal information about you, there is no accounts or billing for this service. But if you want the service to continue, donate at least $5 each month at https://riseup.net/donate-vpn", + "translation": "The RiseupVPN service is expensive to run. Because we don't want to store personal information about you, there is no accounts or billing for this service. But if you want the service to continue, donate at least $5 each month at https://riseup.net/donate-vpn", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Can't contact bitmask", + "message": "Can't contact bitmask", + "translation": "Can't contact bitmask", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": [ + "notRunning", + "Is bitmaskd running? Start bitmask and try again." + ], + "message": "Is bitmaskd running? Start bitmask and try again.", + "translation": "Is bitmaskd running? Start bitmask and try again.", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Missing authentication agent", + "message": "Missing authentication agent", + "translation": "Missing authentication agent", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": [ + "missingAuthAgent", + "Could not find a polkit authentication agent. Please run one and try again." + ], + "message": "Could not find a polkit authentication agent. Please run one and try again.", + "translation": "Could not find a polkit authentication agent. Please run one and try again.", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Checking status...", + "message": "Checking status...", + "translation": "Checking status..." + }, + { + "id": "Turn on", + "message": "Turn on", + "translation": "Turn on" + }, + { + "id": "Turn RiseupVPN on", + "message": "Turn RiseupVPN on", + "translation": "Turn RiseupVPN on" + }, + { + "id": "Turn off", + "message": "Turn off", + "translation": "Turn off" + }, + { + "id": "Turn RiseupVPN off", + "message": "Turn RiseupVPN off", + "translation": "Turn RiseupVPN off" + }, + { + "id": "Cancel", + "message": "Cancel", + "translation": "Cancel" + }, + { + "id": "Cancel connection to RiseupVPN", + "message": "Cancel connection to RiseupVPN", + "translation": "Cancel connection to RiseupVPN" + }, + { + "id": "Help ...", + "message": "Help ...", + "translation": "Help ..." + }, + { + "id": "Donate ...", + "message": "Donate ...", + "translation": "Donate ...!!!!" + }, + { + "id": "... I have donated", + "message": "... I have donated", + "translation": "... I have donated" + }, + { + "id": "About ...", + "message": "About ...", + "translation": "About ..." + }, + { + "id": "Quit", + "message": "Quit", + "translation": "Quit" + }, + { + "id": "Quit BitmaskVPN", + "message": "Quit BitmaskVPN", + "translation": "Quit BitmaskVPN" + }, + { + "id": "Route traffic through", + "message": "Route traffic through", + "translation": "Route traffic through" + }, + { + "id": "Use RiseupVPN {Name} gateway", + "message": "Use RiseupVPN {Name} gateway", + "translation": "Use RiseupVPN {Name} gateway", + "placeholders": [ + { + "id": "Name", + "string": "%[1]v", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "name" + } + ] + }, + { + "id": "Retry", + "message": "Retry", + "translation": "Retry" + }, + { + "id": "blocking internet", + "message": "blocking internet", + "translation": "blocking internet" + }, + { + "id": "RiseupVPN is {StatusStr}", + "message": "RiseupVPN is {StatusStr}", + "translation": "RiseupVPN is {StatusStr}", + "placeholders": [ + { + "id": "StatusStr", + "string": "%[1]v", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "statusStr" + } + ] + }, + { + "id": "VPN is {StatusStr}", + "message": "VPN is {StatusStr}", + "translation": "VPN is {StatusStr}", + "placeholders": [ + { + "id": "StatusStr", + "string": "%[1]v", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "statusStr" + } + ] + } + ] +} diff --git a/locales/es-ES/messages.gotext.json b/locales/es-ES/messages.gotext.json new file mode 100644 index 0000000..3960c2d --- /dev/null +++ b/locales/es-ES/messages.gotext.json @@ -0,0 +1,169 @@ +{ + "language": "es-ES", + "messages": [ + { + "id": "Donate to RiseupVPN", + "message": "Donate to RiseupVPN", + "translation": "Dona a RiseupVPN" + }, + { + "id": [ + "donationText", + "The RiseupVPN service is expensive to run. Because we don't want to store personal information about you, there is no accounts or billing for this service. But if you want the service to continue, donate at least $5 each month at https://riseup.net/donate-vpn" + ], + "message": "The RiseupVPN service is expensive to run. Because we don't want to store personal information about you, there is no accounts or billing for this service. But if you want the service to continue, donate at least $5 each month at https://riseup.net/donate-vpn", + "translation": "El servicio RiseupVPN es caro de mantener. Como no queremos guardar ninguna información personal tuya, no hay cuentas ni servicio de facturación. Si quieres que este servicio continue, dona al menos $5 cada mes en https://riseup.net/donate-vpn" + }, + { + "id": "Can't contact bitmask", + "message": "Can't contact bitmask", + "translation": "No puedo contactar a bitmask" + }, + { + "id": [ + "notRunning", + "Is bitmaskd running? Start bitmask and try again." + ], + "message": "Is bitmaskd running? Start bitmask and try again.", + "translation": "¿Esta bitmask en ejecucion? Arranca bitmask y prueba de nuevo." + }, + { + "id": "Missing authentication agent", + "message": "Missing authentication agent", + "translation": "Falta el agente de autenticación" + }, + { + "id": [ + "missingAuthAgent", + "Could not find a polkit authentication agent. Please run one and try again." + ], + "message": "Could not find a polkit authentication agent. Please run one and try again.", + "translation": "No pude encontrar ningún agente de autenticacion polkit. Por favor ejecuta uno y prueba de nuevo." + }, + { + "id": "Checking status...", + "message": "Checking status...", + "translation": "Comprobando el estado..." + }, + { + "id": "Turn on", + "message": "Turn on", + "translation": "Encender" + }, + { + "id": "Turn RiseupVPN on", + "message": "Turn RiseupVPN on", + "translation": "Enciende RiseupVPN" + }, + { + "id": "Turn off", + "message": "Turn off", + "translation": "Apagar" + }, + { + "id": "Turn RiseupVPN off", + "message": "Turn RiseupVPN off", + "translation": "Apaga RiseupVPN" + }, + { + "id": "Cancel", + "message": "Cancel", + "translation": "Cancelar" + }, + { + "id": "Cancel connection to RiseupVPN", + "message": "Cancel connection to RiseupVPN", + "translation": "Cancela la conexión a RiseupVPN" + }, + { + "id": "Help ...", + "message": "Help ...", + "translation": "Ayuda ..." + }, + { + "id": "Donate ...", + "message": "Donate ...", + "translation": "Dona ..." + }, + { + "id": "... I have donated", + "message": "... I have donated", + "translation": "... ya he donado" + }, + { + "id": "About ...", + "message": "About ...", + "translation": "Acerca de ..." + }, + { + "id": "Quit", + "message": "Quit", + "translation": "Cerrar" + }, + { + "id": "Quit BitmaskVPN", + "message": "Quit BitmaskVPN", + "translation": "Cierra BitmaskVPN" + }, + { + "id": "Route traffic through", + "message": "Route traffic through", + "translation": "Salir a traves de" + }, + { + "id": "Use RiseupVPN {Name} gateway", + "message": "Use RiskieupVPN {Name} gateway", + "translation": "Usa la salida de RiseupVPN en {Name}", + "placeholders": [ + { + "id": "Name", + "string": "%[1]v", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "name" + } + ] + }, + { + "id": "Retry", + "message": "Retry", + "translation": "Reintentar" + }, + { + "id": "blocking internet", + "message": "blocking internet", + "translation": "internet bloqueado" + }, + { + "id": "RiseupVPN is {StatusStr}", + "message": "RiseupVPN is {StatusStr}", + "translation": "RiseupVPN esta {StatusStr}", + "placeholders": [ + { + "id": "StatusStr", + "string": "%[1]v", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "statusStr" + } + ] + }, + { + "id": "VPN is {StatusStr}", + "message": "VPN is {StatusStr}", + "translation": "VPN esta {StatusStr}", + "placeholders": [ + { + "id": "StatusStr", + "string": "%[1]v", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "statusStr" + } + ] + } + ] +} @@ -19,17 +19,22 @@ import ( "log" "0xacab.org/leap/bitmask-systray/bitmask" + "github.com/jmshal/go-locale" + "golang.org/x/text/message" ) const ( provider = "riseup.net" ) +var printer *message.Printer + func main() { conf, err := parseConfig() if err != nil { log.Fatal(err) } + initPrinter() notify := newNotificator(conf) @@ -60,3 +65,12 @@ func checkAndInstallHelpers(b *bitmask.Bitmask, notify *notificator) { } } } + +func initPrinter() { + locale, err := go_locale.DetectLocale() + if err != nil { + log.Println("Error detecting the system locale: ", err) + } + + printer = message.NewPrinter(message.MatchLanguage(locale, "en")) +} diff --git a/notificator.go b/notificator.go index 375b883..cf24797 100644 --- a/notificator.go +++ b/notificator.go @@ -49,7 +49,7 @@ func (n *notificator) donations() { time.Sleep(time.Minute * 5) for { if n.conf.needsNotification() { - n.notify.Push("Donate to RiseupVPN", donationText, "", notif.UR_NORMAL) + n.notify.Push(printer.Sprintf("Donate to RiseupVPN"), printer.Sprintf(donationText), "", notif.UR_NORMAL) n.conf.setNotification() } time.Sleep(time.Hour) @@ -57,9 +57,9 @@ func (n *notificator) donations() { } func (n *notificator) bitmaskNotRunning() { - n.notify.Push("Can't contact bitmask", notRunning, "", notif.UR_CRITICAL) + n.notify.Push(printer.Sprintf("Can't contact bitmask"), printer.Sprintf(notRunning), "", notif.UR_CRITICAL) } func (n *notificator) authAgent() { - n.notify.Push("Missing authentication agent", missingAuthAgent, "", notif.UR_CRITICAL) + n.notify.Push(printer.Sprintf("Missing authentication agent"), printer.Sprintf(missingAuthAgent), "", notif.UR_CRITICAL) } @@ -55,13 +55,13 @@ func (bt bmTray) onExit() { } func (bt *bmTray) onReady() { - bt.mStatus = systray.AddMenuItem("Checking status...", "") + bt.mStatus = systray.AddMenuItem(printer.Sprintf("Checking status..."), "") bt.mStatus.Disable() - bt.mTurnOn = systray.AddMenuItem("Turn on", "Turn RiseupVPN on") + bt.mTurnOn = systray.AddMenuItem(printer.Sprintf("Turn on"), printer.Sprintf("Turn RiseupVPN on")) go bt.mTurnOn.Hide() - bt.mTurnOff = systray.AddMenuItem("Turn off", "Turn RiseupVPN off") + bt.mTurnOff = systray.AddMenuItem(printer.Sprintf("Turn off"), printer.Sprintf("Turn RiseupVPN off")) go bt.mTurnOff.Hide() - bt.mCancel = systray.AddMenuItem("Cancel", "Cancel connection to RiseupVPN") + bt.mCancel = systray.AddMenuItem(printer.Sprintf("Cancel"), printer.Sprintf("Cancel connection to RiseupVPN")) go bt.mCancel.Hide() systray.AddSeparator() @@ -69,13 +69,13 @@ func (bt *bmTray) onReady() { bt.addGateways() } - mHelp := systray.AddMenuItem("Help ...", "") - bt.mDonate = systray.AddMenuItem("Donate ...", "") - bt.mHaveDonated = systray.AddMenuItem("... I have donated", "") - mAbout := systray.AddMenuItem("About ...", "") + mHelp := systray.AddMenuItem(printer.Sprintf("Help ..."), "") + bt.mDonate = systray.AddMenuItem(printer.Sprintf("Donate ..."), "") + bt.mHaveDonated = systray.AddMenuItem(printer.Sprintf("... I have donated"), "") + mAbout := systray.AddMenuItem(printer.Sprintf("About ..."), "") systray.AddSeparator() - mQuit := systray.AddMenuItem("Quit", "Quit BitmaskVPN") + mQuit := systray.AddMenuItem(printer.Sprintf("Quit"), printer.Sprintf("Quit BitmaskVPN")) go func() { ch := bt.bm.GetStatusCh() @@ -131,10 +131,10 @@ func (bt *bmTray) addGateways() { return } - mGateway := systray.AddMenuItem("Route traffic through", "") + mGateway := systray.AddMenuItem(printer.Sprintf("Route traffic through"), "") mGateway.Disable() for i, name := range gatewayList { - menuItem := systray.AddMenuItem(name, "Use RiseupVPN "+name+" gateway") + menuItem := systray.AddMenuItem(name, printer.Sprintf("Use RiseupVPN %v gateway", name)) gateway := gatewayTray{menuItem, name} if i == 0 { @@ -166,7 +166,7 @@ func (bt *bmTray) addGateways() { func (bt *bmTray) changeStatus(status string) { // TODO: ugly hacks with 'go' to hide/show statusStr := status - bt.mTurnOn.SetTitle("Turn on") + bt.mTurnOn.SetTitle(printer.Sprintf("Turn on")) if bt.waitCh != nil { bt.waitCh <- true bt.waitCh = nil @@ -201,16 +201,16 @@ func (bt *bmTray) changeStatus(status string) { case "failed": systray.SetIcon(icon.Blocked) - bt.mTurnOn.SetTitle("Retry") + bt.mTurnOn.SetTitle(printer.Sprintf("Retry")) go bt.mTurnOn.Show() go bt.mTurnOff.Show() go bt.mCancel.Hide() - statusStr = "blocking internet" + statusStr = printer.Sprintf("blocking internet") } - systray.SetTooltip("RiseupVPN is " + statusStr) - bt.mStatus.SetTitle("VPN is " + statusStr) - bt.mStatus.SetTooltip("RiseupVPN is " + statusStr) + systray.SetTooltip(printer.Sprintf("RiseupVPN is %v", statusStr)) + bt.mStatus.SetTitle(printer.Sprintf("VPN is %v", statusStr)) + bt.mStatus.SetTooltip(printer.Sprintf("RiseupVPN is %v", statusStr)) } func (bt *bmTray) updateDonateMenu() { |